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

GET /api/v1/agent/calendar/appointments/{appointmentId} — Карточка записи

Назначение

Отдаёт агенту (или консультанту ПИН) полную карточку записи инвестора: статус и дедлайн решения, снапшот времени, комментарий инвестора, display-данные инвестора из реплики identity, параметры слота-источника (auto-confirm, cutoff) и след переноса. С карточки агент принимает решение — подтвердить, отклонить, отменить или зафиксировать исход.

Metadata

ПолеЗначение
Сервис/контекстcalendar
API areaagent
Feature groupappointments
Статусdraft
Документdocs/06-services/calendar/api/agent/get-appointment.md

Актор и доступ

ПроверкаЗначение
Actor typeUser (агент агентства / консультант ПИН)
Auth policy / Permissionscalendar.appointments.view
Scope (RBAC)организация — компания актора (агентство / ПИН)
Record-levelтолько собственные записи (AgentUserId = actor); чужая запись не раскрывается — APPOINTMENT_NOT_FOUND (fail-closed)
Tenant isolationTenantId из токена (ADR-0052)
Auditread-sensitive: карточка содержит Comment (Internal) и display-данные инвестора — в логи не пишутся

HTTP-контракт

ПолеЗначение
MethodGET
Route/api/v1/agent/calendar/appointments/{appointmentId}
Success status200
Idempotency headerнет (безопасное чтение)
Correlationсквозной trace через заголовок traceparent

Входные данные / параметры запроса

ПолеИсточникТипОбязательностьВалидация / ОграниченияБезопасность
ActorUserIdтокен (sub)GuidДаRequiredrecord-level фильтр AgentUserId
TenantIdтокен (tenant_id)GuidДаRequiredTenant isolation
AppointmentIdrouteGuidДаRequired; валидный Guid

Модель ответа AgentAppointmentDetailsModel

Все поля AgentAppointmentModel (дом — list-appointments.md) плюс параметры слота-источника:

ПолеТипОбязательностьИсточникMaskingОписание
(поля AgentAppointmentModel)list-appointments.mdПроекция записи + контекст слота + InvestorDisplayName.
AutoConfirmboolДаслотЗапись была создана на слоте с автоподтверждением (Pending не проходилась).
CancellationCutoffMinutesintДаслотCutoff отмены/переноса инвестором (INV-APT-3) — агент видит, до какого момента инвестор ещё может отменить.
MinLeadTimeMinutesintДаслотLead time слота — определяет, вернётся ли слот на витрину при отмене (правило освобождения, appointment.md).

Алгоритм

Тривиальное чтение: проверить permission calendar.appointments.view (иначе APPOINTMENT_ACCESS_DENIED); найти запись по AppointmentId среди записей актора в его tenant — не найдена или принадлежит другому агенту → APPOINTMENT_NOT_FOUND (fail-closed, существование чужой записи не раскрывается). К записи подтягиваются параметры слота-источника и InvestorDisplayName из display-реплики identity (../../consumers/identity-user-upserted.md); отставание реплики — не ошибка, поле null. Ответ — AgentAppointmentDetailsModel, HTTP 200; данные записи — из source of truth calendar, актуальны на момент чтения.

Ошибки и failure modes

КодHTTP statusУсловиеСообщениеRetry
VALIDATION_FAILED400AppointmentId — не валидный Guid«Некорректный идентификатор»no retry
UNAUTHORIZED401нет/просрочен JWT«Требуется авторизация»no retry
APPOINTMENT_ACCESS_DENIED403нет permission calendar.appointments.view«Недостаточно прав»no retry
APPOINTMENT_NOT_FOUND404запись не существует или принадлежит другому агенту/tenant (fail-closed)«Запись не найдена»no retry

Acceptance Criteria

  • AC-1 (happy path). Given Pending-запись к актору с комментарием инвестора. When GET карточки. Then 200: статус, PendingExpiresAt, Comment, InvestorDisplayName, параметры слота (AutoConfirm, CancellationCutoffMinutes, MinLeadTimeMinutes).
  • AC-2 (терминальная запись). Given запись Cancelled с CancelledBy = Investor. When GET. Then 200: заполнены CancelReason, CancelledBy; при переносе — RescheduledToAppointmentId.
  • AC-3 (чужая запись). Given запись к другому агенту того же tenant. When GET по её идентификатору. Then 404 APPOINTMENT_NOT_FOUND.
  • AC-4 (лаг реплики). Given display-реплика инвестора отсутствует. When GET. Then 200, InvestorDisplayName = null, остальные поля полны.

Совместимость и наблюдаемость

  • Новые поля — additive nullable; удаление/переименование/смена типа — breaking. Новые значения AppointmentStatus/AppointmentCancelledBy клиент обязан переживать.
  • Logs: TenantId, AgentUserId, AppointmentId, Status (без Comment/display-данных); metrics: calendar_api_request_duration_seconds{route}; traces — сквозной traceparent.

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

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

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