Срез 0: скелет tabular-parser — без фронта и БД, воркер NATS без JetStream, парсер-заглушка, контракт v1.0 #3

Merged
aep merged 50 commits from feat/1-slice-0-skeleton into main 2026-10-04 18:41:02 +03:00
4 changed files with 16 additions and 8 deletions
Showing only changes of commit 67a4311150 - Show all commits

View File

@ -1,8 +1,9 @@
"""Запрос распознавания файла (arm-core → tabular-parser / scan-gateway): `recognition-request.schema.json` v1.0.
"""Запрос распознавания файла: `recognition-request.schema.json` v1.0.
Формируется из `recognition_job ⋈ stored_file ⋈ s3_object` (spec recognition-job-exchange); один файл — один job.
Subject — по `pipeline` (`request_subject`); заголовок `Nats-Msg-Id = <job_id>:<attempt>`
(`request_msg_id`) — не поле тела.
tabular-parser принимает этот запрос из `recognition.tabular.request` (производитель — arm-core); один файл — один job.
Модель намеренно совпадает с копией в arm-core (контракт — `../docs/contracts`, обзор —
`docs/context/03-architecture.md`). Subject — по `pipeline` (`request_subject`); заголовок
`Nats-Msg-Id = <job_id>:<attempt>` (`request_msg_id`) — не поле тела.
"""
from typing import Annotated, Literal

View File

@ -1,7 +1,9 @@
"""Файл результата в S3 (`results/{file_id}/{job_id}/result.json`): `recognition-result.schema.json` v1.0.
Один файл → один job → N документов (ОСВ по счёту / ББ / ОФР / прочее). В Срезе 0 — модели и валидация примеров;
маппинг в таблицы — Срез 2. Суммы — `Decimal` в модели и строка в JSON (`"106311116.46"`, без `float`).
tabular-parser формирует этот файл по запросу; один файл → один job → N документов (ОСВ по счёту / ББ / ОФР / прочее).
Модель намеренно совпадает с копией в arm-core (контракт — `../docs/contracts`, обзор —
`docs/context/03-architecture.md`).
Суммы — `Decimal` в модели и строка в JSON (`"106311116.46"`, без `float`).
Нормализация счетов, резолв контрагентов и проверки — в arm-core, не здесь.
"""

View File

@ -3,6 +3,10 @@
Источник: `docs/context/03-architecture.md`, «Контракт обмена через NATS»; схема recognition-request
(`Nats-Msg-Id = <job_id>:<attempt>`) и recognition-result-message
(`ack:<job_id>:<attempt>` / `result:<job_id>:<attempt>`).
Модуль намеренно совпадает с копией в arm-core. `request_subject`, `REQUEST_SUBJECTS`, `IMAGE_REQUEST_SUBJECT` и
значение `"image"` в `Pipeline` tabular-parser не использует (он слушает только `tabular`) — это сознательный паритет
с arm-core, а не мёртвый код.
"""
import uuid

View File

@ -1,5 +1,6 @@
"""Контракт обмена с сервисами распознавания v1.0 (spec recognition-contract, design D-7).
"""Контракт обмена с сервисами распознавания v1.0.
Спека сервиса — `tabular-recognition-service`; change `recognition-contract` лежит в `../docs`.
Быстрые тесты без БД: вендоренные схемы `api/contracts/` идентичны `../docs/contracts/`; каждый пример проходит и
JSON Schema, и pydantic-модель (с round-trip); модели и схемы выносят один и тот же вердикт на негативных кейсах.
"""
@ -598,7 +599,7 @@ def test_python_float_amount_is_rejected_with_clear_error() -> None:
def test_decimal_object_input_is_accepted_and_dumped_as_string() -> None:
"""Для кода, собирающего результат из `Decimal` (тесты, будущие производители): объект `Decimal` принимается."""
"""Для кода, собирающего результат из `Decimal` (тесты, парсер при сборке результата): `Decimal` принимается."""
payload = _example("result-statement-minimal.json")
payload["documents"][0]["lines"][0]["values"][0]["amount"] = Decimal("1234.50")
result = RecognitionResult.model_validate(payload)