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.

222 lines
19 KiB

1 week ago
# 商机 E2E · 主流程盘点(原型 → 流程 → 接口 → 断言清单)
> 票 `01-flows-inventory`(research)产出 · 20260828 · **v2 冻结 20260828(票 04 拍板:U01-U08 全裁决 + 新增 F15;F01-F15 + R01-R03 为 E2E 执行基线)**
>
> **三源对齐**:
> 1. 蓝湖原型 34 页(scope 内)= 第一依据。逐页元素抽取复用上轮 `.scratch/opportunity-verify/spec-endpoints.md`(657 行,按页蒸馏 + 原型 txt 对应关系),本票不重读原始 txt。
> 2. Bruno 集合实际请求(`D:/code/crm-api-docs/商机模块`,48 个请求,method+path 从 `.bru` docs 反引号行提取)。
> 3. 源码控制器:crm-opportunity 各 Controller + crm-rule 三个规则控制器(`/api/rule/opp-stage-template|opp-scheme-template|opp-pool-rule`,共 25 端点)。
>
> **路径纪律**:本文件一律写 **实际 flat 路径**(Bruno/Controller 证实)。上轮 spec-endpoints 里的 REST 猜测路径仅作元素语义参考,不采用。
> **判定纪律**:flat 风格,禁止按 RESTful 推断缺失;接口存在性以票 07/08 实测为准,本票只标「缺陷候选」。
---
## 一、核心域流程(F01–F14)
### F01 新建商机
- **原型**:A3-1-1-2-1 新增/编辑商机;入口 A3-1-1「+新增商机」(A3-1-1 也是线索转商机入口,跨模块只验商机侧,见 map 范围外)
- **表单要点**(原型第一依据):商机名称*、商机来源*(线索转入/线下挖掘/客户转介绍)、商机行业*(多级)、甲方、意向客户、地区、招标形式、方案预算、项目阶段、描述
- **接口序列**:
1. `GET /api/opportunity/convertible-leads` — 可关联线索下拉(选「线索转入」来源时)
2. `POST /api/opportunity` — 新建
3. `GET /api/opportunity/detail?id=` — 回查
- **断言要点**:必填校验(缺 * 字段报错);初始负责人=当前用户;初始 oppStatus 按 PRD §3.1/§8.2(挂 U01);关联线索时 sourceLeadId 落库;新建后出现在 MINE 视图
- **前置**:至少 1 个可关联线索(票 02 盘点);字典组已就绪(boot 初始化器 22 组)
### F02 列表六视图分页
- **原型**:A3-0-1 最近访问 / A3-1-1 销售机会(我负责的/我参与的/全部个人)/ A3-2-1 管理列表 / A3-3-1 公海列表
- **接口**:`POST /api/opportunity/page`,viewType ∈ RECENT / MINE / PARTICIPATED / FOLLOWED / MANAGE / PUBLIC_POOL(六视图与 Bruno 三 folder「销售机会/商机管理/商机公海」共用同一端点)
- **断言要点**(PRD §6):各视图数据范围正确(本人负责 / 团队参与 / 已关注 / 管理权限范围内全量 / status=1 在池);出参回显列——方案卡状态、节点停留时间 stageStayDays、当前负责人、最近跟进 lastFollowTime、公海视图「入池前工作节点 + 进入公海原因 poolReason」;筛选参数生效(keyword/行业/地区)
- **前置**:seed 矩阵覆盖各状态(票 05)
### F03 看板视图
- **原型**:A3-1-1 / A3-2-1 / A3-3-1 的「看板」形态(PRD §6.8 视图形态正交)
- **接口**:`POST /api/opportunity/board/stage-summary`(各阶段数量+金额汇总);`POST /api/opportunity/board/cards`(单阶段卡片,offset+limit 按需加载)
- **断言要点**:summary 与 page total 一致;卡片按阶段分组、首批限量、加载更多翻页不重不漏;三个视图共用端点(挂 U06)
- **前置**:跨多阶段的 seed 商机
### F04 商机详情 + 最近访问上报
- **原型**:A3-0-1-1 / A3-1-1-1-* / A3-2-1-1 / A3-3-1-1 详情公共头部
- **接口序列**:
1. `POST /api/opportunity/view-touch` — 打开详情同步上报(前端并行调用)
2. `GET /api/opportunity/detail?id=` — 主体
- **断言要点**:detail 出参全(PRD §7.9 字段表:stageStayDays/nextStageName/schemeCardStatus/followed/schemeBudget 等);上报后 RECENT 视图出现该商机且按最近访问倒序、去重(P2-2 已拍板:去重+上限);管理详情(A3-2-1-1)操作区差异=权限侧,不单独测接口
- **前置**:无
### F05 编辑商机
- **原型**:A3-1-1-2-1(同页承载编辑态)
- **接口**:`POST /api/opportunity/edit`
- **断言要点**:字段回写生效;操作日志留痕(旧值/新值,PRD §7.7);暂缓/关闭态编辑受限(P1-7 已拍板:先解除状态才能编辑——负路径断言)
- **前置**:F01 产出 + 一条暂缓态 seed
### F06 关注 / 取关 / 批量关注
- **原型**:列表行操作 + 详情头部(A3-0-1 行操作「关注/取关」;公海批量关注)
- **接口**:`POST /api/opportunity/focus`、`POST /api/opportunity/unfocus`、`POST /api/opportunity/focus-batch`
- **断言要点**:focus 后 FOLLOWED 视图可见、detail.followed=true;unfocus 后退出;批量返回成功/失败明细
- **前置**:两账号互测可见性更佳(票 02 账号矩阵)
### F07 跟进记录
- **原型**:A3-1-1-2-2 写跟进弹窗;A3-1-1-1-6 跟进记录 tab
- **接口**:`POST /api/opportunity/follow/add`、`POST /api/opportunity/follow/page`、`POST /api/opportunity/follow/delete`
- **断言要点**:跟进方式/结果标签走字典(22 组里对应组);写跟进后 lastFollowTime 回显更新;**有效跟进重置公海计时**(P1-8 已拍板:本期仅写跟进算有效——联动 R03 断言);delete 后分页数-1
- **前置**:F01 产出
### F08 附件
- **原型**:A3-1-1-1-5 相关附件 tab(资料类型枚举:现场资料/设计清单图纸/客户需求资料/招投标相关/其它)
- **接口**:`POST /api/opportunity/attachment/add`、`GET /api/opportunity/attachment/list`、`POST /api/opportunity/attachment/delete`
- **断言要点**:add→list 出现→delete 后消失;资料类型字典校验。**前置风险**:MinIO 凭据缺失(boot-verify 已警告)→ 挂 U04,凭据到位才能跑,否则 SKIP
- **前置**:CRM_MINIO_AK/SK 环境变量 + 重启(下载端点 Bruno 无对应请求 → 缺陷候选,见附录二)
### F09 方案卡全生命周期
- **原型**:A3-1-1-2-3 新增方案卡;A3-1-1-1-3 方案卡 tab + A3-1-1-1-3-1 编辑方案卡
- **接口序列**:
1. `GET /api/opportunity/scheme-card/selectable-templates` — 可选模板版本(应只出「发布中」版本,联动 R02)
2. `POST /api/opportunity/scheme-card/save` — 新增/保存(card_status 1→草稿)
3. `GET /api/opportunity/scheme-card/list` / `GET /api/opportunity/scheme-card/detail?id=` — 回查
4. `POST /api/opportunity/scheme-card/submit` — 提交(card_status 推进)
- **断言要点**(P0-4 已拍板锚点):card_status 枚举流转与列表「方案卡状态」列口径一致;可编辑性 `card_status<3`(P1-1);提交后 schemeBudget/schemeCardStatus 回显到主表与 detail;多卡时列表口径(P2-3 已拍板)
- **前置**:R02 先有发布中模板(兜底种子 OPP_SCHEME_TPL_01 已在)
### F10 现场勘察
- **原型**:A3-1-1-2-10 新增现场勘察;A3-1-1-1-4 勘察 tab
- **接口**:`POST /api/opportunity/site-survey/add`、`POST /api/opportunity/site-survey/page`、`POST /api/opportunity/site-survey/delete`
- **断言要点**:勘察次数自动生成(P1-2 已拍板:第一次/第二次/第三次/三次以上);补充说明必填(P1-3);工程师跨部门选人;删除后次数重算口径(实测观察)
- **前置**:F01 产出
### F11 关联客户
- **原型**:A3-1-1-2-4 添加关联客户弹窗;A3-1-1-1-2 客户信息 tab(设为主要意向客户)
- **接口**:`GET /api/opportunity/customer/list`(已有);**添加/搜索、设为主要 → Bruno 无对应请求**(缺陷候选,附录二)
- **断言要点**:list 出参(客户类型/关键联系人/联系方式脱敏/关系标记);primaryCustomerId/primaryCustomerNameSnapshot 与 detail 回显一致
- **前置**:seed 关联客户数据(票 02/05 商定:A4 客户域接口不在本 E2E 范围,直接库插或挑存量)
### F12 团队成员
- **原型**:A3-1-1-1-8 团队成员 tab(+添加成员;一键拉群 out-of-scope)
- **接口**:`GET /api/opportunity/team/list`(已有);**添加/移除 → Bruno 无对应请求**(缺陷候选,附录二)
- **断言要点**:list 出参(成员/部门/职位/项目角色/职责/加入时间);团队成员影响 PARTICIPATED 视图可见性(与 F02 联动)
- **前置**:seed 含团队成员样例(精简矩阵拍板里有)
### F13 操作日志 + 阶段推进历史/指引
- **原型**:A3-1-1-1-9 操作日志 tab;详情头部推进阶段进度条(节点+勾选)
- **接口**:`POST /api/opportunity/oplog/page`;`GET /api/opportunity/stage/history`;`GET /api/opportunity/stage/progress`(Bruno 名「阶段推进指引」)
- **断言要点**:oplog 记录实体/字段/旧值/新值/操作说明(P1-5 已拍板字段),F05/F14 每次状态变更都应可追溯;history 与状态机迁移边一一对应(PRD §3.2);progress 出节点列表+完成状态+当前节点(工作目标文本,挂 U08)
- **前置**:跑在 F05/F14 之后测,日志才有内容
### F14 状态机全家桶(轴 1 归属流转)
- **原型**:A3-1-1-2-6 暂缓 / A3-1-1-2-7 抛公海 / A3-1-1-2-9 关闭 / A3-3-1-1-2 领取 / A3-3-1-1-4 分配 / A3-2-1 管理列表行操作与批量
- **接口**(11 条,全在 Bruno「状态流转」folder):
`POST /api/opportunity/claim`、`/claim-batch`、`/assign`、`/assign-batch`、`/handover`、`/pause`、`/resume`、`/release-pool`、`/close`、`/close-batch`、`/reopen`;`POST /api/opportunity/stage/switch`(轴 2 手动切阶段)
- **断言要点**(PRD §3 全图):
- 每条迁移边前后 oppStatus 断言(§3.2 迁移边全图)
- 受限态出边约束(§3.3):暂缓态不可直接关闭等非法边 4xx/业务错误
- CAS 守卫(§3.4):并发/过期前置态提交失败
- pool_reason 枚举落库(§3.5:长期未有效跟进/客户暂无预算/项目暂停或延期/介入时机不成熟/其他),公海视图回显
- 暂缓弹窗原因字典、预计重启日期必填;关闭弹窗「已确认」勾选
- 分配/移交后负责人变更 + oplog 留痕
- 领取校验走「发布中」公海规则版本(禁领负路径,深度挂 U02)
- **前置**:seed 各状态商机 2-3 条(矩阵);两账号(领取/分配对象)
### F15 自定义视图 CRUD(A3-1-1 筛选区「保存视图」,票 04 U07 改判纳入)
- **原型**:A3-1-1 列表筛选区保存视图入口(PRD §6.4,落 crm-preference)
- **接口**(`/api/preference/view`,源码 SavedViewController 共 4 端点;Bruno 集合无对应请求 → 票 11 缺口 +1):
`GET /api/preference/view/list?scopeKey=`、`POST /api/preference/view/save`(@RequestBody SavedView)、`POST /api/preference/view/delete?viewId=`、`POST /api/preference/view/set-default?viewId=`
- **断言要点**(全 CRUD,票 04 拍板):save→list 查到;set-default→list 回显默认标记;delete→list 消失;scopeKey 维度隔离(不同 scopeKey 互不干扰);同一 viewId 重复 save 的 upsert 语义执行时实测确认;源码无独立 update/share 端点,若原型有对应入口 → 按缺陷候选处理(U05 纪律)
- **前置**:普通用户 A 登录(个人偏好数据,不依赖 seed 商机)
---
## 二、规则族流程(R01–R03,V-CONFIG 范式)
> 设置后台:商机 > 商机管理设置,左侧 tab:商机阶段设置 / 方案卡模板 / 方案推送规则(⊘) / 查重规则(⊘) / 公海与提醒 / 商机相关字典(简测,走 crm-dict 平台)。
> **文档缺口**:规则族 25 端点在 Bruno 集合无对应 folder(票 11 记录补齐)。
### R01 商机阶段模板生命周期(A7-3-2-1 列表/详情/新增编辑)
- **接口**(`/api/rule/opp-stage-template`):`POST /page`、`GET /detail`、`POST /save-draft`、`POST /publish`、`POST /copy`、`POST /disable`、`POST /delete`、`GET /versions`
- **断言要点**:code+version_no 唯一;同一 code 同时仅一个「发布中」(§9/§4.2);发布前必须 save-draft;发布后不可编辑(只能 copy 出新版本草稿);草稿可 delete、发布中不可;disable 后版本状态;versions 版本记录完整;节点配置(字典值+自定义名称+工作目标+固定节点排序);绑定商机数回显
- **联动**:发布新版本后**存量商机不迁移**(§4.5 V-CONFIG 12「绑定与不迁移」);F01 新建商机绑定最新发布中模板
### R02 方案卡模板生命周期(A7-3-2-2)
- **接口**(`/api/rule/opp-scheme-template`):`POST /page`、`GET /detail`、`GET /field-defs`(字段定义库,P0-3 已拍板自建不复用 crm-dict)、`POST /save-draft`、`POST /publish`、`POST /copy`、`POST /disable`、`POST /delete`、`GET /versions`
- **断言要点**:同 R01 的 V-CONFIG 通用断言;field-defs 字段集与附录 A 种子模板「全公司通用」一致;发布中模板出现在 F09 selectable-templates
- **联动**:F09 前置
### R03 公海与提醒规则生命周期(A7-3-2-5)
- **接口**(`/api/rule/opp-pool-rule`):`POST /page`、`GET /detail`、`POST /save-draft`、`POST /publish`、`POST /copy`、`POST /disable`、`POST /delete`、`GET /versions`
- **断言要点**:配置项——允许负责人手动转入公海 / 连续未有效跟进自动回收(开关+天数)/ 允许自由领取 / 提前提醒天数;有效跟进定义(P1-8:本期仅写跟进);**锅版本语义**(§5.4):存量商机按其进池时匹配的规则版本执行,新发布版本只影响新进池商机——实测口径挂 U03;发布中版本作为 F14 领取校验依据
- **联动**:F07 有效跟进重置计时;F14 领取校验;自动回收 Job 是否可触发(若为定时任务,E2E 只验配置不验调度,挂 U03)
---
## 三、不确定点清单(喂票 04-spec-confirm-grill)
| # | 不确定点 | 影响 | 建议默认 |
|---|---------|------|---------|
| U01 | 新建商机初始 oppStatus:手工新建是否直接「推进中(2)」、线索转入是否「待领取(1)」?原型未标注 | F01/F02/F14 断言值 | 按 PRD §3.1 取值域 + 实测观察定,实测前不断言具体值 |
| U02 | 公海领取校验负路径测多深:只测成功领取,还是造「禁止自由领取」规则版本测失败分支? | F14/R03 工作量 | 造 1 条禁领规则草稿→发布→验证 1 次,不再展开 |
| U03 | 公海规则锅版本语义与自动回收 Job 的实测口径:回收是定时调度,E2E 是否只验配置落库+版本匹配,不真实等回收? | R03/F07 | 只验配置与版本匹配;Job 调度标 SKIP |
| U04 | 附件流程前置:MinIO 凭据(CRM_MINIO_AK/SK)何时提供?缺失则 F08 整体 SKIP | F08 | 向用户要凭据;默认先跳过 |
| U05 | 缺陷候选 4 项(附录二)若实测 404:按缺陷报(建议 P1——原型明确有按钮)还是先查源码其他入口? | 报告定级 | 404 即记 P1 缺陷,附原型页截图引用 |
| U06 | 看板三视图共用 board 接口:断言只做「销售机会」视图,还是三视图都过一遍 viewType? | F03 | 只测 MANAGE + PUBLIC_POOL 各一次(数据范围差异最大的两视图) |
| U07 | 自定义视图 CRUD(保存筛选方案,落 crm-preference §6.4):E2E 范围只读还是跳过? | F02 补充 | 跳过 CRUD,仅回归内置六视图 |
| U08 | 阶段推进指引(stage/progress)断言是否校验「阶段工作目标」文本内容?文本源是模板节点配置 | F13 | 校验节点名+完成状态,目标文本存在性即可 |
### 决议(票 04 · 20260828 · 三轮 HITL 拍板)
| # | 决议 |
|---|---|
| U01 | 按默认:E2E 不断言初始状态具体值,实测观察 + PRD §3.1(1 待领取/2 推进中/3 暂缓/4 已关闭/5 已转项目)对照;实测与 PRD 冲突即缺陷 |
| U02 | 造 1 条禁领版本(允许自由领取=关):草稿→发布→普通用户领取验证被拒→停用恢复,1 次不展开 |
| U03 | 只验配置落库 + 锅版本语义配置正确;回收 Job 定时调度标 SKIP 注明 |
| U04 | 已消:MinIO 凭据用户提供(admin),票 07 前设 CRM_MINIO_AK/SK 重启验证,F08 正常执行不 SKIP |
| U05 | 404 即记 P1 缺陷,附原型页码引用(原型第一依据) |
| U06 | 看板 MANAGE + PUBLIC_POOL 各一轮 |
| U07 | **改判——全 CRUD 纳入 E2E**:新增 F15,4 端点全测 |
| U08 | 节点名 + 完成状态断言,工作目标文本只验存在性 |
**seed 决议(票 05 输入)**:① seed 前全量清 26 条存量残留;② 账号=管理员罗伟健 `739564171091247104` + A 赖永利(特战团队)/ B 肖琴(冠军团队)/ C 曾偲青(职员);③ 状态矩阵补 待领取(1)/暂缓(3) 各 2-3 条,已转项目(5) 不造,推进中(2)/已关闭(4) 由流程实测覆盖;④ opp_name 统一前缀 `e2e-`,幂等重跑按前缀先清后造;⑤ 流程清单无遗漏(F01-F15 + R01-R03 = 执行全集,开放确认关闭)。
---
## 四、原型页覆盖矩阵(37 页)
| 原型页 | 流程 | 备注 |
|---|---|---|
| A3-0-1 最近访问列表 | F02/F04 | |
| A3-0-1-1 商机详情 | F04 | |
| A3-1-1 销售机会列表 | F02/F03 | 三视图合一页 |
| A3-1-1-1-1~9 个人详情 8 tab | F04/F07-F13 | 7 号工作计划 tab 原型无页(P1-4 挂起 A1X)|
| A3-1-1-2-1 新增/编辑商机 | F01/F05 | |
| A3-1-1-2-2 写跟进 | F07 | |
| A3-1-1-2-3 新增方案卡 | F09 | |
| A3-1-1-2-4 添加关联客户 | F11 | 添加端点缺陷候选 |
| A3-1-1-2-6 暂缓商机 | F14 | |
| A3-1-1-2-7 抛公海 | F14 | |
| A3-1-1-2-9 关闭商机 | F14 | |
| A3-1-1-2-10 新增现场勘察 | F10 | |
| A3-2-1 管理列表 | F02/F03/F14 | 批量族 + 分配 |
| A3-2-1-1 管理详情 | F04/F14 | 督办 ⊘ |
| A3-3-1 公海列表 | F02/F14 | |
| A3-3-1-1 公海详情 | F04 | |
| A3-3-1-1-2 领取 | F14 | |
| A3-3-1-1-3 关注 | F06 | |
| A3-3-1-1-4 分配 | F14 | |
| A7-3-2-1/1-1/1-2 阶段设置三页 | R01 | |
| A7-3-2-2/2-1/2-2 方案卡模板三页 | R02 | |
| A7-3-2-5/5-1/5-2 公海规则三页 | R03 | |
| A7-3-2-6 商机相关字典 | 简测 | 走 crm-dict 平台读接口(Bruno「数据字典-分组/字典项」folder 有)|
| A7-3-2-3 方案推送规则 | ⊘ | 范围外(map 拍板)|
| A7-3-2-4 查重规则 | ⊘ | 范围外 |
## 附录二:缺陷候选预登记(原型/PRD 有、Bruno 集合无对应请求)
> Bruno 集合由 bruno-sync 从源码生成,理论全覆盖路由;以下标「候选」而非缺失,票 07 实测后定论(命中即按 U05 默认 P1 报)。
| 原型操作 | 页 | Bruno 现状 |
|---|---|---|
| 设为主要意向客户 | A3-1-1-1-2 | customer folder 仅 list |
| 添加关联客户(搜索+关联) | A3-1-1-2-4 | 无 add/search(可能挂 crm-customer 域)|
| 团队成员添加/移除 | A3-1-1-1-8 | team folder 仅 list |
| 附件下载 | A3-1-1-1-5 | attachment folder 仅 add/list/delete |
| 自定义视图 CRUD | A3-1-1 | 无请求(落 crm-preference,U07 裁决范围)|
| 转项目 / 督办 / 一键拉群 | 多页 | ⊘ 明确范围外,不算缺失 |