Files
han-app/architectory/arch-05-agent-development-process.md
T

106 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# arch-05. Правила разработки модулей отдельными агентами
> Термины — в [`arch-00-glossary.md`](arch-00-glossary.md). Настоящий документ описывает процесс разработки и не переопределяет архитектуру. Иерархия приоритета — в [`README.md`](README.md), раздел «Разрешение конфликтов».
## Цель
Этот документ задает единый процесс разработки, чтобы отдельные агенты создавали совместимые части приложения без расхождения архитектуры.
## Общие правила
- Каждый агент работает только в границах назначенного модуля.
- Перед разработкой агент читает [`README.md`](README.md), архитектурные документы и профильный документ назначенного модуля.
- Любое изменение публичного API сопровождается обновлением OpenAPI.
- Любое изменение структуры данных сопровождается миграцией.
- Все **бизнес-параметры** — в таблице `app_settings`; **infra и секреты** — в `.env`.
- Нельзя hardcode-ить телефоны, лимиты, тексты, mime types, feature flags и параметры Битрикс24.
- Модули, принимающие пользовательский ввод, должны учитывать rate limits и security/safety проверки.
## Правила базы данных
- Перечень таблиц, полей, индексов и миграций **определяет модуль-владелец** (`database`, `api-backend`, `bitrix-sync`, `message-safety`, `bitrix-local-app`), а не arch-*.
- Архитектура фиксирует **разделение схем** и общие подходы к ведению баз данных, которые должны соблюдаться при проработке модулей.
- У каждой основной **прикладной** сущности должен быть `record_status`. Базовые статусы: `A` — active, `D` — deleted.
- `record_status` выражает только административное наличие строки. Доменное завершение (например `Notification.lifecycle_status='closed'`) хранится отдельно и не переводит запись в `D`.
- Физическое удаление строк прикладных сущностей запрещено. Если нужно удалить сущность, сервис меняет `record_status` с `A` на `D`.
- При смене статуса на `D` сервис обязан заполнить `status_changed_at` и `status_change_reason`.
- Все сервисы при чтении бизнес-данных по умолчанию запрашивают только `record_status = 'A'`.
- Исключения допускаются только для аудита, админки, технического восстановления и миграций.
- Прикладные сущности, имеют `id`, `created_at`, `updated_at`, `updater_user_id`.
- Системные таблицы (`app_settings`, `text_resources`, `popular_questions`, `sync_queue`, audit, справочники) могут использовать `user_id = NULL` или отдельное поле `actor_type` — по спецификации модуля `database`.
- Для **строковых enum из arch-00** (`Dialog.status`, `Message.safety_status`, `Message.delivery_status`, `sender_type`, `scan_status` и т.п.) справочник sequence **не** обязателен: значения фиксированы контрактом API.
- Для больших/изменяемых списков (типы документов post-MVP, причины, классификаторы UI) — справочники с ID (sequence) и расшифровкой.
- Для часто используемых фильтров добавляются индексы.
- Миграции не должны удалять данные без отдельного согласования.
- Все юзеры должны иметь ИД, которое указывается в `updater_user_id` которое они меняют.
## API
Правила:
- endpoint naming должен следовать `arch-02-api-contracts.md`;
- response schema не должна раскрывать внутренние поля;
- ошибки возвращаются в едином формате;
- для пользовательских данных всегда используется текущий user context из JWT;
- frontend не передает `client_profile_id` для доступа к своим данным;
- профиль в MVP не редактируется через `PATCH /me`;
- сообщения оператора должны приходить в frontend через realtime или polling fallback.
## Логирование и OTP
Каждый модуль должен:
- использовать общий формат JSON-логов;
- добавлять `module`, `event`, `request_id`, `trace_id`;
- для `api-backend` добавлять **`ux_session_id`** в JSON-логи, если передан заголовок `X-Ux-Session-Id`;
- не логировать access token, refresh token, raw OTP, документы, полные PII;
- хранить факт отправки OTP через `provider_message_id`, `sent_at`, `destination_masked`, `otp_hash`, попытки и итог проверки.
Raw OTP запрещено хранить в открытом виде: это временный секрет. Доказательство отправки и проверки строится на аудите, delivery id провайдера и hash-проверке.
## Тесты
Минимум для каждого модуля:
- happy path;
- ошибки авторизации и доступа;
- rate limits, если модуль принимает пользовательский ввод;
- soft delete и фильтрация `record_status = 'A'`, если модуль работает с БД;
- idempotency, если операция может повториться;
- отсутствие секретов и PII в логах.
Дополнительно для модулей с async/worker:
- идемпотентность обработки задач очереди;
- поведение при повторной доставке webhook;
- таймауты и retry/backoff.
Для Notification Center обязательны contract tests каталога без ветвления по виду, бессрочной дедупликации `(source, external_id)`, изоляции producer tokens, TTL с сохранением существующего `date_expired`, первого скачивания любого связанного документа и открытия instruction только в новой вкладке.
## Definition of Done
Модуль считается готовым, если:
- реализованы сценарии из задачи;
- обновлен `{service}/openapi.yaml`, если менялся HTTP API;
- обновлены каталог ошибок в `arch-02` и contract tests, если менялась публичная или internal HTTP-семантика;
- созданы миграции, если менялась БД;
- обновлены seed `app_settings` и `.env.example`, если добавлялись настройки, service tokens, лимиты или feature flags;
- добавлены тесты;
- сервис запускается в Docker Compose;
- worker, указанный в Compose/runbook, имеет реально зарегистрированный entrypoint в image; deployment не может заранее выдумывать имя команды;
- все изменяемые параметры вынесены из кода;
- логи содержат `request_id`, `trace_id` и **`ux_session_id`** (если передан в запросе);
- нет секретов, raw OTP и PII в логах;
- soft delete соблюден;
- агент указал, какие документы архитектуры были затронуты.
## Правила изменения архитектуры
Если агент видит, что текущая архитектура мешает задаче, он должен:
1. описать проблему;
2. предложить минимальное изменение;
3. указать затронутые документы;
4. не делать широкий рефакторинг без подтверждения.