# 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 + PgBouncer (connection pooling) | | Cache/PubSub | Redis 7 (rate limiting, lobby pub/sub, chat real-time, caching) | | 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, redis, rate-limit, lobby-pubsub, chat-pubsub │ ├── 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, redis, pgbouncer, 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 via Redis pub/sub → Host approves → LiveKit token → connect 2. **Real-time chat:** POST message → DB + Redis PUBLISH → SSE `/api/rooms/[id]/chat/stream` → instant delivery to all participants 3. **Real-time transcription:** Audio tracks → AI Agent (Deepgram STT) → DataChannel → Live captions 4. **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` ## Performance Architecture ``` Clients → Traefik (LB) → Next.js (x2 replicas) → PgBouncer (pool 25, max 500) → PostgreSQL → Redis (pub/sub, cache, rate limit) → LiveKit (video/audio SFU) ``` - **Redis pub/sub** replaces DB polling for lobby SSE and chat — instant delivery (<10ms) - **PgBouncer** multiplexes 500 client connections into 25 real PostgreSQL connections - **Chat SSE** via Redis pub/sub + optimistic UI on client — messages appear before server confirms - **Rate limiting** via Redis INCR+EXPIRE — works across multiple app replicas - **Chat cache** in Redis (10s TTL) — reduces DB reads during active rooms - **Prisma select** — only fetch needed columns, not full rows ## Commands ```bash # Dev npm run dev # Next.js dev server (localhost:3000) docker compose up -d postgres minio redis # DB + Storage + Redis 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`. ## Post-Change Checklist (ОБЯЗАТЕЛЬНО) После **каждого** изменения кода или конфигурации Claude **обязан** выполнить: 1. **Обновить `CLAUDE.md`** — если изменились архитектура, endpoints, модели, команды, стек или conventions 2. **Проверить `setup.sh`** — все новые сервисы/зависимости должны быть в скрипте (readiness checks, .env переменные, docker compose команды) 3. **Проверить `README.md`** — инструкции, API таблицы, структура проекта должны отражать текущее состояние 4. **Проверить `PROMPT.md`** — спецификация должна соответствовать реализации 5. **Проверить `.env.example`** — все новые переменные окружения должны быть задокументированы Не пропускать этот чеклист. Если изменение не затрагивает файл — просто подтвердить что файл актуален. ## 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