Это шаблон Python-сервиса на чистой архитектуре с заменяемым web-слоем, типизированным конфигом, явным dependency wiring и observability через порты. ## Что это за проект - Небольшой референсный сервис со слоями `domain/`, `usecase/`, `repository/` и `adapter/` - Шаблон для сервисов на FastAPI, где FastAPI остается только во внешнем HTTP adapter - Проект, где конфиг собирается из `config/app.yaml`, `.env` и env vars в одно дерево dataclass-конфигов - Проект, где repository и usecase создаются один раз на старте приложения в composition root - Проект, где логи, метрики и трейсы скрыты за интерфейсами и могут работать через `stdout`, файл или OpenTelemetry runtime ## Основные идеи - Clean Architecture и границы SOLID - Направление зависимостей только внутрь - Тонкие adapter-слои и явная сборка зависимостей - Заменяемый HTTP-слой - Observability без протекания OpenTelemetry во внутренние слои ## Быстрый старт ```bash make install APP_API_TOKEN=local-api-token APP_SIGNING_KEY=local-signing-key make run ``` Приложение стартует на `http://0.0.0.0:8123` и публикует versioned API под `/api/v1`. ## Документация ### Гайды - [Правила проекта и ограничения для агента](AGENTS.md) - [Кодстайл проекта для AI-агента](docs/CODESTYLE.md) - [Чистая архитектура, SOLID, DIP, Protocol и repository](docs/CLEAN_ARCHITECTURE_RU.md) - [Логи, метрики и трейсы в этом проекте](docs/OBSERVABILITY_RU.md) - [Как чистая архитектура реализована здесь](docs/PROJECT_GUIDE_RU.md) - [План задач и история работ](tasks.md) ### ADR - [001 Composition Root and Lifetimes](docs/001-composition-root-and-lifetimes.md) - [002 Config From YAML and Env](docs/002-config-yaml-plus-env.md) - [003 Observability Via Interfaces](docs/003-observability-via-interfaces.md) - [004 Versioned HTTP API](docs/004-versioned-http-api.md) - [005 Early FastAPI OTel Instrumentation](docs/005-fastapi-otel-early-instrumentation.md) ## Структура проекта - `domain/` - core-сущности и доменные ошибки - `usecase/` - прикладные сценарии и порты - `repository/` - реализации repository - `adapter/config/` - загрузка и модели типизированного конфига - `adapter/observability/` - выбор runtime для logger, metrics и tracer - `adapter/otel/` - OpenTelemetry adapters - `adapter/di/` - composition root и singleton wiring - `adapter/http/fastapi/` - HTTP-схемы, dependencies, middleware и routers - `config/` - YAML-конфиг приложения и локального OTel collector ## Для ИИ Если ты AI-агент и собираешься что-то менять в проекте, сначала прочитай документы в таком порядке: 1. [Правила проекта и ограничения агента](AGENTS.md) - обязательные правила работы в этом репозитории 2. [Кодстайл проекта для AI-агента](docs/CODESTYLE.md) - границы слоев, стиль кода и правила зависимостей 3. [Как чистая архитектура реализована здесь](docs/PROJECT_GUIDE_RU.md) - практическая карта проекта и типовые сценарии изменений 4. [Чистая архитектура, SOLID, DIP, Protocol и repository](docs/CLEAN_ARCHITECTURE_RU.md) - базовые архитектурные принципы и примеры 5. [Логи, метрики и трейсы в этом проекте](docs/OBSERVABILITY_RU.md) - читать перед любыми изменениями в observability, middleware и runtime wiring 6. [ADR в `docs/`](docs/001-composition-root-and-lifetimes.md) - читать релевантные решения перед изменением архитектуры или startup wiring 7. [План задач и история работ](tasks.md) - понять, что уже сделано, что отложено и какие ограничения были зафиксированы Перед началом работы: - Определи, в каком слое будет изменение: `domain/`, `usecase/`, `repository/` или `adapter/` - Убедись, что зависимости идут только внутрь - Не тащи FastAPI и OpenTelemetry во внутренние слои - Сначала изучи существующий код в нужной директории, потом вноси изменения - Если задача затрагивает архитектурное решение, сначала сверяйся с ADR и проектными правилами ## Запуск и команды - Для локального запуска нужны `APP_API_TOKEN` и `APP_SIGNING_KEY` - `make run` запускает приложение локально - `make run-otel` запускает приложение с локальными OTel endpoints из env vars - `make pre-commit` запускает `ruff`, `mypy` и `pytest` - `make compose-up` поднимает приложение и локальный LGTM stack через Docker Compose