Files
lms-sb/CLAUDE.md
T
admins 80ca4b2d9d Initialize Stage 0: Next.js 16 scaffold with auth and role-based routing
- Next.js 16.2.2 + React 19 + TypeScript + Tailwind v4
- Better Auth with email/password and role system (student/curator/admin)
- Prisma 7 schema: User, Session, Account, Verification + full LMS model
- Role-based dashboards: student /dashboard, curator /curator/dashboard, admin /admin/dashboard
- Auth pages: login, register, verify-email
- Better Auth API route handler
- Middleware for route protection
- Docker Compose with PostgreSQL 16
- Seed script with test users (admin/curator/student)
- CLAUDE.md and ROADMAP.md project documentation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 10:32:37 +05:00

10 KiB

CLAUDE.md — LMS Second Brain

Читай AGENTS.md перед тем как писать любой Next.js код — версия отличается от обучающих данных.

Стек и версии

Технология Версия Назначение
Next.js 16.2.2 (App Router) Full-stack фреймворк
Node.js 20 LTS Runtime
TypeScript 5.x Язык
React 19 UI
PostgreSQL 16 База данных
Prisma 6.x ORM + миграции
Better Auth latest Аутентификация и сессии
Tailwind CSS 4.x (CSS-based config) Стили (нет tailwind.config.ts)
shadcn/ui latest UI-компоненты
TipTap 2.x WYSIWYG-редактор уроков
@kinescope/react-kinescope-player latest Видеоплеер
Resend latest Email-уведомления
AWS SDK (S3) 3.x Hetzner Object Storage
Zod 3.x Валидация данных
Docker Compose 2.x Локальная разработка и деплой

Важно по Tailwind v4: конфиг — только в CSS через @import "tailwindcss" и @theme. Нет tailwind.config.ts. Кастомизация — через CSS переменные в globals.css.

Важно по Better Auth: не NextAuth. Сессии — cookie-based. Роли через плагин admin. Подробнее: https://www.better-auth.com/docs


Структура каталогов

lms-system/
├── src/
│   ├── app/                        # Next.js App Router
│   │   ├── (auth)/                 # Вход, регистрация, подтверждение email
│   │   │   ├── login/
│   │   │   ├── register/
│   │   │   └── verify-email/
│   │   ├── (student)/              # Личный кабинет ученика
│   │   │   ├── dashboard/
│   │   │   ├── courses/[slug]/
│   │   │   └── courses/[slug]/lessons/[lessonId]/
│   │   ├── curator/                # Панель куратора
│   │   │   ├── dashboard/
│   │   │   └── homework/
│   │   ├── admin/                  # Панель администратора
│   │   │   ├── courses/
│   │   │   ├── users/
│   │   │   └── settings/
│   │   └── api/                    # API-маршруты
│   │       ├── auth/               # Better Auth handler
│   │       ├── courses/
│   │       ├── lessons/
│   │       ├── progress/
│   │       ├── homework/
│   │       └── upload/
│   ├── components/
│   │   ├── ui/                     # shadcn/ui (не редактировать вручную)
│   │   ├── editor/                 # TipTap WYSIWYG
│   │   ├── player/                 # Kinescope Player wrapper
│   │   ├── course/                 # Компоненты курса
│   │   └── layout/                 # Header, Sidebar, Footer
│   ├── lib/
│   │   ├── auth.ts                 # Better Auth config (сервер)
│   │   ├── auth-client.ts          # Better Auth client (браузер)
│   │   ├── prisma.ts               # Prisma singleton client
│   │   ├── s3.ts                   # Hetzner Object Storage клиент
│   │   ├── email.ts                # Resend email helpers
│   │   └── utils.ts                # cn() и прочие утилиты
│   ├── types/
│   │   └── index.ts                # Общие TypeScript-типы
│   └── middleware.ts               # Auth middleware (защита маршрутов)
├── prisma/
│   ├── schema.prisma               # Схема БД
│   ├── seed.ts                     # Seed-скрипт
│   └── migrations/                 # НИКОГДА не редактировать вручную
├── public/
│   └── images/
├── docker-compose.yml              # Локальная разработка
├── docker-compose.prod.yml         # Production
├── Dockerfile
├── .env.example                    # Шаблон переменных (без секретов)
├── .env.local                      # Локальные секреты (в .gitignore)
├── CLAUDE.md
├── ROADMAP.md
└── PROJECT_BRIEF.md

Команды

# Разработка
npm run dev              # Запустить dev-сервер (localhost:3000)
docker compose up -d     # Поднять PostgreSQL локально

