Max Ronzhin 8e5eda88a2 feat(room): поднятие руки и очередь для организатора
Транспорт — существующий аутентифицированный WS чата (api/chat.py), а не
отдельный эндпоинт: сервер уже держит это соединение на каждого участника
(обоснование — докстринг chat_websocket и useChat.ts). Состояние очереди —
Redis (services/hand_queue.py), не Postgres: это эфемерное состояние звонка,
а не история, и два процесса uvicorn делают наивную память одного процесса
недостаточной. HSETNX даёт идемпотентное «поднять» (повторный клик не
переставляет в конец очереди), снапшот шлётся всем участникам при любом
изменении — организатор, зашедший позже, сразу видит актуальную картину.

Опустить чужую руку может организатор (решение оператора) — проверка через
conference.owner_id, не через identity клиента. Участник, вышедший из
комнаты LiveKit (webhook participant_left), теряет место в очереди
автоматически; переподключение WS чата место не сбрасывает (Redis не привязан
к жизни соединения). room_finished чистит очередь целиком — она не должна
пережить завершение звонка.

Побочный эффект транспортного решения: поднять руку нельзя, если чат выключен
настройкой инстанса (WS вообще не открывается) — принятый компромисс ради
переиспользования уже готового канала.

UI: кнопка «Рука» в тулбаре (у всех, бейдж — общий счётчик), бейдж на плитке
говорящего (видно всем), панель «Очередь» организатору (HandQueuePanel).
Кнопка «Рука» и панель «Очередь» намеренно НЕ прячутся в мобильную шторку
настроек, в отличие от «Вида», — поднятие руки посреди разговора требует
кнопки под рукой, а не в два клика вглубь настроек.

Этим же коммитом (файлы разделяемые с задачей B2, RoomParticipantTile.tsx/
useChat.ts/RoomStage.tsx/RoomPage.tsx/room.css) — проброс conferenceId и
каркас forced_mute-обработки, без которых кнопки принудительного мьюта не
скомпилировались бы; сама реализация мьюта — следующим коммитом.
2026-08-01 22:06:43 +03:00
2026-07-30 00:27:51 +03:00
2026-07-30 00:27:51 +03:00
2026-07-30 00:27:51 +03:00
2026-07-30 00:27:51 +03:00

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             Этот файл

Быстрый старт

📘 Разворачиваете на боевом сервере? Пошаговое руководство — docs/deploy/DEPLOYMENT.md: от голой Ubuntu до https://<домен> (SSL, .env, профили, траблшутинг, мониторинг). Раздел ниже — быстрый старт для разработки.

Требования

  • Docker + Docker Compose v2
  • uv (инструменты Python): brew install uv
  • Node 20+ (frontend)

1. Клонирование и настройка

git clone https://github.com/your-org/vidconf.git
cd vidconf
cp .env.example .env

2. Запуск (три варианта)

Вариант A: Автоматический инсталлятор (рекомендуется)

./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 (1216 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)

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

docker compose -f deploy/docker-compose.yml --env-file .env \
  --profile media --profile transcribe --profile llm up -d

3. Настройка БД

cd backend
uv run alembic upgrade head        # Запуск миграций
uv run python -m scripts.seed      # Идемпотентный сид: единственный админ-пользователь

4. Запуск frontend

cd frontend
npm install
npm run dev

Frontend запущен на http://localhost:5173 (dev сервер).

5. (Опционально) Включение медиа-стека

Для использования видеоконференций с LiveKit + Coturn:

docker compose -f deploy/docker-compose.yml --env-file .env --profile media up -d

Полные детали настройки см. в docs/deploy/dev-setup.md.

Тестирование и качество кода

# 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):

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)

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.

Схема БД

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.

Архитектура

Ключевые архитектурные принципы:

  • Система плагинов: Реализации Transcriber/Summarizer подключаемы через паттерн Strategy + Factory
  • Идемпотентный pipeline: Пост-конференционная обработка (транскрибирование → суммаризация → уведомление) использует state machine в enum pipeline_status
  • Без диаризации: Per-track аудио в SFU исключает необходимость диаризации спикеров
  • Гости как полноценные участники: гостевой доступ (без регистрации) участвует в пайплайне наравне с зарегистрированными пользователями
  • Всё в UTC: Времена всегда UTC в хранилище; преобразование часовых поясов на клиенте

ADR и обоснования дизайна см. в 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/.

Дизайн-система

UI следует строгим рекомендациям дизайна, определённым в 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.

Развёртывание

Полное руководство по боевому развёртыванию: docs/deploy/DEPLOYMENT.md — воспроизводимый путь от голой Ubuntu 24 до рабочего https://<домен>: предусловия, выпуск SSL, разбор .env, запуск, проверка после деплоя, траблшутинг, мониторинг.

Пресеты инсталлятора

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
./install.sh                    # интерактивный опросник с рекомендацией
./install.sh --preset 3         # неинтерактивно (пресет 3 = AI min)
./install.sh --preset 3 --yes   # без подтверждений (для CI/скриптов)

Требования к оборудованию и полное описание см. в docs/deploy/install.md и docs/architecture/adr/004-ai-tier-matrix.md.

Docker Compose профили (низкоуровневый контроль)

Если вы хотите настраивать стек вручную без инсталлятора:

# Минимум (только 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. Запустите проверки качества:
    cd backend && ruff check . && mypy . && pytest -q
    cd frontend && npm run lint && npm run build
    
  5. Создайте коммит с ясным сообщением и ссылками на документацию

Лицензия

[Добавьте вашу лицензию здесь]

Поддержка

  • Ошибки и баги: GitHub Issues
  • Документация: docs/
  • Чат и реал-тайм: Комната конференции в самом приложении

Благодарности

Построено с использованием:

Description
сервис видеоконференций
Readme 5.2 MiB
Languages
Python 51.2%
TypeScript 24.3%
HTML 13.7%
CSS 8.1%
Shell 2.3%
Other 0.3%