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.0 KiB

ADR-0029: crm-opportunity 编译期依赖 crm-lead —— 下游反向依赖上游的技术债

Status

Accepted(技术债,带触发重设计条件)

Context

线索「转商机」由 crm-lead 定义 outbound port OpportunityCreationPortcrm-lead/port/outbound),商机模块提供实现(ADR-0020:首个实现须与 crm-lead 同库同事务)。

票 11/12/13 落地商机侧实现 OpportunityCreationPortImpl 时发现:要实现该 port,crm-opportunity 必须能在编译期 import com.crm.lead.port.outbound.*(接口 OpportunityCreationPort + 命令 CreateOpportunityCmd + 异常 OpportunityCreationException)。而此前 crm-opportunity/pom.xml 并不依赖 crm-lead——这正是该 port 长期「定义了但无人实现」的真实原因(不是遗漏,是依赖方向未解决)。

crm-lead 侧用 ObjectProvider<OpportunityCreationPort>#getIfAvailable() 注入,只解耦了「运行期 bean 是否存在」,没有解耦「编译期接口是否可见」——实现方仍需编译依赖接口所在模块。

领域上商机是线索的下游(线索转商机)。让 crm-opportunity 依赖 crm-lead = 下游反向依赖上游,方向不干净。

Considered Options

  • crm-opportunity 直接依赖 crm-lead(采纳):pom 加一行即可,ADR-0020 的同库同事务立即成立。代价是方向倒置 + 埋循环依赖雷(见 Consequences)。
  • 抽共享 port 契约模块(把 3 个 port 类移到 crm-base 或新建 crm-contract,两边都依赖它,谁都不直接依赖对方):干净、符合 hexagonal、无循环。否决于当前阶段——要动 crm-lead 现有 3 个类的包路径 + 全部 import + 可能新建模块 + 改两个 pom,工作量与影响面明显超出票 11/12/13 范围,属在「商机模块刚落地、crm-lead 尚不读商机」时提前付重构成本。留作终态方向。
  • 事件/最终一致:ADR-0020 已否决为过度设计(近期大概率同库单体)。

Decision

crm-opportunity/pom.xml 显式依赖 crm-lead,以在编译期实现其 outbound port。pom 内以注释标注本 ADR 为技术债来源。

Consequences

  • 技术债(方向倒置):下游 crm-opportunity 依赖上游 crm-lead,商机模块被拖进线索模块的依赖闭包。
  • 循环依赖雷:一旦 crm-lead 将来需要读商机(如线索详情展示「已转的商机」),会形成 crm-lead ⇄ crm-opportunity 循环,Maven 直接编译失败。届时必须改走「抽共享 port 契约模块」方案(上方否决项),并 supersede 本 ADR。
  • 兜底:本债与 ADR-0020 的「独立部署触发重设计」同源——当前同库单体阶段可接受;触发条件(crm-lead 读商机 / 商机独立部署)出现时一并重设计。

决策来源

票 11/12/13 实现(走法甲,customerId 可空占位)+ 用户拍板「甲,但需要记录这一技术债」(20260825 grill)。关联 ADR-0020。