# Сборка и проверка
npm run build            # Production build
npm run lint             # ESLint
npm run type-check       # TypeScript без сборки (tsc --noEmit)

# База данных (Prisma)
npx prisma migrate dev --name <название>   # Создать и применить миграцию
npx prisma migrate deploy                  # Применить миграции в production
npx prisma studio                          # GUI для просмотра БД
npx prisma generate                        # Пересоздать клиент после изменений schema
npx prisma db seed                         # Запустить seed-скрипт

# Docker (production)
docker compose -f docker-compose.prod.yml up -d --build
docker compose -f docker-compose.prod.yml logs -f app

Правила работы

Деплой и окружение

  • Production-домен: school.second-brain.ru
  • Git-сервер: Gitea — https://git.second-brain.ru/admins/lms-sb
  • После завершения каждого этапа из ROADMAP.md — делать git push в Gitea

Коммиты

  • Один коммит = одна логически завершённая единица работы (маршрут, компонент, миграция)
  • Сообщения коммитов — на английском, в повелительном наклонении: Add lesson progress tracking, Fix auth redirect
  • Перед коммитом всегда запускать npm run lint && npm run type-check

Миграции базы данных

  • НИКОГДА не редактировать файлы в prisma/migrations/ вручную
  • ВСЕГДА спрашивать пользователя перед созданием миграции, меняющей или удаляющей существующие поля
  • Называть миграции по-английски, snake_case: add_lesson_progress, add_user_roles
  • Перед prisma migrate deploy на production — делать бэкап БД

Файлы и контент

  • Загружаемые файлы (ДЗ, PDF) — только через Hetzner Object Storage, никогда на диск VPS
  • Секреты (API-ключи, токены, строки подключения) — только в .env.local, в коде запрещено
  • .env.example всегда обновлять при добавлении новых переменных (без реальных значений)

Код

  • UI-строки (заголовки, кнопки, сообщения) — на русском
  • Имена переменных, функций, файлов, комментарии в коде — на английском
  • Компоненты shadcn/ui — добавлять через npx shadcn@latest add <component>, не копировать вручную
  • Не добавлять абстракции "на будущее" — только то, что нужно для текущего этапа
  • Server Actions — использовать для форм и мутаций (auth, прогресс, ДЗ)

Маршруты и роли

  • Защита маршрутов — через middleware.ts (Better Auth), не в каждом компоненте отдельно
  • Роли: student, curator, admin — проверять через auth() или authClient.useSession()
  • Admin-маршруты (/admin/*) доступны только роли admin
  • Curator-маршруты (/curator/*) доступны ролям curator и admin

Переменные окружения (.env.example)

# База данных
DATABASE_URL="postgresql://lms_user:password@localhost:5432/lms_db"

# Better Auth
BETTER_AUTH_SECRET="generate-with-openssl-rand-base64-32"
BETTER_AUTH_URL="http://localhost:3000"

# Email (Resend)
RESEND_API_KEY=""
EMAIL_FROM="noreply@school.second-brain.ru"

# Hetzner Object Storage (S3-совместимый)
S3_ENDPOINT="https://fsn1.your-objectstorage.com"
S3_BUCKET="lms-uploads"
S3_ACCESS_KEY=""
S3_SECRET_KEY=""
S3_REGION="eu-central"

# Kinescope (добавить при получении платного плана)
# KINESCOPE_API_KEY=""

Чек-лист перед каждым коммитом

  • npm run lint — нет ошибок ESLint
  • npm run type-check — нет ошибок TypeScript
  • Новые .env переменные добавлены в .env.example (без значений)
  • Миграция БД одобрена пользователем (если есть)
  • Нет console.log в production-коде (только console.error для реальных ошибок)
  • Нет захардкоженных секретов, URL-ов, ID

Модель данных (основные сущности)

User (id, email, name, role, emailVerified) — управляется Better Auth
Session (id, userId, expiresAt, ...) — управляется Better Auth
Course (id, slug, title, description, coverImage, published)
Module (id, courseId, title, order)
Lesson (id, moduleId, title, order, content, kinescopeId, published)
CourseEnrollment (userId, courseId, enrolledAt)
LessonProgress (userId, lessonId, completedAt)
Quiz (id, lessonId)
QuizQuestion (id, quizId, text, type)
QuizOption (id, questionId, text, isCorrect)
QuizAttempt (id, userId, quizId, score, completedAt)
Homework (id, lessonId, description)
HomeworkSubmission (id, homeworkId, userId, text, files[], submittedAt)
HomeworkFeedback (id, submissionId, curatorId, text, createdAt)
LessonComment (id, lessonId, userId, text, createdAt)