master/tasks.md

11 KiB
Raw Blame History

План работ: web-python-skelet

Контекст

  • Источник требований: AGENTS.md и ADR docs/001-docs/004
  • Текущее состояние: в adapter/, domain/, usecase/, repository/, test/ пока только __init__.py
  • Отсутствуют рабочие каталоги и файлы из целевой структуры: adapter/config/, adapter/otel/, adapter/di/, adapter/http/fastapi/, config/, main.py
  • Ограничения: docs/ и tasks.md не добавлять в git; коммиты не делать; работать по одной задаче
  • ADR пока покрывают архитектуру, новые ADR нужны только если по ходу работ изменится решение

Правила выполнения

  • Каждую задачу выполнять отдельным заходом, без параллельной реализации
  • Каждый субагент отдает diff, список измененных файлов и проверку, но не делает commit
  • Если в задаче всплывает архитектурное изменение, остановиться и вынести вопрос на согласование

Очередь задач

T01. Базовый каркас домена и usecase

  • Исполнитель: primary-agent (scaffolding)
  • Статус: completed
  • Зависимости: нет
  • Commit required: no
  • Scope: создать базовые файлы и контракты в domain/, usecase/, repository/
  • Файлы: domain/error.py, domain/user.py, usecase/interface.py, usecase/user.py, repository/user.py
  • Критерии приемки: зависимости направлены внутрь; в domain/ и usecase/ нет FastAPI/OTel; есть пример сущности, ошибок, портов и простого usecase

