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

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

Назначение

Даёт Менеджеру ПИН сквозной доступ к карточке одного лида по leadId вне зависимости от tenant: «шапка хотелок» (LeadWishes), реквизиты клиента, срок жизни и компактные списки порождённых фиксаций и сделок — для арбитража и ручного ведения (US-MGR-01..06). Возвращает тот же контракт LeadCardModel, что и агентская карточка (../agent/get-lead.md). Отличие от агентской версии — нет record-level ограничения по составу участников: менеджер видит лид любого агентства (в т.ч. лиды «на ПИН»), включая порождённые фиксации/сделки, живущие под tenant застройщика. Лента событий лида на карточку не разворачивается — она читается отдельным пагинированным методом list-lead-events. Только чтение; дом агрегата — lead.md.

Metadata

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

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

ПроверкаЗначение
Actor typeUser (Менеджер ПИН — сотрудник платформы; Служба заботы — read-only через ту же проекцию)
Auth policy / Permissionscrm.leads.view при platform-scope роли Менеджера ПИН (модель — identity/domain/permission.md); 401/403 отдаёт auth-policy до бизнес-логики
Scope (RBAC)платформа (platform-scope): кросс-tenant, любой лид (ADR-0052 — межтенантный доступ разрешён только platform-scope)
Record-levelне применяется — сквозная видимость всех лидов; фильтра по составу участников/TenantId нет
Tenant isolationЗапрос не tenanted: чтение сквозное, без предиката TenantId (авторизовано platform-scope); soft-deleted лиды отсекаются
Auditread-sensitive — межтенантное чтение PII клиента привилегированной ролью логируется (ActorUserId, LeadId, tenant лида)

HTTP-контракт

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

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

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

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

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

Дом модели — агентская карточка ../agent/get-lead.md (полные таблицы полей LeadCardModel, LeadClientModel, LeadWishesModel, LeadFixationRefModel, LeadDealRefModel; дом полей сущностей — lead.md, client.md, fixation-request.md, deal.md). Менеджер ПИН получает тот же контракт без изменения формы, поля здесь не переописываются.

Дельта pin-manager (форма модели не меняется, меняется только выборка/доступ):

ЭлементДельта Менеджера ПИН
Fixations (IReadOnlyList<LeadFixationRefModel>)Компактные ряды порождённых фиксаций, выбираются кросс-tenant: заявки лида живут под tenant застройщика (DeveloperCompanyId), а лид — под tenant агентства (AgencyCompanyId); сквозная выборка возможна только platform-scope. Может быть пустым.
Deals (IReadOnlyList<LeadDealRefModel>)Компактные ряды порождённых сделок, тоже кросс-tenant (владелец сделки — застройщик). Может быть пустым.
Client (LeadClientModel)Реквизиты клиента любого агентства; PhoneNumber наружу отдаётся, в логи — маской +7***NNNN.
Enum-поля (LeadStatus/LeadSource/FixationStatus/FixationUniqueness/DealStatus/PipelineStepGroup)Сериализуются строкой (не числом).
Лента LeadEventEntityВ модель не входит — отдельный platform-scope list-lead-events.

Алгоритм

  1. Контекст и доступ. Операцию выполняет Менеджер ПИН (platform-scope, permission crm.leads.view); авторизация проверена до бизнес-логики (иначе 401/403). TenantId в запрос не передаётся (кросс-tenant).
  2. Проверка входа и предусловий. LeadId != Guid.Empty → иначе VALIDATION_FAILED (400). Карточка доступна в любом Status (Active/Expired/Archived). Проверки tenant/record-level нет — доступ платформенный.
  3. Что читаем. Лид по LeadId сквозным доступом (без предиката TenantId); если лида нет или он soft-deleted → CRM_LEAD_NOT_FOUND. Далее (тоже кросс-tenant): клиента-«шапку» по ClientId, компактные проекции порождённых фиксаций (по LeadId, свежие сверху) и сделок (по LeadId, свежие сверху). Лента LeadEventEntity не грузится (отдельный platform-scope list-lead-events).
  4. Бизнес-правила и маппинг. Record-level не применяется — Менеджер ПИН видит любой лид (проверок членства актора-участника, ExecutorAgentUserId/PrimaryInvestorUserId, нет). Переходов состояний нет. Маппинг: лид → LeadCardModel (форма — дом в ../agent/get-lead.md), LeadWishes → LeadWishesModel (enum строкой), клиент → LeadClientModel (PhoneNumber наружу, в логи — маской), Fixations/Deals — из проекций шага 3.
  5. Результат. Карточка LeadCardModel → HTTP 200. Допустима микро-рассинхронизация лида и списков фиксаций/сделок (карточка — сводка, не финансовая консистентность); свежесть — на момент запроса.

