# Вводная часть Веб‑приложение, в котором авторизованный пользователь выбирает стек (HTML/CSS/JS/Web basics) и уровень (базовый/начинающий), получает тест из 10 или 20 теоретических вопросов, сгенерированных LLM, отвечает, а в конце видит результат с разбором ошибок. ## Минимальный MVP Регистрация / логин / выход ```text ✅ Подтверждение email ✅ Восстановление пароля ✅ Профиль (никнейм, страна) ✅ Создание теста (стек + уровень + количество вопросов) ✅ Прохождение теста (вопросы, таймер, прогресс) ✅ Результаты (балл, разбор, объяснения) ✅ Базовая история (последние 10 тестов) ✅ LLM генерация вопросов + fallback на банк ✅ Минимальная админка (QA очередь вопросов) ``` ## Максимальный MVP (целевое состояние продукта) Это не то, что делаем сейчас — это то, к чему ведём. Все решения в коде, БД и архитектуре принимаем с оглядкой на эту картину. ### Пользователи и роли ```text Guest → видит лендинг, описание тарифов, примеры вопросов Free → базовый функционал, 5 тестов/день, 3 стека Pro → полный функционал, безлимит, все стеки Admin → модерация контента, управление пользователями ``` ### Модули и их максимальный объём #### Auth ```text ✅ Email + пароль ✅ Подтверждение email ✅ Восстановление пароля ✅ OAuth (GitHub + Google) ✅ 2FA (TOTP: Google Authenticator) ✅ Управление сессиями (список устройств, logout везде) ``` #### Профиль ```text ✅ Никнейм, аватар, страна, город ✅ Уровень (jun/mid/sen — самооценка) ✅ Статистика на странице профиля ✅ Публичный профиль (по username) ✅ Приватность (скрыть из рейтингов) ``` #### Тестирование ```text ✅ Стеки: HTML, CSS, JS, TS, React, Vue, Node.js, Git, Web basics ✅ Уровни: Базовый, Начинающий, Средний, Продвинутый, Эксперт ✅ Типы вопросов: - Single choice - Multiple select - True/False - Short text (LLM-верификация) - Code reading (что выведет код) ← Phase 3 - Bug fixing (найди ошибку) ← Phase 3 ✅ Режимы: - Фиксированный (10/20/30 вопросов) - Бесконечный (только Pro) - Марафон (100 вопросов, только Pro) ← Phase 3 ✅ Таймер (на весь тест или на вопрос) ✅ Подсказки (Pro, 1 на вопрос) ✅ Пауза теста (сохранение прогресса) ← Phase 2 ``` #### Результаты и аналитика ```text ✅ Итоговый экран (балл, время, статус) ✅ Детальный разбор (вопрос → ответ → объяснение) ✅ История всех попыток (фильтры, поиск) ✅ Статистика по темам (% правильных) ✅ График прогресса по времени ✅ Слабые места + LLM-рекомендации (Pro) ✅ Экспорт истории в CSV (Pro) ``` #### Рейтинги (Pro) ```text ✅ Глобальный лидерборд (Top 100) ✅ Рейтинг по стекам ✅ Сезонный рейтинг (ежемесячный) ✅ Позиция пользователя (даже вне Top 100) ✅ Бейджи и достижения ✅ Архив сезонов ``` #### Подписка и биллинг ```text ✅ Free план (всегда) ✅ Pro: 699₽/мес или 6999₽/год ✅ Пробный период 5 дней (с привязкой карты) ✅ Автопродление / отмена ✅ ЮKassa (основной провайдер) ✅ CloudPayments (резервный) ✅ Региональные цены (Казахстан, Беларусь, Закавказье) ✅ Промокоды и скидки ✅ История платежей в ЛК ``` #### Уведомления ```text ✅ Email: verify, reset, trial, billing ✅ In-app баннеры и тосты ✅ Telegram-бот (Phase 3) ✅ Push-уведомления (Phase 3) ``` #### Контент / LLM ```text ✅ Генерация вопросов по стеку/уровню/типу ✅ Проверка short text через LLM ✅ Подсказки (один наводящий вопрос) ✅ LLM-рекомендации по слабым местам ✅ Мультимодельная оркестрация (local + cloud fallback) ✅ Банк вопросов с QA-циклом ✅ Кэш и переиспользование вопросов ``` #### Админка ```text ✅ QA очередь вопросов (approve/reject/edit) ✅ Управление пользователями (бан, сброс лимитов) ✅ Просмотр жалоб на вопросы ✅ Операционная панель (метрики, ошибки) ✅ Управление промокодами ✅ Прогрев кэша вопросов ``` *** ### Полная схема данных (ориентир) ```text users ├── subscriptions (план, статус, даты) ├── sessions (устройства, refresh токены) ├── oauth_accounts (GitHub/Google) ├── totp_secrets (2FA) │ ├── tests │ └── test_questions (снепшот вопросов) │ ├── user_stats (агрегаты по темам) ├── user_achievements (бейджи) └── user_question_log (какие вопросы видел, когда) question_bank ├── question_cache_meta (LLM метаданные) └── question_reports (жалобы) payments └── payment_events (webhook лог) audit_logs (действия админов) notifications_log (история отправок) promo_codes (промокоды) ``` *** ### Что закладываем архитектурно с первого дня Это **принципы, не обсуждаемые** при написании любого кода: ```text 1. user.plan всегда читается из БД через subscription middleware → никогда не хардкодить права в контроллерах 2. Вопросы копируются в test_questions при старте теста (снепшот) → никогда не читать question_bank "живьём" во время теста 3. Все LLM-вызовы только через LlmService → остальной код не знает какая модель работает 4. Все внешние события (webhooks, LLM) валидируются по JSON-схеме → никогда не доверять внешним данным без валидации 5. Все проверки прав и лимитов только на backend → frontend только отображает состояние 6. Все даты хранятся в UTC → конвертация в часовой пояс только на фронте 7. Все конфигурации через env переменные → никаких хардкодов в коде ``` *** ### Фазы разработки ```text MVP 0 (сейчас) └── Auth + Test (2 стека) + Results + Базовая история Phase 1 (платный запуск) └── Все стеки + Подписка + Trial + Лимиты FREE/PRO Phase 2 (рост) └── Рейтинги + Аналитика Pro + 2FA + OAuth + Multiple select + Short text Phase 3 (зрелость) └── Код-задачи + Бесконечный режим + Telegram + Достижения + Региональные цены ``` *** ### Фиксируем в docs-репо ```markdown # architecture/decisions/001-max-mvp-scope.md ## Контекст Определяем максимальный целевой объём продукта, чтобы архитектурные решения MVP не конфликтовали с будущим функционалом. ## Решение [ссылка на этот документ] ## Последствия - Схема БД создаётся с заделом на все фазы - LLM-слой абстрагирован с первого дня - Subscription middleware существует с первого дня (даже когда все пользователи Free) ``` *** ## Структура репозиториев ```text samreshu-backend (Node.js + TS + API) samreshu-frontend (React + TS + Vite) samreshu-shared (общие TS-типы/интерфейсы) samreshu-docs (документация, ADR, прогресс) ``` ### Структура samreshu-docs ```text samreshu-docs/ ├── README.md # Навигация по доке ├── architecture/ │ ├── overview.md # Общая архитектура │ ├── decisions/ # ADR │ │ ├── 001-monorepo-vs-polyrepo.md │ │ ├── 002-postgresql-provider.md │ │ ├── 003-llm-abstraction.md │ │ └── ... │ └── diagrams/ # Схемы (Mermaid / draw.io) ├── principles/ │ ├── code-style.md # Соглашения по коду │ ├── git-workflow.md # Ветки, коммиты, PR │ └── security.md # Базовые правила безопасности ├── api/ │ └── openapi.yaml # Контракт API (или ссылка) ├── database/ │ └── schema.md # Описание таблиц и связей ├── progress/ │ ├── roadmap.md # Что планируем │ └── changelog.md # Что сделали └── onboarding/ └── setup.md # Как поднять проект локально ``` *** ## Окружение разработчика ### Базовые требования ```text Node.js >= 20 LTS (через nvm) npm >= 10 Git >= 2.40 Docker + Docker Compose (для локальной БД и Redis) VS Code (рекомендован, настройки в репо) ``` ### .nvmrc (в корне каждого репо) ```text 20 ``` *** ## Backend: вспомогательные инструменты ### 1. ESLint ```bash npm install -D \ eslint \ @eslint/js \ typescript-eslint \ eslint-plugin-import \ eslint-plugin-security \ eslint-config-prettier ``` ```ts // eslint.config.ts (flat config, актуальный формат ESLint 9+) import js from '@eslint/js' import tseslint from 'typescript-eslint' import security from 'eslint-plugin-security' import importPlugin from 'eslint-plugin-import' export default tseslint.config( js.configs.recommended, ...tseslint.configs.recommended, { plugins: { security, import: importPlugin }, rules: { '@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/explicit-function-return-type': 'warn', 'security/detect-object-injection': 'warn', 'import/order': ['error', { 'newlines-between': 'always' }], 'no-console': 'warn', } } ) ``` *** ### 2. Prettier ```bash npm install -D prettier ``` ```json // .prettierrc { "semi": false, "singleQuote": true, "tabWidth": 2, "trailingComma": "all", "printWidth": 100, "endOfLine": "lf" } ``` ```text // .prettierignore dist/ node_modules/ *.sql ``` *** ### 3. Husky + lint-staged (проверки перед коммитом) ```bash npm install -D husky lint-staged npx husky init ``` ```json // package.json { "lint-staged": { "*.{ts,js}": ["eslint --fix", "prettier --write"], "*.{json,md}": ["prettier --write"] } } ``` ```bash # .husky/pre-commit npx lint-staged ``` *** ### 4. Commitlint (единый стиль коммитов) ```bash npm install -D @commitlint/cli @commitlint/config-conventional ``` ```ts // commitlint.config.ts export default { extends: ['@commitlint/config-conventional'], } ``` ```bash # .husky/commit-msg npx --no -- commitlint --edit $1 ``` **Формат коммитов:** ```text feat: добавить генерацию вопросов через LLM fix: исправить подсчёт результатов теста chore: обновить зависимости docs: добавить описание LLM-модуля refactor: переработать subscription middleware test: добавить тесты для auth сервиса ``` *** ### 5. TypeScript (строгий режим) ```json // tsconfig.json { "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true, "noUncheckedIndexedAccess": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "esModuleInterop": true, "skipLibCheck": true, "outDir": "dist", "rootDir": "src", "paths": { "@/*": ["./src/*"] } }, "include": ["src"], "exclude": ["node_modules", "dist"] } ``` *** ### 6. Vitest (тесты) ```bash npm install -D vitest @vitest/coverage-v8 ``` ```ts // vitest.config.ts import { defineConfig } from 'vitest/config' export default defineConfig({ test: { globals: true, environment: 'node', coverage: { provider: 'v8', reporter: ['text', 'lcov'], thresholds: { lines: 70 }, // минимальное покрытие MVP } } }) ``` *** ## Frontend: вспомогательные инструменты ```bash npm install -D \ eslint \ typescript-eslint \ eslint-plugin-react \ eslint-plugin-react-hooks \ eslint-plugin-jsx-a11y \ prettier \ husky \ lint-staged \ @commitlint/cli \ @commitlint/config-conventional \ vitest \ @testing-library/react \ @testing-library/user-event ``` **Отличия от backend:** - `eslint-plugin-react-hooks` — обязателен, ловит типичные ошибки с хуками - `eslint-plugin-jsx-a11y` — базовая доступность (a11y) прямо в линтере - `@testing-library/react` вместо чистого vitest для компонентов *** ## .editorconfig (общий для всех репо) ```ini root = true [*] charset = utf-8 end_of_line = lf indent_style = space indent_size = 2 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false ``` *** ## VS Code: рекомендуемые расширения ```json // .vscode/extensions.json { "recommendations": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "prisma.prisma", "bradlc.vscode-tailwindcss", "eamodio.gitlens", "streetsidesoftware.code-spell-checker-russian", "usernamehw.errorlens", "ms-azuretools.vscode-docker", "mikestead.dotenv" ] } ``` ```json // .vscode/settings.json { "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, "typescript.preferences.importModuleSpecifier": "non-relative" } ``` *** ## Итог: что фиксируем в docs-репо прямо сейчас ```markdown # principles/code-style.md - Язык кода: английский (переменные, функции, комментарии) - Язык коммитов: английский (conventional commits) - Язык документации: русский - Форматтер: Prettier (конфиг в репо — не обсуждается) - Линтер: ESLint strict + security plugin - Тесты: Vitest, минимум 70% покрытие на сервисном слое - any в TypeScript: запрещён (только через явный комментарий с обоснованием) - console.log в коде: запрещён в prod (только через logger) ```