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
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-01:
POST /api/opportunity新建 500。真实肇因 =current_stage_idNOT 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.java:buildOpportunity(spec)组装 Opportunity 实体时未 setcurrentStageId→ insert 命中 DBNOT NULL无默认值- 初始阶段来源:应按商机「适用范围命中的阶段模板」的首个阶段确定(对齐原型「新建即进首阶段」语义)
- 相关:
OpportunityCreateServiceImpl.createOpportunity、阶段模板域crm-rule的opp-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。