# 05 商机公海与提醒规则 Type: grilling Status: resolved Blocked by: 03, 04 ## Question 定商机公海机制,含原型 `A7-3-2-5 公海与提醒规则`(列表/详情/新增3页)。产出公海规则配置规格;明确与 `crm-rule` 线索池的边界;回填票 03/04 的传出决策(`pool_id` 引用/超时回收计时锚点/抛公海回哪个池)。 ## Answer(原型核实后重写,推翻初稿的"对称 lead_pool 池实体"模型) > ⚠️ **重大修订记录**:本票初稿(会话 N)在**未抓到原型正文**时,照搬线索的 `lead_pool` 族(一部门一池实体 + 省/市/区负责市场 + 领取/持有上限)做对称推定,**方向错了**。会话 N+1 用蓝湖 MCP 拉到 `A7-3-2-5` 三页一手正文(存档 `research-a7325-pool-remind-rules.md`),确认商机公海规则是**版本化规则配置**范式,与线索池模型**不同**。以下为按原型正文重写的定稿。初稿的对称推定表格作废。 ### 零、原型真相:商机公海规则 ≠ 线索池实体 | 维度 | 线索 `lead_pool`(既存代码) | 商机公海规则(原型 A7-3-2-5) | |---|---|---| | 建模范式 | **池实体**:一部门一池 `UNIQUE(dept_id)` | **版本化规则配置**:规则编码 + 多版本 + 草稿/发布中/已停用 | | 归属划分 | dept_id + 省/市/区负责市场 | 适用范围 = 所有部门通用 / 对应部门专用(**无地理维度**) | | 兜底 | 无 | **默认规则**(所有部门通用可设默认,唯一);匹配不到部门专用时兜底 | | 回收锚点 | claim_time | **最近一次有效跟进时间**(有效跟进=跟进记录/附件/字段编辑) | | 领取控制 | claim_rule + 每日/持有上限 | **单一开关**「允许自由领取」(无上限字段) | | 抛公海控制 | 无(人工按钮) | **开关**「允许负责人手动转入公海」 | | 提醒 | 无独立配置 | **提前提醒天数**(可配,须 < 自动回收天数) | **结论**:商机公海规则采用与票 06 阶段模板、票 07 方案卡模板**同族的"版本化配置"范式**(草稿/发布中/已停用 + code + 版本号 + 快照),不复用 `lead_pool` 表族。这是产品在商机域统一采用的规则中心范式(`crm-rule` 多域规则中心,票 01)。 ### 一、`opportunity_pool_rule` 规则主表(住 `crm-rule`) 版本化规则配置。**同一 `rule_code` 一套规则、多版本**;每版本一行。 | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | `id` | bigint | ✅ | 版本行主键 | | `rule_code` 规则编码 | varchar(64) | ✅ | 系统生成,唯一标识规则主体(如 `POOL_RULE_01`);同规则多版本共用 | | `rule_name` 规则名称 | varchar(100) | ✅ | 同规则多版本沿用同名 | | `version_no` 版本号 | varchar(20) | ✅ | 系统生成(V1.0/V1.1/V2.0…),只读 | | `status` 状态 | tinyint | ✅ | 1=草稿 / 2=发布中 / 3=已停用(见「二」状态规则) | | `apply_scope` 适用范围 | tinyint | ✅ | 1=所有部门通用 / 2=对应部门专用 | | `is_default` 是否默认 | tinyint | ✅ | 1=是/0=否;仅 apply_scope=1 允许=1;发布中默认唯一 | | `allow_manual_pool` 允许负责人手动转入公海 | tinyint | ✅ | 0/1;控制"抛公海"入口是否对负责人开放 | | `auto_recycle_enabled` 启用自动回收 | tinyint | ✅ | 0/1 | | `recycle_days` 自动回收天数 N | int | ⚠ | auto_recycle_enabled=1 时必填;>0 整数;连续未有效跟进达 N 天回收 | | `allow_free_claim` 允许自由领取 | tinyint | ✅ | 0/1;控制适用范围内销售能否自领 | | `recycle_remind_enabled` 自动回收前提醒 | tinyint | ✅ | 0/1;仅 auto_recycle_enabled=1 时可开 | | `remind_days` 提前提醒天数 | int | ⚠ | recycle_remind_enabled=1 时必填;>0 且 **< recycle_days**(原型硬校验) | | `rule_desc` 规则说明 | varchar | ✕ | 业务用途/兜底说明 | | BaseEntity | | | 创建人/时间等 | **适用对象子表**(apply_scope=2 对应部门专用时): | 表 | 说明 | |---|---| | `opportunity_pool_rule_dept` | 规则版本 → 适用部门多值;apply_scope=2 时必填至少一个 | - **无省/市/区负责市场表**(原型确认商机公海规则不按地理划分,与线索不同)。 - **无领取/持有上限字段**(原型只有「允许自由领取」开关)。 - `apply_scope=1(所有部门通用)` 时无适用对象,`is_default` 可设。 ### 二、版本状态机(对称票 06/07 版本化配置,非商机业务状态机) - **状态**:草稿(1) / 发布中(2) / 已停用(3)。 - **约束**:同一 `rule_code` 同时**仅一个草稿 + 仅一个发布中**。 - **部门覆盖唯一(产品拍板)**:一个部门同时只能被**一条发布中的规则**覆盖——发布一条 `apply_scope=2` 规则时,校验其 `opportunity_pool_rule_dept` 里的部门不与其它发布中规则的适用部门重叠;重叠则拒绝发布。保证「最低层级匹配」结果唯一。 - **发布**:草稿"保存并发布"→ 发布中;**原发布中版本自动转已停用**。 - **默认唯一**:发布新的所有部门通用默认规则 → 原默认自动取消默认。 - **编辑**:草稿直接编辑;发布中/已停用点编辑 → 基于该版本**生成新草稿**(已有草稿则进已有草稿)。 - **复制**:复制适用范围/回收/提醒配置 → **生成独立新规则**(新 rule_code,非后续版本)。 - **删除**:仅草稿可删(二次确认);发布中/已停用不可删/不可覆盖。 - **历史版本**:已停用作快照保留,不覆盖不删;历史提醒/回收/领取日志继续关联原版本。 - **版本快照规则**:商机执行规则时记录实际使用的规则版本;新版本发布不重算历史。 ### 三、规则匹配与执行语义 **匹配(哪套规则管这条商机)**: - 系统按商机所属部门匹配 `apply_scope=2 且部门命中` 的发布中规则; - 匹配不到部门专用 → 用**发布中的所有部门通用默认规则**兜底; - **优先级(产品拍板)**:以**最低层级规则**为准(最靠近该商机所属部门的那条),即部门专用 > 通用默认,多条部门专用取部门层级最低(最具体)者。**发布约束保证唯一**:一个部门同时只能被一条发布中的规则覆盖(见「二」),故按最低层级匹配后**必唯一命中一条**,无需再比较发布时间。 **R1 领取**(对齐票 04 E1/E2): - `allow_free_claim=1`:适用范围内且具备公海权限的销售可自领;领取成功 owner=领取人,记录领取时间/人/**规则版本**。 - `allow_free_claim=0`:不提供自领入口,只能管理员分配(票 04 E2)。 - **无每日/持有上限**(原型无此字段——推翻初稿)。 **R2 超时回收**(回填票 04「五」传出): - 仅 `auto_recycle_enabled=1` 生效。**回收锚点 = 最近一次有效跟进时间**(`last_valid_follow_time`),非 claim_time——**回填票 03 需新增该字段**(推翻初稿的 `recycle_deadline=claim_time+N`)。 - 「有效跟进」= 商机详情产生跟进记录更新 / 附件上传 / 业务字段编辑修订;仅浏览不算。每次有效跟进**重置计时**。 - 计算:连续未有效跟进天数 = now − last_valid_follow_time;≥ recycle_days → 自动回收。 - 回收动作:解除原 owner,商机转入对应公海 → **票 04 批量边 `executeRecycle`**(推进中→待领取)。 - **暂缓中(3) 不参与回收,且回收计时暂停(产品拍板)**:**暂缓**期间冻结回收计时——`executeRecycle` 只扫 `opp_status=2(推进中)`,不扫暂缓中(3)。落地口径:进入暂缓时记录已流逝时长(或以状态过滤即可,因 Job 只算推进中),**取消暂缓**回到推进中后计时按剩余天数续算,不从头重置(重置只发生在有效跟进)。⚠ 实现细节(记暂缓时点 vs 累计已过天数)留待建模,本票只定「暂缓冻结计时」语义。 **R3 回收前提醒**(对齐票 04 R3): - 仅 `recycle_remind_enabled=1` 生效;提醒时间 = 预计回收时间 − remind_days。 - 提醒对象 = 商机当前负责人;**异步通知,不改 `opp_status`**(票 02 通知异步)。 - remind_days < recycle_days(硬校验)。 **R4 手动转入公海(抛公海)**(对齐票 04 E3): - 仅 `allow_manual_pool=1` 时,向负责人开放"转入公海"入口。 - 抛公海只调整归属关系,不删客户/方案卡/跟进/附件/日志(票 04 E3)。 - **回哪个池**:见「四」——商机域**无独立池实体**,"公海"= owner 置空 + opp_status=1(待领取) 的商机集合,按规则适用范围可见。 ### 四、"商机公海"的物理含义(关键澄清,回填票 03) 原型**没有独立的池实体表**——"公海"是**逻辑视图**,不是 `lead_pool` 那样的实体: - **商机在公海 ⟺ `opp_status=1(待领取)` 且 owner 为空**(票 04 状态 1)。 - 谁能看/领某条公海商机 = 按**匹配到的公海规则适用范围**判定(部门专用→该部门;通用→全体)。 - **`pool_id` 的命运**(回填票 03):初稿把 `pool_id` 当"回收/抛公海回池锚点"——但商机域无池实体,**`pool_id` 应改为"来源规则/来源公海标记"或直接删除**。⚠ 决策: - **推定删除 `pool_id`**:公海归属由 `opp_status=1 + owner_dept_id + 匹配规则` 决定,不需要外键指向池实体。 - 抛公海/回收时:`owner=NULL, opp_status=1`,`owner_dept_id` **保留**(决定回哪个部门的公海可见范围)。 - → **回填票 03:删 `pool_id`,保留/强化 `owner_dept_id`(公海可见范围锚点)**。 ### 五、与 `crm-rule` 的边界(票 01 落地) - `opportunity_pool_rule*` 住 `crm-rule` 商机规则子域,与 `lead_pool*`(线索规则子域)**完全独立**,范式都不同(版本化规则 vs 池实体),无共表无共抽象。 - `crm-rule` 对上层零反依赖(票 01):规则表不知道 `opportunity` 实体,靠 `apply_scope`/部门 + `rule_code` 弱关联。 - **与票 06/07 同族**:`opportunity_pool_rule` 与 `opportunity_stage_template`(票 06)、方案卡模板(票 07)共享"版本化配置"范式(草稿/发布中/已停用 + code + version_no + 快照)——建议票 06 定稿时抽公共版本化基类/约定(本票只标记同族,不强抽)。 ## 传出决策 / 回填其他票 - **回填票 03(推翻初稿回填)**: - **新增 `last_valid_follow_time`**(datetime):最近一次有效跟进时间,回收计时锚点;跟进/附件/字段编辑时刷新(票 09 跟进/附件落地时联动)。 - **删 `recycle_deadline`**(初稿加的,锚点改为 last_valid_follow_time,回收由 Job 实时算 now−锚点,不预存 deadline)。 - **删 `pool_id`** 或改语义为"当前无意义":公海 = opp_status=1 逻辑视图,无池实体外键。保留 `owner_dept_id` 作公海可见范围锚点。 - 新增 `pool_rule_version_id`(bigint,⚠ 候选):领取/回收时记录实际执行的规则版本快照(原型「版本快照规则」);或落跟进日志,待票 09。 - **回填票 04**: - 批量边 `executeRecycle(cutoff)` 保留,但触发条件改为"last_valid_follow_time + recycle_days < now"(非 recycle_deadline)。 - 抛公海 E3 / 回收:`owner=NULL, opp_status=1, owner_dept_id 保留`;无 pool_id 目标。 - 抛公海入口受 `allow_manual_pool` 开关控制(规则驱动,非硬编码按钮)。 - **传出票 06**:抽"版本化配置"公共范式(草稿/发布中/已停用 + code + version_no)——本票、票 06、票 07 同族,票 06 定稿时收敛。 - **传出票 09**:`last_valid_follow_time` 刷新时机(跟进记录/附件/字段编辑)绑定跟进/附件表落地。 - **传出票 10**:商机公海列表视图(A3-3-1)= `opp_status=1` 查询 + 规则适用范围过滤;「我的关注」视图归票 10。 - **传出字典**:暂缓原因/关闭原因/商机来源 → 字典清单。 ## 待产品/原型核实(落地前须核) - ✅ **多规则命中优先级(已定)**:以最低层级规则为准;发布约束保证一个部门只被一条发布中规则覆盖,故命中唯一。 - ✅ **暂缓冻结回收计时(已定)**:暂缓期间计时暂停,`executeRecycle` 不扫暂缓中。 - ⚠ `recycle_days`/`remind_days` 数值样例(原型 30/7、45/7、20/5…)均为样例,非验收值。 - ⚠ `pool_rule_version_id` 快照落主表还是落日志(票 09 联动)。 ## 已核实事实(原型 A7-3-2-5 一手正文,存档 research-a7325-pool-remind-rules.md) - 版本化规则配置范式:rule_code + version_no + 草稿/发布中/已停用;同规则同时仅一草稿一发布中;发布使原发布中转停用。 - 适用范围 = 所有部门通用 / 对应部门专用;默认规则兜底(通用可设默认,发布中唯一)。 - 五配置项:allow_manual_pool / auto_recycle + recycle_days / allow_free_claim / recycle_remind + remind_days。 - 回收锚点 = 最近一次有效跟进时间;有效跟进 = 跟进记录/附件/字段编辑(浏览不算),每次重置。 - remind_days 硬校验 < recycle_days;未启用回收则提醒不生效。 - 编辑发布中/停用版本 → 生成新草稿;复制 → 独立新规则(新 code);仅草稿可删。 - 版本快照:商机执行记录实际规则版本,新版本不重算历史。 - 列表按版本维度展示(草稿/发布中/停用各占一行),查询=关键词(名/码/版本)+适用范围+状态。