7.6 KiB
作废态保留 owner 的状态机小改:残留触点核实与文档定稿
Type: grilling Status: resolved Blocked by:
Question
决策 01 已定:作废态保留 owner_user_id(反馈无效自动作废时不再清空),使销售能在「我的线索」看到自己作废的线索;名额 hold_limit / 可转商机目录按 status IN(3,4) 排除作废、不依赖 owner=null,已核实不受影响。
本 ticket 把这个「小改」的边界钉死——核实残留触点,产出改动清单(仍是 spec 层,不写实现):
LeadTransitionImpl#applyFeedback(line 211):改为 targetStatus=VOID 时不set(ownerUserId, null)。但ownerNameSnapshot/claimTime/recycleDeadline是否也保留?(recycleDeadline 关系回收计时,见下。)- 回收计时 N:作废保留 owner 后,回收 job /
LeadDeadlines是否会把「作废且 owner 非空」误当私海去续期或回收?作废态 N 应停(PRD §3.4:作废态 N 不跑,M 继续)。需确认保留 owner 不会让作废线索重新被回收扫描命中。 - 激活恢复(过期失效→失效前态):作废→失效→激活 恢复到作废态,现在 owner 已保留,
statusBeforeExpire恢复逻辑读 owner 是否仍自洽。 @DataScope:作废线索 owner=me 后,会不会改变它在「线索管理」等视图的部门天花板/owner 过滤判定,导致别处列表意外多/少数据。- 边 #15「作废自环换 owner」(管理员把作废线索重新分配给新销售):原逻辑是「作废态 owner 可能为空→写入新 owner」。保留 owner 后,重新分配=覆盖原 owner,语义是否仍正确(原持有人被顶替)。
- 文档:PRD §3.4 / 状态机边 #14 /
crm-lead/CONTEXT.md中「进入作废时清空 owner_user_id」全部要改。列出待改条目(PRD §3.4、边#14、§6.10 G1/G2、CONTEXT「线索作废」段)。 - 回归面:列出受影响的现有测试(
LeadTransitionImplTest的作废/反馈无效用例、ClaimLimitCheckerTest、可转商机目录测试)需要新增/改写的断言清单。
产出:一份「作废保留 owner」改动清单 + 文档待改条目 + 回归断言清单,作为 spec 的领域改动章节。这是 02(口径表)的前置——「我的线索」到底含哪些作废线索,取决于本 ticket 把归属语义钉死。
已定(逐步澄清)
① 作废 VOID 分支的字段取舍(applyFeedback line 211 四个 set(...,null))——用户认可推荐:
owner_user_id— 保留(本 ticket 核心)owner_name_snapshot— 保留(否则列表“归我却无名”)claim_time— 保留(列表显示领取时间;每日领取上限本就按 claim_time 计次,不受影响)recycle_deadline— 继续置 null(PRD §3.4:作废态 N 不跑;且回收扫描recycle_deadline<cutoff AND status IN(3,4)双保险,永不误扫)
扫描层安全性已核实(均 status-keyed,不看 owner):executeRecycle=status IN(3,4);executeExpire=status NOT IN(5,6)(作废本就会失效,M 继续,符 PRD);applyActivate 按 statusBeforeExpire 恢复、不碰 owner。→ 保留 owner 在扫描层安全。
② 边#15「作废自环换 owner」语义(applyAssignToUser VOID 分支,line 149-172)——用户选 甲:顶替。
- 管理员把作废线索改派给新销售 =
set(owner=新销售)覆盖原持有人,线索离开原销售的「我的线索」、进新销售的。符合「当前归属只一人」。 - 现有分配逻辑一行不动(本就是 set 新 owner),无需额外守卫/提示。
③ 名额连带效应(已核实确认):反馈无效作废、owner 仍=小张的线索,不占 小张 hold_limit(只数 status IN(3,4),作废是7)——即用户最初要的「作废不算持有上限、但归属还在」。
④ @DataScope 连带可见性(DataScopeInterceptor)——用户选 甲:可以。
- 数据范围=本人档的用户被注入
owner_user_id=我;改前作废 owner=null 天然被排除,改后 owner=我 会通过过滤,可能出现在该用户能访问的其它视图(如线索管理)。 - 定为合理:“我的作废线索”在我数据范围内任何视图可见,不在视图口径层为作废设限。(部门档/全部可见用户不受影响:部门档按 dept_id、作废 dept_id 不变;全部可见不注入。)
- 对 02 口径表的含义:各视图作废计数 = 各自自然过滤 + status=7,不额外设限。
待改文档与回归面(清单,无需拍板,实现 session 执行)
文档待改(把“进入作废时清空 owner”改为“保留 owner,N 停、清 recycle_deadline”):
.scratch/clue-module/线索业务-PRD.md:line 100(状态表行 #14 “清空 owner_user_id”→“保留 owner;N 停、清 recycle_deadline”)、line 101(行 #15 写新 owner→“覆盖原 owner(顶替)”)、line 126 图“线索作废(清空 owner)”、line 136 §3.4「归属:进入作废时清空 owner_user_id”、G1(“我的线索里作废 owner 必=我”——结论不变,但理由从“重新分派才归我”变为“作废保留原 owner”)。crm-lead/CONTEXT.md:line 12「领取人」段(删“、进入作废时清空”)、line 56「线索作废」段(删“进入时清空 owner_user_id”,改为“保留 owner;N 停、清 recycle_deadline”)。- 注:释放(PRD line 354)/ 回收 清 owner 不动——那是退回公海,非作废。
回归断言(新增/改写):
LeadTransitionImplTest:反馈=无效作废后断言owner_user_id / owner_name_snapshot / claim_time保留、recycle_deadline= null(原用例若断言 owner=null 需反转);作废自环分配断言 owner 被新销售覆盖。ClaimLimitCheckerTest:新增“owner=我且 status=7 的线索不计入 hold_limit”用例(防回归)。LeadViewQueryImplTest:“我的线索”含 owner=我的作废线索;countStats 作废计数(待 03 定字段后写)。- 可转商机目录测试:确认 owner=我的作废线索不入可转商机目录(status IN(3,4) 卡住)。
Answer
结论(在路线上 resolved):作废态保留 owner 的状态机小改馆括已完成,结论比预想更小——无回收/激活/名额副作用,只需一处代码改动 + 两份文档更新 + 一批回归断言。
七个点的决策(与用户逐条澄清):
- 字段取舍(
applyFeedbackVOID 分支):owner_user_id/owner_name_snapshot/claim_time保留;recycle_deadline继续置 null。 - 回收扫描:安全(status-keyed,不看 owner)。
- 激活恢复:自洽(按
statusBeforeExpire恢复、不碰 owner)。 @DataScope连带可见性:选甲——“我的作废线索”在我数据范围内任何视图可见,不在视图口径层为作废设限。- 边 #15 作废自环换 owner:选甲——分配 = 覆盖原 owner(顶替);现有分配逻辑一行不动。
- 文档待改(已钉行号):PRD line 100/101/126/136 + G1;CONTEXT line 12/56。
- 回归断言:
LeadTransitionImplTest/ClaimLimitCheckerTest/LeadViewQueryImplTest/ 可转商机目录测试;具体断言见上文。
对下游 ticket 的预填:
- 02(口径表):各视图作废计数 = 各自自然过滤 + status=7,不额外设限(第 4 点预填)。「我的线索」含 owner=我的作废(第 1 点预填)。
- 03(DTO):字段形态仍等 02 口径表定稿。