Andrey Epifancev a0be5ab5a1 docs: Срез 0 под факты платформы — NATS без JetStream, Python 3.11, PostgreSQL 16, без CI и Nexus
По ответам пользователя 03.10.2026: обмен через recognition_job перестроен на core NATS (queue group'ы,
ack сервиса = конверт status=processing, повторная публикация ядром 30 с × 3 → dlq, дедуп по result_msg_id);
capability ci-template заменена на quality-checks (make check / make check-full, конфигураций CI нет);
compose: PostgreSQL 16, NATS без --jetstream, python:3.11-slim; пакеты raisa_* фильтруются при dev-установке,
npm raisa-* → optionalDependencies. Обновлены 03-architecture, 09-delivery-plan, 00-workspace-layout,
proposal/design/specs/tasks change'а; открытые вопросы к платформе закрыты, остались Node и JWT РАИСА.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 16:21:39 +04:00

86 lines
8.9 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.

# Proposal: Срез 0 — сквозной скелет (контракт v1.0, окружение разработки, проверки качества)
**Срез:** 0 «Скелет» (`docs/context/09-delivery-plan.md`). **Репозиторий:** arm-ka-docs (сквозная часть).
**Issue:** RSHB/arm-ka-docs#1. **Дочерние change'и:** `arm-core/openspec/changes/slice-0-skeleton` (arm-core#1),
`tabular-parser/openspec/changes/slice-0-skeleton` (arm-tabular-parser#1),
`scan-gateway/openspec/changes/slice-0-skeleton` (arm-scan-gateway#1).
## Why
Три сервисных репозитория развёрнуты из шаблона команды, но между ними ещё нет ничего общего: контракт результата
распознавания помечен «черновик», сообщения NATS описаны только таблицей в `03-architecture.md`, локально поднять
PostgreSQL + NATS + MinIO + ИС Сканирование нечем, единого набора проверок перед PR нет. Без этого Срез 1 (справочники)
и Срез 2 (парсер) нельзя начать параллельно в трёх репозиториях: каждый сервис придумает свой формат сообщений и своё
окружение. Срез 0 фиксирует общие точки один раз и проверяет их end-to-end на пустых обработчиках — на той платформе,
которая есть: NATS без JetStream, PostgreSQL 16, Python 3.11, без доступа к Nexus и без CI в Gitea.
## What Changes
- **Контракт распознавания v1.0** (`docs/contracts/`):
- `recognition-result.schema.json` — снять пометку «черновик», `schema_version` = `"1.0"`, добавить код ошибки
`NOT_IMPLEMENTED` (сервис не поддерживает тип документа в текущей версии); структура документов (`osvDocument`,
`statementDocument`) не меняется — она уточняется в Срезе 2/3 версией 1.x (additive) или 2.0 (breaking).
- **Новое:** `recognition-request.schema.json` — тело сообщения `recognition.{tabular|image}.request`
(`job_id`, `file_id`, `pipeline`, `file_type`, `original_name`, `s3 {bucket, key}`, `reply_deadline`, `attempt`).
- **Новое:** `recognition-result-message.schema.json` — тело сообщения `recognition.result`: конверт со `status`
`processing` (подтверждение взятия в работу — замена ack брокера, которого без JetStream нет) | `done` | `needs_check`
| `error`; поля `job_id`, `file_id`, `error`, `service`, `result_s3 {bucket, key}`, `result_schema_version`,
`raw_s3_key`, `metrics`. Поле `group_schema` в конверт **не входит** — ядро берёт его из `documents[].group_schema`
файла результата (правка таблицы в `03-architecture.md`).
- Заголовки NATS: `Nats-Msg-Id` запроса = `<job_id>:<attempt>`, результата = `result:<job_id>:<attempt>`, ack —
`ack:<job_id>:<attempt>`; без JetStream они нужны для трассировки, дедуп результатов — `recognition_job.result_msg_id`.
- Примеры сообщений и результата — `docs/contracts/examples/` (валидируются тестами сервисов).
- **Окружение разработки** `docs/dev/`:
- `docker-compose.yml` workspace-уровня: PostgreSQL 16, NATS 2.10 **без JetStream** (паритет с платформой), MinIO
(+ init-контейнер: бакет `arm-ka`), эмулятор ИС Сканирование (образ `scan-gateway`, команда эмулятора, общая папка
горячих каталогов), сервисы `arm-core`, `tabular-parser`, `scan-gateway` (профиль `services`; сборка из соседних
каталогов workspace, `python:3.11-slim`).
- `.env.example` c переменными шаблона (`OPENBAO__*`, `DEBUG`) и флагами разработки (`AUTH_DEV_ISSUER`, `SCAN_EMULATOR`,
`NATS_ENABLED`).
- `README.md`: как поднять инфраструктуру, как запустить сервисы из venv против compose без Nexus, как прогнать
интеграционные тесты.
- **Проверки качества** `docs/dev/checks.md`: одинаковые цели `make check` (ruff, mypy, pytest без Docker, идентичность
контракта) и `make check-full` (+ интеграционные тесты против compose; для arm-core — цикл миграций и
`check_dbml_vs_orm.py`) в каждом репозитории; `make check-full` обязателен перед PR. Конфигураций CI в репозиториях
нет: в Gitea CI не будет, пайплайн платформы — вне нашей зоны.
- **Документы контекста:** `03-architecture.md` — раздел «Соглашения шаблона команды», раскладка `api/src/`, схема `dkb`,
один бакет S3, обмен через NATS без JetStream (ack, повторная публикация), проверки качества вместо CI; `00-workspace-layout.md`
— worktree-workspace `.wt/<срез>/`, фикстуры для проверок; `06-test-data.md` §6 — справочники для seed продукта живут в
`arm-core/api/seed/`; `09-delivery-plan.md` — Срез 0 по факту; `07-open-questions.md` — новые OQ.
- **Сверка макета** (задача B kickoff): `10-user-journey.md`, `mockup/INDEX.md`, новые снимки `mockup/screens/`,
`scripts/mockup_crawl_extra.py`; расхождения — в `07-open-questions.md`.
## Capabilities
### New Capabilities
- `recognition-contract`: контракт обмена между ядром и сервисами распознавания — тела сообщений NATS (запрос, ack,
результат), файл результата в S3, правила версионирования и идемпотентности без JetStream.
- `dev-environment`: воспроизводимое локальное окружение workspace (PostgreSQL, NATS, MinIO, эмулятор ИС Сканирование,
три сервиса) с одним `docker compose up`, без доступа к Nexus.
- `quality-checks`: единый набор проверок качества перед PR для сервисных репозиториев (`make check`, `make check-full`).
### Modified Capabilities
<!-- openspec/specs пуст — изменяемых capability нет -->
## Impact
- Читают контракт: `arm-core` (outbox публикует запрос, consumer читает ack и конверт результата и файл результата),
`tabular-parser` и `scan-gateway` (читают запрос, пишут ack, результат и конверт). Каждый сервис вендорит копию схем
в `api/contracts/` и проверяет идентичность с `docs/contracts` в `make check`.
- Таблицы DBML v5.13, которые опираются на контракт: `recognition_job` (`request_msg_id`, `result_msg_id`,
`schema_version`, `result_schema_version`, `service_name/version`, `status` включая `processing` и `dlq`, `started_at`,
`result_s3_object_id`, `metrics`, `group_schema`, `error_code`), `s3_object` (`bucket_role`, `bucket`, `key`,
`created_by`), `stored_file` (`file_type`). Новых полей нет.
- Внешние зависимости: Docker/Compose у разработчика; публичные PyPI/npm (пакеты `raisa_*` недоступны — условные импорты
и `optionalDependencies`, см. design D-10).
## Non-goals
- Финальная структура `osvDocument`/`statementDocument` (уточняется в Срезах 2–3 по реальным файлам; здесь только
фиксируется версия и правила эволюции).
- Контракт `ex-payload-v1.schema.json` (Срез 7).
- Production-значения инфраструктуры банка (адреса NATS/S3/OpenBao, nkeys) — compose только для разработки.
- Публикация общего python-пакета контрактов (решено: не делать, см. design D-1).
- Конфигурации CI для Gitea или платформы банка.
- Какие-либо экраны фронта.