# ROADMAP — LMS Second Brain **Стек:** Next.js 16.2.2 · React 19 · PostgreSQL 16 · Prisma 7 · Better Auth 1.6 · Tailwind v4 · shadcn/ui · TipTap · Kinescope · Resend · Hetzner Object Storage **Принцип:** один этап — одна рабочая фича. Не переходим к следующему, пока текущий не работает end-to-end. --- ## Этап 0 — Каркас, auth, роли ✅ ЗАВЕРШЁН (07.04.2026) - [x] Next.js 16.2.2 (App Router, TypeScript, Tailwind v4) - [x] Docker Compose: PostgreSQL 16 (прод на Hetzner) - [x] Prisma 7: схема User, Session, Account + полная LMS-модель - [x] Better Auth: вход по email/password, роли student/curator/admin - [x] Middleware: защита маршрутов по сессии - [x] Дашборды для трёх ролей - [x] Страница входа, регистрации, подтверждения email - [x] Seed: admin/curator/student (пароль: Password123!) - [x] Dockerfile multi-stage + docker-compose.prod.yml - [x] Caddy: school.second-brain.ru → порт 3010 --- ## Этап 1 — Курсы → Модули → Уроки (CRUD в админке) ✅ ЗАВЕРШЁН (07.04.2026) - [x] Prisma-схема: Course, Module, Lesson (с порядком, статусом published) - [x] Admin: список курсов, создать / редактировать / удалить курс - [x] Admin: список модулей внутри курса, drag-and-drop сортировка - [x] Admin: список уроков внутри модуля, drag-and-drop сортировка - [x] Admin: редактор урока с TipTap (заголовки, списки, цитаты, код, картинки, ссылки) - [x] Загрузка картинок в уроке → Hetzner Object Storage - [x] Поле для Kinescope ID в уроке - [x] Публикация/скрытие курса и урока (черновик / опубликован) - [x] Управление доступом: выдать / забрать доступ к курсу для пользователя - [x] Дизайн: Fira Mono, #F5F5F0, Aubade-карточки - [x] Admin: таблица пользователей (/admin/users) --- ## Этап 1.5 — Расширенное управление доступом ✅ ЗАВЕРШЁН (07.04.2026) - [x] Срок доступа: `expiresAt` в `CourseEnrollment`, просроченный подсвечивается красным - [x] Категории курсов: таблица `Category`, `/admin/categories`, привязка к курсу - [x] Расширенный энролл: `/admin/users/[userId]` — выбор нескольких курсов + срок одной операцией - [x] История доступа: `AccessLog` — каждая операция логируется (кто, когда, метод, примечание) --- ## Этап 2 — Интеграция Kinescope, рендер уроков для ученика ✅ ЗАВЕРШЁН (07.04.2026) - [x] Компонент `KinescopePlayer` — обёртка над `@kinescope/react-kinescope-player` - [x] Рендер урока для ученика: видео (если есть Kinescope ID) + текст + файлы - [x] Загрузка PDF/файлов к уроку (Object Storage), список для скачивания - [x] Страница курса для ученика: список модулей и уроков, статус прохождения - [x] Навигация по урокам: предыдущий / следующий - [x] Блокировка доступа к курсу без enrollment (layout server component) - [x] Страница «Мои курсы» в личном кабинете ученика (dashboard) - [x] Кнопки Сохранить / Просмотр в редакторе урока - [x] Иконка-статус уроков в боковой панели курса (✓ пройден) --- ## Этап 3 — Прогресс ✅ ЗАВЕРШЁН (07.04.2026) - [x] Prisma: таблица `LessonProgress` (userId, lessonId, completedAt) - [x] Кнопка «Урок завершён» — создаёт/удаляет запись в LessonProgress - [x] Прогресс-бар по курсу в боковой панели (% завершённых уроков) - [x] Прогресс-бар по курсу на дашборде студента - [x] Admin bypass: администратор видит все уроки без отметок о прогрессе --- ## Этап 5 — Домашние задания и обратная связь куратора ✅ ЗАВЕРШЁН (07.04.2026) - [x] Prisma: Homework, HomeworkSubmission, HomeworkFeedback - [x] Admin: добавить / редактировать / удалить блок ДЗ к уроку (HomeworkEditor) - [x] Ученик: форма отправки ДЗ (текст + файлы → Object Storage) - [x] Ученик: видит статус ДЗ и фидбек куратора в карточке урока - [x] Куратор / Admin: список ДЗ на проверку (`/curator/homework`) - [x] Куратор / Admin: просмотр работы, текстовый комментарий с обратной связью - [x] Admin: AdminShell на `/curator/*` маршрутах (сайдбар не пропадает) - [x] Admin: реальная статистика на дашборде (студенты, курсы, ДЗ, прогресс) --- ## Этап 6 — Обсуждения под уроками ✅ ЗАВЕРШЁН (07.04.2026) - [x] Prisma: LessonComment (soft-delete через поле `deleted`) - [x] Рендер списка комментариев под уроком (server-fetched, client-rendered) - [x] Форма отправки комментария (только для enrolled учеников и admin) - [x] Модерация: автор, куратор или admin может удалить комментарий - [x] Счётчик активных комментариев в заголовке секции --- ## Этап 7 — Email-уведомления ✅ ЗАВЕРШЁН (07.04.2026) - [x] Базовый HTML email-шаблон (фирменный стиль Second Brain) - [x] Приветственное письмо при регистрации (`databaseHooks.user.create.after`) - [x] Письмо ученику об открытии доступа к курсу - [x] Куратор / Admin: уведомление о новом ДЗ на проверку - [x] Ученик: уведомление о полученном фидбеке - [x] Resend domain: mailsend.second-brain.ru (verified) --- ## Этап 8 — Импорт уроков из Markdown (Obsidian) ✅ ЗАВЕРШЁН (07.04.2026) - [x] API: `POST /api/admin/import-md` — принимает .md-файл - [x] Парсинг frontmatter (title, kinescopeId, order, published) через `gray-matter` - [x] Конвертация Markdown → TipTap JSON через `unified` + `remark-parse` - [x] Поддержка: заголовки, параграфы, жирный/курсив/зачёркнутый, инлайн-код, блоки кода, цитаты, списки, ссылки, изображения (HTTP), горизонтальные разделители - [x] Очистка Obsidian-синтаксиса: `![[image]]` удаляется, `[[link|alias]]` → текст - [x] UI: кнопка «Импорт .md» в редакторе урока — заполняет форму без автосохранения --- ## Этап 9 — Миграция с emdesell ← СЛЕДУЮЩИЙ **Цель:** все пользователи и контент перенесены в новую LMS. - [ ] Скрипт импорта пользователей из CSV-экспорта emdesell (email, имя, курсы) - [ ] Создание пользователей без пароля + письмо «установите пароль» - [ ] Назначение доступов к курсам по данным из CSV - [ ] Чек-лист ручного переноса контента (уроки, PDF, структура курсов) - [ ] Скрипт проверки целостности: все enrolled пользователи имеют доступ к нужным курсам - [ ] QA: проверить 10 случайных аккаунтов после импорта **Критерий готовности:** все ученики из emdesell могут войти в новую LMS и продолжить обучение. --- ## Этап 10 — Telegram-бот и аналитика **Цель:** получаю уведомления в Telegram, вижу базовую аналитику. - [ ] Telegram-бот: уведомление куратору/админу о новом ДЗ - [ ] Telegram-бот: уведомление об ошибках (500-е, failed email и т.д.) - [ ] Yandex.Metrika: базовое подключение (pageviews) - [ ] Admin: простая страница аналитики (активные ученики, прогресс по курсам) --- ## Этап 11 — Тесты и квизы **Цель:** можно добавить тест к уроку, ученик проходит и получает результат. - [ ] Prisma: Quiz, QuizQuestion, QuizOption, QuizAttempt (схема уже есть) - [ ] Admin: создание теста к уроку (вопрос → варианты → отметить правильный) - [ ] Типы вопросов: одиночный выбор, множественный выбор, короткий текст - [ ] Рендер теста в уроке для ученика - [ ] Авто-проверка (single/multiple choice), результат сразу - [ ] Настройка: показывать правильные ответы после прохождения (да/нет) - [ ] Интеграция с прогрессом: урок с тестом засчитан только после прохождения теста **Критерий готовности:** добавляю тест из 3 вопросов к уроку, ученик проходит, видит результат, урок засчитывается. --- ## Бэклог (после MVP) - Резервное копирование PostgreSQL (cron → Object Storage) - GitHub Actions: CI/CD pipeline (lint → build → push Docker image → deploy) - Сертификаты по окончании курса - Геймификация (баллы, бейджи, рейтинги) - Промокоды и интеграция с платёжными системами - Дедлайны и расписания - Kinescope DRM (signed URLs) — при переходе на платный план - Водяные знаки на PDF и картинках - Мобильное приложение