Andrey Epifancev 7a35b79d5e docs: change slice-0-skeleton под факты платформы — NATS без JetStream, Python 3.11, без CI и Nexus
Обмен с ядром на core NATS: подписка queue group, ack status=processing сразу по получении, process-local
LRU job_id против повторных запросов, публикация результата с повторами; удалены durable consumer / max_deliver /
ack_wait. Dockerfile python:3.11-slim; make check / make check-full вместо CI; raisa_* фильтруются при
dev-установке. Обновлены proposal, design (решения без обсуждения), specs, tasks, CLAUDE.md, openspec/config.yaml.

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

6.1 KiB
Raw Blame History

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, проверки качества). Соседние: ../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 вместе с ядром на той платформе, что есть: NATS без JetStream, Python 3.11, без Nexus.

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 (python:3.11-slim; строка убрана из .gitignore), Makefile с общими целями up / test / test-integration / lint / check / check-full + venv, .env.example, .env.test; Settings читает ENV_FILE; SERVICE_NAME = "tabular-parser".
  • Контракт: вендоренные схемы api/contracts/ + pydantic-модели src/contract/ (запрос, конверт со статусами processing | done | needs_check | error, файл результата); тест идентичности с ../docs/contracts.
  • Воркер src/core/worker.py (NATS без JetStream): подписка на recognition.tabular.request в queue group tabular-parser; по получении — сразу ack: конверт status = processing в recognition.result (Nats-Msg-Id = ack:<job_id>:<attempt>); затем чтение исходника из S3 uploads/…, вызов парсера, запись results/{file_id}/{job_id}/result.json, публикация конверта результата (Nats-Msg-Id = result:<job_id>:<attempt>). Process-local множество job_id в работе: повторный запрос (ядро публикует повторно, не получив ack) получает 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: make check (ruff, mypy, pytest без Docker, идентичность контракта) и make check-full (+ интеграционный тест против compose, docker build) — по ../docs/dev/checks.md.

Capabilities

New Capabilities

  • tabular-recognition-service: stateless-сервис, который принимает задания из NATS без JetStream, подтверждает их, обменивается файлами через S3 и отвечает по контракту v1.0; в Срезе 0 — с парсером-заглушкой.

Modified Capabilities

Impact

  • Таблицы DBML: сервис не пишет в БД. Косвенно: recognition_job ядра получает status = processing (started_at), затем error, error_code = NOT_IMPLEMENTED, service_name = tabular-parser из конвертов.
  • Правила: §1.0/§12 — только как контракт будущего парсера (интерфейс Parser), §9.4 — статусы задания.
  • Зависимости: удаляются БД/SMB/фронт; добавляются ruff, mypy, pytest*, jsonschema (валидация примеров).
  • Внешние системы: NATS без JetStream (subjects recognition.*), MinIO/S3 (бакет arm-ka).

Non-goals

  • Разбор ОСВ и форм ББ/ОФР (§1, §12) — Срез 2; property-тесты на ../fixtures/osv/** — Срез 2.
  • Словари rules/*.yaml — Срез 2 (здесь только каталог и README).
  • Периодический heartbeat processing — не реализуется (один ack при получении).
  • Любая работа с БД, SMB, фронтом; конфигурации CI.