T02. Конфиг из YAML и env

  • Субагент: feature-developer
  • Статус: completed
  • Зависимости: T01
  • Commit required: no
  • Scope: собрать typed-config слой в adapter/config/ и подготовить базовые yaml-файлы
  • Файлы: adapter/config/*, config/app.yaml
  • Критерии приемки: конфиг собирается в одну dataclass-структуру; секреты читаются из env; парсинг и валидация не протекают в inner layers

T03. Observability порты и OTel adapter

  • Субагент: feature-developer
  • Статус: completed
  • Зависимости: T01, T02
  • Commit required: no
  • Scope: реализовать логгер, метрики, трейсинг и bootstrap OTel в adapter/otel/ через интерфейсы из usecase/interface.py
  • Файлы: adapter/otel/*, config/otel-collector.yaml
  • Критерии приемки: inner layers знают только интерфейсы; OTLP exporter настраивается из конфига; нет кастомного trace middleware

T04. Composition root и lifetime singleton-объектов

  • Субагент: feature-developer
  • Статус: completed
  • Зависимости: T01, T02, T03
  • Commit required: no
  • Scope: собрать контейнер и startup wiring в adapter/di/
  • Файлы: adapter/di/container.py, adapter/di/__init__.py
  • Критерии приемки: repository/usecase создаются один раз на старте; контейнер хранит инстансы явно; нет пересоздания на HTTP-запрос

T05. FastAPI adapter как заменяемый web layer

  • Субагент: feature-developer
  • Статус: completed
  • Зависимости: T04
  • Commit required: no
  • Scope: поднять HTTP adapter в adapter/http/fastapi/ с app factory, lifespan, dependencies, middleware и router /api/v1
  • Файлы: adapter/http/fastapi/*, main.py
  • Критерии приемки: FastAPI изолирован в adapter-слое; handlers тонкие; request logging и metrics middleware подключены; usecase/repository берутся из контейнера

T06. Локальный runtime и compose-окружение

  • Субагент: feature-developer
  • Статус: completed
  • Зависимости: T02, T03, T05
  • Commit required: no
  • Scope: добавить контейнерный runtime для сервиса и compose-окружение с OTel и UI для просмотра логов, метрик и трейсов
  • Файлы: Dockerfile, docker-compose.yml
  • Ограничения: не трогать репозиторный config/app.yaml; docker должен прокидывать свой runtime-config внутрь контейнера; Dockerfile только с двумя стадиями build и run
  • Критерии приемки: make compose-build и make compose-up опираются на существующие файлы; сервис поднимается в контейнере; OTel telemetry уходит в dockerized stack; есть UI для просмотра логов, метрик и трейсов; для локального docker-окружения достаточно только Dockerfile и docker-compose.yml

T07. Тесты на lifetimes, config и HTTP smoke

  • Субагент: test-engineer
  • Статус: pending
  • Зависимости: T01, T02, T03, T04, T05, T06
  • Commit required: no
  • Scope: покрыть тестами ключевые архитектурные гарантии
  • Файлы: test/*
  • Критерии приемки: есть тест на singleton lifetime для repository/usecase; есть тест merge YAML+env; есть smoke-тест для /api/v1; тесты не тянут FastAPI/OTel в inner layers

T08. Архитектурный и boundary review

  • Субагент: code-reviewer
  • Статус: pending
  • Зависимости: T07
  • Commit required: no
  • Scope: проверить импорты, соблюдение слоев, startup lifetimes и заменяемость web adapter
  • Файлы: весь измененный код
  • Критерии приемки: dependency direction не нарушен; FastAPI и OTel не протекают в domain/ и usecase/; замечания сформулированы как точечные правки или подтверждение готовности к review

T09. Конфигурируемый runtime observability

  • Субагент: feature-developer
  • Статус: completed
  • Зависимости: T03, T04, T05
  • Commit required: no
  • Scope: сделать конфигурируемый runtime observability с настраиваемым sink и форматом логов, плюс отдельными флагами для метрик и трейсов
  • Файлы: adapter/config/*, adapter/observability/*, adapter/otel/*, adapter/di/*, adapter/http/fastapi/*, config/app.yaml, при необходимости main.py
  • Конфиг: logging.output=stdout|file|otel, logging.format=text|json, logging.file_path=..., metrics.enabled=true|false, tracing.enabled=true|false
  • Решение: вынести выбор runtime в отдельный adapter-layer factory; domain/ и usecase/ не менять; для stdout и file поддержать оба формата text и json; logging.file_path использовать только при logging.output=file; при отключенных метриках и трейсах использовать Noop-реализации; OTel runtime поднимать только если нужен хотя бы для одного сигнала
  • Критерии приемки: при logging.output=stdout логи идут в stdout в формате text или json по конфигу; при logging.output=file логи пишутся в файл по пути logging.file_path в формате text или json; при logging.output=otel логи уходят в collector; metrics.enabled=false отключает метрики и metrics middleware; tracing.enabled=false отключает FastAPI instrumentation и tracer runtime; DI продолжает отдавать единый runtime через контейнер; внутренние слои по-прежнему знают только порты

T10. ADR: раннее подключение OTel к FastAPI

  • Исполнитель: primary-agent (docs)
  • Статус: completed
  • Зависимости: нет
  • Commit required: no
  • Scope: зафиксировать правило, что FastAPI OTel instrumentation выполняется до первой сборки middleware_stack
  • Файлы: docs/005-fastapi-otel-early-instrumentation.md
  • Критерии приемки: ADR занимает 10-20 строк; описаны context, decision, consequences; решение не переписывает историю прошлых ADR

T11. Перенос FastAPI OTel bootstrap в app factory

  • Субагент: feature-developer
  • Статус: completed
  • Зависимости: T10
  • Commit required: no
  • Scope: перенести создание container, установку FastAPIInstrumentor.instrument_app(...) из lifespan в create_app, оставив в lifespan только shutdown
  • Файлы: adapter/http/fastapi/app.py, adapter/http/fastapi/lifespan.py, при необходимости adapter/http/fastapi/dependencies.py
  • Ограничения: не использовать ручной rebuild app.middleware_stack; не менять domain/ и usecase/; не добавлять бизнес-логику; сохранить singleton-lifetime container
  • Критерии приемки: instrumentation происходит до первой сборки middleware stack; OpenTelemetryMiddleware попадает в runtime stack без workaround; shutdown закрывает instrumentation и runtime один раз; compose-конфиг продолжает работать

T12. Регрессионная проверка HTTP telemetry wiring

  • Субагент: test-engineer
  • Статус: pending
  • Зависимости: T11
  • Commit required: no
  • Scope: добавить проверку, что раннее instrumentation wiring сохраняется и не требует ручного rebuild middleware stack
  • Файлы: test/*
  • Ограничения: без реального collector; проверять через ASGI/lifespan или локальные assertions по app runtime; не тянуть FastAPI и OTel в inner-layer тесты
  • Критерии приемки: тест подтверждает, что при включенных metrics/tracing OpenTelemetryMiddleware присутствует в runtime stack; тест не зависит от внешнего OTel collector; существующие архитектурные границы не нарушены