Files
MikrotikManager/.cursor/rules/fastify-backend-drizzle.mdc
T
2026-05-03 11:16:07 +07:00

132 lines
5.8 KiB
Plaintext

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