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

UC-CRM-018. Несколько сделок из одной одобренной фиксации (по разным объектам застройщика)

Назначение

Показывает связь «фиксация → сделки = 1:N»: одна одобренная фиксация авторизует агента работать с клиентом по проектам застройщика и создать по ней сколько угодно сделок — по разным объектам этого застройщика. Одобрение фиксации не создаёт сделку и не привязано к объекту (пара «клиент × застройщик»); дедуп сделок обеспечивает не фиксация, а инвариант «одно активное намерение на (LeadId, PropertyObjectId)» (INV-INTENT-1). Поэтому FixationRequestId на сделке не уникален. Дома полей — ../domain/fixation-request.md и ../domain/deal.md.

Metadata

ПолеЗначение
IDUC-CRM-018
Контекстcrm (см. docs/06-services/crm/)
Типосновной
Статусdraft

Актор

ПолеЗначение
РольАгент-исполнитель лида (Executor) или Менеджер ПИН
Permissions / scopecrm.deals.manage; агент — record-level по членству лида (ADR-0071); Менеджер ПИН — platform-scope (кросс-tenant, ADR-0052)
TenantЛид TenantId = AgencyCompanyId; каждая создаваемая сделка TenantId = DeveloperCompanyId объекта (тот же застройщик у всех сделок этой фиксации)
Record-levelАгент — активный участник лида; Менеджер ПИН — любой

Предусловие

  • Лид существует и Status = Active (INV-LEAD-2).
  • Для пары «инвестор × застройщик» есть одобренная фиксация (../domain/fixation-request.md; Status = Approved).
  • Несколько объектов этого застройщика — предмет намерений инвестора (ConfirmedByInvestor = true) либо выбираются агентом при создании сделок; по каждой паре (LeadId, PropertyObjectId) нет другой активной сделки/намерения (INV-INTENT-1).

Триггер

ПолеЗначение
ИсточникUI-действие → вызов API (повторяется на каждый объект)
Триггерящий элементКнопка «Создать сделку» на карточке лида для каждого объекта → POST /api/agent/crm/deals

Основной Поток

  1. Контекст. У агента есть активный лид и одна одобренная фиксация для пары «инвестор × застройщик». Инвестор рассматривает несколько объектов этого застройщика (намерения по ним — Flow A/UC-CRM-016).
  2. Создание первой сделки. Агент создаёт сделку по объекту №1. Так как для пары есть одобренная фиксация и объект — подтверждённое намерение инвестора, гейт INV-DEAL-11 выполнен → сделка сразу Application: состав Executor + InvestorPrimary + SellManager + авто-PinManager, FixationRequestId = одобренная фиксация, IntentId = намерение объекта №1, IntentConfirmedAt проставлен, TenantId = DeveloperCompanyId.
  3. Создание последующих сделок. По объектам №2, №3, … агент повторяет создание сделки, ссылаясь на ту же фиксацию. Каждая новая сделка получает тот же FixationRequestId (значение не уникально среди сделок) и собственный IntentId/PropertyObjectId. Одобренную фиксацию повторно оформлять не нужно — она авторизует все объекты застройщика в рамках пары.
  4. Дедуп по объекту (INV-INTENT-1). Уникальность на пару (LeadId, PropertyObjectId) не даёт завести вторую активную сделку по тому же объекту: повтор по уже занятому объекту — конфликт активного намерения CRM_INTENT_ACTIVE_OBJECT_EXISTS; разные объекты — независимые сделки.
  5. Что меняется. На каждый вызов — новая DealEntity (+ участники, таймлайн DealCreated, запись ленты лида DealCreated) в одном согласованном изменении вместе с записью в outbox. Фиксация не меняется — только читается как основание авторизации.
  6. Публикация. На каждую сделку — pin.crm.deal-created.v1 (Status = Application, участники со SellManager). Все сделки попадают на канбан застройщика (одна пара «инвестор × застройщик», один застройщик, разные объекты).
  7. Результат. В лиде — несколько активных сделок к одному застройщику по разным объектам, все с общим FixationRequestId. Агент видит их в списке сделок лида; инвестор — в «Мои сделки».
  8. Завершение/отмена независимы. Каждая сделка проходит свой жизненный цикл. Завершение одной сделки (Completed) не влияет на остальные; отмена одной (Cancelled) освобождает её объект, прочие сделки фиксации остаются активными.

Диаграмма

Альтернативные Потоки

A1. Объект без подтверждённого намерения → Draft
  1. Агент создаёт сделку по объекту той же фиксации, но объект ещё не подтверждён инвестором (нет намерения или ConfirmedByInvestor = false).
  2. Гейт INV-DEAL-11 не выполнен по намерению → сделка заводится в Draft (см. Flow B, UC-CRM-017); фиксация уже одобрена, но условие намерения не снято. После подтверждения инвестором — вовлечение застройщика.
