# CLAUDE.md — tabular-parser Общий контекст системы — `../CLAUDE.md` и `../docs/`. Этот файл — только про этот сервис. ## Что это Stateless-сервис разбора XLS/XLSX/XLSB: ОСВ по счетам (§1 правил) и ББ/ОФР из Excel (§12). Вход — NATS `recognition.tabular.request` + файл в S3 `uploads/`; выход — JSON по `../docs/contracts/recognition-result.schema.json` в S3 `results/` + NATS `recognition.result`. **Нет доступа к БД.** Не знает про организации, периметры, план счетов — возвращает структуру файла; нормализация и резолв — в arm-core. ## Главное правило Структура определяется динамически по содержимому (§1.0 правил): никаких координат ячеек, имён листов, букв колонок в коде. Словари синонимов — `rules/*.yaml`. Фикстуры `../fixtures/osv/**` — регрессия, не спецификация формата: новый формат = новая фикстура + синоним, не новый `if`. ## Тесты - property-тесты инвариантов (§1.4) на всех файлах `../fixtures/osv/**` и `../fixtures/statements-xlsx/**`; - снимки `../fixtures/golden/expected_osv_parse/*.json` — после ручной сверки «Итого»; - синтетика только для вариантов, которых нет в фикстурах (шапка вариант 2, Вал./Кол., xlsb, без outline level). ## Соглашения шаблона Тот же шаблон команды, что у `arm-core` («Шаблон FastAPI», `RSHB/DKB_ARMKA@ba172f8`); общие соглашения — `../docs/context/03-architecture.md`, «Соглашения шаблона команды». Сейчас репозиторий — полная копия каркаса `arm-core`; change `slice-0-skeleton` приводит его к сервису **без фронта и без БД**. Все команды — из `api/`. **Оставлено от шаблона:** `api/run_server.py` (точка входа платформы, `SERVER__HOST/PORT`), `api/src/app.py` (lifespan, `GET /healthcheck`, gzip/proxy middleware, обработчики ошибок), `core/config.py` (pydantic-settings, `OPENBAO__MINIO__*`, `OPENBAO__NATS__*`, `DEBUG`), `core/clients.py` (S3), `core/nats_callback.py`, `core/logger.py`, `core/exception_handlers.py`, `common/exceptions.py`, `pytest.ini`, `requirements*.txt`, `raisa_config.yml`, `setup/setup.sh` + `pip.conf` (без npm-шага). **Вырезано (Срез 0):** `web/` целиком и `setup/.npmrc`; из `app.py` — mount SPA (`SPAStaticFiles`, `os.makedirs("web")`), CORS, регистрация SMB-сессии, импорт `raisa_fastapi_protected_api`; `db/`, `models/`, `repositories/`, `alembic/`, `alembic.ini`; из настроек — `OPENBAO.DATABASE`, `OPENBAO.SMB`; из `requirements.txt` — `asyncpg`, `SQLAlchemy`, `alembic`, `smbprotocol`, `argon2-cffi`, `raisa_fastapi_protected_api`; шаблонный `README.md` заменён описанием сервиса. **Добавлено:** `api/src/parser/` (ОСВ §1 и формы §12 — чистые функции над книгой Excel; Срез 2), `api/src/contract/` (pydantic-модели `recognition-result` v1.0; идентичность с `../docs/contracts` проверяется в `make check`), `api/rules/*.yaml` (словари синонимов — в документах это `rules/*.yaml` относительно `api/`), `api/src/core/worker.py` (подписка queue group `recognition.tabular.request` → S3 `uploads/` → парсер → S3 `results/` → `recognition.result`), `Dockerfile`, `api/pyproject.toml` (ruff, mypy). Проверки: `pytest`, `ruff check . && ruff format --check .`, `mypy src`.