Перейти к основному содержимому

UC-CAL-010. Руководитель ПИН смотрит календари консультантов

Назначение

Описывает read-only обзор загрузки инвест-консультантов ПИН: руководитель (менеджер) компании ПИН видит события и записи всех консультантов своей компании за период — кто когда занят консультациями и показами, где пересечения расписаний, сколько записей ждёт решения и сколько встреч не закрыто исходом. Обзор нужен, чтобы распределять входящие обращения инвесторов между свободными консультантами и контролировать занятость (UC-OVR-002). Просмотр строго внутри компании ПИН и без права управления: изменять чужое событие или запись может только его владелец-консультант — он пользуется теми же операциями, что и агент агентства (UC-CAL-001). Тот же read-only механизм в scope организации обслуживает руководителей агентств (UC-CAL-009); данный сценарий — его платформенный аналог поверх календарей ПИН. Связан с контекстом calendar.

Metadata

ПолеЗначение
IDUC-CAL-010
Контекстcalendar (см. docs/06-services/calendar/)
Типосновной
Статусdraft

Актор

ПолеЗначение
РольМенеджер / руководитель ПИН (сотрудник компании ПИН, распределяющий входящие обращения)
Permissions / scopecalendar.team.view — назначено в scope компании ПИН (read-only обзор команды консультантов)
TenantTenantId = CompanyId компании ПИН, ADR-0052
Record-levelНе применяется к чтению внутри компании ПИН (видны календари всех консультантов); управляющие операции остаются record-level у владельцев

Предусловие

  • Актор — сотрудник компании ПИН, авторизован и имеет calendar.team.view в scope компании ПИН.
  • Инвест-консультанты ПИН ведут собственные календари теми же операциями, что и агенты: события (UC-CAL-001), слоты самозаписи и записи инвесторов (UC-CAL-002, UC-CAL-003).

Триггер

ПолеЗначение
ИсточникUI button
Триггерящий элементЛК ПИН → «Календарь консультантов» (обзор событий; вкладка «Записи»)

Основной Поток

  1. Руководитель ПИН открывает «Календарь консультантов»; клиент вызывает ../api/pin-manager/list-events.md с диапазоном From/To (UTC, To > From, окно ≤ 92 дня) и опциональным фильтром по консультанту (ConsultantUserId), виду (Kind) и статусу (Status).
  2. Система проверяет calendar.team.view в scope компании ПИН и то, что актор — сотрудник компании ПИН; TenantId берётся из токена (не из query). Возвращаются события только компании ПИН: владелец-консультант (display-данные из реплики identity), Kind, Origin, Status, Priority, StartAt/EndAt/TimeZone, заголовок/место, признак HasConflicts (пересечения внутри календаря каждого консультанта, INV-CAL-6) — руководитель видит и занятость, и конфликты расписаний, сгруппированные по OwnerUserId.
  3. Руководитель открывает вкладку «Записи»; клиент вызывает ../api/pin-manager/list-appointments.md (фильтры: консультант, статус, период). Система возвращает записи консультантов компании ПИН: время (снапшот слота), вид, статус, display-данные инвестора и консультанта — видны зависшие Pending (консультант не отвечает, UC-CAL-004) и Confirmed с прошедшим StartAt без исхода (встреча не закрыта, UC-CAL-006 A4).
  4. Руководитель использует картину для распределения нагрузки: направляет входящее обращение инвестора свободному консультанту, инициирует разговор с перегруженным. Само назначение обращения ведётся вне календаря (CRM/консультация); переназначение чужих событий/записей другому консультанту через календарь в v1 не выполняется — управляют владельцы.

Альтернативные Потоки

A1. Попытка управлять чужим событием или записью

  1. Руководитель ПИН вызывает управляющую операцию (изменить/отменить событие, подтвердить запись) над объектом консультанта → отказ CAL_EVENT_ACCESS_DENIED / APPOINTMENT_ACCESS_DENIED (403): calendar.team.view даёт только чтение; управляют владельцы (calendar.events.manage, calendar.appointments.decide). В pin-manager-области управляющих операций нет — клиент их не отображает.

A2. Фильтр по консультанту другого tenant

  1. В ConsultantUserId указан пользователь вне компании ПИН (агент агентства) — его данные не возвращаются (tenant isolation применяется до фильтров, fail-closed); ответ содержит только события/записи консультантов компании ПИН. Пустой результат — не ошибка (200, Items = []).

A3. Руководитель агентства пытается смотреть консультантов ПИН

  1. Актор — руководитель агентства с calendar.team.view своего агентства — обращается к pin-manager-области → 403 FORBIDDEN: обзор консультантов ПИН доступен только сотрудникам компании ПИН. Своя команда — в agency-области (UC-CAL-009).

A4. Нет права обзора

  1. У актора нет calendar.team.view403; доступен только собственный календарь, если актор сам ведёт приём (UC-CAL-001).

Постусловие

  • Состояние системы не изменено (read-only сценарий); руководитель ПИН получил картину загрузки консультантов за период: события с конфликтами, записи со статусами, незакрытые встречи — основу для распределения входящих обращений.

Возможные Ошибки

КодHTTPУсловиеПоведение клиента
VALIDATION_FAILED400Отсутствует/некорректен диапазон From/To; окно > 92 дней; enum/paging вне границПодсветить период/параметры
UNAUTHORIZED401Нет/просрочен токенПовторная аутентификация
CAL_EVENT_ACCESS_DENIED / FORBIDDEN403Нет calendar.team.view в scope ПИН (A4); актор не сотрудник ПИН (A3); управляющая операция над чужим событием (A1)Скрыть обзор / управляющие действия
APPOINTMENT_ACCESS_DENIED403Управляющая операция над чужой записью (A1)Скрыть действия

Acceptance Criteria

#КритерийПроверка
AC1Выборка возвращает события всех консультантов компании ПИН за диапазон и ни одного события другого tenant (агентства)тест tenant isolation
AC2Фильтр ConsultantUserId с пользователем вне компании ПИН не возвращает его данных (A2)негативный тест фильтра (fail-closed)
AC3Признак HasConflicts считается внутри календаря каждого консультанта (пересечения событий разных консультантов конфликтом не являются)тест конфликтов per-owner
AC4Выборка записей показывает Pending и Confirmed с прошедшим StartAt без исходатест управленческих фильтров
AC5Актор с calendar.team.view, но без calendar.events.manage не может изменить чужое событие (403); состояние не меняется (A1)негативный тест read-only
AC6Руководитель агентства получает 403 в pin-manager-области (A3); своя команда — в agency-областинегативный тест scope
AC7Выборки не отдают данные за пределами запрошенного диапазона From/Toтест диапазона

Наблюдаемость

  • Логи (без PII). pin-team-calendar-viewed (tenantId = компания ПИН, actorUserId, from, to, consultantsCount); содержимое событий (заголовки/описания/место) в логи не пишется.
  • Метрики. calendar_team_views_total; латентность выборок (SLO сервиса; выборка ограничена диапазоном и компанией ПИН).

Обратные ссылки

Автоссылки: где используется этот документ.

Связанные Документы

  • API: ../api/pin-manager/list-events.md, ../api/pin-manager/list-appointments.md; дом модели/правил — ../api/agent/list-events.md; agency-аналог — ../api/agency/list-team-events.md, ../api/agency/list-team-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-009 (обзор команды агентства — тот же механизм в scope организации), UC-CAL-001 (собственный календарь консультанта), UC-CAL-004 (зависшие Pending), UC-CAL-006 (незакрытые встречи).