15 KiB
商机模块端到端验收报告(e2e-report.md 终稿)
票 09 聚合产出(20260828)· 聚合自
report-core.md(票 07)+report-rules.md(票 08)+seed-data-manifest.md(票 05)。 环境:本地后端localhost:8080(verify profile,CRM_MINIO_AK=admin)+ 远程 DB8.129.84.155。 数据基线:seed 12 条e2e-商机 + F01 新建 1 条(重跑方式见第六章)。 实测脚本:e2e-core.py(F01-F15)+e2e-rules.py(R01-R03),Python requests、flat 路径实测。 判定纪律:原型 > PRD(.scratch/opportunity-module/商机业务-PRD.md)> 票 04 拍板;判 ❌ 前必须核对 flat 实际路径。 图例:✅ 存在且业务可用|⚠ 行为不符/契约差异/被缺陷阻断|❌ 缺失或真实 bug。
一、执行摘要
| 维度 | 结论 |
|---|---|
| 流程覆盖 | 核心域 F01-F15(15 流程)+ 规则族 R01-R03(3 流程)= 18 流程全部实测 |
| 用例总数 | 104(core)+ 46(rules)= 150 用例:✅ 125 / ⚠ 17 / ❌ 9 · SKIP 0 |
| 缺陷 | 22 条:P1×13 / P2×9 / P0×0(P0=无) |
| 路由缺失(真 404) | 6 个:关联客户 3 + 团队成员 3(原型有按钮无接口);规则族 25 端点全部存在 |
| 与上轮对比 | 上轮 D-01「新建必 500」已修复(本轮 F01 ✅ 回归);「状态机全缺」系上轮误判,本轮 flat 路径全 ✅ |
三大 P1 主题(修复 effort 的优先级线索):
- 6 个 404 端点:关联客户添加/搜索/设主要意向(原型 A3-1-1-2-4、A3-1-1-1-2)+ 团队成员增/删/改(原型 A3-1-1-1-8)——原型有按钮无接口,F11/F12 主流程断链;
- V-CONFIG 版本推进 API 全断(规则族):编辑发布中/停用版本生成新草稿三族同构 50001 主键冲突(
resolveDraft的dto.toEntity()携带源版本 id insert); opportunity.owner_dept_id恒空:创建/领取/分配/移交均不写部门快照(全表 13/13 NULL)→ 部门专用公海规则永不命中 + DataScope 部门天花板同源失效。
二、核心域 F01-F15(票 07 · e2e-core.py · ✅86/⚠12/❌6)
| 流程 | 用例分布 | 关键结论 |
|---|---|---|
| F01 新建 | ✅6 | convertible-leads 下拉接口 ✅(0 条可关联线索);新建成功、初始负责人=当前用户、U01 复核:初始 oppStatus=2(推进中)、MINE 视图即刻可见 |
| F02 四视图 | ✅13 | MANAGE/MINE/PUBLIC_POOL/FOLLOWED/RECENT/PARTICIPATED 全口径 ✅;keyword/statusIn 筛选 ✅;B/MINE 不含公海态、A/MINE 不含 B 商机(范围互斥 ✅);出参回显列(schemeCardStatus/stageStayDays/lastFollowTime)✅ |
| F03 看板 | ✅2 ⚠1 | MANAGE summary 口径 ✅;cards 首批限量+翻页不重不漏 ✅;⚠ PUBLIC_POOL summary=7 未按视图状态过滤(视图内公海态=2) |
| F04 详情 | ✅4 ⚠1 | view-touch 上报 → RECENT 出现且倒序 ✅;⚠ detail 六联动字段 null(节点停留天数/下阶段名/方案卡状态/方案预算/是否关注/最近跟进,PRD §7.9) |
| F05 编辑 | ✅2 ⚠1 | 编辑回写 ✅;⚠ P1:暂缓态商机编辑未被拦截(code=0 成功,PRD §3.3 受限出边违反) |
| F06 关注 | ✅3 ⚠1 | unfocus/focus/focus-batch 计数全 ✅;B 视角关注 A 商机(跨部门)✅;⚠ focus 后 detail.followed 回显 None |
| F07 跟进 | ✅4 | 写跟进/分页/删除 ✅;lastValidFollowTime 刷新(回收锚点)✅ |
| F08 附件 | ✅5 | MinIO 直传→add→list→delete→download 全链 ✅(凭据 AK=admin 补跑);FileInfoDTO 主键=fileId(String) |
| F09 方案卡 | ✅8 ⚠1 | selectable-templates ✅;一客户一卡约束 ✅;草稿→提交 cardStatus 1→2 ✅;⚠ 提交后主表 schemeBudget/schemeCardStatus 未回显 |
| F10 勘察 | ✅3 ⚠2 | ⚠ surveySeq 需调用方传入(与「次数自动生成」拍板相反);⚠ 补充说明未强制必填(与拍板相反) |
| F11 关联客户 | ✅3 ❌3 | list/出参结构/primaryCustomerSnapshot 回显 ✅;❌ add/search/set-primary 三端点 404 |
| F12 团队成员 | ✅2 ❌3 | team/list ✅;❌ add/delete/update 三端点 404(API 无法造团队成员样例) |
| F13 日志 | ✅3 ⚠3 | stage/history 留痕 ✅、progress 5 节点 ✅;⚠ oplog 流转不留痕(A2 历经 6 种流转仅 2 条 ROW_CHANGE 且 fieldName=null) |
| F14 状态机 | ✅21 ⚠2 | E1-E9 主边 + CAS 守卫 + 批量接口全 ✅;⚠ P1:暂缓态可直接关闭;⚠ P1:禁领规则版本未生效(allowFreeClaim=0 发布后仍可领取——U02);poolReason 枚举落库+回显 ✅ |
| F15 自定义视图 | ✅7 | save(upsert)/list/set-default/delete 全 ✅;scopeKey 域隔离(lead/opportunity 不串)✅;B 的 seed 视图隔离 ✅ |
明细证据(请求/响应逐条)见 report-core.md;机读 e2e-core-result.json。
三、规则族 R01-R03(票 08 · e2e-rules.py · ✅39/⚠5/❌3)
| 流程 | 用例分布 | 关键结论 |
|---|---|---|
| R01 阶段模板 | ✅16 ⚠2 ❌1 | 负路径 5 连拒(缺名/部门专用无部门/部门专用设默认/固定节点手配 64013、空模板 publish 64017)✅;V1.0 草稿+节点规范化(末位系统补 OPP_STAGE_05 固定节点+seq 重算)✅;草稿原位编辑(版本编码不变)✅;copy 独立新编码 ✅;disable 草稿拒/delete 草稿级联 ✅;D-01 种子保护(disable 被 64018 拒)✅;绑定锁版本(发新模板后 A1 节点集 5 节点不变)✅;⚠ versions 出参实体直出泄露(P2);❌ 编辑发布中生新草稿 50001(P1,三族同构根因在此实锤);⚠ publish 自我顶替被 P1 阻断(旁证=票 07 U02) |
| R02 方案卡模板 | ✅12 ⚠1 ❌1 | field-defs 16 项系统字段库 ✅;伪造 fieldKey 拒(64022 快照防伪造)✅;字段项快照回显(fieldName/fieldType 服务层写入)✅;关显示同步清必填 ✅;空模板 publish 拒 ✅;copy ✅;❌ 编辑发布中同构 50001 |
| R03 公海规则 | ✅10 ⚠2 ❌1 | 五配置项校验链 5 连拒(64008:缺名/缺 recycleDays/recycleDays=0/remindDays≥recycleDays/未开回收先开提醒)✅;publish 落库 ✅;U03 配置层:部门专用规则发布+deptIds 绑定回显 ✅;⚠ U03 生效层按缺陷预期放行(owner_dept_id 恒空不命中部门索引——见缺陷 D-21);❌ 编辑发布中同构 50001 |
| 清理闭环 | ✅4 | 三族自建规则全部停用/删除,无发布中残留;e2e-seed公海规则 仍发布中(F14 前置未破坏) |
V-CONFIG 生命周期实测覆盖说明:新建草稿→编辑→发布→绑定生效→复制/删除约束全链 ✅;「发布自我顶替(原发布中转停用)」与「编辑已有草稿则拒」两条因 P1 阻断无法经此链实测,顶替语义旁证=票 07 U02(发布禁领版时 seed 规则被顶替取消默认——同 code 发布侧路径存在)。
明细证据见 report-rules.md;机读 e2e-rules-result.json。
四、缺陷清单(22 条,交接修复 effort 的直接输入)
复现基线统一:
python .scratch/opportunity-e2e/seed-opportunity.py后跑对应脚本(核心域e2e-core.py/ 规则族e2e-rules.py,均幂等可重跑);F08 类需环境变量E2E_MINIO_AK/SK(=CRM_MINIO_AK/SK)。下表只写特异点。
P1(13 条)
| 编号 | 现象(期望 vs 实际) | 复现 | 接口/位置 | 原型依据 |
|---|---|---|---|---|
| D-01 | 关联客户添加无端点:原型有「添加客户」按钮,接口 404(期望存在) | F11 端点探测 | POST /api/opportunity/customer/add |
A3-1-1-2-4 |
| D-02 | 客户搜索无端点(添加弹窗第一步):404 | F11 端点探测 | POST /api/opportunity/customer/search |
A3-1-1-2-4 |
| D-03 | 设为主要意向客户无端点:404 | F11 端点探测 | POST /api/opportunity/customer/set-primary |
A3-1-1-1-2 |
| D-04 | 团队成员添加无端点:404 | F12 端点探测 | POST /api/opportunity/team/add |
A3-1-1-1-8 |
| D-05 | 团队成员移除无端点:404 | F12 端点探测 | POST /api/opportunity/team/delete |
A3-1-1-1-8 |
| D-06 | 团队成员角色编辑无端点:404 | F12 端点探测 | POST /api/opportunity/team/update |
A3-1-1-1-8 |
| D-07 | 暂缓态商机可编辑(期望 §3.3 受限态拦截写操作;实际 code=0 成功) | F05 负路径:对 oppStatus=3 商机调 edit | POST /api/opportunity/edit |
PRD §3.3 |
| D-08 | 暂缓态可直接关闭(期望 §3.3 状态机无 3→4 出边;实际成功) | F14:对暂缓态调 close | POST /api/opportunity/close |
PRD §3.3 |
| D-09 | 禁领规则版本未生效:发布 allowFreeClaim=0 版本后仍可自由领取(期望拦截;旁证说明规则版本表数据已落库) | F14 U02:发禁领版后 claim | POST /api/opportunity/claim + 规则发布 |
PRD §5.4 U02 |
| D-10 | V-CONFIG 版本推进 API 全断:编辑发布中版本生成新草稿必 50001;日志 Duplicate entry for opportunity_stage_template.PRIMARY(根因:VersionedConfigSupport.resolveDraft 编辑分支的 dto.toEntity() 携带源版本 id 直接 insert) |
R01:publish 后对发布中版本调 save-draft 带 id | POST /api/rule/opp-stage-template/save-draft |
源码 crm-rule/.../OpportunityStageTemplateServiceImpl |
| D-11 | 同 D-10(方案卡模板族同构现象) | R02 同路径 | POST /api/rule/opp-scheme-template/save-draft |
同上 |
| D-12 | 同 D-10(公海规则族同构现象) | R03 同路径 | POST /api/rule/opp-pool-rule/save-draft |
同上 |
| D-13 | owner_dept_id 恒空:创建/领取/分配/移交均不写部门快照(DB 全表 13/13 NULL)→ ①部门专用公海规则(applyScope=2)对任何商机永不命中(匹配器按 owner_dept_id 查部门索引落空,U03 实测:发布部门专用 allowManualPool=0 后 release-pool 照常成功);②DataScope 部门天花板同源失效 | R03 U03 段 + DB 直查 | OpportunityPoolRuleMatcherImpl / Opportunity deptColumn 锚点 |
PRD §5.4 部门专用 |
P2(9 条)
| 编号 | 现象(期望 vs 实际) | 复现 | 接口/位置 | 原型依据 |
|---|---|---|---|---|
| D-14 | 新建必填校验以 500 类「系统内部错误」返回而非参数错误提示 | F01 缺商机名提交 | POST /api/opportunity(flat create) |
交互惯例 |
| D-15 | PUBLIC_POOL 看板 summary=7 未按视图状态过滤(视图内公海态实际=2) | F03 对比 summary 与 page(statusIn=1) | POST /api/opportunity/board/summary |
§7 看板 |
| D-16 | detail 六联动字段 null:节点停留天数/下阶段名/方案卡状态/方案预算/是否关注/最近跟进 | F04 detail 回显 | GET /api/opportunity/detail |
PRD §7.9 |
| D-17 | 方案卡提交后主表 schemeBudget/schemeCardStatus 未回显(与 D-16 同根因族) | F09 提交后看主表 | 同 detail | P0-4 锚点 |
| D-18 | 勘察次数需调用方传 surveySeq(与「次数自动生成」拍板 P1-2 相反) | F10 不传 surveySeq 被拒 | POST /api/opportunity/survey/add |
拍板 P1-2 |
| D-19 | 勘察补充说明未强制必填(与拍板 P1-3 相反:空说明成功) | F10 空说明提交 | 同上 | 拍板 P1-3 |
| D-20 | oplog 流转不留痕:商机历经 release/claim/assign/close/reopen/handover 仅 2 条 ROW_CHANGE 且 fieldName=null | F13 oplog/page | POST /api/opportunity/oplog/page |
拍板 P1-5 |
| D-21 | attachment/add 可选参数 bizType 缺省即 50001(Controller 声明 optional vs 表 biz_type NOT NULL 无默认,契约矛盾;正路径须显式传值域 OPP/FOLLOW_UP/SITE_SURVEY/SCHEME_CARD) | F08 不传 bizType | POST /api/opportunity/attachment/add |
契约一致性 |
| D-22 | versions 端点返回实体直出,泄露 creatorId/deleted/updaterId(违 ADR-0017 Entity 禁令) | R01 versions 检查 | GET /api/rule/opp-stage-template/versions |
ADR-0017 |
五、与上轮 opportunity-verify/verify-report.md 的差异说明
| 维度 | 上轮(20260827) | 本轮(20260828) |
|---|---|---|
| 范围 | 85 路由黑盒 + 状态机 9 步 | 18 业务流程(含 F15 自定义视图、F08 MinIO 全链、规则族三族 V-CONFIG 生命周期 + U03 配置生效——均为上轮未测面) |
| 上轮 D-01 新建必 500 | ❌(current_stage_id 无默认值,新建 100% 失败) | 已修复回归 ✅(F01 新建成功 + 初始态/负责人/视图可见全对) |
| 上轮「状态机全缺」误判 | ❌(RESTful 路径 404 误判) | flat 路径核对后 E1-E9 主边 + CAS 守卫 + 批量接口全 ✅(翻案延续:map「判定纪律」即因此立) |
| 上轮「唯一致命缺陷」表述 | 新建 500 一项 | 本轮无 P0;P1 主题转向功能缺失(6 个 404)+ 规则引擎断点(V-CONFIG 版本推进)+ 数据链断点(owner_dept_id) |
| MinIO | 未测(凭据缺失) | F08 全链 ✅(AK=admin 实锤) |
| 数据基础 | 存量 26 条测试残留 | seed 12 条矩阵化样例(幂等重跑) |
结论:上轮验收的核心结论(接口存在性、flat 契约差异、状态机守卫)全部被本轮确认;本轮新增的是业务流程级的深度结论(联动回显、约束拦截、规则引擎生效性)——这些是上轮路由级黑盒无法触达的。
六、测试数据指引(seed-data-manifest 速览)
- 完整清单:
seed-data-manifest.md(人读)+seed-manifest.json(机读,不一致时以 json 为准)。 - 账号矩阵(debug token =
GET /api/auth/debug/token?userId=):管理员罗伟健739564171091247104(全量可见)/ A 赖永利744842565802524672(特战团队)/ B 肖琴744842566742048768(冠军团队)/ C 曾偲青744842318024015872(跨中心职员)。 - 商机矩阵 12 条:待领取 2 / 推进 6 / 暂缓 2 / 关闭 2,跨 A/B/C 三人(DataScope 视角差异可直接用);A 已关注 B 一条;子表样例:跟进 2、勘察 1、方案卡 1(已提交·88 万)、关联客户 1(DB 直插——add 端点缺失 D-01)、自定义视图 1(B 名下)。
- 规则前置:
e2e-seed公海规则+全公司通用方案卡模板均发布中(demo 票 10 的 tab3 可直接用)。 - 重跑方式:
python .scratch/opportunity-e2e/seed-opportunity.py—— 先清后造(幂等,ID 会变)python .scratch/opportunity-e2e/e2e-core.py—— 核心域全量(注意:跑完 F14 会把部分商机状态流转偏离 seed 基线,重跑 seed 即复位)python .scratch/opportunity-e2e/e2e-rules.py—— 规则族全量(自带建测清闭环,不污染 seed)
- 已知数据事实(联调者注意):①
opportunity.owner_dept_id全表恒空(D-13,部门维度功能全部失效的数据侧根因);②sys_dept最老 root 部门744636475731083264的 dept_name 是历史 mojibake 存量(选部门时避开);③ e2e-core 跑过后 A1/B1 归属变更、C1/C2/A2 历经关闭/重启/回公海(重跑 seed 复位)。