--- name: add-req description: 增量需求入口——初始 Plan 完结后追加 / 修改需求时运行。基于 lib/req-ledger.mjs 内容哈希台账识别新增 / 变更的 REQ 卡片与 FE 行,只对增量做 A3-delta(写 V_n migration + 同步 docs/03,绝不改 V1)+ A5-delta(补 docs/05 端点 / docs/02 顺序 / docs/08 模块行),并作废变更单元已有的 req-done/milestone tag,使 coding.mjs Router 只重跑增量、不必整仓重跑。 user-invocable: true allowed-tools: Read Write Edit Grep Glob AskUserQuestion Bash(node *) Bash(git *) Bash(ls *) Bash(mkdir *) --- **所有输出必须使用中文。** # add-req — 增量需求识别与生成 用于**初始 Plan(A0~A5)已完结**之后,往项目里**追加新需求**或**修改已有需求**。不重跑整条 Plan,只处理增量;产出与 A1/A3/A5 完全一致,交由 `coding.mjs` Router 增量编码。 > 用法约定:先**人工**在 `docs/01-需求清单/` 里把新 REQ 卡片写好(真实业务内容,同 A1 填法)或修改已有卡片,再运行 `/erp-workflow:add-req`。本 skill 负责「识别 + 下游生成 + 作废过期完成标记」,不替你写业务需求本身。 `` = 项目根(含 `docs/`、`config-vars.yaml`、`sql/`、`.git`)。`${CLAUDE_PLUGIN_ROOT}` = 插件根。 ## 前置:Plan 必须已完结 用 `Read` 读 `docs/08-模块任务管理.md § 一`。若 § 一存在任一 `- [ ]` 未勾子项 → 初始 Plan 未完结,**停下**并提示: ``` [add-req] ⛔ 初始 Plan(A0~A5)尚未完结,增量入口暂不可用。 请先运行 /erp-workflow:plan-start 完成初始规划,再用 /add-req 追加需求。 [ERP-HALT] 初始 Plan 未完结,已停下。 ``` ## 步骤 0:台账基线(首次启用 / 老项目迁移) ``` node ${CLAUDE_PLUGIN_ROOT}/lib/req-ledger.mjs scan ``` 解析输出 JSON 的 `ledgerExists`: - `false`(项目还没有 `.req-ledger.json`)→ 这是首次启用增量台账。**先建基线并提交**: ``` node ${CLAUDE_PLUGIN_ROOT}/lib/req-ledger.mjs commit git -C add .req-ledger.json git -C commit -m "chore(req-ledger): 建立需求台账基线" ``` (`.req-ledger.json` 必须 git 提交——否则它是未提交的脏文件,后续 `coding-start` 起 coding.mjs 时会撞「工作树必须干净」前置。)然后打印并**停下**: ``` [add-req] 已为现有 个需求单元建立台账基线(.req-ledger.json)。 首次基线无法区分存量与新增,故本次不做增量生成。 请在 docs/01 追加 / 修改需求后,再次运行 /erp-workflow:add-req。 [ERP-HALT] 基线已建立,等待人工追加需求。 ``` (理由:首跑若把存量全当新增,会重复生成已有的 docs/03/05 工件并误重跑整仓。基线建立后,后续改动才能被准确 diff。) - `true` → 直接用本次 scan 的输出进入步骤 1 解析(不再重跑 scan)。 ## 步骤 1:检测增量 用步骤 0 已得到的 scan 输出解析 `new[]` / `changed[]` / `removed[]`(每项 `{id, kind}`,kind = `req` 后端卡片 / `fe` 前端功能行)。 - `new` 与 `changed` 均为空 → 打印 `[add-req] 无新增 / 变更需求,无需处理。[ERP-HALT]` **停下**(不提交台账)。 - `removed` 非空 → **仅提示、不自动删**:打印 `检测到台账登记但 docs 已移除的单元:<列出>。下线需求请人工同步 docs/02/03/05 并删除对应 tag,本 skill 不自动执行删除。` 然后继续处理 new/changed(removed 不写回台账,留待人工,下次仍会提示)。 ## 步骤 2:校验新增 / 变更 REQ 卡真实数据(仅 kind=req) 对 `new` ∪ `changed` 里 `kind=req` 的每个 id(卡片路径 `docs/01-需求清单//.md`):`Read` + `Grep` 校验**无 `{{` 残留、无 `【人工填写`**(同 A1 E.1)。命中缺口 → 打印卡片路径 + 缺口行,用 `AskUserQuestion` 引导用户补齐后重检,直到全部为真实数据。 (`kind=fe` 的增量行来自 docs/08 §三 推导,不在此校验。) ## 步骤 3:A3-delta — schema 增量(仅当新增/变更 REQ 影响数据模型) 对 `new`/`changed` 的 REQ 卡片,判断是否需要**新表**或**给已有表加列**(依据卡片业务 + `依赖表`): 1. **写增量 migration(绝不改 V1 或任何已存在 V_n)**: - `ls sql/migrations/V*.sql` 取当前最大版本号 `n`,新文件 `sql/migrations/V__.sql`(如 `V2__add_order_refund.sql`)。 - 新表 → `CREATE TABLE`;给已有表加列 → `ALTER TABLE ... ADD COLUMN`。**追加式**,套用与 A3/A4 相同的命名规范、匈牙利列前缀(`i/s/t/b/d`)、标准列约定(主表 15 列 / 从表 12 列 / 基础 11 列)与 DDL 默认值翻译规则(见 `CLAUDE.md` Schema 演化规约 + db-init 约定)。 2. **同步 docs/03**:参照 `${CLAUDE_PLUGIN_ROOT}/skills/plan/db-design-gen/templates/docs-03-table-template.md`,新表追加表小节 / 已有表小节增列,保持 docs/03 为 schema SSoT。 3. **回填卡片**:把该 REQ 卡片 `依赖表:` 的 `TBD` / 占位 `Edit` 成实际表名。 4. **增量 DDL 校验(fail-closed)**:写完 V_n + 同步 docs/03 后,对**全部 migration 的累积并集**校验 docs/03 一致: ``` node ${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs docs/03-数据库设计文档.md sql/migrations/V*.sql ``` (validate-ddl 已支持多文件:CREATE TABLE + 各 V_n 的 `ALTER ... ADD` 并集 ↔ docs/03 累积 SSoT 做 4 维比对。) - 退出码 `0` → 一致,继续。 - 退出码 `1` → docs/03 与 migration 并集分叉(stderr 有 diff 明细):**就地修正**——通常是 docs/03 表小节/列与 V_n 不一致,或 V_n 漏写某列的 ALTER。修正后重跑校验,直到 `0`。**绝不带分叉进入步骤 4**(schema 不一致会让下游 docs/05/编码全线偏)。 - 仅 ADD 追加式——校验器对 `MODIFY/CHANGE/DROP/RENAME` 子句**硬拒(exit 1)**,不静默放行。改类型/重命名/删列不在 add-req 覆盖范围:需人工写 V_n 并人工核对 docs/03 一致性。 > **不在此 apply 到数据库**:新 schema 由 Coding 阶段冷起栈时 Flyway 自动 apply 全部 `V*.sql`;本步只做静态 DDL↔docs/03 一致性校验,运行时 apply 与 Seed 真跑由 Coding 阶段兜底。 ## 步骤 4:A5-delta — 下游文档增量(每个新增 REQ) 对 `new` 的 `kind=req`: 1. **docs/05 端点**:参照 `${CLAUDE_PLUGIN_ROOT}/skills/plan/downstream-gen/templates/docs-05-endpoint-template.md` 追加该 REQ 的接口小节(对齐 docs/06 实现策略的分页/鉴权/响应包络/错误码风格)。 2. **docs/02 顺序**:把该 REQ 按依赖拓扑插入 `docs/02-开发计划.md` 顺序清单,**同模块 REQ 保持连续**;环依赖按启发式破环并在 `note` 注明。 3. **回填卡片**:`依赖接口:` 的 `TBD` / 占位 `Edit` 成实际 endpoint。 4. **docs/08 §二**: - 该 REQ 属**新模块** → 参照 `${CLAUDE_PLUGIN_ROOT}/skills/plan/downstream-gen/templates/docs-08-module-row-template.md` 追加模块 bullet,`里程碑:` 字段填 `—`。 - 属**已有模块** → 在该模块 bullet 下追加该 REQ 子项行。 对 `changed` 的 `kind=req`:若接口/字段语义变化,相应 `Edit` docs/05 端点小节、按需调整 docs/02(一般顺序不变)。 **前端增量**:若新增需求带来新前端功能,`Glob` `prototype/**/*.html` 确认有原型后,用 `AskUserQuestion` 与用户确认是否新增 FE 行;新增则在 `docs/08 §三` 「功能:」下追加 ` - [ ] FE-NN <功能名>`(NN 取现有最大值+1)。 ## 步骤 5:作废变更单元的完成标记(关键——否则 Router 会跳过) 对每个 `changed` 单元(`new` 单元无 tag,跳过): - **kind=req**: - `git -C tag -l "req-done/"` 存在 → `git -C tag -d req-done/`。 - 该 REQ 所属后端模块若已打里程碑(`git -C tag -l "milestone/"` 存在)→ `git -C tag -d milestone/`,并 `Edit` `docs/08 §二` 该模块 `里程碑:` 字段从 `milestone/` 复位为 `—`。(否则 Router 判定模块 done 而整模块跳过,改动不会重跑。) - **kind=fe**: - `git -C tag -l "req-done/"` 存在 → 删。 - 前端阶段若已 `milestone/frontend-phase` → 删该 tag,并 `Edit` `docs/08 §三` `整体里程碑:` 复位 `—`。 逐条记录已删的 tag,供步骤 6 横幅汇总。 ## 步骤 6:更新台账 + git 提交全部增量产物 + 完成横幅 1. 把当前哈希写回 `.req-ledger.json`(new/changed 单元自此成为新基线): ``` node ${CLAUDE_PLUGIN_ROOT}/lib/req-ledger.mjs commit ``` 2. **git 提交本次全部增量产物**(关键——否则工作树脏,`coding-start` 起 coding.mjs 时会撞 `runBranchSetup`/`runMilestone` 的「工作树必须干净」前置,导致 HALT 或被误并进功能分支)。在**当前分支(默认分支)**提交: ``` git -C add docs/01-需求清单 docs/02-开发计划.md docs/03-数据库设计文档.md docs/05-API接口契约.md docs/08-模块任务管理.md sql/migrations .req-ledger.json git -C commit -m "plan(add-req): 增量需求 <新增/变更 id 摘要>(docs/03+05+02+08 delta + V_n + 台账)" ``` - 覆盖范围 = 步骤 2~5 实际改动的全部文件:人工新写的 REQ 卡(docs/01)、新增 migration(sql/migrations/V_n)、同步的 docs/03、补的 docs/05/02 端点与顺序、docs/08 模块行/FE 行与复位的里程碑字段、`.req-ledger.json`。 - 步骤 5 的 `git tag -d`(删 req-done/milestone)是对 ref 的操作,不产生工作树文件,不需进本 commit。 - commit 后用 `git -C status --porcelain` 复核工作树**干净**(无残留);若仍有未跟踪/未提交项,排查后补提交,确保交给 coding-start 时是干净树。 3. 然后打印横幅并**停下**(不自动进编码,与「Plan 完不自动进 B」一致): ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ [add-req] ✅ 增量需求已处理 新增 REQ:<列出 id 或 无> 变更 REQ:<列出 id 或 无> 新增 FE :<列出 FE-NN 或 无> 新增 migration: 作废 tag:<列出已删的 req-done/* 与 milestone/* 或 无> 台账已更新并随全部增量产物 git 提交(工作树干净)。 运行 /erp-workflow:coding-start 增量编码(Router 只跑缺 tag 的模块/功能)。 [ERP-HALT] 增量处理完成,已停下(不自动进编码)。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` ## 参考 - `${CLAUDE_PLUGIN_ROOT}/lib/req-ledger.mjs`(台账:scan / commit) - `${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs`(增量 DDL↔docs/03 校验,支持多 V 文件累积并集) - `docs/01-需求清单//.md`(REQ SSoT,人工先填) - `docs/03-数据库设计文档.md` + `sql/migrations/V*.sql`(schema 演化,追加 V_n) - `docs/05-API接口契约.md` / `docs/02-开发计划.md` / `docs/08-模块任务管理.md`(下游增量) - `CLAUDE.md` Schema 演化规约(V1 永不改,增量走 V_n) - 跨 skill 模板:`${CLAUDE_PLUGIN_ROOT}/skills/plan/db-design-gen/templates/docs-03-table-template.md`、`${CLAUDE_PLUGIN_ROOT}/skills/plan/downstream-gen/templates/{docs-05-endpoint-template.md,docs-08-module-row-template.md}`