# 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 1. **Guest join (with lobby):** Guest → POST `/api/rooms/[id]/join` → LobbyEntry(PENDING) → SSE `/api/rooms/[id]/lobby/stream` → Host approves → LiveKit token → connect 2. **Real-time transcription:** Audio tracks → AI Agent (Deepgram STT) → DataChannel → Live captions 3. **Post-lecture (`room_finished` webhook):** 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_KEY` middleware: protects local dev from network access - LiveKit webhook: signature verification via `WebhookReceiver` ## Commands ```bash # 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: ```env 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.ts` in project root (required by Prisma 7) - `datasourceUrl` passed via PrismaClient constructor, not in schema - Schema has no `url` in datasource block — only `provider` - Use `-- --webpack` flag for `next build` on 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_id` reserved for future LMS - `sessionId` (UUID) is the cross-cutting key linking LobbyEntry, ParticipantHistory, ChatMessage, SharedFile for guests - `Room.code` is the user-facing invite code (not the DB id) - Files store `fileKey` (S3 object key), not full URLs - `LectureArtifact` is 1:1 with Room - All cascade deletes: removing Room removes all related data