feat: LiveServer-M1 v1 — educational video conferencing platform

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>
This commit is contained in:
2026-03-22 13:57:53 +03:00
parent e5bb4c99ec
commit 3846e3e00d
59 changed files with 12792 additions and 240 deletions
+226 -1
View File
@@ -1,3 +1,228 @@
# LiveServer-M1
Livekit core - Server for VideoHosting
Образовательная видеоконференц-платформа на базе LiveKit. AI-транскрипция, модерация, пост-лекционные артефакты.
## Стек
- **Frontend:** Next.js 16, React 19, TypeScript, Tailwind CSS v4
- **Video:** LiveKit (`@livekit/components-react`)
- **Backend:** Next.js Route Handlers, `livekit-server-sdk`
- **Auth:** `better-auth` + Prisma adapter
- **AI Agent:** Python, `livekit-agents`, Deepgram STT, OpenAI GPT
- **DB:** PostgreSQL + Prisma 7
- **Storage:** MinIO (S3-compatible)
- **Proxy:** Traefik v3 + Let's Encrypt (production)
## Быстрый старт (автоматический)
```bash
git clone <repo-url> && cd LiveServer-M1
bash setup.sh
```
Скрипт проведёт через все шаги: проверит зависимости, спросит настройки, сгенерирует `.env`, поднимет Docker, применит миграции, создаст S3 bucket. Работает для локальной разработки и production.
## Быстрый старт (ручной)
### 1. Клонировать и установить зависимости
```bash
git clone <repo-url> && cd LiveServer-M1
npm install
```
### 2. Настроить окружение
```bash
cp .env.example .env
```
Заполни в `.env`:
| Переменная | Описание |
|---|---|
| `DATABASE_URL` | PostgreSQL connection string. Для Docker: `postgresql://postgres:postgres@localhost:5432/liveserver` |
| `LIVEKIT_URL` | URL LiveKit сервера (`wss://...livekit.cloud` или self-hosted) |
| `LIVEKIT_API_KEY` | API Key из LiveKit Dashboard |
| `LIVEKIT_API_SECRET` | API Secret из LiveKit Dashboard |
| `BETTER_AUTH_SECRET` | Любая случайная строка для подписи сессий |
| `DEV_ACCESS_KEY` | Ключ доступа для локалки (защита от посторонних в сети) |
Остальные переменные опциональны для начала — AI Agent и MinIO нужны позже.
### 3. Запустить базу данных
```bash
docker compose up -d postgres minio
```
Поднимет PostgreSQL на `localhost:5432` и MinIO на `localhost:9000` (консоль: `localhost:9001`).
### 4. Применить миграции
```bash
npx prisma migrate dev --name init
```
Или для быстрого прототипирования без миграций:
```bash
npx prisma db push
```
### 5. Запустить приложение
```bash
npm run dev
```
Приложение: `http://localhost:3000`
### 6. (Опционально) AI Agent
```bash
cd ai-agent
pip install -r requirements.txt
python main.py start
```
Требует `DEEPGRAM_API_KEY` и `OPENAI_API_KEY` в `.env`.
## Защита на локалке
Когда `DOMAIN` не задан, middleware блокирует доступ без ключа:
```
http://192.168.x.x:3000?key=mySecretKey123
```
Ключ задаётся в `DEV_ACCESS_KEY`. После первого входа ставится cookie на 7 дней.
Дополнительно можно ограничить по IP:
```env
ALLOWED_IPS=192.168.1.10,192.168.1.11
```
Localhost (`127.0.0.1`, `::1`) разрешён всегда.
## Production (с доменом)
### 1. Настроить DNS
Направить на IP сервера:
- `live.example.com` → приложение
- `s3.live.example.com` → MinIO API
- `minio.live.example.com` → MinIO Console
### 2. Заполнить `.env`
```env
DOMAIN=live.example.com
ACME_EMAIL=admin@example.com
POSTGRES_PASSWORD=<strong-password>
MINIO_ROOT_PASSWORD=<strong-password>
BETTER_AUTH_SECRET=<random-string>
BETTER_AUTH_URL=https://live.example.com
NEXT_PUBLIC_APP_URL=https://live.example.com
```
### 3. Запустить
```bash
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
```
Traefik автоматически получит SSL-сертификат через Let's Encrypt.
## Команды
```bash
# Разработка
npm run dev # Next.js dev server
npm run lint # TypeScript type-check (tsc --noEmit)
npm run build -- --webpack # Production build
# База данных
npx prisma migrate dev # Создать/применить миграцию
npx prisma db push # Синхронизировать схему без миграции
npx prisma studio # GUI для БД
npx prisma generate # Регенерация Prisma Client
# Docker
docker compose up -d # Локалка (postgres + minio)
docker compose up -d --build # Локалка с билдом app
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build # Прод
docker compose logs -f app # Логи приложения
```
## Структура проекта
```
├── src/
│ ├── app/
│ │ ├── api/
│ │ │ ├── auth/[...all]/ # better-auth handler
│ │ │ ├── rooms/ # CRUD комнат
│ │ │ ├── rooms/[roomId]/ # join, lobby, chat, files, moderate, start, end
│ │ │ ├── rooms/by-code/[code]/ # Публичный поиск по инвайт-коду
│ │ │ └── livekit/ # token, webhook
│ │ ├── (dashboard)/ # Дашборд хоста/админа
│ │ ├── join/[code]/ # Страница входа гостя
│ │ ├── room/[code]/ # Комната видеоконференции
│ │ ├── login/ # Вход
│ │ └── register/ # Регистрация
│ ├── components/
│ │ ├── room/ # ChatPanel, ModerationPanel
│ │ └── lobby/ # WaitingRoom, LobbyManager
│ ├── lib/ # prisma, auth, livekit, auth-helpers
│ ├── middleware.ts # Защита локалки (DEV_ACCESS_KEY, ALLOWED_IPS)
│ └── types/
├── ai-agent/ # Python LiveKit Agent
│ ├── main.py
│ ├── requirements.txt
│ └── Dockerfile
├── prisma/
│ └── schema.prisma
├── docker-compose.yml # Базовые сервисы
├── docker-compose.override.yml # Локальные порты (автоподхват)
├── docker-compose.prod.yml # Traefik + SSL
├── Dockerfile # Multi-stage build Next.js
└── .env.example
```
## API Endpoints
### Публичные (без авторизации)
| Метод | Путь | Описание |
|---|---|---|
| `*` | `/api/auth/*` | better-auth (login, register, session) |
| `GET` | `/api/rooms/by-code/:code` | Инфо о комнате по инвайт-коду |
| `POST` | `/api/rooms/:id/join` | Вход гостя (PIN, fingerprint) |
| `GET` | `/api/rooms/:id/lobby/stream` | SSE ожидание в лобби |
| `POST` | `/api/livekit/webhook` | Вебхуки LiveKit |
### Требуют авторизации (Host/Admin)
| Метод | Путь | Описание |
|---|---|---|
| `GET/POST` | `/api/rooms` | Список / создание комнат |
| `GET/PATCH/DELETE` | `/api/rooms/:id` | Управление комнатой |
| `POST` | `/api/rooms/:id/start` | Старт лекции |
| `POST` | `/api/rooms/:id/end` | Завершение лекции |
| `GET/POST` | `/api/rooms/:id/lobby` | Управление лобби |
| `POST` | `/api/rooms/:id/moderate` | Kick, ban, mute all |
| `POST` | `/api/livekit/token` | Генерация токена LiveKit |
### Требуют участия в комнате (sessionId)
| Метод | Путь | Описание |
|---|---|---|
| `GET/POST` | `/api/rooms/:id/chat` | Чат комнаты |
| `GET/POST` | `/api/rooms/:id/files` | Файлы комнаты |
## Роли
| Роль | Возможности |
|---|---|
| **ADMIN** | Всё + глобальная панель, мониторинг всех комнат |
| **HOST** | Создание комнат, модерация, настройки безопасности |
| **GUEST** | Вход по ссылке, участие в лекции (без регистрации) |