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

UC-OVR-002. Запрос консультации у инвест-консультанта ПИН (+2a)

Назначение

Cross-service сценарий: инвестор просит консультацию, но реферальной привязки к агенту нет (прямой заход на витрину ПИН либо ссылка самого инвестора) — лид попадает сотруднику ПИН (менеджеру / инвест-консультанту). Вариант 2a — заявка уже авторизованного инвестора без контекста объекта. Отличие от UC-OVR-001 — только в стороне привязки: единый публичный вход crm. Альтернативный вход — самозапись на конкретный свободный слот инвест-консультанта ПИН через calendar (см. альтернативный сценарий ниже): консультанта определяет сам инвестор выбором слота, лид создаётся по событию pin.calendar.appointment-created.v1.

Metadata

ПолеЗначение
Статусdraft
Owning teamcrm
Primary capabilityconsultation-lead-intake
Risk levelmedium

Scope И Участники

УчастникРоль
Инвестор / ГостьАктор: форма «ФИО + телефон» с витрины ПИН
crm (public)Оркестратор: Client/Lead в tenant ПИН, событие ConsultationRequested
identity (internal)Lazy-регистрация инвестора; выбор активного сотрудника ПИН
referralПроверка: ссылки агента нет → маршрут ПИН
calendarАльтернативный вход: слоты самозаписи инвест-консультантов ПИН (tenant компании ПИН, UC-CAL-003); оверсайт менеджера ПИН — read-only выборки записей/событий
notificationsConsumer lead-created → уведомление инвест-консультанту ПИН

Preconditions

  • Реферальной cookie агента нет, либо она указывает на самого инвестора (не даёт агентской привязки).
  • В компании ПИН есть хотя бы один активный сотрудник с ролью инвест-консультанта / менеджера.
  • Для слотового входа: инвест-консультант ПИН опубликовал слоты самозаписи (UC-CAL-002) — слоты живут в tenant компании ПИН.

Основной Сценарий

  1. Инвестор жмёт «Получить консультацию» на витрине ПИН (без реф-ссылки агента).
  2. Фронт → POST /api/public/crm/consultation-requests (create-consultation-request.md).
  3. crm дубль-детект по телефону; lazy-регистрация в identityInvestorUserId (вариант 2a: JWT-инвестор уже авторизован — identity не вызывается).
  4. Правила привязки referral → агентской ссылки нет ⇒ TenantId = компания ПИН, AgentUserId = случайный активный сотрудник ПИН.
  5. get-or-create Client + активный Lead в tenant ПИН; лид фиксирует событие ленты ConsultationRequested (см. UC-CRM-001).
  6. В одном согласованном изменении публикуется pin.crm.lead-created.v1 (Source = ConsultationRequest).
  7. notifications уведомляет сотрудника ПИН; лид виден в CRM ПИН.

Sequence

Постусловие

После успешного сценария гарантированно:

  • InvestorUserId существует (lazy-регистрация по телефону; в варианте 2a — взят из JWT-claims, identity не вызывался);
  • в tenant ПИН созданы Client и активный Lead с TenantId = компания ПИН и AgentUserId = выбранный активный сотрудник ПИН (либо лид без назначения — см. edge-case);
  • зафиксировано событие ленты ConsultationRequested;
  • опубликовано pin.crm.lead-created.v1 (Source = ConsultationRequest, key = LeadId) — один раз на новый лид; сотрудник ПИН получает уведомление в пределах окна notifications (< 5 мин);
  • инвестору возвращён 201 {requestId, receivedAt}.

Отличие от UC-OVR-001 — только сторона привязки (tenant/сотрудник ПИН); инварианты клиента/лида и гарантии события идентичны.

Альтернативные Сценарии И Отказы

СитуацияПоведение
2a: инвестор авторизован (JWT)identity get-or-create пропускается, ActorUserId из claims
Появилась валидная реф-ссылка агентаМаршрут переходит в UC-OVR-001
Нет активных сотрудников ПИНЛид создаётся в tenant ПИН без назначения; ставится в общий пул на распределение (уведомление — руководителю пула, не конкретному сотруднику)
Повторная заявка в окне409 DUPLICATE_PHONE
Пустые/некорректные ФИО или телефон400 VALIDATION до создания сущностей
Активный лид пары инвестор↔ПИН уже естьПереиспользуется (один активный лид на пару), интеграционного события нет — только новое событие ленты
identity недоступен (не-2a)503 IDENTITY_UNAVAILABLE, лид не создаётся, форма предлагает повтор
Инвестор выбирает конкретное время консультацииСлотовый вход: запись на слот инвест-консультанта ПИН — см. альтернативный сценарий ниже

Альтернативный Сценарий: Запись На Слот Инвест-Консультанта ПИН

