Первоначальная версия VidConf

This commit is contained in:
2026-07-23 01:04:01 +03:00
commit 896455381a
335 changed files with 61527 additions and 0 deletions

356
backend/README.md Normal file
View File

@@ -0,0 +1,356 @@
# Backend — FastAPI приложение
HTTP API сервер для VidConf: аутентификация (JWT), динамические конференции
(создание, календарь, вход по ссылке/номеру, гостевой доступ), чат в
реальном времени, администрирование (конференции/пользователи/команды/
настройки инстанса), контракты плагинов (Transcriber/Summarizer) и интеграция
с LiveKit (токены, webhook-приёмник).
## Структура
```
backend/
├── api/ HTTP endpoint'ы
│ ├── __init__.py
│ ├── deps.py JWT-зависимости для аутентификации
│ ├── auth.py Регистрация, подтверждение email, вход, refresh, выход
│ ├── users.py Профиль, аватары, поиск пользователей (GET/PATCH /users/me,
│ │ POST/DELETE /users/me/avatar, POST /users/me/password, GET /users?q=)
│ ├── teams.py Справочник команд (GET /teams)
│ ├── admin.py Администрирование конференций, пользователей, команд, настроек инстанса
│ ├── health.py GET /api/health
│ ├── metrics.py GET /metrics (Prometheus)
│ ├── conferences.py Динамические конференции (create, my, calendar, resolve,
│ │ join, guest-join, GET/PATCH/DELETE /{id})
│ ├── chat.py WS-эндпоинт чата (auth по LiveKit-токену, история, broadcast через Redis pub/sub)
│ └── livekit_webhook.py Webhook-приёмник событий LiveKit
├── core/ Основные модули
│ ├── config.py Конфиг из .env (Settings)
│ ├── security.py Hash/verify пароля (argon2), JWT токены
│ ├── db.py Управление сеансами БД (async)
│ ├── redis.py Redis клиент
│ ├── rate_limit.py Rate limiting для публичных endpoint'ов
│ ├── summarization/ Чанкинг транскрипта, LLM-клиент, подсчёт токенов
│ └── plugins/ Контракты Transcriber/Summarizer, factory, реализации
│ ├── transcriber.py Контракт Transcriber
│ ├── summarizer.py Контракт Summarizer
│ ├── config.py Pydantic-конфиг плагинов
│ ├── factory.py Регистрация и создание провайдеров
│ ├── null.py NullTranscriber, NullSummarizer (no-op)
│ ├── faster_whisper.py FasterWhisperCPU, FasterWhisperGPU
│ └── qwen_local.py QwenLocal (map-reduce суммаризация через llama.cpp)
├── models/ SQLAlchemy ORM (14 таблиц, см. docs/db/schema.md)
│ ├── base.py Base class
│ ├── user.py User
│ ├── team.py Team (справочник команд)
│ ├── email_verification.py EmailVerificationToken
│ ├── conference.py Conference (номер, slug, владелец, recurrence)
│ ├── invitee.py ConferenceInvitee (приглашённые: user_id ИЛИ email)
│ ├── guest.py GuestAccess (display_name, email)
│ ├── session.py ConferenceSession (один запуск конференции, pipeline_status)
│ ├── participant.py ConferenceParticipant (user_id ИЛИ guest_id, session_id)
│ ├── audio_track.py SessionAudioTrack (аудиодорожка участника)
│ ├── phrase.py Phrase (текстовые сегменты транскрибации, participant_id, session_id)
│ ├── chat.py ChatMessage (автор: пользователь ИЛИ гость, author_name, session_id)
│ ├── email_delivery.py EmailDelivery (журнал отправленных писем)
│ ├── instance_setting.py InstanceSetting (key-value настройки инстанса, JSONB)
│ └── webhook_event.py LivekitWebhookEvent
├── repositories/ Async слой доступа к данным
│ ├── users.py
│ ├── conferences.py
│ ├── chat.py ChatMessageRepository (последние N сообщений, добавление)
│ └── admin.py
├── services/ Бизнес-логика
│ ├── auth.py Аутентификация (регистрация, вход)
│ ├── conferences.py CRUD и валидация конференций, жизненный цикл, участники, .ics-приглашения
│ ├── conference_access.py Проверка доступа (пароль, статус ended)
│ ├── conference_ids.py Генерация номера (9 цифр) и slug (base64url)
│ ├── recurrence.py RecurrenceRule, развёртка occurrences
│ ├── avatars.py Загрузка, валидация (magic bytes), удаление аватаров
│ ├── profile.py Обновление профиля (ФИО, команда)
│ ├── invitations_producer.py Постановка .ics-приглашений в очередь Celery
│ ├── chat.py ChatService (auth по LiveKit-токену, history, persist+publish)
│ ├── livekit_tokens.py Генерация LiveKit JWT-токенов
│ ├── webhook_handlers.py Обработчики webhook-событий от LiveKit
│ ├── egress.py Запуск/остановка записи аудио через LiveKit Egress
│ ├── email.py / email_templates.py Отправка писем (саммари, приглашения)
│ ├── ics.py Генерация .ics-приглашений
│ ├── instance_settings.py Эффективная конфигурация инстанса (уровень AI, чат и т.д.)
│ ├── ai_levels.py / ai_tiers.py Матрица уровней AI (min/medium/max), детект доступности
│ └── pipeline_producer.py Постановка задач пайплайна пост-обработки в Celery
├── schemas/ Pydantic-схемы для запросов/ответов
│ ├── auth.py Auth, профиль пользователя
│ ├── admin.py Админка (конференции, пользователи, команды, настройки)
│ ├── conferences.py ConferenceCreateIn/UpdateIn, ConferenceOut, JoinOut, ResolveOut, OccurrenceOut, InviteeIn/Out
│ └── chat.py ChatAuthIn, ChatMessageIn/Out, ChatHistoryOut, ChatErrorOut
├── alembic/ Миграции БД
│ ├── versions/ 9 миграций от initial schema до teams/avatars/settings
│ └── env.py
├── scripts/ Утилиты
│ ├── __init__.py
│ ├── seed.py Идемпотентный сид: единственный админ-пользователь
│ └── apply_preset_settings.py Применить настройки инстанса под пресет install.sh
├── tests/ Тесты (pytest, см. полный список файлов в каталоге)
│ ├── conftest.py
│ ├── test_health.py
│ ├── test_auth.py / test_rbac.py / test_tokens.py
│ ├── test_conferences_api.py / test_conference_service.py / test_recurrence.py
│ ├── test_chat_ws.py
│ ├── test_admin_api.py / test_admin_teams.py / test_teams_api.py / test_users_api.py
│ ├── test_plugins_factory.py / test_qwen_local.py / test_llm_client.py
│ ├── test_pipeline.py / test_build_phrases.py / test_summarize_task.py / test_notify_task.py
│ └── ...
├── main.py Точка входа FastAPI приложения
└── README.md Этот файл
```
## Быстрый старт
### Требования
- Python 3.12+
- `uv`: `brew install uv`
- PostgreSQL 16 + Redis (через docker-compose или локально)
### 1. Установка зависимостей
```bash
cd backend
uv sync
```
### 2. Запуск миграций
```bash
uv run alembic upgrade head
```
Создаёт 14 таблиц и включает расширение PostgreSQL `btree_gist` (установлено, но
на текущей схеме не используется ни одним constraint'ом).
### 3. Загрузка тестовых данных (опционально)
```bash
uv run python -m scripts.seed
```
Идемпотентный сид: создаёт единственного администратора (`SEED_ADMIN_EMAIL` /
`SEED_ADMIN_PASSWORD`), если его ещё нет. Конференции создаются пользователями
динамически, предустановленных данных не требуется.
### 4. Запуск сервера
```bash
uv run uvicorn main:app --reload --host 0.0.0.0 --port 8000
```
API доступен по адресу `http://localhost:8000`.
Документация:
- Swagger: `http://localhost:8000/docs`
- ReDoc: `http://localhost:8000/redoc`
## Тестирование
```bash
# Запуск всех тестов
uv run pytest -q
# Запуск с покрытием
uv run pytest --cov=. --cov-report=html
# Запуск конкретного теста
uv run pytest tests/test_health.py -v
```
## Качество кода
```bash
# Linting
uv run ruff check .
# Проверка форматирования
uv run ruff format --check .
# Автоматическое форматирование
uv run ruff format .
# Проверка типов
uv run mypy .
```
Все проверки должны пройти перед мёржем.
## Конфигурация
### Переменные окружения (`.env`)
Полный список переменных (БД, Redis, JWT, LiveKit, Coturn, email/SMTP, уровни
AI, обнаруженное железо для install.sh и т.д.) и их назначение — см.
[docs/deploy/env.md](../docs/deploy/env.md). Модель `Settings` в
`core/config.py` — единственный источник дефолтов.
### Конфигурация плагинов (`config/plugins.yaml`)
```yaml
transcriber:
enabled: true
provider: "null"
model: null
language: ru
summarizer:
enabled: true
provider: "null"
model: null
chunk_minutes: 20
chat:
enabled: true
```
Подробнее о плагинах см. [docs/plugins/contracts.md](../docs/plugins/contracts.md).
## База данных
### Схема
**14 ORM моделей:**
- `users` — зарегистрированные пользователи
- `teams` — справочник команд
- `email_verification_tokens` — одноразовые токены верификации email
- `conferences` — постоянные сущности конференций (номер, slug, владелец, recurrence)
- `conference_invitees` — приглашённые на конференцию (пользователь или внешний email)
- `guest_access` — гости, представившиеся при входе (display_name, email)
- `conference_sessions` — один запуск конференции (pipeline_status, summary_data)
- `conference_participants` — отслеживание присутствия в сеансе (user_id ИЛИ guest_id, session_id)
- `session_audio_tracks` — аудиодорожки участников сеанса
- `phrases` — текстовые сегменты транскрибации (participant_id, session_id)
- `chat_messages` — сообщения в сеансе (session_id, автор — пользователь или гость)
- `email_deliveries` — журнал отправленных писем
- `instance_settings` — key-value настройки инстанса (JSONB)
- `livekit_webhook_events` — журнал webhook-событий для идемпотентности
Полную ER-диаграмму и обоснования дизайна см. [docs/db/schema.md](../docs/db/schema.md).
### Миграции
Alembic управляет схемой:
```bash
# Проверить текущую версию
uv run alembic current
# Обновить до последней версии
uv run alembic upgrade head
# Создать миграцию после изменений модели
uv run alembic revision --autogenerate -m "description"
```
**Правило:** Модель + миграция коммитятся вместе; никогда только модель.
### Временные метки
Все `DateTime(timezone=True)` сохраняются как UTC в PostgreSQL. Клиент преобразует в локальный часовой пояс.
## API
Полная спецификация: [docs/api/README.md](../docs/api/README.md).
- `GET /api/health` — проверка здоровья (БД, Redis)
- `GET /metrics` — метрики Prometheus
- `/api/v1/auth/*` — регистрация, подтверждение email, вход, refresh, выход
- `/api/v1/users/*` — профиль, аватар, смена пароля, поиск пользователей
- `/api/v1/teams` — справочник команд
- `/api/v1/conferences/*` — создание, календарь, вход по ссылке/номеру, гостевой вход, изменение/удаление
- `WS /api/v1/conferences/{id}/chat` — текстовый чат в реальном времени
- `/api/v1/admin/*` — администрирование конференций, пользователей, команд, настроек
- `/api/v1/livekit/webhook` — приёмник webhook-событий LiveKit
## Плагины
Контракты плагинов в `backend/core/plugins/`:
**Transcriber:**
```python
class Transcriber(ABC):
provider: ClassVar[str]
def transcribe(self, audio_path: str, language: str = "ru") -> list[Segment]: ...
```
**Summarizer:**
```python
class Summarizer(ABC):
provider: ClassVar[str]
def summarize(self, transcript: str) -> str: ...
```
**Реализации:**
- `NullTranscriber`, `NullSummarizer` — no-op (`provider: "null"`, дефолт)
- `FasterWhisperCPU`, `FasterWhisperGPU` — [docs/plugins/transcriber.md](../docs/plugins/transcriber.md)
- `QwenLocal` — map-reduce суммаризация через llama.cpp — [docs/plugins/summarizer.md](../docs/plugins/summarizer.md)
**Как добавить новый плагин:**
1. Создайте класс, наследующий Transcriber/Summarizer
2. Декоратор: `@register_transcriber` или `@register_summarizer`
3. Укажите провайдера в `config/plugins.yaml`
Все контракты и фабрика: [docs/plugins/contracts.md](../docs/plugins/contracts.md).
## Celery воркеры
Пост-обработка (транскрибирование, суммаризация, email-уведомления и
приглашения) выполняется в Celery-воркерах. См. [workers/README.md](../workers/README.md).
## Решение проблем
**ImportError:**
```bash
uv sync --all-extras
```
**Ошибка подключения к БД:**
```bash
docker compose -f ../deploy/docker-compose.yml ps
echo $DATABASE_URL
```
**Миграции не выполняются:**
```bash
uv run alembic current
uv run alembic downgrade base
uv run alembic upgrade head
```
**Ошибки типов:**
- Python 3.12+: `python --version`
- Пересборка: `uv sync --refresh`
## Процесс разработки
1. **Ветка:** `git checkout -b feature/my-feature`
2. **Напишите тесты:** `tests/test_*.py`
3. **Реализуйте** в соответствующем модуле
4. **Качество:** `pytest -q && ruff check . && mypy .`
5. **Коммит:** включите резюме тестов
Пример:
```
feat: добавить реестр Transcriber плагинов
- Реализовать декоратор @register_transcriber
- Добавить NullTranscriber no-op реализацию
- Добавить test_plugins_factory.py
Тесты: пройдены
```
## Ссылки
- [Корневой README](../README.md) — обзор проекта
- [Схема БД](../docs/db/schema.md) — ER диаграмма & дизайн
- [Контракты плагинов](../docs/plugins/contracts.md) — гайд расширений плагинов
- [API справка](../docs/api/README.md) — endpoint'ы
- [Архитектура](../docs/architecture/README.md) — дизайн системы
- [Dev Setup](../docs/deploy/dev-setup.md) — локальное окружение