You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3.7 KiB
3.7 KiB
03 商机侧硬依赖契约
Type: research Status: resolved Blocked by: —
Question
crm-customer 对 crm-opportunity 的硬依赖全景,供 Demo「关联商机」相关呈现:
- 客户详情「关联商机」页签:走哪个端点(crm-opportunity 侧 list-by-customer?)、出参字段(brief 提到 G2「关联商机 7 vs 13 列」契约漂移——以实现实际返回为准列出列清单)。
- 新增/编辑客户挂商机:opp_id 可空化(backend 票 ticket01)后的字段语义与端点行为。
- 客户归属变更(换负责人/抛公海/归档/交割)对名下商机的影响:哪些动作会级联商机状态,Demo 流程闭环演示需要覆盖哪些级联现象。
- 商机创建是否依赖客户存在(商机侧硬依赖的反向):Demo 是否需要演示「从客户发起建商机」。
产出:依赖清单(端点×字段×触发场景),落在 Answer 内(量小)或 assets/opp-deps.md。
Pointers
crm-opportunity模块 Controller;crm-customer详情页签实现(CustomerDetailController)。- gap-report G2(7 vs 13 列)原文:
.scratch/customer-frontend-handover/gap-report.md。 - 现有 demo「关联商机」页签实现(
.scratch/customer-e2e/demo/index.html搜「关联商机」)。
Answer
详细依赖清单(端点×字段×触发场景 + SQL + 源码定位):assets/opp-deps.md。要点:
- 关联商机页签:
GET /api/customer/opportunity/page?id=(CustomerDetailController)→ 出站 portCustomerOpportunityQueryPort,crm-opportunityCustomerOpportunityQueryPortImpl(@Primary)承接;SQL =opportunity_customerjoinopportunity(delete_key=0),更新倒序。出参恒 7 字段:id / oppName / stageName(crm-rule describeStages 批量解析当前节点展示名)/ estimateAmount(=project_amount)/ ownerUserId / ownerNameSnapshot / updateTime。G2 的 13 列是原型期望,缺列挂账跨模块票(issues-07 §C 已收窄);Demo 契约事实=7 字段,缺列显「--」。旧 demo 3 处字段名漂移(opportunityName/ownerUserName/statusName 均不命中,回退显 id 或「--」)——新 demo 按真名渲染。 - 「新增/编辑客户挂商机」前提修正:Customer 实体与 Create/UpdateDTO 零商机字段,customer 侧无挂商机关联口;关联唯一真源=商机侧
opportunity_customer子表。ticket01 的opp_id可空化是opportunity_scheme_card.opp_id(方案卡遗留列,ADR-0041;迁移器仅在列仍 NOT NULL 时 ALTER,幂等),与客户域无关。Demo 不做该表单。 - 归属变更级联矩阵:claim/releasePool 前置阻断(hasActiveOpportunity:opp_status IN 1,2,3 计数>0;claim→67007、抛公海→67007、归档→67006;批量归档先整批预检);assign 换负责人不级联(客户/商机负责人可漂移——不对称点,值得 demo 呈现);交割两段强级联:initiate 整批原子(客户+商机+项目 owner 同刷接收总监,任一失败全回滚)、assignOne 逐条独立事务,商机侧刷 owner 三列(owner_dept_id=DataScope 锚点跟人走),不 bump 乐观锁、不写商机 oplog(项目侧才逐项目写 TRANSFER 动态,c9d6e75)。商机终结态 4/5 不阻断抛公海/归档。
- 反向依赖=弱:
POST /api/opportunitycustomerId 可空(非空时 isPrimaryIntended+customerRole 必填);直接新建路径不做客户存在性校验,商机详情POST /api/opportunity/customer/add才走 requireLive(不存在/已归档拒)。归档客户存量关联行不清理(页签仍反查得到),但商机详情侧不可再新挂。客户侧无「从客户建商机」端点——Demo 用POST /api/opportunity预填 customerId 合成该入口即可,无需新后端。