Andrey Epifancev da9b9f66cf openspec: change nats-env-config — subject'ы и JWT NATS по окружению из OpenBao
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 13:38:50 +04:00

61 lines
5.4 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.

## Why
Прод и тест будут работать с разными наборами subject'ов NATS и разными JWT. Платформа РАИСА передаёт в под только
переменные `OPENBAO__*`, поэтому окружение должно настраиваться только секретами OpenBao, без пересборки и релиза
сервисов. Сейчас JWT и seed уже приходят как `OPENBAO__NATS__NATS_JWT` / `NATS_SEED`, а subject'ы зашиты константами
`api/src/contract/subjects.py` трёх сервисов (решение R-4 в #74) и уже раз менялись (`recognition.*` → `files.*`,
08.10.2026). Решение владельца 12.10.2026: subject'ы и JWT задаются по окружению секретами группы `OPENBAO__NATS__` —
так устроен `RSHB/armka_file_worker`, проверенный в контуре (`NATS_COMMAND_SUBJECT`, `NATS_EVENT_SUBJECT` рядом с
`NATS_JWT`).
Срез: вне плана срезов `09-delivery-plan.md` — подготовка к контуру (инфраструктура NATS платформы). Issue
RSHB/arm-ka-docs#80.
## What Changes
- Три настройки окружения, одинаковые ключи во всех трёх сервисах, умолчания — текущие имена:
`OPENBAO__NATS__NATS_TABULAR_REQUEST_SUBJECT` (`files.tabular_uploaded`),
`OPENBAO__NATS__NATS_IMAGE_REQUEST_SUBJECT` (`files.img_uploaded`),
`OPENBAO__NATS__NATS_RESULT_SUBJECT` (`files.tabular_parsed`).
- Контракт: subject'ы — конфигурация окружения; у ядра и сервисов одного окружения значения MUST совпадать; имена
проверяются при старте (непустые, без пробелов и шаблонов `*`/`>`, три разных).
- `NATS_JWT` / `NATS_SEED` — секреты: значения не попадают в `repr`, логи и тексты ошибок валидации конфигурации.
- Каждый сервис пишет свои subject'ы в лог при старте и отдаёт их в `/healthcheck` (объект `subjects`).
- Интеграционные тесты `tabular-parser` и `scan-gateway` берут собственные subject'ы через настройки и не делят их с
контейнерами стенда (OQ-83 в части этих тестов; e2e ядра — без изменений, design R-7).
- Документы: `context/03-architecture.md` (NATS платформы, перечень секретов), `context/07-open-questions.md` (OQ-83),
`dev/README.md`, `dev/contour-transfer-guide.md`, `dev/qa-guide.md`, `dev/frontend-api-guide.md` (ответ
`/healthcheck`, если описан), `dev/.env.example`.
Читают и пишут контракт: `arm-core` (публикует запросы в оба subject'а запроса, подписан на subject ответа),
`tabular-parser` (подписан на subject запроса `tabular`, публикует в subject ответа), `scan-gateway` (подписан на
subject запроса `image`, публикует в subject ответа). Дочерние change'и `nats-env-config`: RSHB/arm-core#106,
RSHB/arm-tabular-parser#31, RSHB/arm-scan-gateway#32.
## Non-goals
- `schema_version` контракта не меняется: тела сообщений, `Nats-Msg-Id`, файл результата — те же.
- Queue group'ы (`arm-core`, `tabular-parser`, `scan-gateway`) остаются константами.
- Механизм аутентификации NATS не меняется (nkeys seed + JWT, оба пусты — без учётных данных).
- Пароли MinIO и SMB в `SecretStr` не переводятся.
- Subject'ы не настраиваются через `OPENBAO__APP__*`: это группа `NATS`, а не настройки верхнего уровня.
- DBML не поднимается; заметки v5.17 про subject'ы — follow-up RSHB/arm-ka-docs#79 (R-3).
- Отдельный NATS для тестов не поднимается.
## Capabilities
### New Capabilities
### Modified Capabilities
- `recognition-contract`: subject'ы запроса и ответа — настройки окружения с умолчаниями `files.*`.
## Impact
- Сервисы: `arm-core`, `tabular-parser`, `scan-gateway` — `core/config.py` (`NATSSettings`), `contract/subjects.py`,
`core/nats.py`, публикация и подписки, `/healthcheck`, тесты, `.env.example`, спеки, README.
- Выкат обратно совместим: без новых ключей всё работает на `files.*`. Для теста платформа кладёт свои `NATS_JWT`,
`NATS_SEED` и три subject'а одинаково всем трём сервисам; JWT окружения должен давать права publish/subscribe на эти
subject'ы.
- Ядро вычисляет subject при каждой публикации по `pipeline`, поэтому после смены настроек повторная публикация
заданий в работе уходит в новый subject; `recognition_job.request_subject` записывает фактический subject.