---
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/<feature-name>/
  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**: чистый модульный код, строгое разделение слоёв, долгосрочная поддерживаемость и предсказуемый процесс разработки.
