По ответам пользователя 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>
86 lines
8.9 KiB
Markdown
86 lines
8.9 KiB
Markdown
# 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 или платформы банка.
|
||
- Какие-либо экраны фронта.
|