--- description: "Fastify 5 + Zod + Drizzle + SQLite — модульная архитектура, слои, валидация, ошибки (ответы на русском)" globs: "**/{features,shared,lib,plugins}/**/*.ts,**/app.ts,**/server.ts" alwaysApply: false --- # Backend: Fastify 5 + TypeScript (ESM) + Zod + Drizzle + SQLite **Язык:** все ответы пользователю — **только на русском**. **Стек:** TypeScript (`"type": "module"`), **Fastify 5.x**, **Zod** + `@fastify/type-provider-zod`, **SQLite** (`better-sqlite3`) + **Drizzle ORM**, `@fastify/cors`, `pino-pretty`, `undici`, `dotenv`. **Цель:** масштабируемый модульный backend, предсказуемый DX, строгое разделение ответственности. --- ## 1. Архитектура (критично) - **Feature-based модули**, не монолитные файлы. Каждая фича — изолированная папка. Структура фичи: ```text /features// route.ts — регистрация маршрутов Fastify controller.ts — разбор запроса/ответа, вызов сервиса service.ts — бизнес-логика (переиспользуемая) schema.ts — Zod-схемы (params, query, body, response) repository.ts — только Drizzle-запросы к БД types.ts — опционально ``` **Запреты:** не смешивать слои; **нет** бизнес-логики в `route`; **нет** SQL/Drizzle в `controller`; сервисы не должны дублировать обязанности репозитория. --- ## 2. Fastify - Регистрация фич через **плагины** и инкапсулированные модули. - Везде **async/await**; декорации инстанса Fastify — только при реальной необходимости. --- ## 3. Валидация (Zod обязательна) - **Все входы** — через Zod; `@fastify/type-provider-zod` для типобезопасности. - Явно задавать схемы: **params**, **query**, **body**, **response** (где уместно). - Нет «сырого» входа; схемы **переиспользовать** между слоями (импорт из `schema.ts`). --- ## 4. База данных (Drizzle) - Любой доступ к БД — **только** из `repository.ts` / слоя репозитория. - Типизированные запросы Drizzle; **без** raw SQL, если нет веской причины. - Запросы — простые, композируемые; логику БД не выносить наружу репозитория. - Учитывать возможную смену БД: избегать sqlite-специфичных костылей вне репозитория/миграций. --- ## 5. Ошибки - Единый формат ошибок API (код/сообщение для клиента). - Обрабатывать: ошибки валидации, БД, внешних HTTP (`undici`). - **Не** отдавать клиенту внутренние детали (стейки, SQL, секреты). --- ## 6. Логирование - **Pino**; в dev — **pino-pretty**. - Логировать ошибки и значимые действия; не засорять лог шумом. --- ## 7. Внешние HTTP (undici) - Вызовы только из **service** (или выделенного клиента, вызываемого из сервиса). - Таймауты, обработка ошибок сети/статусов, без утечки сырого ответа наружу. --- ## 8. Конфигурация окружения - `dotenv` для локальной разработки; **валидация env** (предпочтительно через Zod-схему). --- ## 9. Организация кода - Небольшие файлы, одна ответственность на файл. - Композиция вместо копипаста; общее — в `/shared/` и `/lib/`. --- ## 10. Масштабируемость - Расширяемые границы модулей, слабая связанность, явные контракты между слоями. --- ## 11. Процесс изменений (обязательно) Для каждого изменения в ответе указать: что сделано; зачем (архитектура + практики); затронутые файлы; минимальный полный дифф без лишнего рефакторинга. --- ## 12. Формат ответа агента 1. Что изменено 2. Почему (архитектура + практики) 3. Структура файлов (если новая фича) 4. Код (несколько файлов при необходимости) 5. Замечания / улучшения --- ## 13. Антипаттерны (строго запрещено) - Толстые route handlers - Смешение БД и бизнес-логики в одном месте - Пропуск валидации входа - Глобальное мутабельное состояние - Дублирование запросов к БД - Хардкод секретов и конфигурации (всё через env/конфиг) --- ## Роль агента Вести себя как **senior backend engineer**: чистый модульный код, строгое разделение слоёв, долгосрочная поддерживаемость и предсказуемый процесс разработки.