Диаграмма

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

ТипДетали
Внешние вызовыdisplay-имена агента/клиента резолвит клиент отдельным запросом к identity
Отдельные запросыглубокий просмотр ленты — platform-scope list-lead-events; полные списки фиксаций/сделок — сквозные pin-manager-списки (list-fixations.md, list-deals.md). В этот ответ не входят.

Ошибки и failure modes

КодHTTP statusУсловиеСообщениеRetry
VALIDATION_FAILED400LeadId = Guid.Empty«Некорректный идентификатор лида»no retry
CRM_LEAD_NOT_FOUND404лида с таким Id нет / soft-deleted (tenant для Менеджера ПИН не ограничивает)«Лид не найден»no retry
Доступ

Авторизация (нет platform-scope роли Менеджера ПИН) — 401/403 от auth-policy до бизнес-логики; доменной ошибки FORBIDDEN здесь нет (record-level не применяется — авторизованный менеджер видит любой лид).

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

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

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

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

  • состояние не изменяется (read-only); межтенантное чтение PII клиента логируется (read-sensitive audit);
  • возвращён LeadCardModel с компактными кросс-tenant списками порождённых фиксаций/сделок; лента событий лида (LeadEventEntity) в модель не входит — отдельный platform-scope list-lead-events.

Кросс-сервисные ожидания (eventual-согласованность). Допустима микро-рассинхронизация между лидом (tenant агентства) и списками фиксаций/сделок (tenant застройщика): карточка — сводка, а не финансовая консистентность; свежесть — на момент запроса. Display-имена агента/клиента резолвит фронт отдельным запросом к identity; в карточку кладутся id.

Acceptance Criteria

  • Happy path. Дано: лид с порождёнными фиксациями и сделками (кросс-tenant). Когда: GET …/leads/{leadId}. Тогда: 200, LeadCardModel, Fixations/Deals заполнены сквозной выборкой; лента событий не входит.
  • Лид без фиксаций/сделок. Дано: лид только создан. Когда: GET. Тогда: 200, Fixations = [], Deals = [].
  • Любой статус. Дано: лид Archived (или Expired). Когда: GET. Тогда: 200.
  • Кросс-tenant. Дано: лид другого агентства, а его фиксации/сделки — под tenant застройщика. Когда: GET. Тогда: 200, списки собраны кросс-tenant.
  • Не найден/soft-deleted. Когда: лида с таким Id нет. Тогда: 404 CRM_LEAD_NOT_FOUND.
  • Пустой идентификатор. Когда: LeadId = Guid.Empty. Тогда: 400 VALIDATION_FAILED.
  • Нет platform-scope-роли. Когда: у актора нет роли Менеджера ПИН. Тогда: 401/403 от auth-policy до бизнес-логики.

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

  • LeadCardModel — общий с агентской картой; новые optional поля — additive; удаление/переименование/смена типа поля или enum — breaking (migration + rollout клиентов). Enum-поля сериализуются строкой; неизвестное значение клиент обязан толерантно трактовать как «прочее», не падать.
  • Logs: pin-manager any-lead-card requested (LeadId, ActorUserId, tenant лида, result; телефон клиента — маской); read-sensitive audit межтенантного доступа; metrics: crm_lead_card_requests_total{result, area="pin-manager"}, latency p95 < 500 мс (SLO чтений); traces — сквозной trace через traceparent; dashboard pin-crm.

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

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

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