Зеркало слотового входа UC-OVR-001, сторона привязки — компания ПИН:

  1. Инвест-консультанты ПИН публикуют слоты самозаписи как обычные агенты (UC-CAL-002); слоты и записи живут в tenant компании ПИН.
  2. Инвестор на витрине ПИН открывает свободные слоты консультанта (list-available-slots) и бронирует (book-slot; детально — UC-CAL-003): lazy-регистрация анонима по телефону, слот Available → Booked, запись и календарное событие консультанта — атомарно; публикуется pin.calendar.appointment-created.v1 с TenantId = компания ПИН и AgentUserId = консультант слота.
  3. crm (consumer docs/06-services/crm/consumers/calendar-appointments.md) асинхронно (< 1 мин) делает get-or-create Client/Lead в tenant ПИН с назначением на консультанта слота — выбор из пула (round-robin) не выполняется: консультанта определил сам инвестор выбором слота. Для нового лида — pin.crm.lead-created.v1 и уведомление консультанту.
  4. Решение по Pending-записи принимает консультант (UC-CAL-004); менеджер ПИН контролирует поток самозаписи, скорость реакции (Pending с дедлайном) и долю неявок read-only выборками list-appointments и list-events (calendar.team.view в scope компании ПИН).
  5. Оба входа — слотовый и форма «время обсудим» — сходятся в одном клиенте/лиде tenant ПИН (get-or-create по телефону инвестора).

Согласованность И Идемпотентность

  • Выбор сотрудника ПИН выполняется в system-scope из пула активных менеджеров/инвест-консультантов; политика — round-robin/случайный выбор (метрика перекоса — в «Наблюдаемость»). При пустом пуле лид не теряется, а помечается «без назначения» и ждёт распределения.
  • Идемпотентность. Lazy-регистрация идемпотентна по телефону; дубль-детект в окне → 409 DUPLICATE_PHONE; инвариант «один активный лид на пару» делает повтор no-op для интеграционных потребителей.
  • Порядок и доставка. pin.crm.lead-created.v1: key = LeadId, at-least-once; notifications дедуплицирует по MessageId.
  • Окно eventual-consistency. Между 201 инвестору и появлением лида у сотрудника ПИН — задержка обработки notifications (< 5 мин).
  • Слотовый вход — детерминированное назначение. При записи на слот назначение лида задаётся слотом (консультант выбран инвестором), пул не задействуется; лид появляется в CRM асинхронно по appointment-created (< 1 мин), идемпотентность консюмера — MessageId + business key AppointmentId.

Acceptance Criteria (Given/When/Then)

  • Happy (лид в ПИН). Дано: инвестор на витрине ПИН без реф-ссылки агента, есть активный сотрудник ПИН. Когда: отправляет форму ФИО + телефон. Тогда: Client/Lead создаются в tenant ПИН с AgentUserId = выбранный сотрудник, публикуется pin.crm.lead-created.v1, сотрудник получает уведомление, инвестор — 201.
  • Вариант 2a (авторизован). Дано: инвестор с JWT. Когда: отправляет форму. Тогда: lazy-регистрация пропущена, ActorUserId из claims; остальное как в happy.
  • Пустой пул ПИН. Дано: активных сотрудников ПИН нет. Когда: заявка отправлена. Тогда: лид создан в tenant ПИН без назначения и поставлен в общий пул; событие lead-created опубликовано.
  • Появилась привязка к агенту. Дано: пришла валидная реф-ссылка агента. Когда: форма отправлена. Тогда: сценарий уходит на агентский маршрут (UC-OVR-001).
  • Дубль по телефону. Дано: заявка в окне дедупликации. Когда: повтор формы. Тогда: 409 DUPLICATE_PHONE.
  • Слотовый вход к консультанту ПИН. Дано: консультант ПИН опубликовал слоты, активного лида пары нет. Когда: инвестор бронирует свободный слот консультанта. Тогда: запись создана в tenant ПИН, по appointment-created CRM создаёт Client/активный Lead с назначением на консультанта слота (пул не задействован); менеджер ПИН видит запись в read-only выборке pin-manager.

Source Of Truth И Данные

ДанныеВладелецConsistency rule
Client / Lead / LeadEvent (tenant ПИН)crmВ одном согласованном изменении
UserEntity инвестораidentityLazy-регистрация идемпотентна
Пул сотрудников ПИНidentityВыбор активного менеджера — system-scope

Контракты И Зависимости

Наблюдаемость

  • critical metrics: доля лидов, ушедших в ПИН (без агентской привязки); распределение по сотрудникам ПИН; доля слотового входа vs форма «время обсудим».
  • trace path: витрина → crm.publicidentity (выбор менеджера) → шина событий → notifications.
  • alerts: перекос распределения; лиды без назначенного сотрудника.

Риски И Guardrails

  • Риск: несправедливое распределение лидов между сотрудниками ПИН. Control: round-robin/случайный выбор + метрика перекоса.
  • Риск: инвестор ожидал агента, а попал в ПИН. Control: прозрачные правила привязки (referral/attach-rules).

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

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