Browse Source

docs(opportunity): 票 05 spec 回填(PRD §7.10 幂等批次键具体化 + crm-rule CONTEXT 升级通用规则域/商机规则子域三词汇 + opportunity CONTEXT 落地记录与三项已知缺口登记)

master
luoweijian 2 weeks ago
parent
commit
01372d682c
  1. 2
      .scratch/opportunity-module/商机业务-PRD.md
  2. 4
      crm-opportunity/CONTEXT.md
  3. 22
      crm-rule/CONTEXT.md

2
.scratch/opportunity-module/商机业务-PRD.md

@ -587,7 +587,7 @@ crm-opportunity → crm-rule(阶段模板 / 方案卡模板 / 公海规则
| `payload_json` | text | 提醒上下文(预计回收日/`recycle_days`/已无跟进天数等,**无「剩余天数」伪状态**) |
| `notice_status` | tinyint | 待发0 / 已发1 / 已失效2 |
- **幂等**:`UNIQUE(opportunity_id, notice_type, 批次键)` 防重复堆积;回收 Job upsert 待发记录
- **幂等**:`UNIQUE(opportunity_id, notice_type, plan_notify_time)` 防重复堆积(批次键 = 应发时刻,票 05 落地定案);回收 Job upsert 待发记录(同一计划时刻不重写,锚点刷新后新计划时刻产生新记录)
- **补发**:平台通知能力就绪后,另起消费者扫 `notice_status=待发` 发出、置「已发」。
- **失效**:提醒发出前商机被回收/领取/暂缓/关闭 → 对应待发记录置「已失效」(不再补发过期提醒)。
- 本期只 `RECYCLE_REMIND` 真实写入;`PAUSE_EXPIRE`/`URGE` 随对应 spin-out 功能就绪时接入(不重建表)。

4
crm-opportunity/CONTEXT.md

@ -176,5 +176,5 @@ _Avoid_: 浏览(不算有效跟进)、编辑主表字段(不计)、上
- 「移交」按钮原型位置、「取消暂缓/重启」独立页存否 —— 见 `issues/01` 的 To-verify,以产品口径为准。
- ~~商机主表字段~~ **票 03 已落地**(`Opportunity` 实体 + `OpportunityMapper`,三簇 + Amendment 1 + 乐观锁 version);子表(团队成员 / 方案卡 / 现场勘察 / 跟进 / 附件 / 操作日志)字段仍归后续票(07/08/09)。
- ~~状态机迁移图~~ **票 04 已落地**(`OpportunityTransition` + sealed `OpportunityTransitionCmd` 九边(E1-E9,每带 allowedFromStatuses,无 owner guard)+ `executeRecycle` 批量回收(E10);CAS 两级口径:守卫前置 STATUS_NOT_ALLOWED / 0 行 CAS_FAIL,多起始态边(E6/E9)锚合法起始态集合,E9 另锚 owner;E5 锚点顺推纯函数;`OpportunityStatusHistory` 快照表 + Recorder;`OpportunityConvertPort` 三件套 inbound 端口(幂等含并发复查终态补丁));E9 team 表同步维护待 opportunity_team 结构定稿后接线(javadoc 注明);E7 重启不刷回收锚点为规格空白(PRD §3.2 注记 20260824,待产品拍板)。
- 商机公海规则已定(票 05,版本化配置 `opportunity_pool_rule`,原型 A7-3-2-5);四视图查询与「我的关注」表(票 10)。
- `crm-rule` 从「线索规则」升级为「通用业务规则域」的 CONTEXT.md 改写(本决策副作用)。
- ~~商机公海规则~~ **票 05 已落地**(`OpportunityMaintenanceJob` + 待发通知表):crm-rule 侧实体/版本状态机服务/控制器/菜单种子 + 快照式匹配引擎 `OpportunityPoolRuleMatcher`(见 crm-rule CONTEXT 商机规则子域);本模块侧 `executeRecycle` 演进为 **ids 集合语义**(选择策略归 Job——各部门 recycle_days 不同无法单 cutoff 表达,迁移机制归状态机,按 id+推进中 CAS 复查静默跳过并发变更行)、`OpportunityMaintenanceJob` 单 `@Scheduled`(cron 占位符 `crm.opportunity.maintenance-cron` 默认每日 3 点)**先提醒后回收**串行(ADR-0019 对齐)+ 回收后待发提醒置已失效;`OpportunityPendingNotice` 实体 + 常量(UNIQUE 批次键 = plan_notify_time,幂等口径见 PRD §7.10 回填)。**已知缺口(code-review 20260824 登记)**:① §7.10 失效语义仅落地「回收」来源——领取(E1)/暂缓(E4/E5)/关闭(E6/E9)路径的置失效埋点待通知消费者票统一补(消费者本期 spin-out,误置「待发」无人消费、实际影响为零);② `allow_free_claim`/`allow_manual_pool` 本期仅可配置未生效,消费点随领取/抛公海入口票(票 10/11)接线;③ `invalidatePendingReminds` 按本轮候选全集近似置失效(含 CAS 静默跳过行),已声明由消费者补发时校验商机状态兜底。四视图查询与「我的关注」表(票 10)仍待后续
- ~~`crm-rule` 从「线索规则」升级为「通用业务规则域」的 CONTEXT.md 改写~~ **票 05 已完成**(标题/首段升级 + 商机规则子域三词汇:商机公海规则/规则版本状态机/公海规则匹配引擎;线索子域内容不动)。

22
crm-rule/CONTEXT.md

@ -1,6 +1,10 @@
# 线索规则(crm-rule)
# 业务规则(crm-rule)
线索公海池的配置域:公海池实体(归属部门 + 省/市/区)、人员(负责人 / 协作人 / 成员)、领取规则、超时回收 / 失效 / 领取上限配置。依赖方向单向 `crm-rule → (crm-auth / crm-dict)`,**不得反向依赖 `crm-lead`**——公海池不知道线索存在。公海池表复用 `lead` 数据范围模块(决策 [K])。
多域规则中心(票 01):线索规则子域(公海池配置 + 行政区划)与商机规则子域(公海规则、后续阶段模板/方案卡模板/有效跟进规则,原型 A7-3-2)分域共住本模块,**完全独立无共表无共抽象**(范式都不同:池实体 vs 版本化规则配置)。依赖方向单向 `crm-rule → (crm-auth / crm-dict)`,**不得反向依赖 crm-lead / crm-opportunity**——规则表不知道线索/商机实体存在。
## 线索规则子域
线索公海池的配置域:公海池实体(归属部门 + 省/市/区)、人员(负责人 / 协作人 / 成员)、领取规则、超时回收 / 失效 / 领取上限配置。公海池表复用 `lead` 数据范围模块(决策 [K])。
## Language
@ -55,3 +59,17 @@ _Avoid_: 占用检查服务、lead 查询接口(要点是「crm-rule 声明契
**池批量删除**:
`deletePoolBatch` 一行委派 crm-base `BatchRunner.run(ids, self::deletePool, PoolBatchFailItem::bizOf, PoolBatchFailItem::unknownOf)`(ADR-0028)——非原子、逐条经 self 代理走独立事务、部分成功;失败项 `PoolBatchFailItem`(poolId + `PoolBatchFailReason` + message)与 code→reason 翻译、兜底文案(「删除失败」)由本域自持(ADR-0023 D5)。曾内联的同构编排(与 crm-lead 旧 runBatch 逐字重复)已删除——批量编排协议的家在 crm-base。
_Avoid_: 批量删除服务、池批处理(要点是「编排委派 BatchRunner + 失败语义留在域内」)
## 商机规则子域(票 05 起)
**商机公海规则**:
商机公海/回收/领取/提醒的**版本化规则配置** `opportunity_pool_rule`(票 05 原型 A7-3-2-5):同一 `rule_code` 多版本每版本一行,范式 = 草稿/发布中/已停用 + `version_no`(与票 06 阶段模板、票 07 方案卡模板同族 V-CONFIG),**不是** `lead_pool` 那种「一部门一池」实体(无省/市/区地理维度、无领取/持有上限)。五配置项:`allow_manual_pool` / `auto_recycle_enabled`+`recycle_days` / `allow_free_claim` / `recycle_remind_enabled`+`remind_days`(提醒依赖回收启用,`remind_days < recycle_days` 硬校验)。适用范围两档所有部门通用可设默认)/ 对应部门专用适用部门多值子表 `opportunity_pool_rule_dept`)。
_Avoid_: 商机公海池(无池实体)、商机池、线索池
**规则版本状态机**:
`IOpportunityPoolRuleService` 承担的版本生命周期约束(票 05「二」):同 `rule_code` 仅一草稿一发布中;发布使原发布中转停用、原发布中默认自动取消默认(默认唯一是自动顶替非拒绝);发布时校验**部门覆盖唯一**(一个部门只被一条发布中规则覆盖,重叠拒发 64012)——保证匹配「最低层级必唯一命中」;编辑发布中/停用版本→生成新草稿(版本号 minor 顺延 V1.0→V1.1,同 code 已有草稿则拒 64011);复制→独立新规则(新 `rule_code` + V1.0 草稿);仅草稿可删。版本号/编码系统生成只读。
_Avoid_: 商机状态机(那是 opp_status 归属流转轴,两回事)、直线版本号(minor 顺延非末尾+1)
**公海规则匹配引擎**:
`OpportunityPoolRuleMatcher`(快照式 API:`loadPublished()` 一次加载全部发布中规则 + 部门子表,`match(ownerDeptId)` 纯内存匹配):部门专用(apply_scope=2 命中)优先 → 通用默认(apply_scope=1 且 is_default=1)兜底 → **非默认通用不兜底**(null = 无规则不动作)。公海规则**实时匹配不锁版本**(与阶段模板锁版相反,PRD §5.4)——每次 Job 扫描重载快照。供商机侧维护 Job 批量扫描,避免逐商机查库。
_Avoid_: 锁版本(公海规则实时)、按查看人部门匹配(锚点是商机自身 owner_dept_id)

Loading…
Cancel
Save