# Архитектура проекта ## Слоистая архитектура Проект построен по принципу строгой слоистости. Зависимости могут идти **только внутрь** — от API к Core. ``` ┌─────────────────────────────────────────────────────┐ │ API │ │ HTTP роуты, Pydantic валидация, OpenAPI │ │ Зависимости: Services │ ├─────────────────────────────────────────────────────┤ │ Services │ │ Бизнес-логика, оркестрация │ │ Зависимости: Integrations, Data │ ├─────────────────────────────────────────────────────┤ │ Integrations │ │ Внешние API, AI провайдеры, fallback chain │ │ Зависимости: Data │ ├─────────────────────────────────────────────────────┤ │ Tasks │ │ Фоновые задачи (Celery или прямой вызов) │ │ Зависимости: Services, Integrations │ ├─────────────────────────────────────────────────────┤ │ Agents │ │ Системные агенты (саморазвитие проекта) │ │ Зависимости: Services, Integrations │ ├─────────────────────────────────────────────────────┤ │ Data │ │ Модели БД, репозитории, миграции │ │ Зависимости: Core │ ├─────────────────────────────────────────────────────┤ │ Core │ │ Config, base classes, security, dependencies │ │ Зависимости: нет (фундамент) │ └─────────────────────────────────────────────────────┘ ``` ### Правила слоёв 1. **API** не знает про БД. Он получает `db: AsyncSession` через `Depends(get_db)`, но не создаёт сессии сам. Он не импортирует модели. 2. **Services** не знают про HTTP. Они не импортируют FastAPI, Request, Response, HTTPException. Работают с бизнес-данными через сессию БД. 3. **Integrations** не знают про бизнес-логику. Они оборачивают внешние API, управляют таймаутами и ретраями. 4. **Data** (models) — SQLAlchemy модели. Не содержат бизнес-логики. Только структура данных. 5. **Core** — фундамент. Config читает .env, base содержит абстракции, security управляет JWT, dependencies содержит FastAPI-зависимости. --- ## SOLID в проекте ### S — Single Responsibility Каждый модуль делает одну вещь: - `idea_service.py` — только операции с идеями - `yandex_gpt.py` — только вызов Yandex GPT - `auth.py` — только аутентификация ### O — Open/Closed Новые интеграции — новые классы, а не модификация старых: - `AIProvider` (ABC) → `YandexGPTProvider`, `GigaChatProvider` - `BaseAgent` (ABC) → `DocAgent`, `AuditAgent`, ... ### L — Liskov Substitution Сервисы принимают `AsyncSession` — любую реализацию (SQLite, PostgreSQL): - Код работает одинаково на обеих БД ### I — Interface Segregation Сервис принимает только то, что нужно: - `IdeaService(db)` — не принимает config, security, и т.д. - `AuthService(db, settings)` — принимает то, что реально нужно ### D — Dependency Inversion API зависит от `IdeaService`, а не от `IdeaServicePostgres`: - Сервисы — это абстракция над слоем данных - Можно подменить реализацию не меняя API --- ## Dependency Injection Сессия БД создаётся FastAPI и передаётся через Depends: ```python async def get_db() -> AsyncSession: async with async_session_maker() as session: yield session ``` Сервисы получают сессию в конструкторе: ```python class IdeaService: def __init__(self, db: AsyncSession): self.db = db ``` API создаёт сервис на каждый запрос: ```python @router.get("/") async def list_ideas(db: AsyncSession = Depends(get_db)): service = IdeaService(db) return await service.list_all() ``` --- ## [ASK] Вопросы по архитектуре - Нужен ли Repository Pattern (отдельный слой между сервисами и моделями)? - Использовать ли CQRS (разделение чтения и записи)? - Нужен ли Event Bus для межсервисного взаимодействия?