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

GET /api/pin-manager/crm/deals/{dealId} — Карточка любой сделки (Менеджер ПИН)

Read-модель карточки сделки для Менеджера ПИН: менеджер ПИН — авто-участник всех сделок платформы (ParticipantRole.PinManager, US-MGR-01) и читает любую сделку любого застройщика без ограничения по tenant (платформенный scope), видя привилегированные данные — полный номер эскроу-счёта и все документы, включая PII (ClientPassport/ContractDraftDocument), — для проверки и ручного вмешательства (US-MGR-02/04). Только чтение: дом полей сделки — deal.md, документов — deal-document.md; здесь описана лишь дельта проекции карточки застройщика (developer/get-deal.md) и алгоритм её сборки.

Назначение

Отдаёт Менеджеру ПИН единую карточку одной сделки по dealId без ограничения по tenant (платформенный scope): статус/этап, снимок объекта и цены, ФИО/телефон клиента, условия оплаты и договора, банк и полный номер эскроу-счёта, полный состав участников и все документы сделки любых типов, включая персональные (ClientPassport, ContractDraftDocument) — для проверки и ручного вмешательства (US-MGR-02/04). Менеджер ПИН — авто-участник всех сделок (ParticipantRole.PinManager, US-MGR-01) и привилегированная сторона по deal.md (полный эскроу) и deal-document.md (PII-документы). Только чтение. Таймлайн «Ход сделки» и скачивание файлов — отдельные методы; вкладки «Об объекте недвижимости»/«О проекте» — данные chessboard.

Metadata

ПолеЗначение
Сервис/контекстcrm
API areapin-manager
Feature groupdeals
Статусdraft
Документdocs/06-services/crm/api/pin-manager/get-deal.md

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

ПроверкаЗначение
Actor typeUser (Менеджер ПИН; Служба заботы — read-only через ту же проекцию)
Auth policy / Permissionscrm.deals.view, platform-scope claim Менеджера ПИН (US-MGR)
Scope (RBAC)платформа — кросс-tenant, любой DeveloperCompanyId
Record-levelне применяется (сквозная видимость всех сделок; Менеджер ПИН — авто-участник, US-MGR-01)
Tenant isolationзапрос не tenanted: чтение сквозное, без tenant-предиката (platform-scope, ADR-0052)
Auditread-sensitive: доступ Менеджера ПИН к полному эскроу и PII-документам логируется как факт; сами значения (номер счёта, PII) в логи не пишутся, телефон — маска
Доступ

Менеджер ПИН читает любую сделку любого DeveloperCompanyId без tenant-предиката (platform-scope, US-MGR-01, ADR-0052) — Служба заботы имеет тот же read-only доступ через эту проекцию. Полный номер эскроу-счёта и все документы (включая PII-типы ClientPassport/ContractDraftDocument) отдаются без маскирования: доступ read-sensitive — факт обращения логируется, а сами значения (номер счёта, PII) в логи не пишутся, телефон клиента — маской.

HTTP-контракт

ПолеЗначение
MethodGET
Route/api/pin-manager/crm/deals/{dealId}
Success status200
Idempotency headerне применяется (безопасный GET)
Correlationсквозной trace через заголовок traceparent

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

ПолеИсточникТипОбязательностьВалидация / ОграниченияБезопасность
DealIdrouteGuidДа!= Guid.Empty; сделка любого tenant (шаг 3)
ActorUserIdidentity claimsGuidДаJWT Менеджера ПИН (platform-scope)audit/логи

TenantId в запрос не передаётся: доступ платформенный, сделка выбирается только по DealId.

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

Возвращается та же проекция DealCardModel, что и в карточке застройщика — полный дом полей и под-моделей (MoneyModel, DealMemberModel, DealDocumentSummaryModel) описан в developer/get-deal.md; дом полей сущностей — deal.md (VO Money, enum DealStatus/DealContractType/PaymentMethod/EscrowStatus/DealChatStatus), deal-document.md, client.md. Все enum сериализуются строкой. Ниже — только дельта привилегированного доступа Менеджера ПИН.

ПолеТипИсточникMasking (Менеджер ПИН)Описание дельты
EscrowAccountNumberstring?Deal.EscrowAccountNumberполный (без маски)Менеджер ПИН — привилегированная сторона (deal.md); наружу отдаётся полный номер, в логи не пишется.
ClientPhoneNumberstringClientEntity.PhoneNumber (снимок)полный; маска в логахТелефон покупателя (E.164, PII).
DocumentsDealDocumentSummaryModel[]документы сделки (шаг 3)без фильтра по типуВсе документы, включая PII-типы ClientPassport/ContractDraftDocument (deal-document.md); скачивание файла — пресайн-ссылка storage (отдельный запрос).
MembersDealMemberModel[]активные DealMemberEntity (шаг 3)Полный активный состав, включая PinManager (US-MGR-01).

Прочие поля (DealId, Title, Status, StepId, StepGroup, PropertyObjectId, ProjectId, Price, PaymentMethod, ContractType, BankId, EscrowStatus, BookingId, ChatStatus, CreatedAt, UpdatedAt и др.) — 1:1 с developer/get-deal.md, без масок. Таймлайн в этот ответ не входит — отдельный paged-метод (deal-timeline-event.md).

