Files
git-learn/skill-workbench/generated-skills/skills/value-dig/assets/深度模板/改造方案模板.md
T
zhuyongxin fddefab0c9 Add value-scan and value-dig skills for reverse-engineering value points
- value-scan: read-only breadth inventory of mechanisms in delivered code,

  stopping at the human selection gate

- value-dig: depth write-up of chosen points (feature list, design review,

  refactor plan) with templates and mechanical checkers

- Add skill-workbench design doc for the pair
2026-09-18 18:23:23 +08:00

9.6 KiB
Raw Blame History

⟨主题⟩ · 改造方案

背景:现状问题登记在本文第 0 节(缺陷唯一归属地);复盘视角的"承接不住"见《⟨主题⟩-设计思路与取舍.md》第 5 节 目标:⟨把「X」从一条路的设计,变成覆盖全部写接口的事实⟩ 边界:⟨不改省侧协议、不引入分布式事务(改造点全在本服务内);DDL 只列关键字段,完整建表脚本另出⟩ 与其它方案的关系:⟨一致性异常台账复用《⟨其它⟩-改造方案.md》的 ⟨表名⟩,不重复建表,只新增 ⟨列/取值⟩⟩ 依据:全部改造点均对应代码中已核实的缺陷,非推测 取材:深挖链路时发现的结构性缺口,按 value-dig SKILL 的「机制模式库」(结构性限制 → 可引入机制)比对出改造方向;每个缺陷追问"能否从补漏上升到加机制/重构" 代码讲解要求(必读):本文交付标准是"照着能讲代码"——① §1 先给改造前链路骨架(整体调用关系,用伪代码写清"谁调谁、每一步做了什么",可标类名/方法名,不写文件路径与行号);② 每个改造点必带「关键片段」(伪代码 / SQL,只示形状、不贴源码)。密度基准:docs/order-改造方案.md 产出门槛:缺口中至少存在一个②加机制 / ③重构档的改造点(更好设计、重构、引入中间件级)才立本文档;全是①档补漏(加缓存/加判断/加隔离/改配置)的不产出——在设计复盘"重做改什么"小节记录即可


0. 现状问题登记(缺陷唯一归属地)

功能点清单与设计复盘不承载缺陷表;深挖中发现的问题全部登记在此,后文逐条消化。

严重度:🔴 资金/数据错误 · 🟠 静默失败或重复调用 · 🟡 卫生与可维护性

# 缺陷 证据 后果 严重度
1 ⟨缺陷⟩ ⟨可核对的事实:行为 / 字段 / 日志⟩ ⟨后果⟩ 🔴
2 ⟨…⟩ 🟠
3 ⟨…⟩ 🟡

归纳:这些不是孤立的 bug,而是 ⟨N⟩ 处结构性缺口:

  1. ⟨缺口一⟩ —— ⟨…⟩;
  2. ⟨缺口二⟩ —— ⟨…⟩;
  3. ⟨缺口三⟩ —— ⟨…⟩。

1. 总体思路

改造前链路骨架(先定位"改的是链路的哪一段"——用伪代码写清谁调谁、每一步做了什么):

⟨入口类#方法⟩()
  → ⟨A类#方法⟩()          // 这一步做了什么(对应缺陷 #1)
  → ⟨B类#方法⟩()
  → ⟨C类#方法⟩()          // 对应缺陷 #3

所以改造是做 N 件事,而不是调参数:

  1. ⟨把一个点的分级 → 铺成一张网⟩
  2. ⟨把「不确定」从日志提升为一等状态⟩
  3. ⟨把状态推进的时机对齐到权威事实⟩
flowchart TB
    subgraph BEFORE["改造前"]
        B1["⟨…⟩"] --> B2["⟨…⟩"]
        B3["⟨…⟩"] --> B4["⟨…⟩"]
    end
    subgraph AFTER["改造后"]
        A1["⟨…⟩"] --> A2["⟨…⟩"]
        A2 --> A3["⟨…⟩"]
        A4["⟨…⟩"] --> A5["⟨…⟩"]
    end

2. 阶段一 · ⟨阶段主题:先说止血/可见⟩

成本最低、收益最大,优先做。⟨N⟩ 处改动都只动本服务内部。

