GET /api/messenger/conferences/{conferenceId}/recordings — Записи конференции
Список записей конференции (conference-session.md). Каждая запись —
проекция CallRecordingEntity (дом полей, статусы, инварианты — там).
Запись стартует по политике; ручного старта нет.
Назначение
Вернуть активному участнику Deal-чата записи конференции — метаданные без бинаря и без ссылки на скачивание
(ссылка выдаётся отдельным методом get-recording-download.md). Доступ к
конференции = членство в её Deal-чате (record-level, INV-CHAT-4), а не участие в самой сессии — историю
встречи видит вся команда сделки. Owning-сервис — messenger, feature group recordings.
| Поле | Значение |
|---|
| Сервис/контекст | messenger |
| API area | recordings |
| Feature group | recordings |
| Статус | draft |
| Документ | docs/06-services/messenger/api/recordings/list-conference-recordings.md |
Актор и доступ
| Проверка | Значение |
|---|
| Actor type | User — активный участник Deal-чата конференции |
| Auth policy / Permissions | permission messenger.recordings.view |
| Scope (RBAC) | не применяется (доступ — по членству, не по scope) |
| Record-level | активное членство в ChatId конференции: активный ParticipantEntity (RemovedAt is null), INV-CHAT-4 |
| Tenant isolation | нет (кросс-tenant Deal-чата); изоляция — по членству |
| Audit | read (нечувствительный): метаданные без FileId-ссылки/URL |
HTTP-контракт
| Поле | Значение |
|---|
| Method | GET |
| Route | /api/messenger/conferences/{conferenceId}/recordings |
| Success status | 200 (OK) |
| Idempotency header | не применяется (чтение) |
| Correlation | сквозной trace через traceparent |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|
ConferenceId | route | Guid | Да | != Empty; существующая конференция, актор — член её ChatId (шаги 3–4) | — |
ActorUserId | identity claims | Guid | Да | из JWT; активный участник ChatId | — |
Take | query | int | Нет | 1..100, default 20 | — |
Offset | query | int | Нет | >= 0, default 0 | — |
Модель ответа RecordingListModel
Тот же wrapper, что в list-call-recordings.md:
{ Items: RecordingEntry[], Total, Take, Offset }. Элемент RecordingEntry — компактная проекция
CallRecordingEntity (SessionKind = Conference, SessionId = ConferenceId); полное описание полей — там же. Ссылка FileId/URL в список не входит.
Алгоритм
- Контекст и доступ. Операцию выполняет участник Deal-чата (
User); ActorUserId — из JWT; требуется
право messenger.recordings.view. Запись включена флагом RECORDINGS_ENABLED, иначе MSG_RECORDINGS_DISABLED.
- Проверка входа.
ConferenceId непустой; Take/Offset в диапазонах — иначе ошибка валидации.
- Загрузка конференции. Конференция по
ConferenceId; нет → MSG_CONFERENCE_NOT_FOUND. Читаем её ChatId.
- Право. Актор должен быть активным членом
ChatId конференции (INV-CHAT-4): нет активного участия
(RemovedAt проставлен либо участия не было) → MSG_CHAT_ACCESS_DENIED. Доступ определяется актуальным
членством в Deal-чате, а не фактом присутствия на самой встрече: участник встречи, позже исключённый из
чата, историю встреч теряет; новый член чата, добавленный после встречи, записи прошлых встреч команды
видит.
- Что читаем. Записи с
SessionKind = Conference и ConferenceSessionId == ConferenceId, сортировка по
CreatedAt убыв., страница Take/Offset; Total — общее число. Статусы — снимок на момент чтения
(запись, дозревающая до Available, обновит метаданные при повторном запросе).
- Результат.
RecordingListModel (метаданные без ссылок) → HTTP 200 OK. Пустой список — валидный ответ.
Ошибки и failure modes
| Код | HTTP status | Условие | Сообщение | Retry |
|---|
VALIDATION_FAILED | 400 | ConferenceId = Empty / Take/Offset вне диапазона | «Проверьте параметры запроса» | no retry |
MSG_CONFERENCE_NOT_FOUND | 404 | конференции нет | «Конференция не найдена» | no retry |
MSG_CHAT_ACCESS_DENIED | 403 | актор не активный член Deal-чата конференции | «Нет доступа к чату» | no retry |
MSG_RECORDINGS_DISABLED | 503 | RECORDINGS_ENABLED = false | «Записи временно недоступны» | retry позже |
Acceptance Criteria
- Given активный член Deal-чата и конференция с
Available-записью, When запрашивает список, Then
200, Items содержит записи встречи (метаданные без FileId-ссылки), Total соответствует.
- Given новый член чата, добавленный после встречи, When запрашивает список, Then
200 — видит
записи прошлых встреч команды сделки.
- Given участник встречи, позже исключённый из чата (
RemovedAt), When запрашивает список,
Then 403 MSG_CHAT_ACCESS_DENIED (доступ — по актуальному членству).
- Given конференции нет, When запрос, Then
404 MSG_CONFERENCE_NOT_FOUND.
- Given
Take/Offset вне диапазона, When запрос, Then 400 VALIDATION_FAILED.
- Given
RECORDINGS_ENABLED = false, When любой запрос, Then 503 MSG_RECORDINGS_DISABLED.
Совместимость и наблюдаемость
- Новые optional-поля
RecordingEntry — additive; удаление/смена типа — breaking. Kafka-контракта нет.
- Logs:
conference recordings listed (ConferenceId, ChatId, Total); metrics:
messenger_recordings_list_total{scope="conference"}, latency p95; correlation через traceparent;
ссылки/URL/бинарь в логи не пишутся.
Обратные ссылки
Автоссылки: где используется этот документ.
Связанные документы