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>
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
# 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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Команды
|
||||
|
||||
```bash
|
||||
# Разработка
|
||||
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`)
|
||||
|
||||
```env
|
||||
# База данных
|
||||
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)
|
||||
```
|
||||
Reference in New Issue
Block a user