# ADR-002. Атрибуция аудиотреков и фраз к участнику сеанса (participant_id вместо user_id)

## Статус
ПРИНЯТО

## Контекст
FR-4.2 ТЗ фиксирует схему `phrases (id, user_id, conferences_id, data, t_start,
t_end)` — атрибуция фразы к зарегистрированному пользователю. После перехода
на динамические конференции (ADR-001) среди участников сеанса есть ГОСТИ без `user_id`
(`conference_participants` допускает ровно одну identity: `user_id` ИЛИ
`guest_id`). Кроме того, для записи per-track аудио (LiveKit Track Egress)
нужен персистентный маппинг «файл записи ↔ участник сеанса», которого в схеме
нет. Альтернативы:

- пара nullable-колонок `user_id`/`guest_id` в `phrases` — дублирует
  CHECK-логику `conference_participants` в каждой таблице пайплайна;
- заводить фиктивного user для гостя — нарушает модель auth и FR-1.

## Решение
1. В `phrases` колонка `user_id` заменяется на `participant_id` —
   NOT NULL FK на `conference_participants.id` (ON DELETE CASCADE). Спикер
   фразы — всегда строка участника сеанса; имя/email для отображения и
   рассылки берутся join'ом через `user_id`/`guest_id` участника.
2. Вводится таблица `session_audio_tracks`: одна строка на audio-трек сеанса
   (track SID, egress ID, путь к файлу, статус, `started_at`,
   `segments` JSONB) с тем же FK `participant_id`. Она — источник маппинга
   «файл ↔ спикер» и точка идемпотентного возобновления транскрибации.

## Последствия
- **Плюсы:** гости атрибутируются без костылей; единая точка истины об
  identity (`conference_participants`); повторное подключение того же
  пользователя даёт разные строки участника — тайм-окна присутствия точны.
- **Минусы:** выборка фраз «по пользователю» требует join через
  `conference_participants`; отступление от буквы FR-4.2 (фиксируется этим ADR).
- **Нейтрально:** `segments` JSONB — промежуточный артефакт пайплайна,
  очищается не обязательно (объём мал: текст+тайминги).

## Ссылки
- ADR-001 (динамические конференции, гостевой доступ).
- `backend/models/phrase.py`, `backend/models/participant.py`,
  `backend/models/audio_track.py`.
- Сеанс (`conference_sessions`) — единица пайплайна пост-обработки.
