docker compose определяет .env для подстановки ${VAR} по каталогу
compose-файла (deploy/), а не по текущей директории — repo-root .env,
который использует install.sh и вся документация, молча не подхватывался.
Это и была причина "WARN: LIVEKIT_API_KEY not set" на боевом сервере:
секреты были в .env, но compose их не видел и подставлял небезопасные
дефолты (см. таблицу разведки сервера).
Теперь ставшие обязательными ${VAR:?} в docker-compose.yml (см. предыдущий
коммит) без этого немедленно проваливали бы конфиг на любой из
документированных команд. Добавлен `--env-file .env`/"$ENV_FILE" ко всем
вызовам docker compose в install.sh и в командах из README/docs.
install.sh дополнительно: ensure_default (аналог ensure_secret без генерации
секрета) для новых не-секретных параметров nginx/coturn/livekit
(NGINX_SERVER_NAMES, NGINX_CERT_NAME, LIVEKIT_USE_EXTERNAL_IP,
LIVEKIT_NODE_IP, TURN_EXTERNAL_IP) — дефолты только для локальной
разработки, не перезаписывают значения, заданные вручную на боевом
сервере. Плюс вызов deploy/render-templates.sh перед сборкой/подъёмом
стека.
314 lines
17 KiB
Markdown
314 lines
17 KiB
Markdown
# VidConf — самоуправляемые видеоконференции с AI-транскрибацией и суммаризацией
|
||
|
||
Открытая платформа видеоконференций с встроенной AI-транскрибацией и суммаризацией. Построена на LiveKit SFU, Python FastAPI backend и современном React frontend.
|
||
|
||
## Функциональность
|
||
|
||
- **Видеоконференции:** Потоки аудио/видео отдельно для каждого участника через LiveKit SFU
|
||
- **Транскрибация:** Автоматическое преобразование речи в текст (faster-whisper, уровни CPU-only или GPU, подключаемо)
|
||
- **Суммаризация:** AI-резюме сессий (Qwen3.5-4B/9B/35B-A3B через llama.cpp, 3 уровня качества, подключаемо)
|
||
- **Динамические конференции:** Создание мгновенно из лобби или планово из календаря, вход по ссылке/номеру, закрепление с повторением
|
||
- **Чат:** Текстовое общение в конференции с сохранением сообщений
|
||
- **Экспорт:** Трансцрибции и резюме конференций через email + iCalendar (.ics)
|
||
- **Мультипользовательский режим:** Доступ на основе ролей (админ/пользователь), проверка почты
|
||
- **Самоуправляемо:** Docker Compose стек с PostgreSQL, Redis, Nginx (инсталлятор `install.sh` с автодетектом железа)
|
||
|
||
## Стек технологий
|
||
|
||
- **Backend:** Python 3.12, FastAPI, SQLAlchemy 2.0 async, Alembic, Celery + Redis
|
||
- **БД:** PostgreSQL 16 (с расширением btree_gist для EXCLUDE constraints)
|
||
- **Медиа:** LiveKit SFU + Coturn (TURN)
|
||
- **AI (подключаемо, 3 уровня качества):** faster-whisper (small/medium/large-v3), Qwen3.5 (4B/9B/35B-A3B) Q4_K_M через llama.cpp
|
||
- **Frontend:** React + TypeScript + Vite, Tailwind CSS, shadcn/ui, FullCalendar, LiveKit JS SDK
|
||
- **Развёртывание:** Docker Compose (5 пресетов инсталлятора), Nginx (TLS), Ansible; Prometheus + Grafana для мониторинга
|
||
|
||
## Структура проекта
|
||
|
||
```
|
||
├── backend/ FastAPI приложение (api/, core/, models/, repositories/, services/)
|
||
├── workers/ Celery воркеры (transcriber, summarizer, notifier)
|
||
├── frontend/ React SPA (TypeScript, Vite, Tailwind)
|
||
├── deploy/ Docker Compose, Nginx, Ansible, конфиги LiveKit/Coturn
|
||
├── design/ Дизайн-система (DESIGN_SYSTEM.md, tokens.css, mockups/)
|
||
├── docs/ Архитектура, API, плагины, развёртывание, БД
|
||
│ ├── architecture/ ADR (записи архитектурных решений)
|
||
│ ├── api/ Документация API endpoint'ов
|
||
│ ├── plugins/ Контракты плагинов и руководство расширений
|
||
│ ├── deploy/ Гайды развёртывания и профили оборудования
|
||
│ └── db/ Схема БД и миграции
|
||
├── config/ Конфигурация plugins.yaml
|
||
└── README.md Этот файл
|
||
```
|
||
|
||
## Быстрый старт
|
||
|
||
### Требования
|
||
|
||
- Docker + Docker Compose v2
|
||
- `uv` (инструменты Python): `brew install uv`
|
||
- Node 20+ (frontend)
|
||
|
||
### 1. Клонирование и настройка
|
||
|
||
```bash
|
||
git clone https://github.com/your-org/vidconf.git
|
||
cd vidconf
|
||
cp .env.example .env
|
||
```
|
||
|
||
### 2. Запуск (три варианта)
|
||
|
||
**Вариант A: Автоматический инсталлятор (рекомендуется)**
|
||
|
||
```bash
|
||
./install.sh # интерактивный опросник: автодетект железа
|
||
# и рекомендация пресета
|
||
./install.sh --preset 1 # MVP-ядро: лобби, конференции, календарь,
|
||
# закреплённые, гости (без чата и AI)
|
||
./install.sh --preset 2 # пресет 1 + чат конференции (без AI)
|
||
./install.sh --preset 3 # пресет 2 + AI «мин» — CPU: faster-whisper
|
||
# small + Qwen (8 vCPU / 16 ГБ RAM / 100 ГБ)
|
||
./install.sh --preset 4 # пресет 2 + AI «средний» — CPU: faster-whisper
|
||
# medium + Qwen (12–16 vCPU / 32 ГБ RAM / 150 ГБ)
|
||
./install.sh --preset 5 # пресет 2 + AI «макс» — GPU NVIDIA ≥16 ГБ VRAM
|
||
# ОБЯЗАТЕЛЕН: whisper large-v3 + Qwen MoE
|
||
# (16+ vCPU / 64 ГБ RAM / 250 ГБ)
|
||
./install.sh --preset 3 --yes # без подтверждений (скрипты/CI)
|
||
```
|
||
|
||
Повторный запуск инсталлятора идемпотентен: смена пресета докачивает модели
|
||
и переключает compose-профили на месте, секреты и правки `.env` сохраняются.
|
||
Точные требования пресетов по железу — `docs/architecture/adr/004-ai-tier-matrix.md`.
|
||
|
||
**Вариант B: Вручную (базовый стек без AI)**
|
||
```bash
|
||
docker compose -f deploy/docker-compose.yml --env-file .env up -d
|
||
```
|
||
|
||
Это запустит PostgreSQL, Redis, backend (FastAPI) и Nginx. API доступен по адресу:
|
||
- Прямой доступ: `http://localhost:8000/api/health`
|
||
- Через Nginx: `http://localhost/api/health`
|
||
|
||
**Вариант C: Вручную с видеоконференциями и AI**
|
||
```bash
|
||
docker compose -f deploy/docker-compose.yml --env-file .env \
|
||
--profile media --profile transcribe --profile llm up -d
|
||
```
|
||
|
||
### 3. Настройка БД
|
||
|
||
```bash
|
||
cd backend
|
||
uv run alembic upgrade head # Запуск миграций
|
||
uv run python -m scripts.seed # Идемпотентный сид: единственный админ-пользователь
|
||
```
|
||
|
||
### 4. Запуск frontend
|
||
|
||
```bash
|
||
cd frontend
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
Frontend запущен на `http://localhost:5173` (dev сервер).
|
||
|
||
### 5. (Опционально) Включение медиа-стека
|
||
|
||
Для использования видеоконференций с LiveKit + Coturn:
|
||
|
||
```bash
|
||
docker compose -f deploy/docker-compose.yml --env-file .env --profile media up -d
|
||
```
|
||
|
||
Полные детали настройки см. в [docs/deploy/dev-setup.md](docs/deploy/dev-setup.md).
|
||
|
||
## Тестирование и качество кода
|
||
|
||
```bash
|
||
# Backend
|
||
cd backend
|
||
uv run ruff check . && uv run ruff format --check . # Lint + проверка форматирования
|
||
uv run mypy . # Проверка типов
|
||
uv run pytest -q # Unit тесты
|
||
|
||
# Frontend
|
||
cd frontend
|
||
npm run lint # ESLint
|
||
npm run build # Проверка сборки
|
||
```
|
||
|
||
## Конфигурация
|
||
|
||
### Переменные окружения (.env)
|
||
|
||
Скопируйте `.env.example` в `.env` и настройте (полный справочник переменных — [docs/deploy/env.md](docs/deploy/env.md)):
|
||
|
||
```
|
||
POSTGRES_USER=vidconf
|
||
POSTGRES_PASSWORD=vidconf
|
||
POSTGRES_DB=vidconf
|
||
|
||
REDIS_URL=redis://localhost:6379/0
|
||
|
||
JWT_SECRET=change-me-generate-a-long-random-secret
|
||
|
||
SEED_ADMIN_EMAIL=admin@vidconf.example
|
||
SEED_ADMIN_PASSWORD=change-me
|
||
```
|
||
|
||
### Конфигурация плагинов (config/plugins.yaml)
|
||
|
||
```yaml
|
||
transcriber:
|
||
enabled: true
|
||
provider: "null" # или "faster_whisper_cpu"/"faster_whisper_gpu"
|
||
model: null
|
||
language: ru
|
||
|
||
summarizer:
|
||
enabled: true
|
||
provider: "null" # или "qwen_local"
|
||
model: null
|
||
chunk_minutes: 20
|
||
|
||
chat:
|
||
enabled: true
|
||
```
|
||
|
||
Архитектуру плагинов и как добавлять пользовательские реализации см. в [docs/plugins/contracts.md](docs/plugins/contracts.md).
|
||
|
||
## Схема БД
|
||
|
||
VidConf использует 14 таблиц:
|
||
- **users** — зарегистрированные пользователи с доступом на основе ролей
|
||
- **teams** — организационные единицы
|
||
- **email_verification_tokens** — одноразовые токены подтверждения почты
|
||
- **conferences** — динамические конференции с номером, slug, владельцем, жизненным циклом
|
||
- **conference_invitees** — приглашённые на конференцию (зарегистрированные пользователи или внешние email)
|
||
- **guest_access** — гостевой доступ (display_name, email, разовые ссылки)
|
||
- **conference_sessions** — отдельные сессии конференции с состоянием pipeline (recording→transcribing→summarizing→notified)
|
||
- **conference_participants** — отслеживание участия (время присоединения/отключения)
|
||
- **session_audio_tracks** — аудиотреки per-участника с записями
|
||
- **phrases** — текстовые сегменты транскрибации (выход faster-whisper)
|
||
- **chat_messages** — текстовые сообщения в конференции (WebSocket, Redis pub/sub)
|
||
- **email_deliveries** — журнал отправленных писем (саммари, приглашения)
|
||
- **instance_settings** — настройки инстанса (уровень AI, чат, таймзона и т.д.)
|
||
- **livekit_webhook_events** — журнал webhook-событий LiveKit для идемпотентности
|
||
|
||
Все временные метки хранятся в UTC; клиент преобразует в локальный часовой пояс. Полную ER-диаграмму и решения по проектированию см. в [docs/db/schema.md](docs/db/schema.md).
|
||
|
||
## Архитектура
|
||
|
||
Ключевые архитектурные принципы:
|
||
- **Система плагинов:** Реализации Transcriber/Summarizer подключаемы через паттерн Strategy + Factory
|
||
- **Идемпотентный pipeline:** Пост-конференционная обработка (транскрибирование → суммаризация → уведомление) использует state machine в enum `pipeline_status`
|
||
- **Без диаризации:** Per-track аудио в SFU исключает необходимость диаризации спикеров
|
||
- **Гости как полноценные участники:** гостевой доступ (без регистрации) участвует в пайплайне наравне с зарегистрированными пользователями
|
||
- **Всё в UTC:** Времена всегда UTC в хранилище; преобразование часовых поясов на клиенте
|
||
|
||
ADR и обоснования дизайна см. в [docs/architecture/](docs/architecture/).
|
||
|
||
## Документация API
|
||
|
||
Основные endpoint'ы:
|
||
- `GET /api/health` — проверка здоровья
|
||
- `POST /api/v1/auth/register` — регистрация пользователя
|
||
- `POST /api/v1/auth/token` — вход, выдача access + refresh токенов
|
||
- `POST /api/v1/conferences` — создать конференцию (мгновенную или плановую)
|
||
- `GET /api/v1/conferences/my` — мои конференции (закреплённые + предстоящие)
|
||
- `GET /api/v1/conferences/resolve` — найти конференцию по номеру или ссылке
|
||
- `POST /api/v1/conferences/{id}/join` — войти в конференцию
|
||
- `GET /api/v1/admin/conferences` — список всех конференций (админ)
|
||
|
||
Полную спецификацию API см. в [docs/api/](docs/api/).
|
||
|
||
## Дизайн-система
|
||
|
||
UI следует строгим рекомендациям дизайна, определённым в [design/DESIGN_SYSTEM.md](design/DESIGN_SYSTEM.md):
|
||
- **Светлая тема** для оболочки приложения (лобби-хаб, календарь, админка, профиль)
|
||
- **Тёмная тема** для комнаты конференции
|
||
- **Пастельная палитра:** мятный акцент `#D4F2E3`, смягченные статус-индикаторы
|
||
- **Логотип:** стилизованный объектив камеры (`design/logo.svg`, `design/favicon.svg`)
|
||
- **Макеты** в `design/mockups/` (lobby.html, calendar.html, my-conferences.html, join.html и др.)
|
||
- **Проверка контраста:** скрипт `design/tools/contrast.py` (WCAG 2.1, 24/24 пар PASS)
|
||
|
||
Все компоненты используют Tailwind CSS + shadcn/ui.
|
||
|
||
## Развёртывание
|
||
|
||
### Пресеты инсталлятора
|
||
|
||
VidConf использует единый инсталлятор `install.sh` с 5 пресетами и автодетектом железа:
|
||
|
||
1. **MVP-ядро** — лобби, конференции, календарь, закреплённые, гости
|
||
2. **+чат** — текстовое общение
|
||
3. **+AI min (CPU)** — faster-whisper small + Qwen3.5-4B
|
||
4. **+AI medium (CPU/GPU опционально)** — faster-whisper medium + Qwen3.5-9B
|
||
5. **+AI max (GPU обязателен)** — faster-whisper large-v3 + Qwen3.5-35B-A3B
|
||
|
||
```bash
|
||
./install.sh # интерактивный опросник с рекомендацией
|
||
./install.sh --preset 3 # неинтерактивно (пресет 3 = AI min)
|
||
./install.sh --preset 3 --yes # без подтверждений (для CI/скриптов)
|
||
```
|
||
|
||
Требования к оборудованию и полное описание см. в [docs/deploy/install.md](docs/deploy/install.md) и [docs/architecture/adr/004-ai-tier-matrix.md](docs/architecture/adr/004-ai-tier-matrix.md).
|
||
|
||
### Docker Compose профили (низкоуровневый контроль)
|
||
|
||
Если вы хотите настраивать стек вручную без инсталлятора:
|
||
|
||
```bash
|
||
# Минимум (только backend, БД, Redis)
|
||
docker compose -f deploy/docker-compose.yml --env-file .env up -d
|
||
|
||
# + видеоконференции (LiveKit + Coturn)
|
||
docker compose -f deploy/docker-compose.yml --env-file .env --profile media up -d
|
||
|
||
# + AI transcription/summarization (CPU)
|
||
docker compose -f deploy/docker-compose.yml --env-file .env --profile media --profile transcribe --profile llm up -d
|
||
|
||
# + мониторинг (Prometheus + Grafana)
|
||
docker compose -f deploy/docker-compose.yml --env-file .env --profile monitoring up -d
|
||
```
|
||
|
||
## Вклад в проект
|
||
|
||
**Код без документации не мёржится.** Каждое изменение функциональности должно включать:
|
||
1. Обновлённый код
|
||
2. Тесты (unit + интеграционные)
|
||
3. Миграции БД (если меняется схема)
|
||
4. Документацию API/плагинов
|
||
5. ADR или ссылку на существующий ADR
|
||
|
||
Процесс разработки:
|
||
1. Напишите тесты сначала (TDD для бизнес-логики)
|
||
2. Реализуйте функцию
|
||
3. Обновите документацию в `docs/`
|
||
4. Запустите проверки качества:
|
||
```bash
|
||
cd backend && ruff check . && mypy . && pytest -q
|
||
cd frontend && npm run lint && npm run build
|
||
```
|
||
5. Создайте коммит с ясным сообщением и ссылками на документацию
|
||
|
||
## Лицензия
|
||
|
||
[Добавьте вашу лицензию здесь]
|
||
|
||
## Поддержка
|
||
|
||
- Ошибки и баги: GitHub Issues
|
||
- Документация: `docs/`
|
||
- Чат и реал-тайм: Комната конференции в самом приложении
|
||
|
||
## Благодарности
|
||
|
||
Построено с использованием:
|
||
- [LiveKit](https://livekit.io/) — SFU
|
||
- [faster-whisper](https://github.com/guillaumekln/faster-whisper) — транскрибация
|
||
- [Qwen](https://github.com/QwenLM/Qwen) — LLM
|
||
- [FastAPI](https://fastapi.tiangolo.com/) — backend фреймворк
|
||
- [React](https://react.dev/) — frontend
|