A2. Повтор по уже занятому объекту
  1. По паре (LeadId, PropertyObjectId) уже есть активная сделка/намерение.
  2. CRM_INTENT_ACTIVE_OBJECT_EXISTS (409); вторая активная сделка по тому же объекту не создаётся.

Возврат: работать с существующей сделкой объекта либо выбрать другой объект.

A3. Фиксация не одобрена / отозвана
  1. Фиксация для пары не Approved (на рассмотрении, отклонена, истекла).
  2. CRM_DEAL_FIXATION_REQUIRED (409) при попытке сразу Application (или сделка остаётся Draft до выполнения гейта).

Возврат: дождаться одобрения (UC-FIX-002) или повторно отправить заявку на фиксацию.

A4. Лид неактивен
  1. Лид Expired/Archived.
  2. CRM_LEAD_NOT_ACTIVE (409); сделки не создаются.

Возврат: продлить/реактивировать лид (INV-LEAD-3).

Постусловие

  • В лиде — несколько активных DealEntity к одному застройщику по разным объектам; у всех общий FixationRequestId (не уникален среди сделок), у каждой собственный IntentId/PropertyObjectId.
  • Ни по одному объекту нет двух активных сделок (INV-INTENT-1); фиксация не изменена (используется как основание авторизации).
  • На каждую созданную сделку опубликован pin.crm.deal-created.v1; все Application-сделки видны застройщику.
  • Завершение/отмена любой из сделок не затрагивает остальные сделки той же фиксации.

Возможные Ошибки

КодHTTPУсловиеПоведение клиента
CRM_INTENT_ACTIVE_OBJECT_EXISTS409По паре (LeadId, PropertyObjectId) уже есть активная сделка/намерение (INV-INTENT-1)Работать с существующей сделкой объекта или выбрать другой
CRM_DEAL_FIXATION_REQUIRED409Для пары «инвестор × застройщик» нет одобренной фиксации (создание сразу в Application / гейт INV-DEAL-11)Дождаться одобрения фиксации; иначе сделка заводится в Draft
CRM_DEAL_INTENT_NOT_CONFIRMED409Объект без подтверждённого инвестором намерения — сразу в Application нельзяСделка заводится в Draft; подтвердить намерение, затем вовлечь застройщика
CRM_DEAL_PAYMENT_METHOD_REQUIRED422Создание сразу в Application без PaymentMethod (INV-DEAL-1)Форма требует выбрать способ оплаты
CRM_LEAD_NOT_ACTIVE409Лид Expired/Archived (INV-LEAD-2)Предложить продлить/реактивировать лид

Доменные События

СобытиеКогда поднимаетсяSubscribers
DealCreated / DealMemberAddedКаждое создание сделки по объекту фиксацииТаймлайн сделки DealCreated, запись ленты лида LeadEventEntity(DealCreated)

Kafka Интеграционные События

СобытиеTopicКогда публикуетсяConsumers
DealCreatedEventpin.crm.deal-created.v1На каждую созданную сделку (одна фиксация → N сделок), через outbox атомарноmessenger (чат сделки + участники), notifications (участникам) — контракт ../events/deal-created.md

Последующие изменения каждой сделки независимы — ../events/deal-stage-changed.md, ../events/deal-completed.md, ../events/deal-cancelled.md.

Acceptance Criteria

#КритерийПроверка
AC1По одной одобренной фиксации агент создаёт сделки по объектам №1 и №2 → две сделки Application с общим FixationRequestId и разными IntentId/PropertyObjectIdИнтеграционный тест: 2× POST /api/agent/crm/deals; FixationRequestId совпадает, объекты разные
AC2FixationRequestId не уникален среди сделок — вторая сделка с той же фиксацией создаётся успешноТест: отсутствует unique-конфликт по FixationRequestId
AC3Повтор по уже занятому объекту → CRM_INTENT_ACTIVE_OBJECT_EXISTS (409), вторая активная сделка по объекту не создаётсяНегативный тест INV-INTENT-1
AC4Объект без подтверждённого намерения → сделка заводится в Draft (гейт по намерению не выполнен), не в ApplicationТест A1
AC5Все Application-сделки одной фиксации видны застройщику на канбане; пара «инвестор × застройщик» однаТест видимости застройщика
AC6Завершение одной сделки (Completed) не влияет на остальные; отмена одной освобождает её объект, прочие активныТест независимости жизненных циклов
AC7Фиксация используется только как основание — её состояние (Approved) не меняется при создании сделокТест: FixationRequestEntity без изменений

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

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

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