arm-scan-gateway/CLAUDE.md
Andrey Epifancev 17e334f556 Срез 0 [fix docs]: README, CLAUDE.md и design.md #32 сверены с кодом
README: настройки шлюза читаются при импорте `src.app`, пакет `src` и эмулятор их не читают (после C-1);
`data_ocr` реальных фикстур — объект с пустыми полями и `table_structure: []`; непустой `data_ocr` в `ok_doc.json` —
требование тестовой фикстуры, не NullNormalizer; в «Ограничения Среза 0» — зависший вызов SMB и поздний TIMEOUT
(T12.2/T8.4), перечитывание недописанного ответа (T3.5), битая фикстура эмулятора.
CLAUDE.md: TIMEOUT по `min(reply_deadline, старт + SCAN_TIMEOUT_SECONDS=300)`; заглушки шаблона перечислены.
design.md, строка 32: формулировка про `data_ocr` реальных фикстур.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 05:05:42 +04:00

54 lines
5.5 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.

# CLAUDE.md — scan-gateway
Общий контекст системы — `../CLAUDE.md` и `../docs/`. Этот файл — только про этот сервис.
## Что это
Адаптер внешней ИС Сканирование (Content AI) для PDF/PNG/JPG: переименовать файл `UUID_имя`, положить в «Входящие»,
забрать `Исходящие/UUID/UUID.json`, сохранить сырой ответ в S3 `raw/{job_id}.json` (в БД не регистрируется),
нормализовать в `../docs/contracts/recognition-result.schema.json` (`statementDocument`), опубликовать
`recognition.result`. Таймаут → ошибка `TIMEOUT` по `min(reply_deadline, старт + SCAN_TIMEOUT_SECONDS=300)`, старт —
запись файла во «Входящие». **Нет доступа к БД.**
## Правила
- Нормализация по фактическим ответам `../fixtures/ocr/aep_*.json`, а не по ТЗ (OQ-13, OQ-14): confidence → 0–100,
поля организации/даты — по тому, что реально приходит.
- Один PDF может содержать ББ и ОФР → два документа в результате.
- Dev-режим: эмулятор ИС Сканирование, возвращающий `aep_N.json` по имени файла: `make emulator` (то же, что
`python -m src.scan_emulator` из `api/`); в контейнере — тот же образ с `command: python -m src.scan_emulator`.
- Описание сервиса, протокол горячих папок, env, запуск и коды ошибок — `README.md`; требования и решения Среза 0 —
`openspec/changes/slice-0-skeleton/` (`design.md`).
## Соглашения шаблона
Тот же шаблон команды, что у `arm-core` («Шаблон FastAPI», `RSHB/DKB_ARMKA@ba172f8`); общие соглашения —
`../docs/context/03-architecture.md`, «Соглашения шаблона команды». Репозиторий приведён к сервису **без фронта и без
БД**, но с SMB. Команды `make` — из корня репозитория (рецепты сами заходят в `api/`), `pytest` — из `api/`.
**Оставлено от шаблона:** `api/run_server.py` (точка входа платформы, `SERVER__HOST/PORT`), `api/src/app.py` (lifespan:
SMB-сессия, S3, NATS, воркер; `GET /healthcheck`; gzip/proxy middleware), `core/config.py` (pydantic-settings,
`OPENBAO__MINIO__*`, `OPENBAO__NATS__*`, `OPENBAO__SMB__*`, `DEBUG`), `core/exception_handlers.py` (подключается в
`create_app`), `api/pytest.ini`, `api/requirements*.txt` (включая `smbprotocol`), `raisa_config.yml`,
`setup/setup.sh` + `setup/pip.conf` (без npm-шага). Заглушки шаблона без кода сервиса: `src/api/` (пустой `router`,
пустые `dependencies/` и `endpoints/`), `src/schemas/` и `src/services/` (пустые пакеты), `common/exceptions.py`
(`NotFoundError`, `CouldntCreateError` нигде не используются), `core/logger.py` (`setup_logger` нигде не вызывается).
**Вырезано (Срез 0):** `web/`, `setup/.npmrc`; из `app.py` — mount SPA, CORS, `raisa_fastapi_protected_api`; `db/`,
`models/`, `repositories/`, `alembic/`; `OPENBAO.DATABASE`; из `requirements.txt` — `asyncpg`, `SQLAlchemy`, `alembic`,
`raisa_fastapi_protected_api`; шаблонные `core/nats_callback.py` и `README.md` заменены своими.
**Добавлено:**
- `api/src/gateway/` — горячие папки: протокол `HotFolder` (`hotfolder.py`: `LocalHotFolder`, `inbox_name`), `smb.py`
(`SmbHotFolder`, импортируется лениво), фабрика `create_hotfolder`; референс поллинга — `../reference-old-arm/api/src/core/PDFWorker`.
- `api/src/core/` — `worker.py` (задание: проверка → ack → S3 → горячая папка → опрос → `raw/` → нормализатор →
результат; ошибки по таблице D-7), `nats.py` (core NATS без JetStream, queue group `scan-gateway`, публикация с
повторами), `clients.py` (`S3Storage`), `health.py` (`nats`/`hotfolder` в `/healthcheck`).
- `api/src/normalizer/` — `Normalizer`, `NullNormalizer` (Срез 0: ошибка ИС → её код, успех → `NOT_IMPLEMENTED`);
настоящая нормализация — Срез 3.
- `api/src/contract/` + `api/contracts/` — pydantic-модели и байт-в-байт копии схем `../docs/contracts`; идентичность
проверяет `api/tests/unit/test_contract.py` (входит в `make check`).
- `api/src/scan_emulator/` — эмулятор ИС Сканирование (`SCAN_FIXTURES_DIR`, `SCAN_EMULATOR_DELAY`,
`SCAN_EMULATOR_POLL_SECONDS`); в compose контейнера пока нет — `make emulator`.
- `Makefile` (`venv`, `lint`, `test`, `test-integration`, `check`, `docker-build`, `check-full`, `up`,
`emulator`), `api/pyproject.toml` (ruff, mypy), `Dockerfile` + `.dockerignore` (один образ: шлюз и эмулятор),
`api/.env.example`, `api/.env.test`.
- Тесты: `api/tests/unit/`, `api/tests/integration/` (маркеры `integration`, `fixtures`); перед PR — `make check-full`.