GET /api/v1/pin-manager/calendar/events — Календари консультантов ПИН (read-only)
Назначение
Отдаёт менеджеру ПИН события календарей инвест-консультантов компании ПИН: загрузку консультантов,
запланированные консультации и их статусы — чтобы распределять входящие обращения инвесторов и
контролировать занятость
(UC-OVR-002).
Выборка строго read-only: своим календарём консультант управляет сам через agent-область — консультанты ПИН
пользуются теми же операциями, что и агенты агентств.
| Поле | Значение |
|---|
| Сервис/контекст | calendar |
| API area | pin-manager |
| Feature group | pin-calendar |
| Статус | draft |
| Документ | docs/06-services/calendar/api/pin-manager/list-events.md |
Актор и доступ
| Проверка | Значение |
|---|
| Actor type | User (менеджер / руководитель ПИН — сотрудник компании ПИН) |
| Auth policy / Permissions | calendar.team.view (назначено в scope компании ПИН) |
| Scope (RBAC) | организация: компания ПИН — актор не из компании ПИН доступа не имеет |
| Record-level | не применяется — видны события всех консультантов компании ПИН |
| Tenant isolation | TenantId из токена (tenant_id) = компания ПИН; календари агентств этой областью недоступны (ADR-0052) |
| Audit | read-sensitive: актор, фильтры и ConsultantUserId фиксируются в trace; Title/Description/Location в логи не пишутся |
HTTP-контракт
| Поле | Значение |
|---|
| Method | GET |
| Route | /api/v1/pin-manager/calendar/events |
| Success status | 200 |
| Idempotency header | нет (безопасное чтение) |
| Correlation | сквозной trace через заголовок traceparent |
Входные данные / параметры запроса
Все фильтры комбинируются по «И».
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|
TenantId | токен (tenant_id) | Guid | Да | Required (= компания ПИН); не принимается из query | Tenant isolation |
From | query | DateTimeOffset | Да | UTC; начало диапазона | — |
To | query | DateTimeOffset | Да | UTC; To > From; To − From ≤ 92 дня | — |
ConsultantUserId | query | Guid? | Нет | календарь конкретного консультанта (фильтр по владельцу события); пользователь вне компании ПИН → пустая выборка (fail-closed) | — |
Kind | query | EventKind? | Нет | enum-строка Showing/Consultation/Meeting/Task/BookingDeadline (у консультантов преобладает Consultation) | — |
Status | query | EventStatus? | Нет | enum-строка Planned/InProgress/Completed/Cancelled | — |
Page / PageSize | query | int | Нет | Page ≥ 1; PageSize 1..500, default 200 | — |
Модель ответа — страница CalendarEventModel
Модель, правило выборки диапазона и правило HasConflicts — по дому
list-events.md; OwnerUserId строки — консультант ПИН. Сортировка —
OwnerUserId, затем StartAt возр., затем Id (как в agency-выборке);
HasConflicts вычисляется per-owner.
Алгоритм
- Контекст и доступ. Актор — сотрудник компании ПИН с
calendar.team.view; нет права или актор не из
компании ПИН → FORBIDDEN. TenantId берётся из токена.
- Проверка входа.
From/To заданы, To > From, диапазон ≤ 92 дней; enum-значения допустимы;
paging в границах — иначе VALIDATION_FAILED.
- Что читаем. Страница событий
TenantId = компания ПИН по правилу выборки диапазона с наложением
фильтров ConsultantUserId (владелец)/Kind/Status по «И»; сортировка OwnerUserId, StartAt
возр., Id; HasConflicts — per-owner.
- Результат. Страница
CalendarEventModel → HTTP 200; пустая выборка — 200 с Items = [].
Данные — из source of truth calendar, актуальны на момент чтения.
Ошибки и failure modes
| Код | HTTP status | Условие | Сообщение | Retry |
|---|
VALIDATION_FAILED | 400 | From/To отсутствуют; To ≤ From; диапазон > 92 дней; enum вне значений; paging вне границ | «Некорректные параметры выборки» | no retry |
UNAUTHORIZED | 401 | нет/просрочен JWT | — | no retry |
FORBIDDEN | 403 | нет права calendar.team.view в scope компании ПИН / актор не сотрудник ПИН | — | no retry |
Совместимость и наблюдаемость
- Контракт модели — по дому list-events.md; правила additive/breaking — там же.
- Logs: актор,
ConsultantUserId-фильтр, диапазон, TotalCount (без содержимого событий); metrics:
calendar_api_request_duration_seconds{route}; traces — сквозной traceparent.
Acceptance Criteria
- AC-1 (загрузка консультантов). Дано: у двух консультантов ПИН консультации в диапазоне недели.
Когда:
GET с From/To. Тогда: 200, события обоих, сгруппированы по OwnerUserId; менеджер видит
свободные и занятые интервалы.
- AC-2 (один консультант). Дано:
ConsultantUserId консультанта ПИН. Тогда: только его события.
- AC-3 (не сотрудник ПИН). Дано: руководитель агентства с
calendar.team.view своего агентства.
Тогда: 403 FORBIDDEN для этой области (его команда — agency-область).
- AC-4 (календари агентств недоступны). Дано:
ConsultantUserId агента стороннего агентства. Тогда:
200, Items = [] — события чужого tenant не раскрываются.
- AC-5 (read-only). Дано: менеджер ПИН. Тогда: операций изменения чужих событий в pin-manager-области
нет; событиями управляет консультант-владелец.
Обратные ссылки
Автоссылки: где используется этот документ.
Связанные документы