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.

38 lines
3.8 KiB

6 hours ago
# 07 — ref_count 引用计数全量接线(业务三模块)
**Type:** task (HITL)
**Status:** resolved (20260907)
**Blocked by:** 03
## What to build
拍板 1:把 `DictReferenceService`(increment/decrement/batchApply,均 @Transactional)接进业务写路径,**与业务写入同一事务**。约 8-10 处写点:
1. **crm-lead**:新增/编辑保存与清除 `lead_source`、`brand`、`product`、`scene` 字典编码处,旧值 decrement、新值 increment;线索导入 executor 走 `batchApply`(应用层聚合 delta,禁循环逐条——ADR-0015 热点对策)。
2. **crm-opportunity**:OpportunityIntake(建档)、销售直接新建、编辑——`opp_source`、`industry` 两字段同上。
3. **crm-customer**:新增/编辑——`customer_type`、`industry`;客户导入走 `batchApply`
4. **getNames 回显悬空容错**:管理员 force-delete(兵底)仍可造出悬空编码——名称缺失时降级(返回编码原样或空串,实现票内定并写进 CONTEXT.md「名称回显」词条)。
**验收**:每模块接线点集成测试(保存/清除/换值/批量导入的计数断言);计数增减与业务写入同事务回滚验证(抛异常后计数不变);既有三模块测试回归全绿。
## Answer
全部落地(20260907)。四模块测试全绿:crm-dict **55/55**、crm-lead **131/131**、crm-opportunity **262/262**、crm-customer **186/186**(含上游 rule/preference 回归)。
**缝设计(crm-dict 侧,一处机制)**:
- `DictReferenceService.applyFieldChange(group, oldCode, newCode)` 字段级随迁:相等不动、**空白串归一 null**(表单"清空"常以空串到达)、旧减新加;新建传 null、清除传 null。
- `getNames` 悬空兜底:未命中编码回显**编码本身**(force-delete 后历史数据不出现空名称);CONTEXT.md「名称回显」「引用计数」两词条已同步。
**接线点(业务侧,全部与业务写入同事务)**:
| 模块 | 写点 | 字段(分组) |
|---|---|---|
| crm-lead | `createLead`(save 后入账)/ `editLead`(updateById 后,null=未传不动守卫) | channelCode(lead_source)、brandCode(brand)、productCode(product)、sceneCode(scene) |
| crm-opportunity | `OpportunityIntakeImpl.open`(建档入账,覆盖线索转入+直接新建两入口)/ `OpportunityDetailServiceImpl.edit`——**EDIT_FIELDS record 加 `dictGroup` 分量**,引用计数与 SET 子句、字段审计同一字段表同源(加字段只动一处) | oppSource(opp_source)、industryCode(industry) |
| crm-customer | `CustomerServiceImpl.create/update`(全量覆盖语义:拷贝前抓旧值,CAS 成功后随迁)/ `CustomerImportExecutor`(行级聚合 delta,客户 sheet 收尾一次 `batchApply`——ADR-0015 热点对策) | customerType(customer_type)、industryCode+industryChildCode(industry) |
| 常量 | OpportunityConstants/CustomerConstants 补 `DICT_GROUP_*` 常量(customer detail 原字面量一并换常量) | — |
**测试说明(验收项的如实偏差)**:计数级断言落在 crm-dict 的 H2 集成测试(`DictReferenceServiceTest` 新增 2 例:新建/换值/清除/相等不动 + 空白归一);三业务模块测试为 Mockito 单测(H2 基建无 dict 表),接线点以 mock 注入回归 + 既有用例全绿兜底,未在业务侧做计数断言。"同事务回滚"由业务方法既有 `@Transactional` + `DictReferenceServiceImpl` REQUIRED 传播结构保证,未单独做回滚断言。
**过程中的顺带修复**:`OpportunityIntakeImplTest` 缺新依赖 mock 导致 12 个 NPE(补 `@Mock DictReferenceService` 后全绿);客户模块直跑报 `CustomerReminderRuleDTO` NoClassDefFound 系本地仓库 crm-rule 构件过期(与本次无关,`-am` 源码构建即解)。