# 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`, «Соглашения шаблона команды». Репозиторий приведён к сервису **без фронта и без БД** (change `slice-0-skeleton`). Команды backend — из `api/`, `make` — из корня репозитория. **Оставлено от шаблона:** `api/run_server.py` (точка входа платформы, `SERVER__HOST/PORT`), `api/src/app.py` (lifespan: подключение к MinIO и NATS, ошибка подключения логируется и не мешает старту; `GET /healthcheck`, gzip/proxy middleware), `core/config.py` (pydantic-settings, `SERVICE_NAME` — только `service.name` конвертов (queue group — константа в `core/nats.py`), `OPENBAO__MINIO__*` включая `MINIO_SECURE`, `OPENBAO__NATS__*`, `DEBUG`, `ENV_FILE`, `NATS_ENABLED`, `WORKER_CONCURRENCY`, `PUBLISH_RETRIES`, `DONE_CACHE_SIZE`), `core/clients.py` (S3), `core/logger.py`, `core/exception_handlers.py` (без SQLAlchemy), `common/exceptions.py`, `pytest.ini`, `requirements*.txt`, `raisa_config.yml`, `setup/setup.sh` + `pip.conf` (без npm-шага). Шаблонный `core/nats_callback.py` (consumer `recognition.result` — зона ядра) удалён задачей 4.3: его место занял воркер `core/worker.py`. **Вырезано (Срез 0):** `web/` целиком и `setup/.npmrc`; из `app.py` — mount SPA (`SPAStaticFiles`, `os.makedirs("web")`), CORS, регистрация SMB-сессии, импорт `raisa_fastapi_protected_api`, зависимость от SQLAlchemy в обработчиках ошибок; `db/`, `models/`, `repositories/`, `alembic/`, `alembic.ini`; из настроек — `OPENBAO.DATABASE`, `OPENBAO.SMB`; из `requirements.txt` — `asyncpg`, `SQLAlchemy`, `alembic`, `smbprotocol`, `argon2-cffi`, `greenlet`, `Mako`, `raisa_fastapi_protected_api`; шаблонный `README.md` заменён описанием сервиса. **Добавлено** (в скобках — задача `openspec/changes/slice-0-skeleton/tasks.md`): - `api/src/parser/` — интерфейс `Parser` и заглушка `NullParser`; разбор ОСВ §1 и форм §12 — чистые функции над книгой Excel, Срезы 2+; - `api/src/contract/` — pydantic-модели контракта v1.1 (запрос, результат, конверт); `api/contracts/` — копии схем (идентичность с `../docs/contracts` проверяется в `make check`) — 3.1; - `api/rules/` — README о назначении; сами словари `*.yaml` (в документах `rules/*.yaml` относительно `api/`) появятся в Срезе 2 — 4.1; - `api/src/core/nats.py` и `api/src/core/worker.py` — подписка queue group `tabular-parser` на `recognition.tabular.request` → ack → S3 `uploads/` → парсер → S3 `results/` → `recognition.result` — 4.2–4.3; - `api/pyproject.toml` (ruff, mypy) и `Makefile` — 2.1; `Dockerfile`, `api/.env.example`, `api/.env.test` — 2.2. Проверки: `make check` (`pytest`, `ruff check . && ruff format --check .`, `mypy src`), `make check-full` перед PR.