Full MVP implementation: - Next.js 16 + React 19 + TypeScript + Tailwind CSS v4 - LiveKit integration (rooms, tokens, webhooks, moderation) - better-auth (email/password, sessions, roles) - Prisma 7 + PostgreSQL (9 models, 3 enums) - 15 API routes (auth, rooms, lobby, chat, files, moderation, hand-raise) - 7 pages (landing, auth, dashboard, join, video room) - SSE-based waiting room with host approval flow - Security: PIN rate limiting, session fingerprint bans, chat/files auth - Python AI Agent (Deepgram STT + OpenAI summarization) - Docker Compose (local + production with Traefik + Let's Encrypt) - Interactive setup script (setup.sh) - Dev protection middleware (DEV_ACCESS_KEY, ALLOWED_IPS) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6.8 KiB
6.8 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
LiveServer-M1 — образовательная видеоконференц-платформа на базе LiveKit.
Ключевые фичи:
- AI-ассистент: авто-подключение к комнатам, real-time транскрипция (Deepgram), суммаризация лекций (OpenAI GPT)
- Защита от Zoom-bombing: lobby/waiting room, PIN-коды, kick/ban по session fingerprint, panic button
- Пост-лекционная панель: чат, файлы, транскрипт, AI-саммари, экспорт в PDF/Google Drive
Полная спецификация: PROMPT.md
Tech Stack
| Слой | Технологии |
|---|---|
| Frontend | Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS v4 |
| Video | LiveKit Cloud → self-hosted, @livekit/components-react |
| Backend | Next.js Route Handlers, livekit-server-sdk |
| Auth | better-auth + Prisma adapter |
| AI Agent | Python, livekit-agents, livekit-plugins-deepgram (STT), livekit-plugins-openai (LLM) |
| DB | PostgreSQL + Prisma 7 ORM |
| Storage | MinIO (S3-compatible) |
| Proxy | Traefik v3 + Let's Encrypt (prod only) |
Architecture
├── src/
│ ├── app/
│ │ ├── api/ # 15 API route handlers
│ │ │ ├── auth/[...all]/ # better-auth catch-all
│ │ │ ├── rooms/ # CRUD, by-code lookup
│ │ │ ├── rooms/[roomId]/ # join, lobby, lobby/stream (SSE), chat, files, moderate, hand-raise, start, end
│ │ │ └── livekit/ # token generation, webhook receiver
│ │ ├── (dashboard)/ # Host/Admin pages
│ │ ├── join/[code]/ # Guest entry
│ │ ├── room/[code]/ # Video room (LiveKit)
│ │ ├── login/ & register/ # Auth pages
│ │ └── page.tsx # Landing
│ ├── components/
│ │ ├── room/ # ChatPanel, ModerationPanel
│ │ └── lobby/ # WaitingRoom, LobbyManager
│ ├── lib/ # prisma, auth, auth-helpers, livekit
│ ├── middleware.ts # Dev protection (DEV_ACCESS_KEY, ALLOWED_IPS)
│ └── types/
├── ai-agent/ # Python LiveKit Agent
├── prisma/schema.prisma # 9 models, 3 enums
├── docker-compose.yml # Base: postgres, minio, ai-agent, app
├── docker-compose.override.yml # Local dev: direct ports, no SSL
├── docker-compose.prod.yml # Traefik + Let's Encrypt
└── Dockerfile # Multi-stage Next.js standalone build
Key Data Flows
-
Guest join (with lobby): Guest → POST
/api/rooms/[id]/join→ LobbyEntry(PENDING) → SSE/api/rooms/[id]/lobby/stream→ Host approves → LiveKit token → connect -
Real-time transcription: Audio tracks → AI Agent (Deepgram STT) → DataChannel → Live captions
-
Post-lecture (
room_finishedwebhook): Transcript → OpenAI GPT → LectureArtifact →/lectures/[id]
User Roles
- ADMIN — global panel, all rooms monitoring
- HOST — room creation, moderation, security
- GUEST — join by link, no registration required
Security Layers
sessionFingerprint(required) for bans — IP is secondary only- PIN hashed with bcrypt, rate-limited (5 attempts/min per IP)
- Chat/files auth: verified via ParticipantHistory
- SSE lobby: verified against existing LobbyEntry
- Token generation: only room owner can get LiveKit token
DEV_ACCESS_KEYmiddleware: protects local dev from network access- LiveKit webhook: signature verification via
WebhookReceiver
Commands
# Dev
npm run dev # Next.js dev server (localhost:3000)
docker compose up -d postgres minio # DB + Storage only
npm run lint # TypeScript type-check (tsc --noEmit)
# Database
npx prisma migrate dev # Create + apply migration
npx prisma db push # Quick schema sync (no migration)
npx prisma studio # DB GUI
npx prisma generate # Regenerate Prisma Client
# Build
npm run build -- --webpack # Production build (Webpack, not Turbopack — WASM limitation on Windows)
# Docker (full stack)
docker compose up -d --build # Local
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build # Prod (with Traefik)
# AI Agent
cd ai-agent && python main.py start
Environment Variables
See .env.example for all variables. Key ones:
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/liveserver
LIVEKIT_URL=wss://...
LIVEKIT_API_KEY=...
LIVEKIT_API_SECRET=...
BETTER_AUTH_SECRET=...
# Local dev protection (when DOMAIN is not set)
DEV_ACCESS_KEY=mySecretKey123
# ALLOWED_IPS=192.168.1.10,192.168.1.11
# Production
# DOMAIN=live.example.com
# ACME_EMAIL=admin@example.com
Deployment Modes
| Mode | Command | Description |
|---|---|---|
| Local dev | docker compose up -d |
Direct ports (3000, 5432, 9000). docker-compose.override.yml auto-applied |
| Production | docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d |
Traefik reverse proxy, auto SSL via Let's Encrypt |
Prisma 7 Notes
prisma.config.tsin project root (required by Prisma 7)datasourceUrlpassed via PrismaClient constructor, not in schema- Schema has no
urlin datasource block — onlyprovider - Use
-- --webpackflag fornext buildon Windows (Turbopack WASM issue)
Agent Orchestration
| Task | Agent |
|---|---|
| API routes, backend logic | backend-architect |
| React components, LiveKit UI | frontend-developer |
| DB schema, indexes, queries | database-optimizer |
| Python AI Agent, Deepgram/OpenAI | ai-engineer |
| System architecture | software-architect |
| UI design, components | ui-designer |
| UX flows, accessibility | ux-architect |
| Code review before commit | code-reviewer |
Rule: for tasks spanning 2+ layers — use agents-orchestrator.
Conventions
- Communication language: Russian
- Guests don't register, but
user_idreserved for future LMS sessionId(UUID) is the cross-cutting key linking LobbyEntry, ParticipantHistory, ChatMessage, SharedFile for guestsRoom.codeis the user-facing invite code (not the DB id)- Files store
fileKey(S3 object key), not full URLs LectureArtifactis 1:1 with Room- All cascade deletes: removing Room removes all related data