US-реестр «Участники и владение процессами» (US-CRM-PART / US-AG-ADMIN / US-AGT-MULTI / US-INV-CO)
Назначение
Реестр user stories вокруг состава участников лидов и сделок и владения процессами CRM: кто ведёт
процесс (исполнитель Executor), кто со-агент/ассистент/юрист, кто основной и дополнительные инвесторы,
как передаётся ведение (reassign), как руководитель агентства управляет назначениями и увольнением, как
агент работает сразу в нескольких агентствах и как со-инвесторы участвуют в процессе. Единая модель
участников ParticipantRole — общая для лида, сделки и фиксации
(ADR-0071); историческая
Origin-атрибуция иммутабельна (ADR-0061 п.4, ADR-0072). Каждая story ссылается на покрывающие домены
(../domain/), API-методы, события (../events/) и соседний контекст identity
(членство агента, выбор активного агентства).
Metadata
| Поле | Значение |
|---|---|
| ID-диапазоны | US-CRM-PART-01..10, US-AG-ADMIN-01..06, US-AGT-MULTI-01..05, US-INV-CO-01..05 |
| Контекст | crm (владение процессами, состав участников) + граница с identity (членство агента, активное агентство) и messenger (участники чата) |
| Статус | draft |
| Правило покрытия | Каждая story обязана иметь ≥ 1 покрывающий домен-документ и ≥ 1 операционный документ (api / consumer / событие / UC) |
Карта покрытия (обзор)
Роль: Агент-исполнитель — состав и передача ведения (US-CRM-PART-01..10)
Доступ к процессу — по членству (record-level, ADR-0071): актор ∈ активные участники лида/сделки любой
роли ParticipantRole, либо руководитель/админ компании-владельца, либо Менеджер ПИН (platform-scope).
Историческая Origin-атрибуция (OriginAgentUserId/OriginAgencyCompanyId) иммутабельна и передачей ведения
не меняется (INV-DEAL-10 / INV-LEAD-6).
| № | User Story | Покрытие: домен | Покрытие: API / события / UC |
|---|---|---|---|
| US-CRM-PART-01 | Как Агент, я хочу добавлять в сделку дополнительных участников (со-агент, ассистент, юрист, соинвестор), чтобы они получили доступ к сделке и её чату. | ../domain/deal.md — DealMemberEntity, ParticipantRole (CoAgent/Assistant/Lawyer/InvestorSecondary), INV-DEAL-3 | ../api/agent/add-deal-participant.md; pin.crm.deal-members-changed.v1 (../events/deal-members-changed.md) → messenger |
| US-CRM-PART-02 | Как Агент, я хочу добавлять участников в лид (со-агент/ассистент/юрист/соинвестор) до появления сделки, чтобы вести клиента командой на ранней стадии. | ../domain/lead.md — LeadParticipantEntity, единый ParticipantRole | ../api/agent/add-lead-participant.md; pin.crm.lead-participants-changed.v1 (../events/lead-participants-changed.md) |
| US-CRM-PART-03 | Как Агент, я хочу удалять участника из сделки/лида (кроме единственного исполнителя и основного инвестора), чтобы убирать доступ у тех, кто больше не работает по процессу; история переписки команде сохраняется. | ../domain/deal.md / ../domain/lead.md — soft-remove (RemovedAt), INV-DEAL-3 / INV-LEAD-7 | ../api/agent/remove-deal-participant.md, ../api/agent/remove-lead-participant.md; события состава → messenger (снять доступ, история сохранена) |
| US-CRM-PART-04 | Как Агент/руководитель, я хочу менять роль уже добавленного участника (например, поднять со-агента в кураторы), чтобы отражать реальное распределение обязанностей. | ../domain/deal.md — смена роли, singleton-инварианты (Executor/InvestorPrimary/Responsible), INV-DEAL-3 | ../api/agent/change-participant-role.md; pin.crm.deal-members-changed.v1 (ChangeType = RoleChanged) |
| US-CRM-PART-05 | Как Руководитель/исполнитель, я хочу передать ведение процесса другому агенту моего агентства (сменить исполнителя), чтобы процесс не остался без ответственного при отпуске/перегрузке; новый исполнитель становится получателем комиссии. | ../domain/deal.md (INV-DEAL-3, «нельзя оставить без активного Executor»), ../domain/lead.md (INV-LEAD-8) — атомарная передача (CRM_LAST_EXECUTOR_REQUIRED недостижим) | ../api/agent/reassign-executor.md; pin.crm.deal-members-changed.v1 / pin.crm.lead-participants-changed.v1 (ChangeType = ExecutorChanged) |
| US-CRM-PART-06 | Как Руководитель, я хочу при передаче ведения выбрать: снять прежнего исполнителя из состава или оставить его со-агентом, чтобы гибко управлять доступом уходящего. | ../domain/deal.md — DemotePriorToCoAgent (снятие членства vs понижение до CoAgent) | ../api/agent/reassign-executor.md |
| US-CRM-PART-07 | Как Руководитель, я хочу назначать/менять ответственного-куратора процесса (Responsible), не трогая исполнителя, чтобы разделить «ведёт» и «курирует». | ../domain/deal.md / ../domain/lead.md — Responsible (≤1, может ≠ Executor) | ../api/agent/reassign-responsible.md; события состава (ResponsibleChanged) |
| US-CRM-PART-08 | Как Агент, я хочу быть уверен, что передача ведения не искажает историческую атрибуцию (кто привёл клиента), чтобы воронка агентства и основание комиссии остались корректны. | ../domain/deal.md — INV-DEAL-10 (иммутабельные Origin-поля), CommissionRecipientUserId = Executor на момент завершения | ../api/agent/reassign-executor.md; ../events/deal-completed.md |
| US-CRM-PART-09 | Как Участник процесса, я хочу видеть полный актуальный состав участников с ролями, чтобы понимать, кто и в каком качестве работает по лиду/сделке. | ../domain/deal.md / ../domain/lead.md — активный состав (RemovedAt is null) | ../api/agent/get-deal.md, ../api/agent/get-lead.md; полный ActiveMembers в событиях состава |
| US-CRM-PART-10 | Как Менеджер ПИН, я хочу добавлять/менять участников в любой сделке платформы (обход record-level), чтобы помогать в спорных ситуациях. | ../domain/deal.md — авто-PinManager, platform-scope доступ | ../api/agent/add-deal-participant.md (platform-scope); UC-CRM-006 |
Роль: Руководитель агентства — назначения и увольнение (US-AG-ADMIN-01..06)
Руководитель/админ агентства работает в scope своей организации (scope-иерархия ADR-0025); увольнение агента и его каскад отвязки от CRM-процессов — ADR-0072.
| № | User Story | Покрытие: домен | Покрытие: API / consumer / события |
|---|---|---|---|
| US-AG-ADMIN-01 | Как Руководитель агентства, я хочу приглашать агентов в моё агентство (по телефону), чтобы формировать ростер. | ../../identity/domain/agent-membership.md — открытие Active по паре (INV-AM1), ../../identity/domain/company-invitation.md | ../../identity/api/company-user/invite-agent-by-phone.md; pin.identity.agent-membership-changed.v1 (Status = Active) |
| US-AG-ADMIN-02 | Как Руководитель агентства, я хочу передавать ведение любого лида/сделки моего агентства другому агенту, чтобы перераспределять нагрузку внутри команды. | ../domain/deal.md (INV-DEAL-3), ../domain/lead.md (INV-LEAD-8) — доступ по агентству-владельцу | ../api/agent/reassign-executor.md; события состава (ExecutorChanged) |
| US-AG-ADMIN-03 | Как Руководитель агентства, я хочу уволить агента (принудительно исключить из агентства), чтобы он потерял доступ к процессам агентства; история найма и комиссий прошлого периода сохраняются. | ../../identity/domain/agent-membership.md — Active → Left, LeaveReason = ExcludedByAgency, guard единственного Executor | ../../identity/api/company/terminate-agent-membership.md; pin.identity.agent-membership-changed.v1 (Status = Left) |
| US-AG-ADMIN-04 | Как Руководитель агентства, я хочу, чтобы при увольнении агента его вспомогательные участия (со-агент/куратор/ассистент/юрист) автоматически снялись с процессов агентства, чтобы не осталось «мёртвого» доступа. | ../domain/deal.md / ../domain/lead.md — soft-remove участий; каскад offboarding | ../consumers/agent-offboarding.md; pin.crm.deal-members-changed.v1 / pin.crm.lead-participants-changed.v1 → messenger |
| US-AG-ADMIN-05 | Как Руководитель агентства, я хочу получить пометку и уведомление о процессах, где уволенный оставался исполнителем, чтобы срочно назначить преемника (процесс нельзя оставить без Executor). | ../domain/deal.md / ../domain/lead.md — ExecutorReassignRequiredAt (durable-сигнал), ../domain/fixation-request.md для Pending-фиксаций | ../consumers/agent-offboarding.md (защитная ветка Executor); ../api/agent/reassign-executor.md (назначение преемника) |
| US-AG-ADMIN-06 | Как Руководитель агентства, я хочу быть уверен, что увольнение агента не пересчитывает историческую атрибуцию и уже подтверждённые начисления, чтобы воронка и комиссии прошлого не «переехали». | ../domain/deal.md — иммутабельные OriginAgencyCompanyId/OriginAgentUserId (INV-DEAL-10); earned/paid rewards не трогаются | ../consumers/agent-offboarding.md (AC-6); ADR-0072 |
Роль: Мульти-агентский агент — несколько агентств и переключение (US-AGT-MULTI-01..05)
Агент может состоять сразу в нескольких агентствах (ADR-0070); tenant его CRM-операций определяет выбранное активное агентство.
Владение уже созданными процессами иммутабельно и переключением не меняется.
| № | User Story | Покрытие: домен | Покрытие: API / события |
|---|---|---|---|
| US-AGT-MULTI-01 | Как Агент, я хочу состоять в нескольких агентствах одновременно, чтобы работать на несколько компаний, не заводя разные учётки. | ../../identity/domain/agent-membership.md — несколько Active-записей, INV-AM1 SingleActivePerCompany | ../../identity/api/company-user/invite-agent-by-phone.md / ../../identity/api/investor/accept-invitation.md |
| US-AGT-MULTI-02 | Как Агент, я хочу выбирать активное агентство (в контексте которого сейчас работаю) и переключаться между ними из личного кабинета, чтобы создавать процессы в нужном агентстве. | ../../identity/domain/agent-membership.md — зеркало CompanyId = выбранное (INV-AM6); durable-указатель сессии | ../../identity/api/me/set-active-agency.md (claim tenant_id = ActiveCompanyId) |
| US-AGT-MULTI-03 | Как Агент, я хочу, чтобы новые лиды/сделки создавались в моём текущем активном агентстве (по tenant из JWT), чтобы атрибуция была верной с момента создания. | ../domain/lead.md / ../domain/deal.md — TenantId/OriginAgencyCompanyId из активного агентства при создании | ../api/agent/create-lead.md, ../api/agent/create-deal.md; set-once Origin (INV-LEAD-6 / INV-DEAL-10) |
| US-AGT-MULTI-04 | Как Агент, я хочу, чтобы переключение активного агентства не пересчитывало атрибуцию ранее созданных процессов, чтобы прошлые сделки остались за тем агентством, в котором были заведены. | ../domain/deal.md — иммутабельный Origin-снимок; ../../identity/domain/agent-membership.md — historical-снапшоты не трогаются | ../../identity/api/me/set-active-agency.md (AC «CRM-ресурсы не пересчитываются») |
| US-AGT-MULTI-05 | Как Агент, я хочу добровольно выйти из агентства (или стать независимым/инвестором), сохранив учётку, метрики и достижения, при этом мои активные процессы должны быть переданы преемнику до выхода. | ../../identity/domain/agent-membership.md — self-leave (LeaveReason = SelfLeave), guard единственного Executor (IDENTITY_AGENT_HAS_ACTIVE_PROCESSES) | ../../identity/api/agent/leave-agency.md, ../../identity/api/agent/become-investor.md; каскад — ../consumers/agent-offboarding.md |
Роль: Инвестор и со-инвесторы (US-INV-CO-01..05)
Инвесторы ведутся составом участников: ровно один основной (InvestorPrimary) + произвольное число
созаёмщиков/соинвесторов (InvestorSecondary).
Инвестор видит процесс как участник, без данных о фиксации (record-level).
Основной инвестор определяет уникальность активной пары «исполнитель ↔ основной инвестор» (INV-CRM-001).
| № | User Story | Покрытие: домен | Покрытие: API / события |
|---|---|---|---|
| US-INV-CO-01 | Как Агент, я хочу добавлять со-инвесторов (созаёмщиков) в лид/сделку, чтобы отражать, что покупателей несколько. | ../domain/deal.md / ../domain/lead.md — InvestorSecondary (произвольное число) | ../api/agent/add-deal-participant.md, ../api/agent/add-lead-participant.md |
| US-INV-CO-02 | Как Агент, я хочу назначать основного инвестора среди инвесторов-участников (поднять созаёмщика в основные, прежний основной становится дополнительным), чтобы корректно определять «шапку» процесса и пару. | ../domain/lead.md — INV-LEAD-7 (ровно один InvestorPrimary), guard пары INV-CRM-001 | ../api/agent/set-primary-investor.md; pin.crm.lead-participants-changed.v1 (RoleChanged) |
| US-INV-CO-03 | Как Со-инвестор, я хочу видеть сделку/лид, в которых я участвую, и их чат, чтобы следить за процессом наравне с основным инвестором. | ../domain/deal.md — доступ по членству (любая инвестор-роль), проекция ChatStatus | ../api/investor/get-deal.md, ../api/investor/list-deals.md; синк чата — messenger (ADR-0055) |
| US-INV-CO-04 | Как Агент, я хочу удалять со-инвестора из процесса (но не оставлять процесс без основного инвестора), чтобы поддерживать актуальный состав покупателей. | ../domain/lead.md — снятие InvestorSecondary; попытка снять активного InvestorPrimary без замены → CRM_PRIMARY_INVESTOR_REQUIRED | ../api/agent/remove-lead-participant.md, ../api/agent/remove-deal-participant.md |
| US-INV-CO-05 | Как Инвестор, я хочу быть уверен, что не вижу деталей фиксации у застройщика, даже участвуя в сделке, чтобы соблюдались record-level-границы CRM. | ../domain/deal.md — «инвестор видит сделку как участник, без данных о фиксации» (Безопасность) | ../api/investor/get-deal.md; ../domain/fixation-request.md (видимость агентской стороны) |
Зафиксированные границы покрытия
| US | Граница | Принято |
|---|---|---|
| US-AG-ADMIN-03, US-AGT-MULTI-05 | Членство агента и увольнение — контекст identity, не crm | Дом — ../../identity/domain/agent-membership.md; CRM реагирует каскадом offboarding (ADR-0072) |
| US-AGT-MULTI-02 | Выбор активного агентства — состояние сессии identity, не отдельное CRM-действие | ../../identity/api/me/set-active-agency.md; claim tenant_id (ADR-0070) |
| US-CRM-PART-01/03, US-INV-CO-03 | Участники чата — контекст messenger | CRM поставляет deal-members-changed/lead-participants-changed с полным составом; messenger реконсилирует чат (ADR-0055) |
| US-CRM-PART-08, US-AG-ADMIN-06 | Пересчёт комиссий/атрибуции | Origin иммутабелен (INV-DEAL-10), получатель — Executor на момент завершения; исправление получателя — компенсацией в rewards, не разворотом атрибуции |
Интеграционные ожидания US-блока «Участники»
Строгая согласованность — внутри одной операции crm (состав участников + денормализованные скаляры
ExecutorAgentUserId/ResponsibleAgentUserId/PrimaryInvestorUserId + запись outbox — атомарно); между
контекстами — eventual (SLA консюмеров < 1 мин).
| US-кластер | Синхронно (в ответе операции) | Асинхронно (событие → консюмер) | Что видит пользователь до доставки |
|---|---|---|---|
| US-CRM-PART-01..07, US-INV-CO-01/02/04 (правка состава) | Обновлённый активный состав + денормализация в карточке | pin.crm.deal-members-changed.v1 / pin.crm.lead-participants-changed.v1 (полный ActiveMembers + дельта) → messenger (участники чата), notifications | Состав актуален сразу; участники чата и уведомления — с задержкой |
| US-AG-ADMIN-03/04/05, US-AGT-MULTI-05 (увольнение/выход) | identity: членство Left; guard блокирует выход единственного Executor без преемника | pin.identity.agent-membership-changed.v1 (Status = Left) → crm offboarding: soft-remove участий + пометка reassign → далее события состава → messenger | Доступ уходящего снимается по мере обработки; процессы без исполнителя помечены руководителю |
| US-AGT-MULTI-02/03 (активное агентство) | Новый claim tenant_id; смена немедленна | pin.identity.users.v1 (CompanyId = ActiveCompanyId) → downstream видит текущее агентство агента | Последующие create-* берут агентство из claim; historical-снапшоты не трогаются |
Полный состав в событиях (ActiveMembers) — идемпотентный набор, устойчивый к переупорядочиванию доставки;
ключ партиционирования DealId/LeadId (crm) и AgentUserId (identity) гарантирует per-process/per-agent
порядок; каскад offboarding идемпотентен по {MembershipId}:{EffectiveAt}.
Обратные ссылки
Автоссылки: где используется этот документ.
- registries (1): Реестр use cases и user stories PIN
Связанные документы
- Домены: ../domain/deal.md (
DealMemberEntity,ParticipantRole, INV-DEAL-3/10), ../domain/lead.md (LeadParticipantEntity, INV-LEAD-7/8, INV-CRM-001), ../domain/fixation-request.md, ../../identity/domain/agent-membership.md. - API (crm): ../api/agent/add-deal-participant.md, ../api/agent/remove-deal-participant.md, ../api/agent/change-participant-role.md, ../api/agent/reassign-executor.md, ../api/agent/reassign-responsible.md, ../api/agent/set-primary-investor.md, ../api/agent/add-lead-participant.md, ../api/agent/remove-lead-participant.md.
- API (identity): ../../identity/api/me/set-active-agency.md, ../../identity/api/agent/leave-agency.md, ../../identity/api/agent/become-investor.md, ../../identity/api/company/terminate-agent-membership.md, ../../identity/api/company-user/invite-agent-by-phone.md.
- Consumer/события: ../consumers/agent-offboarding.md, ../events/deal-members-changed.md, ../events/lead-participants-changed.md, ../../identity/events/agent-membership-changed.md.
- Реестр «Сделка»: user-stories-deal.md; README контекста ../README.md.
- ADR: 0071 (владение,
ParticipantRole, видимость по составу), 0070 (мульти-агентство, активное агентство), 0072 (self-leave/terminate, offboarding-каскад), 0025 (scope-иерархия), 0052 (tenancy).