Срез 0 (issue #1): раздел «Соглашения шаблона» (что оставлено от шаблона команды, что вырезается, что добавляется); change openspec/changes/slice-0-skeleton — proposal, design с таблицей «Decisions made without discussion», спеки и tasks; в openspec/config.yaml строки с двоеточием взяты в кавычки (YAML разбирал их как словари). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
59 lines
5.1 KiB
Markdown
59 lines
5.1 KiB
Markdown
# Proposal: Срез 0 — скелет tabular-parser
|
||
|
||
**Срез:** 0 «Скелет» (`../docs/context/09-delivery-plan.md`). **Репозиторий:** tabular-parser. **Issue:** RSHB/arm-tabular-parser#1.
|
||
**Родительский change:** `../docs/openspec/changes/slice-0-skeleton` (контракт v1.0, compose, CI-шаблон).
|
||
**Соседние:** `../arm-core/openspec/changes/slice-0-skeleton`, `../scan-gateway/openspec/changes/slice-0-skeleton`.
|
||
|
||
## Why
|
||
|
||
Репозиторий сейчас — полная копия каркаса `arm-core` с фронтом, Alembic и моделями, то есть противоречит DECISION-4
|
||
(сервис без БД, видит только NATS и S3). Прежде чем в Срезе 2 писать парсер ОСВ, нужен сервис, который уже умеет
|
||
принять запрос из NATS, прочитать файл из S3, положить результат и ответить по контракту v1.0 — чтобы парсер стал
|
||
чистой функцией «байты → документы», а транспорт был проверен end-to-end вместе с ядром.
|
||
|
||
## What Changes
|
||
|
||
- **Вырезать из шаблона** (список — `CLAUDE.md`, «Соглашения шаблона»): `web/`, `setup/.npmrc` и npm-шаги
|
||
`setup/setup.sh`; из `app.py` — mount SPA, CORS, SMB-сессия, импорт `raisa_fastapi_protected_api`; `db/`, `models/`,
|
||
`repositories/`, `alembic/`, `alembic.ini`; настройки `OPENBAO.DATABASE`, `OPENBAO.SMB`; зависимости `asyncpg`,
|
||
`SQLAlchemy`, `alembic`, `smbprotocol`, `argon2-cffi`, `raisa_fastapi_protected_api`; шаблонный `README.md`.
|
||
- **Инструменты**: `api/pyproject.toml` (ruff, mypy), `requirements-dev.txt` = `-r requirements.txt` + инструменты,
|
||
`Dockerfile` (строка убрана из `.gitignore`), `Makefile` (`up / test / lint`), `.env.example`, `.env.test`;
|
||
`Settings` читает `ENV_FILE`; `SERVICE_NAME = "tabular-parser"`.
|
||
- **Контракт**: вендоренные схемы `api/contracts/` + pydantic-модели `src/contract/` (запрос, конверт результата, файл
|
||
результата); тест идентичности с `../docs/contracts`.
|
||
- **Воркер** `src/core/worker.py`: durable pull-consumer `tabular-parser` на `recognition.tabular.request`
|
||
(`max_deliver` 3 — OQ-15), чтение исходника из S3 `uploads/…`, вызов парсера, запись `results/{file_id}/{job_id}/result.json`,
|
||
публикация конверта `recognition.result` с `Nats-Msg-Id = result:<job_id>:<attempt>`, ack после публикации.
|
||
- **Парсер как интерфейс**: `src/parser/` — протокол `Parser` и `NullParser`, возвращающий `status = error`,
|
||
`error.code = NOT_IMPLEMENTED` для любого файла (Срез 2 заменяет реализацией §1/§12); `api/rules/README.md` —
|
||
место словарей синонимов.
|
||
- **Ошибки транспорта** всегда превращаются в результат: запрос не по схеме → `SCHEMA_MISMATCH`; файл не читается из
|
||
S3 → `FILE_READ_ERROR`; неожиданное исключение → `UNKNOWN_ERROR`. Ядро не ждёт таймаута, если сервис жив.
|
||
- **Healthcheck** `/healthcheck` шаблона дополняется полем `nats` (`ok`/`down`).
|
||
- **CI**: `.gitea/workflows/ci.yml` из шаблона docs (ruff, mypy, pytest c NATS/MinIO, идентичность контракта, сборка образа).
|
||
|
||
## Capabilities
|
||
|
||
### New Capabilities
|
||
- `tabular-recognition-service`: stateless-сервис, который принимает задания из NATS, обменивается файлами через S3 и
|
||
отвечает по контракту v1.0; в Срезе 0 — с парсером-заглушкой.
|
||
|
||
### Modified Capabilities
|
||
<!-- openspec/specs пуст -->
|
||
|
||
## Impact
|
||
|
||
- **Таблицы DBML:** сервис не пишет в БД. Косвенно: `recognition_job` ядра получает `status = error`,
|
||
`error_code = NOT_IMPLEMENTED`, `service_name = tabular-parser` из конверта.
|
||
- **Правила:** §1.0/§12 — только как контракт будущего парсера (интерфейс `Parser`), §9.4 — статусы задания.
|
||
- **Зависимости:** удаляются БД/SMB/фронт; добавляются `ruff`, `mypy`, `pytest*`, `jsonschema` (валидация примеров).
|
||
- **Внешние системы:** NATS JetStream (stream `RECOGNITION`), MinIO/S3 (бакет `arm-ka`).
|
||
|
||
## Non-goals
|
||
|
||
- Разбор ОСВ и форм ББ/ОФР (§1, §12) — Срез 2; property-тесты на `../fixtures/osv/**` — Срез 2.
|
||
- Словари `rules/*.yaml` — Срез 2 (здесь только каталог и README).
|
||
- Heartbeat `processing` (DBML: «опц. heartbeat») — не реализуется.
|
||
- Любая работа с БД, SMB, фронтом.
|