Files
LiveServer-M1/README.md
joylessorchid a42ec96965 perf: Redis pub/sub, PgBouncer, optimistic UI for high concurrency
- Add Redis 7 for pub/sub (lobby + chat real-time), rate limiting, caching
- Replace SSE DB polling with Redis pub/sub (lobby: instant approval, chat: instant delivery)
- Add PgBouncer (transaction mode, 500 client → 25 pool connections)
- Chat SSE stream via Redis pub/sub instead of 3s polling
- Optimistic UI in ChatPanel (messages appear before server confirms)
- Redis-based rate limiter (works across multiple app replicas)
- Prisma query optimization (select only needed fields)
- Chat message cache in Redis (10s TTL)
- Docker Compose: add redis, pgbouncer services with healthchecks
- Production: resource limits, 2 app replicas behind Traefik
- Update CLAUDE.md, README.md, .env.example, setup.sh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:17:25 +03:00

230 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LiveServer-M1
Образовательная видеоконференц-платформа на базе 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 + PgBouncer (connection pooling)
- **Cache/PubSub:** Redis 7 (real-time chat, lobby, rate limiting)
- **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 redis
```
Поднимет PostgreSQL (`localhost:5432`), MinIO (`localhost:9000`, консоль: `9001`), Redis (`localhost:6379`), PgBouncer (`localhost:6432`).
### 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** | Вход по ссылке, участие в лекции (без регистрации) |