c647b29712
- md-to-tiptap.ts: remark-based converter (headings, lists, blockquotes, code blocks, bold/italic/strike, links, images, hr) - Obsidian ![[wikilink]] stripped, [[link|alias]] → plain text - POST /api/admin/import-md: parses frontmatter (gray-matter) + converts content - LessonEditor: "Импорт .md" button populates editor without auto-save - ROADMAP: marked Stages 2, 3, 5, 6, 7, 8 as complete, fixed numbering Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
11 KiB
11 KiB
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)
- Next.js 16.2.2 (App Router, TypeScript, Tailwind v4)
- Docker Compose: PostgreSQL 16 (прод на Hetzner)
- Prisma 7: схема User, Session, Account + полная LMS-модель
- Better Auth: вход по email/password, роли student/curator/admin
- Middleware: защита маршрутов по сессии
- Дашборды для трёх ролей
- Страница входа, регистрации, подтверждения email
- Seed: admin/curator/student (пароль: Password123!)
- Dockerfile multi-stage + docker-compose.prod.yml
- Caddy: school.second-brain.ru → порт 3010
Этап 1 — Курсы → Модули → Уроки (CRUD в админке) ✅ ЗАВЕРШЁН (07.04.2026)
- Prisma-схема: Course, Module, Lesson (с порядком, статусом published)
- Admin: список курсов, создать / редактировать / удалить курс
- Admin: список модулей внутри курса, drag-and-drop сортировка
- Admin: список уроков внутри модуля, drag-and-drop сортировка
- Admin: редактор урока с TipTap (заголовки, списки, цитаты, код, картинки, ссылки)
- Загрузка картинок в уроке → Hetzner Object Storage
- Поле для Kinescope ID в уроке
- Публикация/скрытие курса и урока (черновик / опубликован)
- Управление доступом: выдать / забрать доступ к курсу для пользователя
- Дизайн: Fira Mono, #F5F5F0, Aubade-карточки
- Admin: таблица пользователей (/admin/users)
Этап 1.5 — Расширенное управление доступом ✅ ЗАВЕРШЁН (07.04.2026)
- Срок доступа:
expiresAtвCourseEnrollment, просроченный подсвечивается красным - Категории курсов: таблица
Category,/admin/categories, привязка к курсу - Расширенный энролл:
/admin/users/[userId]— выбор нескольких курсов + срок одной операцией - История доступа:
AccessLog— каждая операция логируется (кто, когда, метод, примечание)
Этап 2 — Интеграция Kinescope, рендер уроков для ученика ✅ ЗАВЕРШЁН (07.04.2026)
- Компонент
KinescopePlayer— обёртка над@kinescope/react-kinescope-player - Рендер урока для ученика: видео (если есть Kinescope ID) + текст + файлы
- Загрузка PDF/файлов к уроку (Object Storage), список для скачивания
- Страница курса для ученика: список модулей и уроков, статус прохождения
- Навигация по урокам: предыдущий / следующий
- Блокировка доступа к курсу без enrollment (layout server component)
- Страница «Мои курсы» в личном кабинете ученика (dashboard)
- Кнопки Сохранить / Просмотр в редакторе урока
- Иконка-статус уроков в боковой панели курса (✓ пройден)
Этап 3 — Прогресс ✅ ЗАВЕРШЁН (07.04.2026)
- Prisma: таблица
LessonProgress(userId, lessonId, completedAt) - Кнопка «Урок завершён» — создаёт/удаляет запись в LessonProgress
- Прогресс-бар по курсу в боковой панели (% завершённых уроков)
- Прогресс-бар по курсу на дашборде студента
- Admin bypass: администратор видит все уроки без отметок о прогрессе
Этап 5 — Домашние задания и обратная связь куратора ✅ ЗАВЕРШЁН (07.04.2026)
- Prisma: Homework, HomeworkSubmission, HomeworkFeedback
- Admin: добавить / редактировать / удалить блок ДЗ к уроку (HomeworkEditor)
- Ученик: форма отправки ДЗ (текст + файлы → Object Storage)
- Ученик: видит статус ДЗ и фидбек куратора в карточке урока
- Куратор / Admin: список ДЗ на проверку (
/curator/homework) - Куратор / Admin: просмотр работы, текстовый комментарий с обратной связью
- Admin: AdminShell на
/curator/*маршрутах (сайдбар не пропадает) - Admin: реальная статистика на дашборде (студенты, курсы, ДЗ, прогресс)
Этап 6 — Обсуждения под уроками ✅ ЗАВЕРШЁН (07.04.2026)
- Prisma: LessonComment (soft-delete через поле
deleted) - Рендер списка комментариев под уроком (server-fetched, client-rendered)
- Форма отправки комментария (только для enrolled учеников и admin)
- Модерация: автор, куратор или admin может удалить комментарий
- Счётчик активных комментариев в заголовке секции
Этап 7 — Email-уведомления ✅ ЗАВЕРШЁН (07.04.2026)
- Базовый HTML email-шаблон (фирменный стиль Second Brain)
- Приветственное письмо при регистрации (
databaseHooks.user.create.after) - Письмо ученику об открытии доступа к курсу
- Куратор / Admin: уведомление о новом ДЗ на проверку
- Ученик: уведомление о полученном фидбеке
- Resend domain: mailsend.second-brain.ru (verified)
Этап 8 — Импорт уроков из Markdown (Obsidian) ✅ ЗАВЕРШЁН (07.04.2026)
- API:
POST /api/admin/import-md— принимает .md-файл - Парсинг frontmatter (title, kinescopeId, order, published) через
gray-matter - Конвертация Markdown → TipTap JSON через
unified+remark-parse - Поддержка: заголовки, параграфы, жирный/курсив/зачёркнутый, инлайн-код, блоки кода, цитаты, списки, ссылки, изображения (HTTP), горизонтальные разделители
- Очистка Obsidian-синтаксиса:
![[image]]удаляется,[[link|alias]]→ текст - 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 и картинках
- Мобильное приложение