2.1 ⟨改造点名⟩(P0,最重要)

  • 现状:⟨…⟩(对应第 0 节缺陷 #⟨N⟩)。
  • 后果(真金白银):⟨…⟩ 这违反了 ⟨不变量一⟩。
  • 改造:⟨…⟩

关键片段 · ⟨片段名⟩(伪代码 / SQL,只示形状)

⟨改造后的语句或结构;与改造前的旧写法形成对照⟩
⟨对象⟩ ⟨写/读⟩ 可逆性 处置
⟨接口/动作⟩ 写 ⟨拒绝可逆、超时不可逆⟩ ⟨…⟩
  • 注意:⟨切换后必须同步补"超时不可逆"的判断,否则只是把"归档超时 → 退款"换成"归档超时 → 抛异常 → 同样退款",问题原地不动⟩。
flowchart TD
    A["⟨入口⟩"] --> B{"⟨判断⟩"}
    B -->|"改造后"| C{"分类"}
    B -->|"现状"| Z["⟨旧行为⟩"]
    C -->|"⟨可逆⟩"| D["⟨处置⟩"]
    C -->|"⟨不确定⟩"| E["⟨处置⟩"]

2.⟨N⟩ ⟨改造点名⟩

  • 现状:⟨…⟩(对应第 0 节缺陷 #⟨N⟩)
  • 改造:⟨…⟩ 原则:⟨异常类型就是后果分类的载体,不能在中间被抹平⟩。
  • 验收:⟨人为造一次 ⟨场景⟩,应出现 ⟨可观测结果⟩⟩。

关键片段 · ⟨片段名⟩

⟨改造后的分支形状,只示形状⟩

2.⟨N⟩ 阶段一验收标准

指标 目标
⟨…⟩ ⟨100% 不产生 ⟨错误动作⟩,转 ⟨正确处置⟩⟩
⟨人为造 X⟩ ⟨出现可观测的 ⟨证据⟩⟩

3. 阶段二 · ⟨阶段主题:再说可靠/对称/一等状态⟩

阶段一保证"不再做错",阶段二保证"⟨挂起能被收走⟩"。

3.1 ⟨幂等键改造⟩

  • 现状:⟨没有幂等键 → 可被重复执行;MQ maxRetry=3 在异常路径上会重复调用外部⟩(对应缺陷 #⟨N⟩)
  • 改造:⟨唯一索引 · 冲突当幂等命中 · 语义:"同一 X + 同一动作 = 只允许一次对外调用"⟩
  • 迁移:⟨先查存量重复,治理后再加索引⟩

关键片段 · 索引 + 冲突即命中

ALTER TABLE ⟨表名⟩ ADD UNIQUE KEY ⟨uk名⟩ (⟨列⟩, ⟨列⟩);
try { ⟨对外调用⟩; }
catch (DuplicateKeyException e) { return; }   // 已执行过 → 直接返回,不再调外部

3.2 ⟨挂起态 + 巡检⟩

  • 现状:⟨…⟩(对应缺陷 #⟨N⟩)
  • 改造:
    1. ⟨新增挂起态⟩,与"失败""成功"并列,不占用失败的语义;
    2. 巡检任务(⟨XXL-Job⟩)按"距离挂起时长"分级:⟨<1h 自动重放一次 / 1–24h 告警 / >24h 人工队列⟩;
    3. 重放走同一套分级链路(不新开代码路径)。

关键片段 · ⟨片段名⟩

⟨挂起态写入 / 巡检取单的形状⟩
flowchart TD
    A["⟨不确定⟩"] --> B["⟨挂起 + 台账⟩"]
    B --> C["告警"]
    B --> D["巡检任务"]
    D --> E{"挂起时长"}
    E -->|"⟨短⟩"| F["自动重放"]
    E -->|"⟨中⟩"| G["升级告警"]
    E -->|"⟨长⟩"| H["人工队列"]

关键设计:重放不是"再调一次接口",而是"重新走一遍分级"。 因为对方的状态可能已经变了,重放必须能得出"成功"这个结论。

3.⟨N⟩ ⟨改造点名⟩

⟨anomaly_type⟩ 取值 触发场景 处置方向
⟨…⟩
  • 收益:⟨两侧的失败进同一张台账、走同一套告警和处理台——运维只需要看一个地方。这是"复用"而不是"新建"的价值。⟩

3.⟨N⟩ 阶段二验收标准

指标 目标
⟨重复调用外部⟩ 0 次
⟨挂起单⟩ 100% 台账可见 + 100% 被巡检捞到

4. 阶段三 · ⟨阶段主题:最后收口卫生问题⟩

# 改什么 现状证据(缺陷 #⟨N⟩) 成本
1 ⟨…⟩ ⟨可核对的事实⟩ 低
2 ⟨…⟩ 低

⟨某条不是文档工作,是防错工作⟩:⟨文档漂移会让后来人按错误的图改代码,成本远高于改文档。⟩


5. 实施顺序与成本收益

阶段 内容 成本 解决的根问题 关键收益
一 ⟨…⟩ 低 ⟨…⟩ 不再出错
二 ⟨…⟩ 中 ⟨…⟩ 不确定可运营
三 ⟨…⟩ 低 卫生与可维护性 可观测与可维护

顺序逻辑:先修会花错钱的(阶段一),再修会重复调用外部系统 / 卡住看不见的(阶段二),最后才是卫生(阶段三)。


6. 迁移与灰度

  1. ⟨逐项切⟩:先切风险最高、问题最实的 ⟨X⟩,观察一周无异常再切 ⟨Y⟩;每次切换只改一个调用点,便于回滚。
  2. ⟨新增状态先"只记录不流转"⟩:先写台账 + 告警观察一周,确认没有误报,再打开自动重放。
  3. ⟨索引先查存量⟩:先排查存量重复;加索引后观测冲突命中次数——这个数就是"原设计漏掉的重复调用次数"。
  4. 回滚:全部改造以"新增状态 + 新增列 + 开关"方式落地,回滚只需关开关/停调度,不动存量数据。

7. 改造后:⟨N⟩ 条不变量由谁保证

不变量 改造前 改造后
⟨不变量一⟩ ⟨只有一条路成立;某路径会被错退⟩ ⟨全部写类接口统一分类⟩
⟨不变量二⟩ ⟨只有一行日志,库里无痕⟩ ⟨挂起态 + 台账 + 巡检 + 重放⟩
⟨不变量三⟩ ⟨实际只有两态(超时被降级抹平)⟩ ⟨异常类型不被中间层改写⟩

附:与《⟨其它⟩-改造方案.md》的关系

项 ⟨其它侧⟩ ⟨本文⟩
⟨一致性异常台账⟩ 建 ⟨表名⟩ 复用,只加取值
⟨Outbox⟩ 建 ⟨表名⟩ 复用同表,⟨biz_type⟩ 区分
⟨幂等⟩ ⟨…⟩ ⟨…⟩

两边的根因是同一个:⟨设计了机制,但没有为"需要人介入"这个信号建自动出口⟩。所以两套改造共用一套台账与告警,是结构上的必然,而不是为了省事。