# 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`. Таймаут 5 мин → `timeout`. **Нет доступа к БД.** ## Правила - Нормализация по фактическим ответам `../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/logger.py`, `core/exception_handlers.py`, `common/exceptions.py`, `api/pytest.ini`, `api/requirements*.txt` (включая `smbprotocol`), `raisa_config.yml`, `setup/setup.sh` + `setup/pip.conf` (без npm-шага). **Вырезано (Срез 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`, `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`.