openspec: архив nats-env-config (#80) #100
@ -2,13 +2,15 @@
|
|||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
Контракт обмена между ядром `arm-core` и stateless-сервисами распознавания (`tabular-parser`, `scan-gateway`):
|
Контракт обмена между ядром `arm-core` и stateless-сервисами распознавания (`tabular-parser`, `scan-gateway`):
|
||||||
тела сообщений NATS `files.tabular_uploaded`, `files.img_uploaded` и `files.tabular_parsed`, файл результата в S3 и правила
|
тела сообщений NATS на subject'ах запроса и ответа (настройки окружения `OPENBAO__NATS__NATS_*_SUBJECT`, по умолчанию
|
||||||
версионирования и идемпотентности. Сервисы не знают БД; ядро — единственный писатель (DECISION-4).
|
`files.tabular_uploaded`, `files.img_uploaded` и `files.tabular_parsed`), файл результата в S3 и правила версионирования и
|
||||||
|
идемпотентности. Сервисы не знают БД; ядро — единственный писатель (DECISION-4).
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
### Requirement: Сообщение запроса распознавания
|
### Requirement: Сообщение запроса распознавания
|
||||||
Тело сообщения на subject `files.tabular_uploaded` или `files.img_uploaded` SHALL соответствовать
|
Тело сообщения на subject запроса `tabular` или `image` (настройки окружения `NATS_TABULAR_REQUEST_SUBJECT` /
|
||||||
|
`NATS_IMAGE_REQUEST_SUBJECT`, по умолчанию `files.tabular_uploaded` / `files.img_uploaded`) SHALL соответствовать
|
||||||
`docs/contracts/recognition-request.schema.json` v1.0: обязательные поля `schema_version` (`"1.0"`), `job_id` (uuid =
|
`docs/contracts/recognition-request.schema.json` v1.0: обязательные поля `schema_version` (`"1.0"`), `job_id` (uuid =
|
||||||
`recognition_job.id`), `file_id` (uuid = `stored_file.id`), `pipeline` (`tabular` | `image`), `file_type`
|
`recognition_job.id`), `file_id` (uuid = `stored_file.id`), `pipeline` (`tabular` | `image`), `file_type`
|
||||||
(`XLS` | `XLSX` | `XLSB` | `PDF` | `PNG` | `JPG`), `original_name`, `s3 {bucket, key}` исходника в роли `uploads`,
|
(`XLS` | `XLSX` | `XLSB` | `PDF` | `PNG` | `JPG`), `original_name`, `s3 {bucket, key}` исходника в роли `uploads`,
|
||||||
@ -67,7 +69,8 @@ ack не получен за `ACK_TIMEOUT_SECONDS` (по умолчанию 30),
|
|||||||
- **THEN** сервис публикует ack повторно и не начинает вторую обработку
|
- **THEN** сервис публикует ack повторно и не начинает вторую обработку
|
||||||
|
|
||||||
### Requirement: Сообщение результата распознавания
|
### Requirement: Сообщение результата распознавания
|
||||||
Тело сообщения на subject `files.tabular_parsed` SHALL соответствовать `docs/contracts/recognition-result-message.schema.json`
|
Тело сообщения на subject ответа (настройка окружения `NATS_RESULT_SUBJECT`, по умолчанию `files.tabular_parsed`)
|
||||||
|
SHALL соответствовать `docs/contracts/recognition-result-message.schema.json`
|
||||||
v1.0: обязательные поля `schema_version` (`"1.0"`), `job_id`, `file_id`, `status` (`processing` | `done` | `needs_check` |
|
v1.0: обязательные поля `schema_version` (`"1.0"`), `job_id`, `file_id`, `status` (`processing` | `done` | `needs_check` |
|
||||||
`error`), `service {name, version}`; при `status ∈ {done, needs_check}` обязательны `result_s3 {bucket, key}` и
|
`error`), `service {name, version}`; при `status ∈ {done, needs_check}` обязательны `result_s3 {bucket, key}` и
|
||||||
`result_schema_version`; при `status = error` обязателен `error {code, message}`; опциональны `raw_s3_key`
|
`result_schema_version`; при `status = error` обязателен `error {code, message}`; опциональны `raw_s3_key`
|
||||||
@ -170,3 +173,37 @@ v1.0: обязательные поля `schema_version` (`"1.0"`), `job_id`, `f
|
|||||||
#### Scenario: Копия устарела
|
#### Scenario: Копия устарела
|
||||||
- **WHEN** в `docs/contracts/` изменена схема, а копия в сервисе — нет
|
- **WHEN** в `docs/contracts/` изменена схема, а копия в сервисе — нет
|
||||||
- **THEN** тест идентичности в `make check` сервиса падает с указанием имени файла
|
- **THEN** тест идентичности в `make check` сервиса падает с указанием имени файла
|
||||||
|
|
||||||
|
### Requirement: Subject'ы NATS — настройки окружения
|
||||||
|
Subject'ы обмена SHALL задаваться секретами группы `OPENBAO__NATS__` с одинаковыми ключами во всех трёх сервисах:
|
||||||
|
`NATS_TABULAR_REQUEST_SUBJECT` (по умолчанию `files.tabular_uploaded`), `NATS_IMAGE_REQUEST_SUBJECT` (по умолчанию
|
||||||
|
`files.img_uploaded`), `NATS_RESULT_SUBJECT` (по умолчанию `files.tabular_parsed`). У ядра и сервисов одного окружения
|
||||||
|
значения MUST совпадать. Каждый сервис SHALL при старте проверять все три имени: непустое, без пробельных символов, без
|
||||||
|
шаблонов `*` и `>`, без пустых токенов, три имени попарно различны; при нарушении сервис MUST NOT стартовать.
|
||||||
|
Учётные данные NATS (`OPENBAO__NATS__NATS_JWT`, `OPENBAO__NATS__NATS_SEED`) SHALL задаваться по окружению теми же
|
||||||
|
секретами, и их значения MUST NOT попадать в логи, `repr` настроек и тексты ошибок валидации конфигурации. Каждый
|
||||||
|
сервис SHALL писать используемые subject'ы в лог при старте и отдавать их в `/healthcheck` объектом `subjects`
|
||||||
|
(ключи `tabular_request`, `image_request`, `result` — только те, что использует сервис) независимо от состояния NATS.
|
||||||
|
Queue group'ы и `schema_version` от настроек subject'ов не зависят.
|
||||||
|
|
||||||
|
#### Scenario: Умолчания
|
||||||
|
- **WHEN** сервис стартует без ключей `OPENBAO__NATS__NATS_*_SUBJECT`
|
||||||
|
- **THEN** обмен идёт по `files.tabular_uploaded`, `files.img_uploaded`, `files.tabular_parsed`
|
||||||
|
|
||||||
|
#### Scenario: Набор тестового окружения
|
||||||
|
- **WHEN** всем трём сервисам заданы одинаковые `OPENBAO__NATS__NATS_TABULAR_REQUEST_SUBJECT`,
|
||||||
|
`NATS_IMAGE_REQUEST_SUBJECT`, `NATS_RESULT_SUBJECT`, `NATS_JWT`, `NATS_SEED` тестового окружения
|
||||||
|
- **THEN** ядро публикует запросы и получает ack и результаты только по этим subject'ам; subject'ы по умолчанию не
|
||||||
|
используются, `recognition_job.request_subject` содержит subject тестового окружения
|
||||||
|
|
||||||
|
#### Scenario: Недопустимый набор
|
||||||
|
- **WHEN** `NATS_RESULT_SUBJECT` совпадает с одним из subject'ов запроса, или имя содержит `*`, `>` или пробел
|
||||||
|
- **THEN** сервис не стартует с ошибкой конфигурации, называющей ключ
|
||||||
|
|
||||||
|
#### Scenario: Разъехавшиеся настройки видны
|
||||||
|
- **WHEN** у ядра и сервиса заданы разные subject'ы ответа
|
||||||
|
- **THEN** `/healthcheck.subjects.result` ядра и сервиса различаются; JWT и seed в ответе `/healthcheck` отсутствуют
|
||||||
|
|
||||||
|
#### Scenario: Ошибка конфигурации не раскрывает JWT
|
||||||
|
- **WHEN** сервис не стартует из-за ошибки валидации настроек при заданных `NATS_JWT` и `NATS_SEED`
|
||||||
|
- **THEN** текст ошибки и лог не содержат значений JWT и seed
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user