diff --git a/context/03-architecture.md b/context/03-architecture.md index 6a1bcb1..9bc4e22 100644 --- a/context/03-architecture.md +++ b/context/03-architecture.md @@ -28,7 +28,7 @@ (вычисления), согласование, ЕХ, аудит, права. Один Alembic, одна схема. - **tabular-parser** — читает файл из S3 `uploads/`, находит на листах ОСВ (§1) и формы ББ/ОФР (§12) **по содержимому**, пишет нормализованный JSON в S3 `results/`, публикует `recognition.result`. Контракт результата — - `docs/contracts/recognition-result.schema.json` (черновик; финализировать в срезе 2). Правила распознавания + `docs/contracts/recognition-result.schema.json` (контракт v1.0). Правила распознавания заголовков/группировок — `rules/*.yaml`. - **scan-gateway** — адаптер ИС Сканирование: переименовать файл `UUID_имя.pdf`, положить в «Входящие», опросить «Исходящие/UUID/UUID.json», сохранить сырой ответ в S3 `raw/{job_id}.json` (в БД не регистрируется), нормализовать @@ -47,8 +47,8 @@ | Поток | Subject | Кто пишет | Полезная нагрузка | `Nats-Msg-Id` | Схема | |---|---|---|---|---|---| | запрос | `recognition.tabular.request` / `recognition.image.request` | arm-core (outbox из `recognition_job`) | `schema_version`, `job_id`, `file_id`, `pipeline`, `file_type`, `original_name`, `s3 {bucket, key}` исходника, `reply_deadline`, `attempt` | `:` | [request](../contracts/recognition-request.schema.json) | -| ack | `recognition.result` | tabular-parser / scan-gateway | конверт со `status = processing`, `job_id`, `file_id`, `service {name, version}` | `ack::` | [message](../contracts/recognition-result-message.schema.json) | -| результат | `recognition.result` | tabular-parser / scan-gateway | `schema_version`, `job_id`, `file_id`, `status` (done / needs_check / error), `service {name, version}`, `metrics`, `raw_s3_key` (только scan-gateway); при `done` / `needs_check` обязательны `result_s3 {bucket, key}` и `result_schema_version`, при `error` — `error {code, message}` | `result::` | [message](../contracts/recognition-result-message.schema.json); файл в S3 — [result](../contracts/recognition-result.schema.json) | +| ack | `recognition.result` | tabular-parser / scan-gateway | конверт со `schema_version`, `status = processing`, `job_id`, `file_id`, `service {name, version}` | `ack::` | [message](../contracts/recognition-result-message.schema.json) | +| результат | `recognition.result` | tabular-parser / scan-gateway | `schema_version`, `job_id`, `file_id`, `status` (done / needs_check / error), `service {name, version}`, `metrics` (опц.), `raw_s3_key` (опц., только scan-gateway); при `done` / `needs_check` обязательны `result_s3 {bucket, key}` и `result_schema_version`, при `error` — `error {code, message}` | `result::` | [message](../contracts/recognition-result-message.schema.json); файл в S3 — [result](../contracts/recognition-result.schema.json) | `group_schema` в конверт не входит — ядро берёт его из `documents[].group_schema` файла результата при маппинге. @@ -69,8 +69,11 @@ - Три формы `Nats-Msg-Id`: запрос `:`, ack `ack::`, результат `result::`. Ack (`processing`) сервис публикует **до чтения файла из S3**; повторная публикация запроса ядром идёт с тем же `Nats-Msg-Id` и тем же `attempt`. Дубликат результата ядро определяет по `recognition_job.result_msg_id`. -- `schema_version` — `MAJOR.MINOR`; сервис отвергает запрос с неизвестным MAJOR результатом `error` с кодом `SCHEMA_MISMATCH` и подтверждает его - ack'ом, чтобы не зациклить доставку. +- `schema_version` — `MAJOR.MINOR`; ядро и сервисы принимают тот же MAJOR и любой MINOR. Сервис отвергает запрос с + неизвестным MAJOR результатом `error` с кодом `SCHEMA_MISMATCH` и подтверждает его ack'ом, чтобы не зациклить + доставку. Новый MINOR раскатывается сначала на потребителей + (ядро и сервисы обновляют копии схем раньше, чем производитель начнёт слать 1.1), потому что закрытые enum отвергают + незнакомые значения. - Сервисы не знают про БД и про бизнес-смысл: они возвращают структуру файла; нормализация счетов, резолв контрагентов, проверки — в ядре.