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.
 
 
 
 
 

4.9 KiB

Map: 商机模块接口整改

wayfinder:map

2026-08-27 重大修订:本 effort 原 destination/整改清单建立在 verify-report 旧版(已作废) 之上,旧版把大量其实已实现的接口误判为 缺失(详情主体、编辑、状态机 8 Cmd、6 个 tab、协作、看板、访问上报、规则 versions)。经重新黑盒实测(见重写版 .scratch/opportunity-verify/verify-report.md + supplement_test.py),这些接口全部存在且业务可用。整改范围随之坍缩为唯一一件真事:D-01 新建商机 500。原整改清单作废,见下。

Destination

修复商机模块唯一的真实致命缺陷 D-01:POST /api/opportunity 新建商机必然 500,使商机业务链的入口可用。

  • 合法入参新建返回 code:0 + 新商机 id
  • 新建商机 current_stage_id 非空,能进列表、看板、阶段进度
  • 回归:opportunity-verify/e2e_test.py 重跑,新建条转 [OK],原被 SKIP 的 8 条状态机全部 [OK]

作废的原整改清单(旧报告误判,实测均已实现,不再整改)

原列"待补齐" 实测真相 实际路径
GET /api/opportunity/{id} 详情主体 已实现 GET /api/opportunity/detail?id=
PUT /api/opportunity/{id} 编辑 已实现 POST /api/opportunity/edit
状态机 8 Cmd Controller 已实现(+批量) POST /api/opportunity/{claim,assign,release-pool,pause,resume,close,reopen,handover}
6 个 tab 子域 全实现 /customer/list/follow/*/site-survey/*/attachment/*/team/list/oplog/page
协作 关注/取关 已实现 /focus/unfocus/focus-batch
看板 stage-summary/cards 已实现 /board/stage-summary/board/cards
访问上报 已实现 /view-touch(非 spec 的 recent-visits/touch)
规则族 /versions ×3 全实现 GET /api/rule/opp-*/versions?id=

上述均为**路径风格差异(flat vs RESTful)**导致旧报告误判,属前端对接契约问题,不改后端。契约差异清单见重写版报告第八节 C-01~C-06。

out-of-scope(沿用锁定范围,不改):W-01 分页字段 content / C-02 参数名 oppId / C-03~C-06 契约差异 / 一键拉群 / 推送方案 / 督办 / 转项目 / 工作计划联动 / 项目查重规则。

唯一整改项(P0)

  • D-01POST /api/opportunity 新建 500。真实肇因 = current_stage_id NOT NULL 无默认值(旧报告 W-02 误写为 bid_form),OpportunityIntakeImpl.buildOpportunity 未给该列赋值。详见 bug 票 opportunity-verify/issues/07-bug-create-opportunity-500-current-stage-id.md

票依赖图

01 (P0: 修 D-01 新建 current_stage_id)  ──→  02 (回归验证 + 关闭 effort)

Tickets

  • 01(P0): 修 D-01——新建商机入库前赋 current_stage_id(按适用范围解析初始阶段),使 POST /api/opportunity 可用 = open
  • 02(回归): 重跑 e2e_test.py,确认新建 + 8 条状态机全绿,关闭 effort = open,blocked by 01

Notes

编码约定

  • 薄适配层:Controller 只做入参绑定 + 调 Service/Domain
  • 参数名沿用现有 flat 风格(oppId 不改)
  • 编码 UTF-8 无 BOM
  • 构建验证:mvn compile -pl crm-opportunity -am -q

D-01 白盒线索

  • crm-opportunity/.../intake/impl/OpportunityIntakeImpl.javabuildOpportunity(spec) 组装 Opportunity 实体时未 set currentStageId → insert 命中 DB NOT NULL 无默认值
  • 初始阶段来源:应按商机「适用范围命中的阶段模板」的首个阶段确定(对齐原型「新建即进首阶段」语义)
  • 相关:OpportunityCreateServiceImpl.createOpportunity、阶段模板域 crm-ruleopp-stage-template

收尾(2026-08-27 effort 已关闭)

  • 票 01 resolved:修 OpportunityIntakeImpl.applyInitialStage 无模板兜底回填零值,根因 = 全库无发布中阶段模板(默认模板被停用)+ 三列 NOT NULL。
  • 票 02 resolved:e2e_test.py 回归 OK=37 / FAIL=0 / SKIP=0
  • 商机模块唯一真实致命缺陷 D-01 已修复,业务主链路全通。其余「待补齐」皆旧报告误判,实测本就可用,未改后端。

最终定案(2026-08-27,策略 B + 预设保护)

  • 代码撤销零值兜底,改 fail-fast:无发布中默认阶段模板 → 新建报友好业务错(code 60001,非 500)。
  • 后台阶段配置加系统预设保护:SEED_STAGE_TPL_CODE=OPP_STAGE_TPL_01(客户圈定/关系摸排/资料采集/方案卡/已转项目)不可删除、不可停用(错误码 64018),保证「始终有一个发布中默认模板」不变式。
  • 数据已恢复预设发布中态。e2e OK=37/0/0。
  • 改动 3 文件:OpportunityIntakeImpl / OpportunityRuleConstants / OpportunityStageTemplateServiceImpl,均 UTF-8 无 BOM。