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 area | pin-manager |
| Feature group | leads |
| Статус | draft |
| Документ | docs/06-services/crm/api/pin-manager/get-lead.md |
Актор и доступ
| Проверка | Значение |
|---|---|
| Actor type | User (Менеджер ПИН — сотрудник платформы; Служба заботы — read-only через ту же проекцию) |
| Auth policy / Permissions | crm.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 лиды отсекаются |
| Audit | read-sensitive — межтенантное чтение PII клиента привилегированной ролью логируется (ActorUserId, LeadId, tenant лида) |
HTTP-контракт
| Поле | Значение |
|---|---|
| Method | GET |
| Route | /api/pin-manager/crm/leads/{leadId} |
| Success status | 200 |
| Idempotency header | не применяется (безопасный GET) |
| Correlation | сквозной trace через заголовок traceparent |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|---|---|---|---|---|
LeadId | route | Guid | Да | != Guid.Empty; существующий лид любого tenant (шаг 3) | — |
ActorUserId | identity claims | Guid | Да | 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. |
Алгоритм
- Контекст и доступ. Операцию выполняет Менеджер ПИН (platform-scope, permission
crm.leads.view); авторизация проверена до бизнес-логики (иначе 401/403).TenantIdв запрос не передаётся (кросс-tenant). - Проверка входа и предусловий.
LeadId != Guid.Empty→ иначеVALIDATION_FAILED(400). Карточка доступна в любомStatus(Active/Expired/Archived). Проверки tenant/record-level нет — доступ платформенный. - Что читаем. Лид по
LeadIdсквозным доступом (без предикатаTenantId); если лида нет или он soft-deleted →CRM_LEAD_NOT_FOUND. Далее (тоже кросс-tenant): клиента-«шапку» поClientId, компактные проекции порождённых фиксаций (поLeadId, свежие сверху) и сделок (поLeadId, свежие сверху). ЛентаLeadEventEntityне грузится (отдельный platform-scopelist-lead-events). - Бизнес-правила и маппинг. Record-level не применяется — Менеджер ПИН видит любой лид (проверок
членства актора-участника,
ExecutorAgentUserId/PrimaryInvestorUserId, нет). Переходов состояний нет. Маппинг: лид →LeadCardModel(форма — дом в ../agent/get-lead.md),LeadWishes → LeadWishesModel(enum строкой), клиент →LeadClientModel(PhoneNumberнаружу, в логи — маской),Fixations/Deals— из проекций шага 3. - Результат. Карточка
LeadCardModel→ HTTP200. Допустима микро-рассинхронизация лида и списков фиксаций/сделок (карточка — сводка, не финансовая консистентность); свежесть — на момент запроса.
Диаграмма
Побочные эффекты
| Тип | Детали |
|---|---|
| Внешние вызовы | display-имена агента/клиента резолвит клиент отдельным запросом к identity |
| Отдельные запросы | глубокий просмотр ленты — platform-scope list-lead-events; полные списки фиксаций/сделок — сквозные pin-manager-списки (list-fixations.md, list-deals.md). В этот ответ не входят. |
Ошибки и failure modes
| Код | HTTP status | Условие | Сообщение | Retry |
|---|---|---|---|---|
VALIDATION_FAILED | 400 | LeadId = Guid.Empty | «Некорректный идентификатор лида» | no retry |
CRM_LEAD_NOT_FOUND | 404 | лида с таким 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-scopelist-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; dashboardpin-crm.
Обратные ссылки
Автоссылки: где используется этот документ.
- registries (1): Реестр API-методов PIN
Связанные документы
- Дом модели
LeadCardModel(полные поля): ../agent/get-lead.md; инвесторский урезанный аналог: ../investor/get-lead.md. - Сущности: lead.md (дом полей,
LeadWishes,LeadStatus/LeadSource), client.md (FullName), fixation-request.md, deal.md (Money,DealStatus). - Лента событий лида: ../agent/list-lead-events.md (агентский дом) +
platform-scope
list-lead-events. - Жизненный цикл лида (результат отражается в карточке): lead-created.md
(
pin.crm.lead-created.v1), lead-expired.md (pin.crm.lead-expired.v1). - Карта областей — README контекста; tenancy/platform-scope — ADR-0052.