# Tasks: Срез 0 — скелет tabular-parser Репозиторий — tabular-parser; команды — из `api/`. Зависимости: 3.1 ждёт контракт v1.0 (`docs` 1.1–1.4); интеграционные тесты 4.x — compose инфраструктуры (`docs` 2.1). Каждая задача ≤ половины дня. CI нет — проверки локальные. ## 1. Вырезать фронт и БД из шаблона - [x] 1.1 Удалить `web/`, `setup/.npmrc`, npm-шаги из `setup/setup.sh`, `api/alembic/`, `api/alembic.ini`, `api/src/db/`, `api/src/models/`, `api/src/repositories/`; из `.gitignore` убрать `Dockerfile`; проверка: `git status` показывает только удаления и `.gitignore`; `python -c "import src"` пока падает ожидаемо (чинится в 1.2) - [ ] 1.2 `src/app.py`: убрать mount SPA/`os.makedirs("web")`, CORS, SMB-сессию, импорт `raisa_fastapi_protected_api`; `src/core/config.py`: убрать `DBSettings`, `SMBSettings`, оставить `MINIO`, `NATS`; добавить `ENV_FILE`, `SERVICE_NAME="tabular-parser"`, `NATS_ENABLED=true`, `WORKER_CONCURRENCY=1`, `PUBLISH_RETRIES=3`, `DONE_CACHE_SIZE=1000`; `requirements.txt` без `asyncpg`, `SQLAlchemy`, `alembic`, `smbprotocol`, `argon2-cffi`, `raisa_fastapi_protected_api`; проверка: `pip install -r requirements.txt` в чистом venv (python3.11), `python run_server.py` стартует c `.env.example`, `/healthcheck` 200 - [ ] 1.3 `README.md` — описание сервиса (назначение, команды `make`, env, запуск против compose), `CLAUDE.md` — актуализировать раздел «Соглашения шаблона» по факту вырезанного; проверка: все упомянутые файлы существуют ## 2. Инструменты - [ ] 2.1 `api/pyproject.toml` (ruff: line-length 120, E,F,I,UP,B,PL; mypy с плагином pydantic), `requirements-dev.txt` = `-r requirements.txt` + ruff, mypy, pytest, pytest-asyncio, pytest-env, httpx, jsonschema; `Makefile`: `venv` (python3.11), `lint`, `test`, `test-integration`, `check`, `check-full`, `up`; проверка: `make venv && make lint` зелёные - [ ] 2.2 `Dockerfile` (`python:3.11-slim`), `.env.example`, `.env.test`; проверка: `docker build -t tabular-parser .` успешен ## 3. Контракт - [ ] 3.1 `api/contracts/` — копии трёх схем + `examples/` из `../docs/contracts`; `src/contract/` — pydantic-модели (`RecognitionRequest`, `RecognitionResultMessage` со статусами `processing | done | needs_check | error`, `RecognitionResult`, `OsvDocument`, `StatementDocument`, деньги как `Decimal` ↔ строка); `tests/unit/test_contract.py` — идентичность с docs (skip без docs), валидация примеров, round-trip модели → JSON → схема; проверка: тесты зелёные ## 4. Воркер и парсер-заглушка - [ ] 4.1 `src/parser/__init__.py`: протокол `Parser`, `ParseOutcome`, `NullParser` (`NOT_IMPLEMENTED`); `api/rules/README.md`; `tests/unit/test_null_parser.py`; проверка: заглушка возвращает код и сообщение, не трогая входные байты - [ ] 4.2 `src/core/clients.py`: `S3Storage.get_bytes(bucket, key)`, `put_json(bucket, key, obj)`; `src/core/nats.py`: подключение (с/без nkeys, автопереподключение), `subscribe_requests(queue="tabular-parser", cb)`, `publish(subject, payload, msg_id)` с повторами; проверка: unit-тесты с фейковым соединением; интеграционный тест подключения к compose-NATS без JetStream и получения сообщения с заголовком - [ ] 4.3 `src/core/worker.py`: `on_request(msg)`: валидация → множество `job_id` в работе/обработано (LRU) → ack `processing` → очередь; рабочая корутина: S3 get → `Parser` → S3 put результата → конверт → publish; таблица ошибок D-5; `metrics.duration_ms`; запуск/остановка в lifespan при `NATS_ENABLED`; `/healthcheck.nats`; проверка: unit-тесты с фейками — сценарии spec (ack раньше результата, повторный запрос, NOT_IMPLEMENTED, FILE_READ_ERROR, SCHEMA_MISMATCH без ack, подмена парсера → `done`, повтор публикации) - [ ] 4.4 `tests/integration/test_roundtrip.py` (маркер `integration`): положить файл в MinIO `uploads/…`, опубликовать `request-tabular.json`, собрать сообщения `recognition.result`: первое — `processing`, второе — `error NOT_IMPLEMENTED` с правильными `Nats-Msg-Id`; повторная публикация запроса даёт только ещё один ack; проверка: зелёный против compose ## 5. Проверки и завершение - [ ] 5.1 `make check-full`: `make check` + `pytest -m integration` + `docker build`; проверка: зелёный против compose docs на ветке `feat/1-slice-0-skeleton` - [ ] 5.2 Прогон DoD: `make up` → `make check-full` → ручная проверка из `docs/dev/README.md` («проверка окружения»); `openspec validate slice-0-skeleton --strict`; вывод `make check-full` — в описание PR