140 lines
16 KiB
Markdown
140 lines
16 KiB
Markdown
# AGENTS.md — рабочие инструкции pnd8_app
|
||
|
||
Версия: 2026-08-10
|
||
Кодировка: UTF-8
|
||
|
||
## Назначение
|
||
|
||
- Этот файл — входная карта проекта для AI-ассистентов и разработчиков.
|
||
- Перед нетривиальной правкой сначала изучить затрагиваемый модуль, соседний модуль того же типа и связанные XML/шаблоны/миграции.
|
||
- Новые устойчивые правила проекта добавлять сюда. Не превращать файл в журнал реализации отдельных задач.
|
||
- Не удалять и не откатывать чужие изменения в dirty worktree без явного запроса.
|
||
- Не хранить в этом файле пароли, токены, API-ключи и другие секреты.
|
||
|
||
## Контекст проекта
|
||
|
||
`pnd8_app` — веб-приложение для поиска участка обслуживания ПНД по адресу и показа врачей с расписанием приёма.
|
||
|
||
Основной пользовательский сценарий:
|
||
|
||
1. Пользователь вводит адрес на публичной странице.
|
||
2. Яндекс Карты определяют координаты.
|
||
3. Приложение находит содержащий точку полигон `pnd_zone_geometry`.
|
||
4. Через `zone_id` загружаются участок `pnd_zones` и врачи `pnd_doctors`.
|
||
5. Расписание врача читается из JSON-поля `schedule` и отображается/печатается.
|
||
|
||
Данные врачей, участков и расписаний синхронизируются из внешней старой МИС cron-скриптом. FAQ, документы и статические страницы управляются через собственный движок и админку.
|
||
|
||
## Стек
|
||
|
||
- PHP 7.4 FPM и Composer 2.
|
||
- Собственный legacy PHP-фреймворк: `module`, `cat`, `cobject`, XML-компоновка, legacy `.htm` и BladeOne.
|
||
- MariaDB 10.6.21 в текущем `docker-compose.yml`; слой доступа к БД — собственный `db`/`cobject` поверх `mysqli`.
|
||
- Nginx 1.24, Docker Compose, phpMyAdmin.
|
||
- Публичный frontend: Bootstrap 4, jQuery 3.4.1, Font Awesome 5, Яндекс Карты и Suggest API.
|
||
- PHP CS Fixer подключён как Composer-зависимость; автоматизированного тестового набора в репозитории сейчас нет.
|
||
|
||
Не применять синтаксис и API PHP 8.x. Не обновлять версии runtime, Composer-зависимостей или frontend-библиотек попутно с прикладной задачей.
|
||
|
||
## Карта проекта
|
||
|
||
- `app/` — код приложения; в контейнерах монтируется в `/var/www/html`.
|
||
- `app/public_html/` — фактический web root и публичная точка входа `index.php`.
|
||
- `app/public_html/admin/` — точка входа админки.
|
||
- `app/public_html/assets/` — публичные CSS, JS, SCSS, шрифты и генератор статических include-файлов.
|
||
- `app/engine/bootstrap.php` — общая загрузка конфигурации, БД, ядра и BladeOne.
|
||
- `app/engine/core/` — ядро, `cobject`, БД, формы, фильтры, роутинг и типы атрибутов.
|
||
- `app/engine/www/modules/` — контроллеры публичной части.
|
||
- `app/engine/www/bladetpl/` — Blade-шаблоны публичной части.
|
||
- `app/engine/www/tpls/` — legacy-шаблоны и XML include-файлы публичной части.
|
||
- `app/engine/www/xml/` — XML-компоновка публичных категорий.
|
||
- `app/engine/admin/modules/`, `bladetpl/`, `tpls/`, `xml/` — соответствующие части админки.
|
||
- `app/engine/migrations/` — плоский каталог SQL-миграций и исполнитель `_migrate.php`.
|
||
- `app/engine/cron/data_sync/` — импорт врачей, участков и расписания из внешней МИС.
|
||
- `app/config/` — конфигурация и подключения приложения; считать содержимое чувствительным.
|
||
- `config/`, `docker/`, `docker-compose.yml` — инфраструктура контейнеров.
|
||
- `db/`, `logs/`, `sessions/` — runtime-данные; не редактировать и не добавлять в Git.
|
||
- `Договор/`, архивы и дампы в корне — не код приложения; не открывать и не изменять без прямой необходимости задачи.
|
||
|
||
README унаследован от Bambolo и местами устарел: в этом репозитории web root называется `public_html`, а текущий Compose содержит только `php`, `nginx`, `mariadb` и `phpmyadmin`. Проверять фактическую конфигурацию, а не слепо следовать README или `deploy.cmd`.
|
||
|
||
## Архитектурные правила
|
||
|
||
- Сначала искать аналогичный существующий модуль и сохранять принятый проектом паттерн.
|
||
- У модуля параметры запроса явно перечислять в `$_get_vars`, `$_post_vars` и `$_loc_vars`; внутри action использовать `$this->имяПараметра`.
|
||
- Action этого движка реализуются методами `_on_*`/`_ajax_*`; не смешивать несвязанные action и представления в одном шаблоне.
|
||
- Для Blade использовать общий `$blade` через `global $blade` и `$blade->run($this->getBladeTempl(...), $data)`.
|
||
- Для текущей категории использовать `global $cat` и `$cat->cat`, для редиректа — `_redirect()`.
|
||
- Не использовать `$GLOBALS[...]` и не добавлять новый прямой доступ к `$_REQUEST`.
|
||
- Бизнес-вычисления и SQL готовить в PHP-модуле; в Blade оставлять преимущественно отображение. При доработке существующего шаблона постепенно выносить сложную подготовку данных, если это входит в задачу.
|
||
- Не вводить новый фреймворк, ORM или сборщик ради локальной правки.
|
||
- Сохранять обратную совместимость публичных URL, XML-категорий и связки `module -> XML/category -> template`.
|
||
|
||
## База данных и миграции
|
||
|
||
- Перед изменением сущности проверить таблицу, `_sys_datatypes`, использующие её модули и предыдущие миграции.
|
||
- Любое изменение схемы или системных метаданных оформлять новым `.sql` в `app/engine/migrations/`; уже применённые миграции не переписывать.
|
||
- Имена новых миграций продолжать в существующем формате `YYYYMMDD-HHMM-description.sql` и обеспечивать уникальность имени.
|
||
- Исполнитель миграций примитивно делит SQL по `;` перед переводом строки. Не добавлять процедуры, триггеры или конструкции с внутренними `;` без предварительной доработки/проверки runner.
|
||
- SQL строить с приведением числовых значений через `(int)`/`intval()` и экранированием строк через `db_escape_string()`. Предпочитать методы `cobject`, когда они покрывают операцию.
|
||
- Не использовать `REPLACE INTO`; для upsert применять `INSERT ... ON DUPLICATE KEY UPDATE` либо явные `UPDATE`/`INSERT`.
|
||
- Геометрия зон хранится как MySQL spatial `POLYGON`. Сохранять действующий порядок координат и замыкать контур; проверять поиск точки через `ST_WITHIN`.
|
||
- Не запускать миграции на production и не импортировать дампы без явного запроса.
|
||
|
||
## Синхронизация с МИС
|
||
|
||
- `sync_doctors_and_zones.php` — потенциально разрушительная операция: она создаёт временные таблицы, очищает основные `pnd_zones`/`pnd_doctors`, переносит данные и удаляет временные таблицы.
|
||
- Не запускать этот скрипт автоматически для проверки. Сначала использовать режим dry-run или отдельную тестовую БД и явно проверить подключения.
|
||
- После миграции МИС рабочие слоты врачей находятся в `SimpleSchedule`; старую цепочку `Event`/`Action`/`ActionProperty_Time` для расписания не использовать.
|
||
- Рабочее время дня вычислять по всем действующим амбулаторным слотам `SimpleSchedule`, независимо от `ticket`. Исключать удалённые, отключённые, сверхурочные и нулевые слоты, а также строки с `absence_reason`.
|
||
- `SimpleSchedule.ticket` ссылается на `TicketInfo.id`; `NULL` означает свободный слот. Для синхронизации только рабочих часов `TicketInfo` не читать и пациентские данные не переносить.
|
||
- ID врачей и участков сейчас совпадают с внешними ID старой МИС. Не менять эту семантику без миграционного плана.
|
||
- Поле `pnd_doctors.schedule` содержит JSON вида `YYYY-MM-DD => {start, end}` либо `null`; при изменениях сохранять обратную совместимость формата.
|
||
- Расписание формируется на 10 дней, включая текущий. Проверять границы дат, отсутствие приёма и часовой пояс `Europe/Moscow`.
|
||
- Не добавлять новые реквизиты подключения в код. Обнаруженные hardcoded-пароли и API-ключи не копировать в логи, ответы, документацию или новые файлы; при отдельной задаче переносить их в переменные окружения.
|
||
|
||
## UI и шаблоны
|
||
|
||
- Админка и публичная часть используют Bootstrap 4; не применять классы и `data-bs-*` из Bootstrap 5.
|
||
- Использовать существующие jQuery/Bootstrap/Font Awesome 5 и визуальные паттерны соседних шаблонов.
|
||
- Сохранять адаптивность крупного адресного поля, списка подсказок, модального результата и печати.
|
||
- Для изменений карты проверять оба сценария: выбор адреса по координатам и клик по полигону.
|
||
- Пользовательские и внешние строки не конкатенировать в HTML без экранирования. В Blade по умолчанию использовать `{{ ... }}`, а `{!! ... !!}` — только для заранее подготовленного доверенного содержимого.
|
||
- Не коммитить скомпилированные файлы из `app/engine/*/bladetpl/cache/`, если задача прямо не требует обновления уже отслеживаемых артефактов.
|
||
- После изменения перечня CSS/JS или исходной статики пересобрать include-файлы соответствующим `static_optimization.php` и проверить diff сгенерированных файлов.
|
||
|
||
## Кодировка и стиль
|
||
|
||
- Все новые и изменённые текстовые файлы сохранять в UTF-8 без порчи русских строк.
|
||
- В старых файлах уже встречается повреждённая кириллица. Не распространять её копированием и не делать массовое исправление кодировки вне отдельной задачи.
|
||
- Следовать стилю ближайшего файла; не проводить широкий форматирующий рефакторинг вместе с функциональной правкой.
|
||
- PHP-файлы проверять на синтаксис под PHP 7.4. Форматтер запускать только для файлов в области задачи и внимательно просматривать diff.
|
||
|
||
## Рабочие команды
|
||
|
||
Из корня проекта:
|
||
|
||
```powershell
|
||
docker compose up -d
|
||
docker compose ps
|
||
docker compose logs --tail=100 php
|
||
docker compose exec php composer install
|
||
docker compose exec php php -l engine/www/modules/site_index.php
|
||
docker compose exec php sh -lc "cd engine/migrations && php _migrate.php"
|
||
```
|
||
|
||
Последнюю команду запускать только когда задача действительно требует применения миграций к выбранной локальной БД.
|
||
|
||
Проверка синтаксиса всех изменённых PHP-файлов должна выполняться адресно. `app/php-cs-fixer.cmd` с `fix` изменяет много файлов, поэтому не запускать его по всему проекту без отдельного согласования.
|
||
|
||
## Минимальная проверка перед завершением
|
||
|
||
- Просмотреть `git status --short` и `git diff`; убедиться, что изменены только файлы задачи.
|
||
- Для каждого изменённого PHP-файла выполнить `php -l` в PHP 7.4 контейнере.
|
||
- Для SQL проверить совместимость с MariaDB 10.6.21 и ограничения `_migrate.php`.
|
||
- Для изменений публичного сценария вручную проверить: загрузку карты, подсказки адресов, поиск зоны, карточки врачей, пустое расписание, модальное окно и печать.
|
||
- Для изменений полигонов проверить создание/редактирование/удаление в админке и попадание точки внутрь зоны на публичной странице.
|
||
- Для cron сначала проверить dry-run/тестовую БД; убедиться, что временные таблицы и основные данные остаются согласованными при ошибке.
|
||
- После массовых замен отдельно проверить русские строки на «кракозябры».
|
||
- Не считать отсутствие автоматических тестов основанием пропустить адресную проверку.
|