Задача 2.1. make test допускает код 5 pytest (тестов пока нет). README: все цели Makefile создаются в 2.1 (T3.1). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
8.1 KiB
8.1 KiB
Срез 0 — скелет tabular-parser — план исполнения (Срез 0)
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Branch: feat/1-slice-0-skeleton (worktree .wt/slice-0/tabular-parser). Issue: #1.
Spec: openspec/changes/slice-0-skeleton/ — proposal.md, design.md, specs/*/spec.md этого change'а. Спека — единственный источник истины при рулингах; этот план сгенерирован из её tasks.md 1:1 (номера в скобках — исходные номера задач tasks.md; по завершении задачи отметить её - [x] и в tasks.md).
Global Constraints
- Сервис без БД и фронта (DECISION-4): видит только NATS и S3. Раскладка шаблона, команды из
api/. - Платформа: Python 3.11, NATS без JetStream (подписка queue group
tabular-parser, ackstatus = processingдо чтения S3, process-local LRUjob_id, публикация с повторами), один бакет S3, Nexus недоступен, CI нет (make check/make check-full). - Контракт: копии схем из
../docs/contracts/вapi/contracts/байт в байт;service.name = "tabular-parser"; результатresults/{file_id}/{job_id}/result.json;Nats-Msg-Idпо правилам контракта; заглушка парсера —NOT_IMPLEMENTED. - Парсер — интерфейс без NATS/S3; никаких координат ячеек, букв колонок, имён листов в коде (Срез 2 — вне этого плана).
- Ошибки транспорта → конверт
status = error(SCHEMA_MISMATCH,FILE_READ_ERROR,UNKNOWN_ERROR); процесс не падает. - Линтеры: ruff (120, E,F,I,UP,B,PL) + mypy; pytest-asyncio auto; маркеры
integration/fixtures. - Язык комментариев/коммитов — русский, идентификаторы — английские; коммит заканчивается строкой
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>.
Задачи
Task 1: [1.1] Удалить web/, setup/.npmrc, npm-шаги из setup/setup.sh, api/alembic/, `a
- Удалить
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)
Task 2: [1.2] src/app.py
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,/healthcheck200
Task 3: [1.3] README.md — описание сервиса (назначение, команды make, env, запуск против c
README.md— описание сервиса (назначение, командыmake, env, запуск против compose),CLAUDE.md— актуализировать раздел «Соглашения шаблона» по факту вырезанного; проверка: все упомянутые файлы существуют
Task 4: [2.1] api/pyproject.toml (ruff
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зелёные
Task 5: [2.2] Dockerfile (`python
Dockerfile(python:3.11-slim),.env.example,.env.test; проверка:docker build -t tabular-parser .успешен
Task 6: [3.1] api/contracts/ — копии трёх схем + examples/ из ../docs/contracts
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 → схема; проверка: тесты зелёные
Task 7: [4.1] src/parser/__init__.py
src/parser/__init__.py: протоколParser,ParseOutcome,NullParser(NOT_IMPLEMENTED);api/rules/README.md;tests/unit/test_null_parser.py; проверка: заглушка возвращает код и сообщение, не трогая входные байты
Task 8: [4.2] src/core/clients.py
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 и получения сообщения с заголовком
Task 9: [4.3] src/core/worker.py
src/core/worker.py:on_request(msg): валидация → множествоjob_idв работе/обработано (LRU) → ackprocessing→ очередь; рабочая корутина: 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, повтор публикации)
Task 10: [4.4] tests/integration/test_roundtrip.py (маркер integration)
tests/integration/test_roundtrip.py(маркерintegration): положить файл в MinIOuploads/…, опубликоватьrequest-tabular.json, собрать сообщенияrecognition.result: первое —processing, второе —error NOT_IMPLEMENTEDс правильнымиNats-Msg-Id; повторная публикация запроса даёт только ещё один ack; проверка: зелёный против compose
Task 11: [5.1] make check-full
make check-full:make check+pytest -m integration+docker build; проверка: зелёный против compose docs на веткеfeat/1-slice-0-skeleton
Task 12: [5.2] Прогон DoD
- Прогон DoD:
make up→make check-full→ ручная проверка изdocs/dev/README.md(«проверка окружения»);openspec validate slice-0-skeleton --strict; выводmake check-full— в описание PR