From 01372d682cc3460062dd130db444723e52e86824 Mon Sep 17 00:00:00 2001 From: luoweijian <1329394916@qq.com> Date: Tue, 25 Aug 2026 09:04:05 +0800 Subject: [PATCH] =?UTF-8?q?docs(opportunity):=20=E7=A5=A8=2005=20spec=20?= =?UTF-8?q?=E5=9B=9E=E5=A1=AB=EF=BC=88PRD=20=C2=A77.10=20=E5=B9=82?= =?UTF-8?q?=E7=AD=89=E6=89=B9=E6=AC=A1=E9=94=AE=E5=85=B7=E4=BD=93=E5=8C=96?= =?UTF-8?q?=20+=20crm-rule=20CONTEXT=20=E5=8D=87=E7=BA=A7=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E8=A7=84=E5=88=99=E5=9F=9F/=E5=95=86=E6=9C=BA?= =?UTF-8?q?=E8=A7=84=E5=88=99=E5=AD=90=E5=9F=9F=E4=B8=89=E8=AF=8D=E6=B1=87?= =?UTF-8?q?=20+=20opportunity=20CONTEXT=20=E8=90=BD=E5=9C=B0=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E4=B8=8E=E4=B8=89=E9=A1=B9=E5=B7=B2=E7=9F=A5=E7=BC=BA?= =?UTF-8?q?=E5=8F=A3=E7=99=BB=E8=AE=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../opportunity-module/商机业务-PRD.md | 2 +- crm-opportunity/CONTEXT.md | 4 ++-- crm-rule/CONTEXT.md | 22 +++++++++++++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/.scratch/opportunity-module/商机业务-PRD.md b/.scratch/opportunity-module/商机业务-PRD.md index 0a4664a..ba91d6d 100644 --- a/.scratch/opportunity-module/商机业务-PRD.md +++ b/.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 功能就绪时接入(不重建表)。 diff --git a/crm-opportunity/CONTEXT.md b/crm-opportunity/CONTEXT.md index 128eff9..a909230 100644 --- a/crm-opportunity/CONTEXT.md +++ b/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 已完成**(标题/首段升级 + 商机规则子域三词汇:商机公海规则/规则版本状态机/公海规则匹配引擎;线索子域内容不动)。 diff --git a/crm-rule/CONTEXT.md b/crm-rule/CONTEXT.md index 8141263..822f8af 100644 --- a/crm-rule/CONTEXT.md +++ b/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)