Срез 0 (issue #1): раздел «Соглашения шаблона» (что оставлено от шаблона команды, что вырезается, что добавляется); change openspec/changes/slice-0-skeleton — proposal, design с таблицей «Decisions made without discussion», спеки и tasks; в openspec/config.yaml строки с двоеточием взяты в кавычки (YAML разбирал их как словари). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
55 lines
5.3 KiB
Markdown
55 lines
5.3 KiB
Markdown
# Tasks: Срез 0 — скелет tabular-parser
|
||
|
||
Репозиторий — tabular-parser; команды — из `api/`. Зависимости: 3.1 ждёт контракт v1.0 (`docs` 1.1–1.4);
|
||
интеграционные тесты 4.x — compose инфраструктуры (`docs` 2.1). Каждая задача ≤ половины дня.
|
||
|
||
## 1. Вырезать фронт и БД из шаблона
|
||
|
||
- [ ] 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`, `NATS_ACK_WAIT_SECONDS=600`, `NATS_MAX_DELIVER=3`;
|
||
`requirements.txt` без `asyncpg`, `SQLAlchemy`, `alembic`, `smbprotocol`, `argon2-cffi`, `raisa_fastapi_protected_api`;
|
||
проверка: `pip install -r requirements.txt` в чистом venv, `python run_server.py` стартует c `.env.example`, `/healthcheck` 200
|
||
- [ ] 1.3 `README.md` — описание сервиса (назначение, команды, 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; проверка: `ruff check . &&
|
||
ruff format --check . && mypy src` зелёные
|
||
- [ ] 2.2 `Dockerfile` (python:3.12-slim), `Makefile` (`up` — compose docs, `test`, `test-integration`, `lint`),
|
||
`.env.example`, `.env.test`; проверка: `docker build -t tabular-parser .` успешен
|
||
|
||
## 3. Контракт
|
||
|
||
- [ ] 3.1 `api/contracts/` — копии трёх схем + `examples/` из `../docs/contracts`; `src/contract/` — pydantic-модели
|
||
(`RecognitionRequest`, `RecognitionResultMessage`, `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()` с повтором при отсутствии stream, `publish_result(envelope,
|
||
msg_id)`; проверка: unit-тесты с фейковым соединением; интеграционный тест подключения к compose-NATS
|
||
- [ ] 4.3 `src/core/worker.py`: цикл `fetch(1)` → `handle(msg)`: валидация запроса → S3 get → `Parser` → S3 put результата →
|
||
конверт → publish → ack; таблица ошибок D-5; `metrics.duration_ms`; запуск/остановка в lifespan при `NATS_ENABLED`;
|
||
`/healthcheck.nats`; проверка: unit-тесты `handle` с фейками — сценарии spec (NOT_IMPLEMENTED, FILE_READ_ERROR,
|
||
SCHEMA_MISMATCH, подмена парсера → `done`, ошибка публикации → nak)
|
||
- [ ] 4.4 `tests/integration/test_roundtrip.py` (маркер `integration`): положить файл в MinIO `uploads/…`, опубликовать
|
||
`request-tabular.json`, дождаться конверта в `recognition.result`; проверить `Nats-Msg-Id`, `error.code = NOT_IMPLEMENTED`,
|
||
ack запроса (consumer info: `num_ack_pending = 0`); проверка: зелёный против compose
|
||
|
||
## 5. CI и завершение
|
||
|
||
- [ ] 5.1 `.gitea/workflows/ci.yml` из `../docs/dev/ci/python-service.yml` (блок `env`: tabular-parser, порт 8001, без шагов
|
||
arm-core); проверка: зелёный run на ветке `feat/1-slice-0-skeleton`
|
||
- [ ] 5.2 Прогон DoD: `make up` → `make test` → `make test-integration` → ручная проверка из `docs/dev/README.md`
|
||
(«проверка окружения»); `openspec validate slice-0-skeleton --strict`; результаты — в описание PR
|