Алгоритм

  1. Контекст и доступ. Операцию выполняет Менеджер ПИН с permission crm.deals.view в platform-scope; TenantId в запрос не передаётся (кросс-tenant, сквозной доступ).
  2. Проверка входа и предусловий. DealId != Guid.Empty → иначе VALIDATION_FAILED. Чтение разрешено во всех статусах, включая терминальные Completed/Cancelled. Проверок tenant/record-level нет — доступ платформенный.
  3. Что читаем. Сделку по DealId сквозным доступом (без tenant-предиката, читается сделка любого DeveloperCompanyId); если сделки нет или она soft-deleted → CRM_DEAL_NOT_FOUND. Дополнительно: активных участников сделки (включая PinManager); клиента ClientId — display-снимок ФИО/телефона (только контактные поля); все документы сделки без фильтра по типу (Менеджер ПИН видит PII-типы). Таймлайн «Ход сделки» здесь не загружается — отдельный paged-метод.
  4. Бизнес-правила и маппинг. Переходов состояний нет (чтение). Сделка → DealCardModel (developer/get-deal.md); MoneyMoneyModel; клиент → ClientName/ClientPhoneNumber; участники → DealMemberModel[]; документы → DealDocumentSummaryModel[]. Эскроу не маскируется (Менеджер ПИН привилегирован, deal.md). Enum-поля сериализуются строкой.
  5. Результат. Карточка DealCardModel → HTTP 200. Данные согласованы на момент запроса; ФИО клиента — eventual-реплика из identity, ChatStatus — eventual-проекция из messenger. Ручные вмешательства Менеджера ПИН (смена статуса/этапа, ручная запись в таймлайн — US-MGR-02/04) выполняют отдельные операции; карточка лишь отражает их результат.

Диаграмма

Побочные эффекты

ТипДетали
Отдельные запросы вкладок«Ход сделки» — таймлайн (deal-timeline-event.md); скачивание документа — пресайн-ссылка storage (Менеджер ПИН имеет доступ к PII-типам); объект/проект/банк — данные chessboard/catalog. В этот ответ не входят.

Ошибки и failure modes

Ошибки
КодHTTP statusУсловиеСообщениеRetry
VALIDATION_FAILED400DealId = Guid.Empty«Некорректный идентификатор сделки»no retry
CRM_DEAL_NOT_FOUND404сделки нет или soft-deleted (tenant для Менеджера ПИН не ограничивает)«Сделка не найдена»no retry

Предусловия и постусловия

Предусловия (истинны до сценария):

  • актор — Менеджер ПИН (или Служба заботы, read-only) с permission crm.deals.view в platform-scope; кросс-tenant, TenantId в запрос не передаётся;
  • чтение разрешено во всех статусах сделки, включая терминальные Completed/Cancelled.

Постусловия (после запроса):

  • состояние не изменяется (read-only); факт read-sensitive доступа к полному эскроу и PII-документам логируется (сами значения — номер счёта, PII — не пишутся, телефон маскируется);
  • возвращена полная карточка: полный EscrowAccountNumber (без маски), все документы включая PII-типы (ClientPassport/ContractDraftDocument), полный активный состав участников (включая PinManager).

Кросс-сервисные ожидания (eventual-реплики). ФИО/телефон клиента — eventual-реплика из identity (допустимо отставание display-данных); ChatStatus — eventual-проекция из messenger (Pending/Provisioning/Ready/Failed, ADR-0055): до готовности чата возможен Provisioning/Pending. Ручные вмешательства (смена статуса/этапа, ручная запись) — отдельные операции; карточка лишь отражает их результат.

Acceptance Criteria

  • Happy path. Дано: существующая сделка любого застройщика. Когда: GET …/deals/{dealId}. Тогда: 200, полный EscrowAccountNumber без маски, Documents включают PII-типы, Members включают PinManager.
  • Кросс-tenant. Дано: сделка чужого DeveloperCompanyId. Когда: GET. Тогда: 200 (tenant не ограничивает — platform-scope).
  • Терминальная сделка. Дано: Status = Completed/Cancelled. Когда: GET. Тогда: 200 (чтение разрешено во всех статусах).
  • Чат ещё не готов. Дано: проекция messenger для сделки — Provisioning. Когда: GET. Тогда: 200, ChatStatus = Provisioning (промежуточное eventual-состояние).
  • Не найдена/soft-deleted. Когда: сделки нет или она скрыта. Тогда: 404 CRM_DEAL_NOT_FOUND.
  • Пустой идентификатор. Когда: DealId = Guid.Empty. Тогда: 400 VALIDATION_FAILED.

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

  • Новые optional поля DealCardModel — additive (без breaking change); удаление/переименование/смена типа — breaking (migration + rollout). Enum-поля (DealStatus/ContractType/PaymentMethod/EscrowStatus/ DealDocumentStatus/…) сериализуются строкой; клиент обязан толерантно обрабатывать неизвестное значение.
  • Logs: pin-manager deal-card viewed (DealId, tenant сделки, ActorUserId; read-sensitive audit — факт доступа к полному эскроу/PII; сам номер счёта и PII не пишутся, телефон — маской); metrics: crm_deal_card_requests_total{result, area="pin-manager"}, latency p95 < 1 с (SLO чтений); traces — сквозной trace через traceparent; dashboard pin-crm.

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

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

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