UC-CAL-009. Руководитель смотрит календарь команды
Назначение
Описывает read-only обзор загрузки команды: руководитель агентства видит события и записи всех агентов
своей компании за период — кто когда занят показами и консультациями, где пересечения, сколько записей
ждёт решения и сколько встреч не закрыто исходом. Просмотр строго внутри своего tenant и без права
управления: изменять события и записи может только их владелец. Тот же механизм в платформенном scope
обслуживает менеджеров ПИН (календари инвест-консультантов). Связан с контекстом calendar.
| Поле | Значение |
|---|
| ID | UC-CAL-009 |
| Контекст | calendar (см. docs/06-services/calendar/) |
| Тип | основной |
| Статус | draft |
Актор
| Поле | Значение |
|---|
| Роль | Руководитель агентства (или иной сотрудник с правом обзора команды); вариант — менеджер ПИН в платформенном scope (A3) |
| Permissions / scope | calendar.team.view — scope Organization (read-only) |
| Tenant | TenantId = CompanyId агентства актора, ADR-0052 |
| Record-level | Не применяется к чтению внутри tenant (видны календари всех агентов компании); управляющие операции остаются record-level у владельцев |
Предусловие
- Актор авторизован и имеет
calendar.team.view в своей компании.
- Агенты компании ведут календари: события (UC-CAL-001), слоты и
записи (UC-CAL-002,
UC-CAL-003).
Триггер
| Поле | Значение |
|---|
| Источник | UI button |
| Триггерящий элемент | ЛК агентства → «Календарь команды» (обзор событий; вкладка «Записи») |
Основной Поток
- Руководитель открывает «Календарь команды»; клиент вызывает
../api/agency/list-team-events.md с
диапазоном from/to и опциональным фильтром по агентам (OwnerUserIds).
- Система проверяет
calendar.team.view и возвращает события только tenant-а актора: владелец
(display-данные из реплики identity), Kind, Origin, Status, Priority,
StartAt/EndAt/TimeZone, заголовок/место, признак HasConflicts (пересечения внутри календаря
каждого владельца, INV-CAL-6) — руководитель видит и занятость, и конфликты расписаний агентов.
- Руководитель открывает вкладку «Записи»; клиент вызывает
../api/agency/list-team-appointments.md
(фильтры: агент, статус, период). Система возвращает записи агентов tenant-а: время (снапшот слота),
вид, статус, display-данные инвестора и агента — видны зависшие Pending (агент не отвечает) и
Confirmed с прошедшим StartAt без исхода (встреча не закрыта,
UC-CAL-006 A4).
- Руководитель использует картину для управленческих решений вне системы (перераспределение нагрузки,
разговор с агентом); переназначение событий/записей другому агенту платформа в v1 не поддерживает
(ADR-0064 п.7).
Альтернативные Потоки
A1. Попытка управлять чужим событием или записью
- Руководитель вызывает управляющую операцию (изменить/отменить событие, подтвердить запись) над объектом
другого агента → отказ
CAL_EVENT_ACCESS_DENIED / APPOINTMENT_ACCESS_DENIED (403):
calendar.team.view даёт только чтение; управляют владельцы (calendar.events.manage,
calendar.appointments.decide). Клиент не отображает управляющие действия в командном обзоре.
A2. Фильтр по постороннему агенту
- В
OwnerUserIds указан пользователь другого tenant — его данные не возвращаются (tenant isolation
применяется до фильтров); ответ содержит только события/записи агентов компании актора. Пустой
результат — не ошибка.
A3. Менеджер ПИН смотрит календари консультантов
- Менеджер ПИН в платформенном scope использует
../api/pin-manager/list-events.md и
../api/pin-manager/list-appointments.md — та же read-only семантика поверх календарей
инвест-консультантов ПИН
(UC-OVR-002).
Завершается.
A4. Нет права обзора
- У актора нет
calendar.team.view → 403; доступен только собственный календарь
(UC-CAL-001).
Постусловие
- Состояние системы не изменено (read-only сценарий); руководитель получил картину загрузки команды за
период: события с конфликтами, записи со статусами, незакрытые встречи.
Возможные Ошибки
| Код | HTTP | Условие | Поведение клиента |
|---|
VALIDATION_FAILED | 400 | Некорректный диапазон from/to | Подсветить период |
CAL_EVENT_ACCESS_DENIED | 403 | Нет calendar.team.view (A4); управляющая операция над чужим событием (A1) | Скрыть командный обзор / управляющие действия |
APPOINTMENT_ACCESS_DENIED | 403 | Управляющая операция над чужой записью (A1) | Скрыть действия |
Acceptance Criteria
| # | Критерий | Проверка |
|---|
| AC1 | Выборка команды возвращает события всех агентов tenant-а актора за диапазон и ни одного события другого tenant | тест tenant isolation |
| AC2 | Фильтр OwnerUserIds с пользователем чужого tenant не возвращает его данных (A2) | негативный тест фильтра |
| AC3 | Признак HasConflicts в командной выборке считается внутри календаря каждого владельца (пересечения событий разных агентов конфликтом не являются) | тест конфликтов |
| AC4 | Выборка записей команды показывает Pending с PendingExpiresAt и Confirmed с прошедшим StartAt без исхода | тест управленческих фильтров |
| AC5 | Актор с calendar.team.view, но без calendar.events.manage не может изменить чужое событие (403); состояние не меняется (A1) | негативный тест read-only |
| AC6 | Актор без calendar.team.view получает 403 на командные выборки (A4) | негативный тест доступа |
| AC7 | Командные выборки не отдают данные за пределами запрошенного диапазона from/to | тест диапазона |
Наблюдаемость
- Логи (без PII).
team-calendar-viewed (tenantId, actorUserId, from, to, agentsCount);
содержимое событий (заголовки/описания) в логи не пишется.
- Метрики.
calendar_team_views_total; латентность командных выборок (p95 < 300 мс — SLO сервиса;
выборка ограничена диапазоном и tenant-ом).
Обратные ссылки
Автоссылки: где используется этот документ.
Связанные Документы
- API:
../api/agency/list-team-events.md, ../api/agency/list-team-appointments.md,
../api/pin-manager/list-events.md, ../api/pin-manager/list-appointments.md.
- Domain: calendar-event.md (INV-CAL-6, permission-модель),
appointment.md (статусы записей).
- Permissions: permission.md (
calendar.team.view и весь набор
calendar.*).
- Сценарий: UC-OVR-002
(консультанты ПИН).
- Связанные UC: UC-CAL-001 (собственный календарь агента),
UC-CAL-004 (зависшие
Pending),
UC-CAL-006 (незакрытые встречи).