- Architecture: overview, 7 ADR, tech stack - Principles: code-style, git-workflow, security - API contracts: auth, profile, tests, admin endpoints - Database schema: tables, relationships, indexes - LLM strategy: prompts, fallback, validation, Qwen 2.5 14B - Onboarding: setup, Docker, .env template - Progress: roadmap, changelog - Agents: context, backend instructions Made-with: Cursor
3.3 KiB
Общая архитектура
Tech stack
| Слой | Технология | Назначение |
|---|---|---|
| Backend | Fastify + TypeScript | REST API сервер |
| ORM | Drizzle ORM | Типизированный доступ к БД |
| Database | PostgreSQL | Основное хранилище |
| Cache | Redis | Кэш вопросов, сессии, rate limiting |
| Frontend | React + TypeScript + Vite | SPA клиент |
| LLM | Локальный LLM (dev), облачный API (prod) | Генерация вопросов |
| Логирование | Pino | Структурированные JSON-логи |
| Мониторинг ошибок | Sentry | Отлов ошибок в production |
| Deploy | VPS + Docker Compose | Хостинг |
Схема взаимодействия
flowchart TB
Browser["Browser (React SPA)"]
API["Fastify API"]
DB["PostgreSQL"]
Cache["Redis"]
LLM["LLM Service"]
LocalLLM["Local LLM (dev)"]
CloudLLM["Cloud API (prod)"]
Browser -->|"HTTP/JSON"| API
API --> DB
API --> Cache
API --> LLM
LLM --> LocalLLM
LLM --> CloudLLM
Структура репозиториев
samreshu-backend Fastify + TS + Drizzle
samreshu-frontend React + TS + Vite
samreshu-docs Документация, ADR, прогресс
Общие типы хранятся в каждом репо отдельно — без отдельного shared-пакета.
Архитектурные принципы
Принципы, не обсуждаемые при написании любого кода:
1. Подписка читается из БД через middleware
user.plan всегда определяется через subscription middleware. Права никогда не хардкодятся в контроллерах.
2. Снепшот вопросов при старте теста
Вопросы копируются в test_questions при создании теста. Во время прохождения теста question_bank никогда не читается напрямую.
3. LLM-вызовы только через LlmService
Остальной код не знает, какая модель работает. Провайдер, URL и ключ задаются через переменные окружения.
4. Валидация внешних данных по JSON-схеме
Все внешние события (webhooks, ответы LLM) валидируются. Внешним данным не доверяем без проверки.
5. Проверки прав и лимитов только на backend
Frontend только отображает состояние. Все авторизационные решения принимаются на сервере.
6. Все даты в UTC
Хранение и передача дат — UTC. Конвертация в часовой пояс пользователя только на фронте.
7. Конфигурация через переменные окружения
Никаких хардкодов. Все настройки (БД, Redis, LLM, ключи) читаются из .env.