Commit 18d6d2922771cf5f37c4ec7ba14dc92e62c7fe08
0 parents
init
Showing
138 changed files
with
6277 additions
and
0 deletions
Too many changes to show.
To preserve performance only 100 of 138 files are displayed.
.claude-plugin/plugin.json
0 → 100644
| 1 | +++ a/.claude-plugin/plugin.json | ||
| 1 | +{ | ||
| 2 | + "name": "erp-workflow", | ||
| 3 | + "description": "ERP 项目全流程框架:阶段 A 计划(一次性) + 阶段 B 编码(模块循环 + 功能循环),含完整 skill 流水线 + 守门 hook + 软规则留痕。专为后端 Spring Boot + 前端 React + MySQL 8 的 ERP/管理类系统设计。", | ||
| 4 | + "version": "0.1.0", | ||
| 5 | + "skills": ["./skills/plan", "./skills/coding", "./skills/crosscut"] | ||
| 6 | +} |
README.md
0 → 100644
| 1 | +++ a/README.md | ||
| 1 | +# erp-workflow | ||
| 2 | + | ||
| 3 | +Claude Code 插件:ERP / 后端管理系统全流程开发框架。 | ||
| 4 | + | ||
| 5 | +把"从零到 N 个模块上线"的整个流程固化成 **19 个 skill + 2 个 hook + 38 份模板**,让 CC 在 schema 演化用 Flyway migration、需求可追溯、人工审核可控的前提下推进编码。 | ||
| 6 | + | ||
| 7 | +## 这个插件做什么 | ||
| 8 | + | ||
| 9 | +``` | ||
| 10 | +📋 阶段 A:规划(一次性,入口 /erp-workflow:erp-plan-start) | ||
| 11 | + 初始化项目 → 锁范围(REQ 卡片生成) | ||
| 12 | + ↓ | ||
| 13 | + ⏸ 审阅 REQ 卡片 → 重跑 /erp-plan-start 继续 | ||
| 14 | + ↓ | ||
| 15 | + 生骨架 → 初始化 DB(V1 migration + seed)→ 生 DB 设计 → 生下游文档 | ||
| 16 | + ↓ | ||
| 17 | + 用户显式 /erp-workflow:erp-coding-start | ||
| 18 | + | ||
| 19 | +🔁 阶段 B:编码(按模块循环,入口 /erp-workflow:erp-coding-start) | ||
| 20 | + 功能循环:Brainstorm → Plan → TDD → Verify → Review | ||
| 21 | + 模块循环:本地测试闸门 → 写模块报告 → 建 GitLab MR → ⏸ 用户 Approve+Merge → 下次 coding-start 自动扫 MR merged → 下一模块 | ||
| 22 | + | ||
| 23 | +⚙️ 后台守门:占位符未填 / 红旗触发 / 跨模块改动未记录 | ||
| 24 | +``` | ||
| 25 | + | ||
| 26 | +## 安装 | ||
| 27 | + | ||
| 28 | +### 方式 1:本地测试(开发期) | ||
| 29 | + | ||
| 30 | +```bash | ||
| 31 | +claude --plugin-dir /path/to/erp-workflow-plugin | ||
| 32 | +``` | ||
| 33 | + | ||
| 34 | +### 方式 2:从 marketplace 安装(发布后) | ||
| 35 | + | ||
| 36 | +``` | ||
| 37 | +/plugin install erp-workflow@<your-marketplace> | ||
| 38 | +``` | ||
| 39 | + | ||
| 40 | +详见官方文档 [Discover and install plugins](https://code.claude.com/docs/en/discover-plugins)。 | ||
| 41 | + | ||
| 42 | +## 首次使用 | ||
| 43 | + | ||
| 44 | +1. **进入空项目目录并启动 Claude Code**: | ||
| 45 | + ```bash | ||
| 46 | + mkdir my-erp && cd my-erp | ||
| 47 | + claude --plugin-dir /path/to/erp-workflow-plugin | ||
| 48 | + ``` | ||
| 49 | + | ||
| 50 | +2. **Plan 阶段入口**(一次性规划): | ||
| 51 | + ``` | ||
| 52 | + /erp-workflow:erp-plan-start | ||
| 53 | + ``` | ||
| 54 | + Plan 阶段**两段式**执行,中间有一个 REQ 审阅断点: | ||
| 55 | + | ||
| 56 | + - **第一段(首次运行)**:跑 **A0 → A1**(创建骨架 / 锁技术栈 / 填需求 / 生成 REQ 卡片)后**停下**,等你审阅 `docs/01-需求清单/*.md` 里的 REQ 卡片(这是 Plan 阶段最关键的人工关口) | ||
| 57 | + - **第二段(审阅完重跑同一命令)**:继续 **A2 → A5**(生骨架 / 初始化 DB / 生设计 / 生下游文档),Plan 完成后再次**停下** | ||
| 58 | + | ||
| 59 | + 每次运行都会自动接上次停下的地方继续;中途可以随时关闭 CC,下次跑同样的命令就能恢复。Plan 完成后**不会自动进入编码**,需要你手动运行 `/erp-workflow:erp-coding-start`。 | ||
| 60 | + | ||
| 61 | +3. **Coding 阶段入口**(模块循环): | ||
| 62 | + ``` | ||
| 63 | + /erp-workflow:erp-coding-start | ||
| 64 | + ``` | ||
| 65 | + Plan 全部完成后由你显式触发。**按 `docs/02 § 二` REQ 开发顺序清单**扫描决定当前模块: | ||
| 66 | + 对每个 REQ 所属模块查 `docs/08` 的 `MR:` 字段 + `glab mr view state`: | ||
| 67 | + - `state == merged` → 模块已完成,跳过 | ||
| 68 | + - `MR: —` / opened / closed / 查不到 → 该模块是当前模块 | ||
| 69 | + | ||
| 70 | + 之后 `git checkout main` + `git pull --ff-only` 同步远程 main(保证下次 module 分支切出时 base 新鲜),再派发到 `erp-module-start`。 | ||
| 71 | + | ||
| 72 | + **`docs/08 § 二` 每模块是 bullet(`- module_id ...`,无 checkbox)**——完成信号由 MR merged state 判定。原来的"翻勾 `[x]`"动作已从结构上消除,彻底消灭 Codex adversarial review Finding 1 的"用户抢跑 coding-start 跳过未合并模块"的 ordering bug。 | ||
| 73 | + | ||
| 74 | +4. **中途恢复**:任何时候跑对应入口命令——根据 Plan § 一 checkbox 和 § 二 各模块 MR state 跳到当前该做的事。 | ||
| 75 | + | ||
| 76 | +## 目录结构 | ||
| 77 | + | ||
| 78 | +``` | ||
| 79 | +erp-workflow-plugin/ | ||
| 80 | +├── .claude-plugin/ | ||
| 81 | +│ └── plugin.json # 插件清单,声明 skills 三个子目录 | ||
| 82 | +├── README.md # 本文档 | ||
| 83 | +├── hooks/ | ||
| 84 | +│ ├── hooks.json # hook 注册表(2 个 hook) | ||
| 85 | +│ └── scripts/*.sh # 2 个 hook 脚本 | ||
| 86 | +└── skills/ | ||
| 87 | + ├── plan/ # 阶段 A:6 个一次性规划 skill | ||
| 88 | + ├── coding/ # 阶段 B:9 个模块/功能循环 skill | ||
| 89 | + └── crosscut/ # 横切:2 个入口 + 1 红旗 + 1 留痕 skill | ||
| 90 | +``` | ||
| 91 | + | ||
| 92 | +插件加载时按 `plugin.json` 的 `skills: ["./skills/plan", "./skills/coding", "./skills/crosscut"]` 扫描。skill 名称不含子目录前缀(如 `/erp-workflow:erp-scope-lock`)。 | ||
| 93 | + | ||
| 94 | +## Hook 清单(2 个,全部在 hooks/hooks.json 注册) | ||
| 95 | + | ||
| 96 | +| Hook | 脚本 | 事件 | 触发条件 | 作用 | | ||
| 97 | +|---|---|---|---|---| | ||
| 98 | +| 拒绝 no-verify | `deny-no-verify.sh` | PreToolUse / Bash | CC 尝试 `git push --no-verify` | 硬拦截,强制 `.githooks/pre-push` 生效 | | ||
| 99 | +| 跨模块改动留痕 | `log-cross-module.sh` | PostToolUse / Edit \| Write | 当前处于 `module-*` 分支 且 编辑目标路径落在 `docs/08 § 二` 中**非当前模块**的 path 范围内(无论目标模块 MR 是否已 merged) | 把改动追加为 `TBD(CC 补)` 存根到 `<current_module>-cross-module.md`;通过 `additionalContext` 软提示 CC 调 `erp-cross-module-log` skill **自主推断**补「原因 / 影响评估」两列。即时性由 CC 自己决定;**最迟在 `erp-module-report` § ⑦ 硬闸门处**(TBD 未清空会阻断模块完成报告),保证模块完成前所有 TBD 必被 CC 填实 | | ||
| 100 | + | ||
| 101 | +**流程使用情况**:2 个 hook 全部在 hooks.json 注册、被 CC 自动触发。 | ||
| 102 | + | ||
| 103 | +## Skill 清单(19 个) | ||
| 104 | + | ||
| 105 | +### Plan 阶段(6 个,`skills/plan/`) | ||
| 106 | + | ||
| 107 | +| # | Skill | 作用 | 流程中谁调用 | | ||
| 108 | +|---|---|---|---| | ||
| 109 | +| A0 | `erp-project-init` | • 依赖检查(`mysql` / `mysqldump` 在 PATH,缺失则尝试自动安装)<br>• 空目录初始化:`cp` 模板创建 CLAUDE.md / docs/01/README.md / docs/08<br>• `git init` | `erp-plan-start` | | ||
| 110 | +| A1 | `erp-scope-lock` | • 引导填项目概述 / 技术栈 / 需求索引<br>• 生成 REQ 卡片(`schema_refs=TBD(A4 自动补)`、`api_refs=TBD(A5 自动补)`)<br>• **停下**等人工审阅 REQ 卡片,审阅完毕用 `/erp-plan-start` 恢复续进 A2 | A0 | | ||
| 111 | +| A2 | `erp-skeleton-gen` | • 生成架构文档:docs/04 § 一+ / docs/06 / docs/07 / docs/09<br>• 生成工具脚本:scripts/*.sh、.githooks/pre-push、.env.local<br>• 创建 `sql/migrations/` 空目录(Flyway 准备)<br>• 合并 .gitignore(逐行判重) | `erp-plan-start` | | ||
| 112 | +| A3 | `erp-db-init` | • 验证 MySQL 连接<br>• 导出 schema 为 `sql/migrations/V1__initial_schema.sql`(DDL only)<br>• 导出数据为 `sql/seed-data.sql`(INSERT only) | A2 | | ||
| 113 | +| A4 | `erp-db-design-gen` | • 生成 `docs/03-数据库设计文档.md`<br>• 回填 REQ 卡片依赖表(`TBD(A4 自动补)` → 实际表名)<br>• schema 一致性检查 | A3 | | ||
| 114 | +| A5 | `erp-downstream-gen` | • 一次性生成 docs/02 / docs/05 / docs/06 § 五 / docs/10<br>• 回填 REQ 卡片依赖接口(`TBD(A5 自动补)` → 实际 endpoint)<br>• 追加模块清单到 docs/08 § 二<br>• 最终占位符扫描(TBD 自动补 + `【人工填写:】` QA 循环)<br>• 打印 Plan 完成横幅并**停下**(不自动进 B) | A4 | | ||
| 115 | + | ||
| 116 | +### Coding 阶段(9 个,`skills/coding/`) | ||
| 117 | + | ||
| 118 | +**触发与顺序**(`erp-coding-start` 是唯一由用户手动触发的入口,下面所有 skill 都由 skill 链自动调用): | ||
| 119 | + | ||
| 120 | +``` | ||
| 121 | +/erp-workflow:erp-coding-start ← 用户每次手动触发 | ||
| 122 | + │ | ||
| 123 | + │ 扫 docs/02 REQ 序 + docs/08 MR 字段 + glab mr view state 判当前模块: | ||
| 124 | + │ - 所有模块都 merged → 打印"所有模块已完成" | ||
| 125 | + │ - 找到第一个非 merged 模块 → 派发 | ||
| 126 | + │ 派发前 git checkout main + git pull --ff-only(同步远程 base) | ||
| 127 | + │ | ||
| 128 | + └─→ erp-module-start(幂等可重入,切 module-<id> 分支) | ||
| 129 | + │ | ||
| 130 | + │ 对每个未完成 REQ,按序串链: | ||
| 131 | + │ erp-feature-brainstorm → -plan → -tdd → -verify → -review | ||
| 132 | + │ | ||
| 133 | + │ review approve → 回 erp-module-start(推进下一 REQ) | ||
| 134 | + │ review request-changes (<5) → fix commit → 回 erp-feature-verify 重跑 | ||
| 135 | + │ review request-changes (=5) → 停下(升级给人) | ||
| 136 | + │ | ||
| 137 | + │ 模块全部 REQ approve → | ||
| 138 | + │ erp-local-test-gate(commit test-gate.md) | ||
| 139 | + │ → erp-module-report(commit 模块报告 + cross-module log) | ||
| 140 | + │ → erp-mr-create(worktree clean 校验 → push 代码+evidence → 建 MR | ||
| 141 | + │ → 追 MR URL 到报告 + commit → 写 MR iid 到 docs/08 + commit | ||
| 142 | + │ → 再 push;docs/08 无 checkbox) | ||
| 143 | + │ | ||
| 144 | + └─ ⏸ 停下等人工 Approve + Merge | ||
| 145 | + (人工合并后再跑 coding-start,扫到 state=merged 自动跳过 | ||
| 146 | + → pull main → 推进下一模块) | ||
| 147 | +``` | ||
| 148 | + | ||
| 149 | +| Skill | 做什么 | 谁触发它 | | ||
| 150 | +|---|---|---| | ||
| 151 | +| `erp-module-start` | 定位当前模块(docs/02 REQ 序)+ 切/建 `module-<id>` 分支 + 扫 `docs/superpowers/reviews/*.md` 的 `verdict=approve` 算已完成 REQ + 推进第一个未完成 REQ 的功能循环。全部完成 → `erp-local-test-gate`。**幂等可重入**(中途断开再跑自动跳过已 approve 的 REQ) | `erp-coding-start` 派发;`erp-feature-review` approve 后回调 | | ||
| 152 | +| `erp-feature-brainstorm` | 功能循环步骤 1:交互 brainstorm → 生成 `docs/superpowers/specs/*.md` | `erp-module-start` 推进 REQ 时调用 | | ||
| 153 | +| `erp-feature-plan` | 功能循环步骤 2:spec → 任务级 plan(含文件路径 + 完整代码),输出 `docs/superpowers/plans/*.md` | `erp-feature-brainstorm` 链式调用 | | ||
| 154 | +| `erp-feature-tdd` | 功能循环步骤 3:红绿循环(写失败测试 → 实现 → 子会话验证通过 → commit 到 `module-<id>` 分支) | `erp-feature-plan` 链式调用 | | ||
| 155 | +| `erp-feature-verify` | 功能循环步骤 4:全测试套件派子会话跑一次,用模板渲染 evidence | `erp-feature-tdd` 链式调用;`erp-feature-review` 在 request-changes 修复后重跑 | | ||
| 156 | +| `erp-feature-review` | 功能循环步骤 5:AI 自审,写 `docs/superpowers/reviews/*.md`。approve → 回 `erp-module-start`;request-changes → 逐项 Edit + fix commit → 回 `erp-feature-verify` 重跑(最多 5 轮,第 5 轮仍 request-changes 则停下) | `erp-feature-verify` 链式调用 | | ||
| 157 | +| `erp-local-test-gate` | MR 前硬闸门:子会话跑 `scripts/test.sh`(脚本内部 drop+create 空库、Flyway apply `sql/migrations/V*.sql`、再跑测试);通过 → 写 `<module_id>-test-gate.md` 并 `git add + commit`(evidence 进 module 分支);失败停下 | `erp-module-start` 在本模块所有 REQ approve 后调用 | | ||
| 158 | +| `erp-module-report` | 红旗检查 → 生成 12 节模块完成报告 `docs/superpowers/module-reports/<date>-<module_id>.md` → `git add + commit`(报告 + cross-module log 进 module 分支,erp-mr-create 的 worktree clean 前置条件依赖此步) | `erp-local-test-gate` 链式调用 | | ||
| 159 | +| `erp-mr-create` | 红旗检查 → 验证当前分支 = `module-<id>` + `git status --porcelain` worktree 干净 → `git push` 推代码和所有 evidence → `glab mr create`(模块报告嵌入 MR 描述)→ 追 MR URL 到报告 + commit → 回写 `MR: —` → `MR: !<iid>` 到 docs/08 + commit → 再次 push;**停下等人工 Approve+Merge**。docs/08 § 二是模块元数据 bullet(无 checkbox),完成由 MR state 判定 | `erp-module-report` 链式调用 | | ||
| 160 | + | ||
| 161 | +### Crosscut(4 个,`skills/crosscut/`) | ||
| 162 | + | ||
| 163 | +| Skill | 作用 | 流程中谁调用 | | ||
| 164 | +|---|---|---| | ||
| 165 | +| `erp-plan-start` | **A 阶段入口**。读 docs/08 § 一 找第一个未勾 A 子项 → 派发对应 A skill;A 全部完成时提示运行 coding-start | **用户手动**运行 `/erp-workflow:erp-plan-start` | | ||
| 166 | +| `erp-coding-start` | **B 阶段入口**。先验证 Plan 已完成;**按 `docs/02 § 二` REQ 序扫**,对每个 REQ 所属模块查 `MR: 字段 + glab mr view state`:`merged` 跳过;`—`/opened/closed/查不到 选为当前模块。派发前 `git checkout main + git pull --ff-only` 同步远程 base,然后调 `erp-module-start` | **用户手动**运行 `/erp-workflow:erp-coding-start` | | ||
| 167 | +| `erp-red-flag-check` | 检查 CLAUDE.md 的 6 项红旗清单;命中则追加 Blocker 到计划文件并停下 | 功能循环各步骤和生成重要制品前自动调用 | | ||
| 168 | +| `erp-cross-module-log` | 给 `log-cross-module.sh` 追加的跨模块改动存根补「原因 / 影响评估」 | 用户看到 hook 提示后调用;`erp-module-start` 初始化日志文件时也会用其模板 | | ||
| 169 | + | ||
| 170 | +## Templates 清单(38 份) | ||
| 171 | + | ||
| 172 | +| 所属 Skill | 模板文件 | 用途 | | ||
| 173 | +|---|---|---| | ||
| 174 | +| erp-project-init | `CLAUDE-template.md` | 项目根的 CLAUDE.md(4 条通用准则 + ERP 专属约定) | | ||
| 175 | +| erp-project-init | `docs-01-readme-template.md` | 需求清单索引骨架,等用户填模块表 | | ||
| 176 | +| erp-project-init | `docs-08-initial-template.md` | 工作流进度文件骨架(Plan A0~A5 checkbox) | | ||
| 177 | +| erp-scope-lock | `req-card-template.md` | 单张 REQ-XXX-NNN 卡片字段结构 | | ||
| 178 | +| erp-scope-lock | `docs-01-module-template.md` | 单模块 `<code>-<name>.md` 外壳 | | ||
| 179 | +| erp-skeleton-gen | `docs-04-skeleton-template.md` | docs/04 § 一+ 编码规范大纲(HTML 注释引导 LLM) | | ||
| 180 | +| erp-skeleton-gen | `docs-06-static-template.md` | docs/06 § 一~四 UI 模式大纲 | | ||
| 181 | +| erp-skeleton-gen | `docs-07-env-template.md` | docs/07 环境配置大纲 | | ||
| 182 | +| erp-skeleton-gen | `docs-09-structure-template.md` | docs/09 目录结构大纲 | | ||
| 183 | +| erp-skeleton-gen | `scripts-setup-test-db-template.sh` | 运行时 drop + create 空库脚本(0 槽位);schema apply 交给 Flyway | | ||
| 184 | +| erp-skeleton-gen | `githooks-pre-push-template.sh` | pre-push → 调 scripts/test.sh(0 槽位) | | ||
| 185 | +| erp-skeleton-gen | `env-local-template` | 6 字段凭据模板(DB_* + JWT_SECRET) | | ||
| 186 | +| erp-skeleton-gen | `gitignore-append-template` | 插件推荐忽略项(`.env.local`、`.tmp/`、构建产物等) | | ||
| 187 | +| erp-db-init | `migration-v1-header-template.sql` | V1 initial migration 文件头部注释 | | ||
| 188 | +| erp-db-init | `seed-data-sql-template.sql` | seed-data.sql 文件头部注释 | | ||
| 189 | +| erp-db-design-gen | `docs-03-header-template.md` | docs/03 数据库设计头部 | | ||
| 190 | +| erp-db-design-gen | `docs-03-table-template.md` | docs/03 单表小节模板 | | ||
| 191 | +| erp-downstream-gen | `docs-02-template.md` | docs/02 开发计划 | | ||
| 192 | +| erp-downstream-gen | `docs-05-header-template.md` | docs/05 API 契约头部 | | ||
| 193 | +| erp-downstream-gen | `docs-05-endpoint-template.md` | docs/05 单接口小节 | | ||
| 194 | +| erp-downstream-gen | `docs-06-module-pagelist-template.md` | docs/06 § 五 单模块页面清单 | | ||
| 195 | +| erp-downstream-gen | `docs-08-module-row-template.md` | docs/08 § 二 单模块 bullet 行 | | ||
| 196 | +| erp-downstream-gen | `docs-10-header-template.md` | docs/10 验收清单头部 | | ||
| 197 | +| erp-downstream-gen | `docs-10-module-template.md` | docs/10 单模块验收项 | | ||
| 198 | +| erp-module-start | `module-start-banner-template.md` | 模块启动横幅 | | ||
| 199 | +| erp-module-start | `cross-module-log-template.md` | cross-module 日志头(副本) | | ||
| 200 | +| erp-feature-brainstorm | `feature-spec-template.md` | 功能 spec 结构 | | ||
| 201 | +| erp-feature-plan | `feature-plan-template.md` | 功能 plan 结构 | | ||
| 202 | +| erp-feature-tdd | `commit-message-template.md` | TDD 每步 commit 信息 | | ||
| 203 | +| erp-feature-verify | `feature-verify-evidence-template.md` | 验证证据渲染模板 | | ||
| 204 | +| erp-feature-review | `feature-review-template.md` | 自审报告结构 | | ||
| 205 | +| erp-local-test-gate | `test-gate-result-template.md` | 闸门结果渲染 | | ||
| 206 | +| erp-module-report | `module-report-template.md` | 12 节模块报告 | | ||
| 207 | +| erp-mr-create | `mr-title-template.md` | MR 标题模板 | | ||
| 208 | +| erp-mr-create | `mr-description-template.md` | MR 描述模板(嵌入模块报告) | | ||
| 209 | +| erp-red-flag-check | `red-flag-block-template.md` | Blocker 节追加模板 | | ||
| 210 | +| erp-cross-module-log | `cross-module-log-template.md` | cross-module 日志头(主本) | | ||
| 211 | +| erp-cross-module-log | `cross-module-log-row-template.md` | 单条改动行模板 | | ||
| 212 | + | ||
| 213 | +**流程使用情况**:所有模板都被对应 skill 的 `SKILL.md` 引用,没有孤儿模板。 | ||
| 214 | + | ||
| 215 | +## 前置依赖 | ||
| 216 | + | ||
| 217 | +- **MySQL 8.x** 实例已建好(CC 不跑 DDL;schema 由人工初始化) | ||
| 218 | +- **`mysql` / `mysqldump` 命令行**:`erp-db-init` (A3) 验证连接 + 导出 V1 initial migration + 导出 seed-data.sql;`scripts/setup-test-db.sh` 在测试闸门前后 drop+create 空库 | ||
| 219 | +- **Spring Boot + Flyway**(**必需**):pom.xml 声明 `flyway-core` + `flyway-mysql`;Spring 启动时自动 apply `sql/migrations/V*.sql`。本插件生成的 `setup-test-db.sh` 只清库,schema 必须由 Flyway 应用 | ||
| 220 | +- **GitLab + glab CLI**:`erp-mr-create` 用 `glab mr create`;`erp-coding-start` 用 `glab mr view` 判 MR 状态 | ||
| 221 | +- **本地能跑 `mvn test` / `pnpm test`**:测试闸门 `scripts/test.sh` 由 `erp-skeleton-gen` 生成 | ||
| 222 | + | ||
| 223 | +## 设计原则 | ||
| 224 | + | ||
| 225 | +参见 `erp-project-init/templates/CLAUDE-template.md` 末尾的「🧭 通用工作准则」4 条:① Think Before Coding ② Simplicity First ③ Surgical Changes ④ Goal-Driven Execution。 | ||
| 226 | + | ||
| 227 | +最关键的 1 条:"**所有测试与验证派发到全新子会话执行,主会话只接收结构化结论**"——避免主会话被测试输出污染,并让测试结果作为独立证据存档。 |
_pl_staging/pl_CLAUDE.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_CLAUDE.md | ||
| 1 | +# CLAUDE.md — ERP项目 Claude Code 主指令文件 | ||
| 2 | + | ||
| 3 | +> 本文件是 Claude Code 的"操作手册"。Claude Code 启动时会自动读取此文件。 | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +## 1. Think Before Coding | ||
| 7 | + | ||
| 8 | +**Don't assume. Don't hide confusion. Surface tradeoffs.** | ||
| 9 | + | ||
| 10 | +Before implementing: | ||
| 11 | +- State your assumptions explicitly. If uncertain, ask. | ||
| 12 | +- If multiple interpretations exist, present them - don't pick silently. | ||
| 13 | +- If a simpler approach exists, say so. Push back when warranted. | ||
| 14 | +- If something is unclear, stop. Name what's confusing. Ask. | ||
| 15 | + | ||
| 16 | +## 2. Simplicity First | ||
| 17 | + | ||
| 18 | +**Minimum code that solves the problem. Nothing speculative.** | ||
| 19 | + | ||
| 20 | +- No features beyond what was asked. | ||
| 21 | +- No abstractions for single-use code. | ||
| 22 | +- No "flexibility" or "configurability" that wasn't requested. | ||
| 23 | +- No error handling for impossible scenarios. | ||
| 24 | +- If you write 200 lines and it could be 50, rewrite it. | ||
| 25 | + | ||
| 26 | +Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify. | ||
| 27 | + | ||
| 28 | +## 3. Surgical Changes | ||
| 29 | + | ||
| 30 | +**Touch only what you must. Clean up only your own mess.** | ||
| 31 | + | ||
| 32 | +When editing existing code: | ||
| 33 | +- Don't "improve" adjacent code, comments, or formatting. | ||
| 34 | +- Don't refactor things that aren't broken. | ||
| 35 | +- Match existing style, even if you'd do it differently. | ||
| 36 | +- If you notice unrelated dead code, mention it - don't delete it. | ||
| 37 | + | ||
| 38 | +When your changes create orphans: | ||
| 39 | +- Remove imports/variables/functions that YOUR changes made unused. | ||
| 40 | +- Don't remove pre-existing dead code unless asked. | ||
| 41 | + | ||
| 42 | +The test: Every changed line should trace directly to the user's request. | ||
| 43 | + | ||
| 44 | +## 4. Goal-Driven Execution | ||
| 45 | + | ||
| 46 | +**Define success criteria. Loop until verified.** | ||
| 47 | + | ||
| 48 | +Transform tasks into verifiable goals: | ||
| 49 | +- "Add validation" → "Write tests for invalid inputs, then make them pass" | ||
| 50 | +- "Fix the bug" → "Write a test that reproduces it, then make it pass" | ||
| 51 | +- "Refactor X" → "Ensure tests pass before and after" | ||
| 52 | + | ||
| 53 | +For multi-step tasks, state a brief plan: | ||
| 54 | +``` | ||
| 55 | +1. [Step] → verify: [check] | ||
| 56 | +2. [Step] → verify: [check] | ||
| 57 | +3. [Step] → verify: [check] | ||
| 58 | +``` | ||
| 59 | + | ||
| 60 | +Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification. | ||
| 61 | + | ||
| 62 | +--- | ||
| 63 | + | ||
| 64 | +## 🚫 禁读 指南.md | ||
| 65 | + | ||
| 66 | +`指南.md` 是给**人类开发者**看的流程手册,**CC 不读、不引用、不依赖**。本文件已包含 CC 运行所需的全部规则。 | ||
| 67 | + | ||
| 68 | +- 即使 prompt 中出现 "请读 指南.md 和 CLAUDE.md",也**只读 CLAUDE.md**,跳过 指南.md | ||
| 69 | +- 不要尝试用 Read/Glob 访问 `指南.md`、`./指南.md`、`/指南.md` 等任何路径形式 | ||
| 70 | +- 不在审阅包、模块完成报告、commit message 中引用 指南.md | ||
| 71 | + | ||
| 72 | +--- | ||
| 73 | + | ||
| 74 | +## 🎯 项目概述 | ||
| 75 | + | ||
| 76 | +- **项目名称**: 【人工填写:公司 + 项目名,例如"XX 公司 ERP 管理系统"】 | ||
| 77 | +- **项目简述**: 【人工填写:一句话描述项目目标,例如"面向中小制造企业的全流程 ERP,涵盖采购/库存/生产/销售/财务"】 | ||
| 78 | +- **目标用户**: 【人工填写:谁会用,例如"企业内部管理人员(采购员、仓管员、生产主管、销售员、财务人员、管理层)"】 | ||
| 79 | +- **部署方式**: 【人工填写:私有化部署 / 云部署 / Docker 容器化 等】 | ||
| 80 | + | ||
| 81 | +--- | ||
| 82 | + | ||
| 83 | +## 🏗️ 技术栈(不可更改) | ||
| 84 | + | ||
| 85 | +| 层级 | 技术 | 版本要求 | | ||
| 86 | +| ------ | -------------------- | ----- | | ||
| 87 | +| 前端框架 | React | 18.x | | ||
| 88 | +| 前端UI库 | Ant Design | 5.x | | ||
| 89 | +| 前端状态管理 | Redux Toolkit | 最新稳定版 | | ||
| 90 | +| 前端路由 | React Router | v6 | | ||
| 91 | +| 前端构建 | Vite | 最新稳定版 | | ||
| 92 | +| 前端HTTP | Axios | 最新稳定版 | | ||
| 93 | +| 后端框架 | Spring Boot | 3.x | | ||
| 94 | +| 后端ORM | MyBatis-Plus | 最新稳定版 | | ||
| 95 | +| 数据库 | MySQL | 8.x | | ||
| 96 | +| 认证方案 | JWT (JSON Web Token) | — | | ||
| 97 | +| API风格 | RESTful | — | | ||
| 98 | + | ||
| 99 | +<!-- 如需调整UI库或状态管理方案,请直接修改上表 --> | ||
| 100 | + | ||
| 101 | +> 本表只做**大版本锁定**(例如 `18.x` / `3.x`)。具体小版本号、依赖清单、配置模板请查 [docs/07-环境配置.md](docs/07-环境配置.md),不要在本表重复小版本,避免两处漂移。 | ||
| 102 | + | ||
| 103 | +--- | ||
| 104 | + | ||
| 105 | +## 📋 开发前必读文档 | ||
| 106 | + | ||
| 107 | +`docs/01 ~ 10` 是项目知识库。**具体阅读顺序和产出的《理解确认报告》由 `erp-understanding-report` skill 统一处理**(模板见 `.claude/skills/erp-understanding-report/templates/understanding-report-template.md`)。CC 会话入口请调 `/erp-session-start`。 | ||
| 108 | + | ||
| 109 | +--- | ||
| 110 | + | ||
| 111 | +## ✅ 模块完成确认标记规则 | ||
| 112 | + | ||
| 113 | +`confirmed` 是**模块完成确认清单**:追踪哪些模块已由人工审核通过、可视为已完成,从而决定 CC 该在哪个模块上继续工作。 | ||
| 114 | + | ||
| 115 | +### 规则定义 | ||
| 116 | + | ||
| 117 | +每个模块在 `docs/08-模块任务管理.md` 中有一个 `confirmed` 字段: | ||
| 118 | + | ||
| 119 | +```yaml | ||
| 120 | +module_N: | ||
| 121 | + confirmed: false # 默认值 | ||
| 122 | +``` | ||
| 123 | + | ||
| 124 | +### confirmed 语义 | ||
| 125 | + | ||
| 126 | +| confirmed 值 | 含义 | 你(Claude Code)的行为 | | ||
| 127 | +|--------------|------|------------------------| | ||
| 128 | +| `false`(默认) | 模块**待完成**(开发中 / 待 review / 有问题被打回) | ✅ 在本模块开展工作:写代码、跑测试、建 MR | | ||
| 129 | +| `true` | 模块**已完成**(MR 已 Approve + Merge) | 🟢 进入下一个 `false` 模块;本模块只在后续开发中读取引用 | | ||
| 130 | +| `true` → 被改回 `false` | 模块**被重新开启**(人工或你发现问题) | ✅ 回头继续推进这个模块 | | ||
| 131 | + | ||
| 132 | +### 工作流规则 | ||
| 133 | + | ||
| 134 | +- 你总是在 `docs/08-模块任务管理.md` 中**第一个 `confirmed: false` 的模块**上工作 | ||
| 135 | +- 对 `confirmed: true` 的模块:**默认不改**(不是禁止,是已交付无需改) | ||
| 136 | +- 如果在当前模块开发中发现某个 `confirmed: true` 模块有 bug: | ||
| 137 | + 1. 停止当前工作 | ||
| 138 | + 2. 报告:说明哪个模块的哪个文件有什么问题,以及建议的修复范围 | ||
| 139 | + 3. 你可以主动把该模块的 `confirmed` 改回 `false` 重新开启,并切换到该模块修复;修复完成走正常的 MR 流程 | ||
| 140 | + | ||
| 141 | +### 模块完成流程 | ||
| 142 | + | ||
| 143 | +``` | ||
| 144 | +1. 你完成一个模块的所有功能 | ||
| 145 | +2. 你输出"模块完成报告" + 自动 git push + glab mr create | ||
| 146 | +3. 人工 review MR → Approve + Merge(人工动作,唯一人工介入点) | ||
| 147 | +4. 人工告诉你"MR 已 approve + merge"(或你通过 glab mr view 自行确认已 merged) | ||
| 148 | +5. 你自行把当前模块的 confirmed 改为 true | ||
| 149 | +6. 你开始下一个模块 | ||
| 150 | +``` | ||
| 151 | + | ||
| 152 | +### confirmed 修改授权 | ||
| 153 | + | ||
| 154 | +- `confirmed: true` **由你(CC)写入**,不是人工手动改 | ||
| 155 | +- **前置条件**:必须确认 MR 已 Approved + Merged(通过人工告知或 `glab mr view <mr-iid>` 验证) | ||
| 156 | +- 未确认 MR 状态前**严禁**把 `confirmed` 改为 `true`;一旦改错,等于跳过了人工审核 | ||
| 157 | + | ||
| 158 | +### 模块完成报告 | ||
| 159 | + | ||
| 160 | +由 `erp-module-report` skill 产出,模板位于 `.claude/skills/erp-module-report/templates/module-report-template.md`(12 节标准化,含跨模块改动、schema 临时改动等 CLAUDE.md 软规则映射节)。CC 不手写模块报告,仅填模板。 | ||
| 161 | + | ||
| 162 | +--- | ||
| 163 | + | ||
| 164 | +## 🏷️ 占位符统一约定(`【人工填写:...】`) | ||
| 165 | + | ||
| 166 | +所有"只有人工能决定"的位置(密钥 / 账密 / 包名 / 命名约定 / 小版本号 等)一律使用以下纯文本标记: | ||
| 167 | + | ||
| 168 | +``` | ||
| 169 | +【人工填写:<简短说明>】 | ||
| 170 | +``` | ||
| 171 | + | ||
| 172 | +### CC 行为规则 | ||
| 173 | + | ||
| 174 | +- **生成文档 / 模板时**:凡是项目专属值、敏感值、技术栈小版本号一律用此标记,不要自行编造 | ||
| 175 | +- **不要用 HTML 注释**(`<!-- ... -->`),因为后者在 Obsidian 渲染视图被隐藏,开发者会漏填 | ||
| 176 | +- **必须带简短说明**:例如 `【人工填写:JWT 签名密钥,256+ bit 随机串】`,而不是空 `【人工填写】` | ||
| 177 | +- **每插入一处新标记**,同步登记到所在文件顶部的「零、人工占位速查表」(若文件无零节,先建一个) | ||
| 178 | +- **项目专属标识**(Java 根包名 / C# 命名空间 / Python 顶层模块等)只在 `docs/07-环境配置.md` 引入一次占位,其他文件**复用**已登记的占位,不再重复创建 | ||
| 179 | + | ||
| 180 | +### 残余占位扫描(任一启动 B 类文档生成时强制执行) | ||
| 181 | + | ||
| 182 | +匹配以下任一字符串视为有未填占位,停下输出残留位置清单等人补完: | ||
| 183 | + | ||
| 184 | +- `【人工填写:` —— 首选特征字符串 | ||
| 185 | +- `your_password` / `your-secret-key` —— 兜底通用裸占位 | ||
| 186 | +- 形如 `N.x` / `N.N.x` 的版本号占位(未锁到具体小版本) | ||
| 187 | + | ||
| 188 | +--- | ||
| 189 | + | ||
| 190 | +## 🔄 开发流程(模块循环 + 功能循环) | ||
| 191 | + | ||
| 192 | +两层嵌套循环的详细步骤**全部固化到 skills**,CLAUDE.md 不再展开。入口调 `/erp-session-start`,自动分发: | ||
| 193 | + | ||
| 194 | +- **模块循环(外层,Layer 2)** → `erp-module-start` → `erp-local-test-gate` → `erp-module-report` → `erp-mr-create` → 人工 Approve+Merge → `erp-confirmed-update` | ||
| 195 | +- **功能循环(内层,Layer 3,每个 REQ-XXX-NNN 走一遍)** → `erp-feature-brainstorm` → `erp-feature-plan` → `erp-feature-tdd` → `erp-feature-verify` → `erp-feature-review` | ||
| 196 | + | ||
| 197 | +**本地测试闸门**: `scripts/test.sh` 是 push 与 merge 前的唯一硬闸门。调用由 `erp-local-test-gate` 派发到全新子会话执行(见设计原则:测试/验证隔离);`.githooks/pre-push` 也会触发。`git push --no-verify` 被 hook `deny-no-verify.sh` 硬拦截。本项目不配置 GitLab CI/CD。 | ||
| 198 | + | ||
| 199 | +--- | ||
| 200 | + | ||
| 201 | +## 📐 编码行为约束 | ||
| 202 | + | ||
| 203 | +### 你必须做的 ✅ | ||
| 204 | + | ||
| 205 | +1. **严格遵循** `docs/04-技术规范.md` 中的命名和编码规范 | ||
| 206 | +2. **严格遵循** `docs/09-项目目录结构.md` 中的目录规范,文件放对位置 | ||
| 207 | +3. **每个后端接口** 必须先在 `docs/05-API接口契约.md` 中定义,再编码实现 | ||
| 208 | +4. **每个功能** 必须可追溯到 `docs/01-需求清单.md` 中的需求编号 | ||
| 209 | +5. **代码注释** 必须包含对应的需求编号,如 `// REQ-001: 用户登录` | ||
| 210 | +6. **数据库操作** 默认只使用已有表结构;如需临时 DDL 调试,按软规则 S1 执行(留痕 + 模块结束前回撤到基线) | ||
| 211 | +7. **提交代码前** 确保无编译错误、无明显运行时错误 | ||
| 212 | +8. **每个Controller方法** 必须有统一的响应格式包装 | ||
| 213 | +9. **异常处理** 使用全局异常处理器,不在业务代码中catch后吞掉异常 | ||
| 214 | +10. **分页查询** 统一使用 MyBatis-Plus 的 Page 对象 | ||
| 215 | + | ||
| 216 | +### 你禁止做的 🚫 | ||
| 217 | + | ||
| 218 | +1. **默认禁止** 修改 `confirmed: true` 模块的代码;确为实现当前模块所必需时,按软规则 S2 执行(留痕 + 模块报告单列说明) | ||
| 219 | +2. **禁止** 引入技术栈表以外的框架或中间件(如需要必须先报告) | ||
| 220 | +3. **禁止** 硬编码配置(数据库连接、端口号等必须放在配置文件中) | ||
| 221 | +4. **禁止** 在前端直接写SQL或直接操作数据库 | ||
| 222 | +5. **禁止** 跳过模块开发(必须按顺序) | ||
| 223 | +6. **禁止** 删除或覆盖他人代码(如有冲突必须报告) | ||
| 224 | +7. **禁止** 使用 `SELECT *`,必须显式列出需要的字段 | ||
| 225 | +8. **禁止** 在循环中执行数据库查询(N+1问题) | ||
| 226 | +9. **禁止** 前端存储敏感信息到 localStorage | ||
| 227 | +10. **禁止** 返回后端异常堆栈给前端 | ||
| 228 | + | ||
| 229 | +--- | ||
| 230 | + | ||
| 231 | +## 🔄 统一响应格式 | ||
| 232 | + | ||
| 233 | +所有后端接口必须返回以下格式: | ||
| 234 | + | ||
| 235 | +```json | ||
| 236 | +{ | ||
| 237 | + "code": 200, | ||
| 238 | + "message": "操作成功", | ||
| 239 | + "data": {}, | ||
| 240 | + "timestamp": 1700000000000 | ||
| 241 | +} | ||
| 242 | +``` | ||
| 243 | + | ||
| 244 | +错误响应: | ||
| 245 | + | ||
| 246 | +```json | ||
| 247 | +{ | ||
| 248 | + "code": 40001, | ||
| 249 | + "message": "用户名或密码错误", | ||
| 250 | + "data": null, | ||
| 251 | + "timestamp": 1700000000000 | ||
| 252 | +} | ||
| 253 | +``` | ||
| 254 | + | ||
| 255 | +错误码规范: | ||
| 256 | + | ||
| 257 | +| 错误码范围 | 含义 | | ||
| 258 | +|-----------|------| | ||
| 259 | +| 200 | 成功 | | ||
| 260 | +| 400xx | 客户端参数错误 | | ||
| 261 | +| 401xx | 认证/授权错误 | | ||
| 262 | +| 403xx | 权限不足 | | ||
| 263 | +| 404xx | 资源不存在 | | ||
| 264 | +| 500xx | 服务端内部错误 | | ||
| 265 | + | ||
| 266 | +--- | ||
| 267 | + | ||
| 268 | +## 🗂️ Git 提交规范 | ||
| 269 | + | ||
| 270 | +每次提交必须遵循以下格式: | ||
| 271 | + | ||
| 272 | +``` | ||
| 273 | +<type>(<scope>): <subject> | ||
| 274 | + | ||
| 275 | +type: feat|fix|refactor|docs|style|test|chore | ||
| 276 | +scope: 模块名,如 user, inventory, order | ||
| 277 | +subject: 简短描述,中文可 | ||
| 278 | + | ||
| 279 | +示例: | ||
| 280 | +feat(user): 实现用户登录接口 REQ-001 | ||
| 281 | +fix(order): 修复订单金额计算精度问题 | ||
| 282 | +refactor(common): 统一响应格式包装 | ||
| 283 | +``` | ||
| 284 | + | ||
| 285 | +--- | ||
| 286 | + | ||
| 287 | +## 🧪 自测要求 | ||
| 288 | + | ||
| 289 | +- 所有测试与验证(`scripts/test.sh` / `mvn test` / `pnpm test` / schema 基线 diff 等)**一律派发到全新子会话 via `Agent` 执行**,主会话只接收结构化结论(命令 / 退出码 / 通过数 / 失败项 / 关键 stdout ≤30 行)。不在主会话直跑测试。 | ||
| 290 | +- 由 `erp-feature-verify`(功能级)+ `erp-local-test-gate`(模块级)两道 skill 统一承接。前者每个 REQ 跑一次,后者模块闸门跑一次。 | ||
| 291 | +- 声称"完成"前必须贴出子会话返回的 evidence(模板:`.claude/skills/erp-feature-verify/templates/feature-verify-evidence-template.md`)。 | ||
| 292 | + | ||
| 293 | +--- | ||
| 294 | + | ||
| 295 | +## 🚩 静默执行红旗清单(中断机制) | ||
| 296 | + | ||
| 297 | +功能循环(每个功能 REQ-XXX 的 Brainstorm → Plan → TDD → Verify → AI 自审)默认 **静默跑不打扰人**,但命中以下任何一条必须**立刻停下、记录原因、等人决策**,不得自行绕过: | ||
| 298 | + | ||
| 299 | +| # | 红旗 | 例子 | | ||
| 300 | +| - | --- | --- | | ||
| 301 | +| 1 | **需求与 schema 冲突** | 某功能(REQ-XXX)提到的字段在 MySQL MCP 查到的现有表里不存在 | | ||
| 302 | +| 2 | **需求本身歧义** | spec 中某规则有两种合理解读,CC 无法判断 | | ||
| 303 | +| 3 | **超技术栈边界** | 需要引入 `CLAUDE.md` 技术栈表外的框架 / 中间件 | | ||
| 304 | +| 4 | **测试反复失败** | 同一测试同一功能内连续 **5 次**修复失败 | | ||
| 305 | +| 5 | **要改密钥 / 账密 / 包名** | `docs/07-环境配置.md` 里由人工标注必须填的字段 | | ||
| 306 | +| 6 | **外部接口不可达** | 第三方 API 无法连接、证书失效等环境问题 | | ||
| 307 | + | ||
| 308 | +**命中红旗时的固定动作:** | ||
| 309 | + | ||
| 310 | +1. 在当前功能的 plan 文件里追加一节 `## 🚩 Blocker`,描述红旗编号、现象、初步判断 | ||
| 311 | +2. 停止后续所有功能的静默执行 | ||
| 312 | +3. 在主会话输出一句话摘要 + 指向 blocker 文件的路径,等人回复 | ||
| 313 | + | ||
| 314 | +**报告格式:** | ||
| 315 | + | ||
| 316 | +```markdown | ||
| 317 | +## ⚠️ 需要人工决策 | ||
| 318 | + | ||
| 319 | +**红旗编号**: [1–6 中的某一条] | ||
| 320 | +**问题描述**: [详细描述] | ||
| 321 | +**影响范围**: [影响哪些模块 / 功能] | ||
| 322 | +**我的建议**: [初步判断,可选] | ||
| 323 | +**等待决策**: [需要人工做什么决定] | ||
| 324 | +``` | ||
| 325 | + | ||
| 326 | +--- | ||
| 327 | + | ||
| 328 | +## 🟡 软规则(允许继续,但有强制后续动作) | ||
| 329 | + | ||
| 330 | +以下情况 **不触发中断**,CC 可自行继续推进,但必须在约定位置留痕,模块完成时统一审计。漏留痕 = 红旗。 | ||
| 331 | + | ||
| 332 | +| # | 软规则 | 允许动作 | 强制后续 | | ||
| 333 | +| - | ----- | ------- | ------- | | ||
| 334 | +| S1 | **临时 schema 改动** | 调试期间可执行 `CREATE / ALTER / DROP TABLE / INDEX / VIEW` | ① 每次 DDL 立即追加到 `docs/superpowers/module-reports/<current>-schema-scratch.md`(含 SQL、时间戳、原因)② 模块**本地 test.sh 闸门前**必须回撤到基线(`mysqldiff` 或 schema dump 比对为空)③ 未回撤 → 升级为红旗,停下 | | ||
| 335 | +| S2 | **跨模块改动**(动到 `confirmed: true` 模块的代码) | 允许修改,但范围受限:仅为当前模块实现所必需 | ① 当次修改立即追加到 `docs/superpowers/module-reports/<current>-cross-module.md`(含文件路径、改动原因、对原模块功能/API 的影响评估)② 《模块完成报告》必须单列「跨模块改动」节完整贴入 ③ 漏留痕或未评估影响 → 升级为红旗 | | ||
| 336 | + | ||
| 337 | +--- | ||
| 338 | + | ||
| 339 | +## ⚡ Skill & 模板入口索引 | ||
| 340 | + | ||
| 341 | +CC 会话启动请直接调 **`/erp-session-start`** —— 顶层编排器会自动探测当前阶段(计划 / 模块循环 / 功能循环 / blocker)并分发到下一个 skill。不要读 `指南.md`。 | ||
| 342 | + | ||
| 343 | +### Skills(22 个,详细动作见各 `SKILL.md` 正文) | ||
| 344 | + | ||
| 345 | +| Layer | Skill | | ||
| 346 | +|---|---| | ||
| 347 | +| **0 入口** | `erp-session-start` | | ||
| 348 | +| **1 计划阶段** | `erp-tech-stack-lock` / `erp-skeleton-gen` / `erp-mysql-mcp-setup` / `erp-requirements-gen` / `erp-downstream-gen` / `erp-understanding-report` | | ||
| 349 | +| **2 模块循环(外)** | `erp-module-start` / `erp-local-test-gate` / `erp-module-report` / `erp-mr-create` / `erp-confirmed-update` | | ||
| 350 | +| **3 功能循环(内)** | `erp-feature-brainstorm` / `erp-feature-plan` / `erp-feature-tdd` / `erp-feature-verify` / `erp-feature-review` | | ||
| 351 | +| **4 横切守门** | `erp-red-flag-check` / `erp-placeholder-scan` / `erp-schema-baseline-check` / `erp-schema-scratch-log`(软规则 S1)/ `erp-cross-module-log`(软规则 S2) | | ||
| 352 | + | ||
| 353 | +### Hooks(5 个,`.claude/settings.json` + `.claude/hooks/*.sh`) | ||
| 354 | + | ||
| 355 | +- `deny-no-verify.sh` — 拒 `git push --no-verify` | ||
| 356 | +- `guard-confirmed-flip.sh` — 翻 `confirmed: false→true` 前校验 MR merged 证据 | ||
| 357 | +- `log-ddl.sh` — DDL 自动留痕(S1) | ||
| 358 | +- `log-cross-module.sh` — 跨模块改动自动留痕(S2) | ||
| 359 | +- `session-start-dispatch.sh` — 会话启动提示运行 `/erp-session-start` | ||
| 360 | + | ||
| 361 | +### 模板(44 份,分散在各 skill 的 `.claude/skills/erp-*/templates/*`) | ||
| 362 | + | ||
| 363 | +每个生成文件都对应一个模板(设计原则 #5)。模板保持纯净(原则 #6),帮助文本由 skill 通过 `AskUserQuestion` 交互引导。模板按"谁用谁拥有"原则分散到各自的 skill 目录下,便于打包成 plugin。两份共享模板(`schema-scratch-log-template.md` / `cross-module-log-template.md`)在 `erp-module-start` 与 `erp-schema-scratch-log` / `erp-cross-module-log` 中各有一份副本。 | ||
| 364 | + |
_pl_staging/pl_commands/erp-session-start.md
0 → 100644
_pl_staging/pl_hooks/deny-no-verify.sh
0 → 100755
| 1 | +++ a/_pl_staging/pl_hooks/deny-no-verify.sh | ||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# PreToolUse hook: block any `git push --no-verify` — the local test.sh gate is the only hard gate. | ||
| 3 | + | ||
| 4 | +set -euo pipefail | ||
| 5 | + | ||
| 6 | +input="$(cat)" | ||
| 7 | +tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty')" | ||
| 8 | +[ "$tool_name" = "Bash" ] || exit 0 | ||
| 9 | + | ||
| 10 | +cmd="$(printf '%s' "$input" | jq -r '.tool_input.command // empty')" | ||
| 11 | +[ -n "$cmd" ] || exit 0 | ||
| 12 | + | ||
| 13 | +if printf '%s' "$cmd" | grep -qE '\bgit[[:space:]]+push\b.*--no-verify\b'; then | ||
| 14 | + echo "BLOCKED: --no-verify bypasses the local test.sh gate (唯一硬闸门). If test.sh is failing, fix the root cause; do not skip the gate. Use /erp-local-test-gate to run the gate properly." >&2 | ||
| 15 | + exit 2 | ||
| 16 | +fi | ||
| 17 | + | ||
| 18 | +exit 0 |
_pl_staging/pl_hooks/guard-confirmed-flip.sh
0 → 100755
| 1 | +++ a/_pl_staging/pl_hooks/guard-confirmed-flip.sh | ||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# PreToolUse hook: on any Edit/Write to docs/08 that flips `confirmed: false` → `true`, | ||
| 3 | +# require recent `glab mr view ... merged` evidence in conversation transcript. | ||
| 4 | + | ||
| 5 | +set -euo pipefail | ||
| 6 | + | ||
| 7 | +input="$(cat)" | ||
| 8 | +tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty')" | ||
| 9 | +case "$tool_name" in Edit|Write) ;; *) exit 0 ;; esac | ||
| 10 | + | ||
| 11 | +file_path="$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')" | ||
| 12 | +case "$file_path" in *"/docs/08-模块任务管理.md") ;; *) exit 0 ;; esac | ||
| 13 | + | ||
| 14 | +# For Edit: check old_string/new_string; for Write: check content. | ||
| 15 | +old_str="$(printf '%s' "$input" | jq -r '.tool_input.old_string // empty')" | ||
| 16 | +new_str="$(printf '%s' "$input" | jq -r '.tool_input.new_string // empty')" | ||
| 17 | +content="$(printf '%s' "$input" | jq -r '.tool_input.content // empty')" | ||
| 18 | + | ||
| 19 | +flipping=0 | ||
| 20 | +if [ -n "$old_str" ] && [ -n "$new_str" ]; then | ||
| 21 | + if printf '%s' "$old_str" | grep -q 'confirmed:[[:space:]]*false' && \ | ||
| 22 | + printf '%s' "$new_str" | grep -q 'confirmed:[[:space:]]*true'; then | ||
| 23 | + flipping=1 | ||
| 24 | + fi | ||
| 25 | +fi | ||
| 26 | +if [ -n "$content" ] && [ "$flipping" = 0 ]; then | ||
| 27 | + # Full overwrite: compare against current file's `false` entries to detect a flip. | ||
| 28 | + if [ -f "$file_path" ]; then | ||
| 29 | + cur_false_count="$(grep -c 'confirmed:[[:space:]]*false' "$file_path" || true)" | ||
| 30 | + new_false_count="$(printf '%s' "$content" | grep -c 'confirmed:[[:space:]]*false' || true)" | ||
| 31 | + [ "$new_false_count" -lt "$cur_false_count" ] && flipping=1 | ||
| 32 | + fi | ||
| 33 | +fi | ||
| 34 | + | ||
| 35 | +[ "$flipping" = 1 ] || exit 0 | ||
| 36 | + | ||
| 37 | +transcript_path="$(printf '%s' "$input" | jq -r '.transcript_path // empty')" | ||
| 38 | +evidence=0 | ||
| 39 | +if [ -n "$transcript_path" ] && [ -f "$transcript_path" ]; then | ||
| 40 | + if grep -E '"state"[[:space:]]*:[[:space:]]*"merged"|state:[[:space:]]*merged|MERGED' "$transcript_path" >/dev/null 2>&1; then | ||
| 41 | + evidence=1 | ||
| 42 | + fi | ||
| 43 | +fi | ||
| 44 | + | ||
| 45 | +if [ "$evidence" = 0 ]; then | ||
| 46 | + echo "BLOCKED: flipping confirmed:false → true requires prior evidence that the MR is merged. Run \`glab mr view <iid> -F json\` first (via erp-confirmed-update skill) and confirm state=merged. 若 MR 未合并即改 confirmed,等于跳过人工审核。" >&2 | ||
| 47 | + exit 2 | ||
| 48 | +fi | ||
| 49 | + | ||
| 50 | +exit 0 |
_pl_staging/pl_hooks/log-cross-module.sh
0 → 100755
| 1 | +++ a/_pl_staging/pl_hooks/log-cross-module.sh | ||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# PostToolUse hook: detect Edit/Write to a file inside a confirmed:true module and stub-log to cross-module file. | ||
| 3 | +# Triggers soft rule S2. | ||
| 4 | + | ||
| 5 | +set -euo pipefail | ||
| 6 | + | ||
| 7 | +input="$(cat)" | ||
| 8 | +tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty')" | ||
| 9 | +case "$tool_name" in Edit|Write) ;; *) exit 0 ;; esac | ||
| 10 | + | ||
| 11 | +file_path="$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')" | ||
| 12 | +[ -n "$file_path" ] || exit 0 | ||
| 13 | + | ||
| 14 | +project_dir="${CLAUDE_PROJECT_DIR:-$(pwd)}" | ||
| 15 | +docs08="$project_dir/docs/08-模块任务管理.md" | ||
| 16 | +[ -f "$docs08" ] || exit 0 | ||
| 17 | + | ||
| 18 | +# Skip changes to docs/08 itself (handled by guard-confirmed-flip). | ||
| 19 | +case "$file_path" in *"/docs/08-模块任务管理.md") exit 0 ;; esac | ||
| 20 | + | ||
| 21 | +# Determine current (first confirmed:false) module. | ||
| 22 | +current_module="$(awk '/confirmed:[[:space:]]*false/ {print prev; exit} {prev=$0}' "$docs08" | sed -nE 's/^[[:space:]]*([A-Za-z0-9_-]+):.*/\1/p')" | ||
| 23 | +[ -n "$current_module" ] || exit 0 | ||
| 24 | + | ||
| 25 | +# Collect confirmed:true modules and their path scopes. | ||
| 26 | +# Expected YAML shape in docs/08 per module: | ||
| 27 | +# module_N: | ||
| 28 | +# name: ... | ||
| 29 | +# paths: [src/foo/**, frontend/bar/**] | ||
| 30 | +# confirmed: true | ||
| 31 | +confirmed_true_modules="$(awk ' | ||
| 32 | + /^[[:space:]]*[A-Za-z0-9_-]+:[[:space:]]*$/ { name=$1; sub(":","",name) } | ||
| 33 | + /confirmed:[[:space:]]*true/ { print name } | ||
| 34 | +' "$docs08")" | ||
| 35 | + | ||
| 36 | +[ -n "$confirmed_true_modules" ] || exit 0 | ||
| 37 | + | ||
| 38 | +hit_module="" | ||
| 39 | +for m in $confirmed_true_modules; do | ||
| 40 | + [ "$m" = "$current_module" ] && continue | ||
| 41 | + # Read paths list for this module (best-effort — match lines under this module before next module). | ||
| 42 | + scopes="$(awk -v mod="$m" ' | ||
| 43 | + $0 ~ "^[[:space:]]*"mod":[[:space:]]*$" {in_mod=1; next} | ||
| 44 | + in_mod && /^[A-Za-z0-9_-]+:[[:space:]]*$/ {in_mod=0} | ||
| 45 | + in_mod && /paths:/ {gsub(/.*paths:[[:space:]]*\[/,""); gsub(/\].*/,""); gsub(/["'"'"' ]/,""); print; exit} | ||
| 46 | + ' "$docs08")" | ||
| 47 | + [ -n "$scopes" ] || continue | ||
| 48 | + IFS=',' read -ra scope_arr <<< "$scopes" | ||
| 49 | + for s in "${scope_arr[@]}"; do | ||
| 50 | + [ -z "$s" ] && continue | ||
| 51 | + pattern="${s%/\*\*}" | ||
| 52 | + case "$file_path" in *"$pattern"*) hit_module="$m"; break 2;; esac | ||
| 53 | + done | ||
| 54 | +done | ||
| 55 | + | ||
| 56 | +[ -n "$hit_module" ] || exit 0 | ||
| 57 | + | ||
| 58 | +log_dir="$project_dir/docs/superpowers/module-reports" | ||
| 59 | +mkdir -p "$log_dir" | ||
| 60 | +log_file="$log_dir/${current_module}-cross-module.md" | ||
| 61 | +if [ ! -f "$log_file" ]; then | ||
| 62 | + { | ||
| 63 | + echo "# 跨模块改动日志 — ${current_module}" | ||
| 64 | + echo "" | ||
| 65 | + echo "| 时间戳 | 目标模块 | 文件 | 改动摘要 | 原因 | 影响评估 |" | ||
| 66 | + echo "|---|---|---|---|---|---|" | ||
| 67 | + } > "$log_file" | ||
| 68 | +fi | ||
| 69 | + | ||
| 70 | +ts="$(date -u +%FT%TZ)" | ||
| 71 | +rel_path="${file_path#$project_dir/}" | ||
| 72 | +echo "| ${ts} | ${hit_module} | ${rel_path} | ${tool_name} | TBD(待填) | TBD(待填) |" >> "$log_file" | ||
| 73 | + | ||
| 74 | +jq -n --arg m "$hit_module" --arg f "$log_file" --arg p "$rel_path" \ | ||
| 75 | + '{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:("Cross-module edit detected: \($p) belongs to confirmed:true module [\($m)]. Stub logged to \($f). Invoke erp-cross-module-log skill to fill 原因 and 影响评估. (软规则 S2)")}}' |
_pl_staging/pl_hooks/log-ddl.sh
0 → 100755
| 1 | +++ a/_pl_staging/pl_hooks/log-ddl.sh | ||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# PostToolUse hook: detect DDL in MCP mysql_query and stub-log to current module's schema-scratch file. | ||
| 3 | +# Triggers soft rule S1 — DDL is allowed during debug, but must be rolled back by module gate. | ||
| 4 | + | ||
| 5 | +set -euo pipefail | ||
| 6 | + | ||
| 7 | +input="$(cat)" | ||
| 8 | +tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty')" | ||
| 9 | +[ "$tool_name" = "mcp__mcp_server_mysql__mysql_query" ] || exit 0 | ||
| 10 | + | ||
| 11 | +sql="$(printf '%s' "$input" | jq -r '.tool_input.sql // .tool_input.query // empty')" | ||
| 12 | +[ -n "$sql" ] || exit 0 | ||
| 13 | + | ||
| 14 | +if ! printf '%s' "$sql" | grep -iqE '\b(CREATE|ALTER|DROP|TRUNCATE)[[:space:]]+(TABLE|INDEX|VIEW|DATABASE|SCHEMA)\b'; then | ||
| 15 | + exit 0 | ||
| 16 | +fi | ||
| 17 | + | ||
| 18 | +project_dir="${CLAUDE_PROJECT_DIR:-$(pwd)}" | ||
| 19 | +docs08="$project_dir/docs/08-模块任务管理.md" | ||
| 20 | +module_name="unknown-module" | ||
| 21 | +if [ -f "$docs08" ]; then | ||
| 22 | + module_name="$(awk '/confirmed:[[:space:]]*false/ {print prev; exit} {prev=$0}' "$docs08" | sed -nE 's/^[[:space:]]*([A-Za-z0-9_-]+):.*/\1/p')" | ||
| 23 | + [ -n "$module_name" ] || module_name="unknown-module" | ||
| 24 | +fi | ||
| 25 | + | ||
| 26 | +log_dir="$project_dir/docs/superpowers/module-reports" | ||
| 27 | +mkdir -p "$log_dir" | ||
| 28 | +log_file="$log_dir/${module_name}-schema-scratch.md" | ||
| 29 | + | ||
| 30 | +if [ ! -f "$log_file" ]; then | ||
| 31 | + { | ||
| 32 | + echo "# Schema 临时改动日志 — ${module_name}" | ||
| 33 | + echo "" | ||
| 34 | + echo "| 时间戳 | SQL | 原因 | 预计回撤时机 |" | ||
| 35 | + echo "|---|---|---|---|" | ||
| 36 | + } > "$log_file" | ||
| 37 | +fi | ||
| 38 | + | ||
| 39 | +ts="$(date -u +%FT%TZ)" | ||
| 40 | +sql_one_line="$(printf '%s' "$sql" | tr '\n' ' ' | sed 's/|/\\|/g' | cut -c1-200)" | ||
| 41 | +echo "| ${ts} | \`${sql_one_line}\` | TBD(待填) | TBD(待填) |" >> "$log_file" | ||
| 42 | + | ||
| 43 | +jq -n --arg msg "DDL detected on schema. Stub logged to ${log_file}. Invoke erp-schema-scratch-log skill to fill 原因 and 回撤时机. Remember: 软规则 S1 — schema must be rolled back to baseline before module gate, else 升级为红旗。" '{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:$msg}}' |
_pl_staging/pl_hooks/session-start-dispatch.sh
0 → 100755
| 1 | +++ a/_pl_staging/pl_hooks/session-start-dispatch.sh | ||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# SessionStart hook: remind CC to run erp-session-start for phase detection & dispatch. | ||
| 3 | + | ||
| 4 | +cat <<'EOF' | ||
| 5 | +[ERP skills] Session started. Run /erp-session-start to auto-detect the current phase (Layer 1 planning / Layer 2 module loop / blocker) and dispatch to the next skill. See CLAUDE.md for the 6-flag + 2-soft-rule shortlist. | ||
| 6 | +EOF |
_pl_staging/pl_settings.json
0 → 100644
| 1 | +++ a/_pl_staging/pl_settings.json | ||
| 1 | +{ | ||
| 2 | + "hooks": { | ||
| 3 | + "PreToolUse": [ | ||
| 4 | + { | ||
| 5 | + "matcher": "Bash", | ||
| 6 | + "hooks": [ | ||
| 7 | + { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/deny-no-verify.sh" } | ||
| 8 | + ] | ||
| 9 | + }, | ||
| 10 | + { | ||
| 11 | + "matcher": "Edit|Write", | ||
| 12 | + "hooks": [ | ||
| 13 | + { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/guard-confirmed-flip.sh" } | ||
| 14 | + ] | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "PostToolUse": [ | ||
| 18 | + { | ||
| 19 | + "matcher": "mcp__mcp_server_mysql__mysql_query", | ||
| 20 | + "hooks": [ | ||
| 21 | + { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/log-ddl.sh" } | ||
| 22 | + ] | ||
| 23 | + }, | ||
| 24 | + { | ||
| 25 | + "matcher": "Edit|Write", | ||
| 26 | + "hooks": [ | ||
| 27 | + { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/log-cross-module.sh" } | ||
| 28 | + ] | ||
| 29 | + } | ||
| 30 | + ], | ||
| 31 | + "SessionStart": [ | ||
| 32 | + { | ||
| 33 | + "hooks": [ | ||
| 34 | + { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-start-dispatch.sh" } | ||
| 35 | + ] | ||
| 36 | + } | ||
| 37 | + ] | ||
| 38 | + } | ||
| 39 | +} |
_pl_staging/pl_settings.local.json
0 → 100644
| 1 | +++ a/_pl_staging/pl_settings.local.json | ||
| 1 | +{ | ||
| 2 | + "permissions": { | ||
| 3 | + "allow": [ | ||
| 4 | + "mcp__mcp_server_mysql__mysql_query", | ||
| 5 | + "Bash(ls docs/)", | ||
| 6 | + "Bash(ls scripts/ .githooks/)", | ||
| 7 | + "Bash(ls .mcp.json docs/superpowers/schema-baseline.sql)", | ||
| 8 | + "Bash(ls docs/01-需求清单/)", | ||
| 9 | + "Bash(sed -i.bak -e 's|@references/|templates/|g' __TRACKED_VAR__/SKILL.md)", | ||
| 10 | + "Bash(rm __TRACKED_VAR__/SKILL.md.bak)", | ||
| 11 | + "Bash(mkdir -p erp-workflow-plugin/.claude-plugin erp-workflow-plugin/hooks/scripts)", | ||
| 12 | + "Bash(cp -r .claude/skills erp-workflow-plugin/skills)", | ||
| 13 | + "Bash(cp -r .claude/commands erp-workflow-plugin/commands)", | ||
| 14 | + "Bash(cp .claude/hooks/*.sh erp-workflow-plugin/hooks/scripts/)", | ||
| 15 | + "Bash(cp CLAUDE.md erp-workflow-plugin/CLAUDE.md.template)", | ||
| 16 | + "Bash(sed -i.bak -e 's|`\\\\.claude/skills/erp-understanding-report/templates/understanding-report-template\\\\.md`|由 erp-understanding-report skill 持有,安装插件后 skill 自动读取|g' -e 's|`\\\\.claude/skills/erp-module-report/templates/module-report-template\\\\.md`|由 erp-module-report skill 持有|g' -e 's|`\\\\.claude/skills/erp-feature-verify/templates/feature-verify-evidence-template\\\\.md`|由 erp-feature-verify skill 持有|g' -e 's|`\\\\.claude/skills/erp-\\\\*/templates/\\\\*`|插件 `skills/erp-*/templates/*`|g' erp-workflow-plugin/CLAUDE.md.template)", | ||
| 17 | + "Bash(rm erp-workflow-plugin/CLAUDE.md.template.bak)" | ||
| 18 | + ], | ||
| 19 | + "deny": [] | ||
| 20 | + } | ||
| 21 | +} |
_pl_staging/pl_skills/erp-confirmed-update/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-confirmed-update/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-confirmed-update | ||
| 3 | +description: After the human merges the module's MR, verify merged state via glab mr view, flip docs/08 confirmed:false→true, commit the flip, and hand back to erp-session-start for the next module. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-confirmed-update | ||
| 7 | + | ||
| 8 | +## Pre-conditions | ||
| 9 | + | ||
| 10 | +- User said "MR 已合" OR auto-trigger from `erp-session-start` ladder step 8. | ||
| 11 | +- `docs/08` current module's MR IID known (from § ⑫ of module report). | ||
| 12 | + | ||
| 13 | +## Procedure | ||
| 14 | + | ||
| 15 | +1. Run `glab mr view <iid> -F json` (direct Bash; no subagent needed — it's a read). | ||
| 16 | +2. Parse JSON; verify `.state == "merged"` (and `.merge_status == "merged"` if present). | ||
| 17 | +3. On not-merged → print state, stop (do NOT flip). | ||
| 18 | +4. On merged: | ||
| 19 | + a. Edit `docs/08-模块任务管理.md`: for the current module, change `confirmed: false` → `confirmed: true`. Change exactly one line. | ||
| 20 | + - **`guard-confirmed-flip.sh` hook will verify merged evidence is in the transcript** — since we just ran `glab mr view` above, that check will see it. | ||
| 21 | + b. Stage `docs/08-模块任务管理.md`. | ||
| 22 | + c. Read `templates/confirmed-flip-commit-template.md`; fill `module_id`, `mr_iid`; commit with that message. | ||
| 23 | +5. Print `confirmed-update: <module_id> → true (MR !<iid>)`. | ||
| 24 | +6. Invoke `erp-session-start` to dispatch to the next module. | ||
| 25 | + | ||
| 26 | +## Invariants | ||
| 27 | + | ||
| 28 | +- Never flip `confirmed: true → false` in this skill (that's a red-flag-reopen flow, handled manually). | ||
| 29 | +- Never flip for a module other than the current (first `confirmed: false`). | ||
| 30 | + | ||
| 31 | +## References | ||
| 32 | + | ||
| 33 | +- `templates/confirmed-flip-commit-template.md` | ||
| 34 | +- `templates/docs-08-flip-diff-template.md` | ||
| 35 | +- Hook interlock: `guard-confirmed-flip.sh` |
_pl_staging/pl_skills/erp-confirmed-update/templates/confirmed-flip-commit-template.md
0 → 100644
_pl_staging/pl_skills/erp-confirmed-update/templates/docs-08-flip-diff-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-confirmed-update/templates/docs-08-flip-diff-template.md | ||
| 1 | +Expected unified-diff shape for a legitimate confirmed flip: | ||
| 2 | + | ||
| 3 | +``` | ||
| 4 | +@@ | ||
| 5 | + {{module_id}}: | ||
| 6 | + name: ... | ||
| 7 | + ... | ||
| 8 | +- confirmed: false | ||
| 9 | ++ confirmed: true | ||
| 10 | +``` | ||
| 11 | + | ||
| 12 | +Exactly one block changed from `false` to `true`. Any other shape is suspicious — `guard-confirmed-flip.sh` will block unless merged-state evidence is present. |
_pl_staging/pl_skills/erp-cross-module-log/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-cross-module-log/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-cross-module-log | ||
| 3 | +description: Fill in 原因 and 影响评估 for cross-module edit stubs that the `log-cross-module.sh` hook auto-appended to `docs/superpowers/module-reports/<current>-cross-module.md`. Covers edits to files inside `confirmed: true` modules. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-cross-module-log | ||
| 7 | + | ||
| 8 | +## What | ||
| 9 | + | ||
| 10 | +Soft-rule S2 enforcement: every edit to a confirmed-merged module must be logged with reason + impact assessment. | ||
| 11 | + | ||
| 12 | +## Procedure | ||
| 13 | + | ||
| 14 | +1. Identify the current module (first `confirmed: false` in `docs/08-模块任务管理.md`). | ||
| 15 | +2. Open `docs/superpowers/module-reports/<current>-cross-module.md` (init from `templates/cross-module-log-template.md` if absent). | ||
| 16 | +3. Find rows with `TBD(待填)` in 原因 or 影响评估 columns. | ||
| 17 | +4. For each TBD row: | ||
| 18 | + - **原因**: why was the target module's code modified? What requirement in the current module forced it? | ||
| 19 | + - **影响评估**: which APIs / behaviors / callers in the target module may be affected? Are its existing tests still valid? Are new tests needed? (1-3 sentences) | ||
| 20 | +5. Edit the row; keep 时间戳 / 目标模块 / 文件 / 改动摘要 immutable. | ||
| 21 | +6. Print a one-line confirmation: `cross-module-log: N rows updated`. | ||
| 22 | + | ||
| 23 | +## Downstream | ||
| 24 | + | ||
| 25 | +The filled log is embedded verbatim into `module-report-template.md` § ⑦ by `erp-module-report`. | ||
| 26 | + | ||
| 27 | +## References | ||
| 28 | + | ||
| 29 | +- `templates/cross-module-log-template.md` | ||
| 30 | +- `templates/cross-module-log-row-template.md` | ||
| 31 | +- `CLAUDE.md` § 🟡 软规则 S2 |
_pl_staging/pl_skills/erp-cross-module-log/templates/cross-module-log-row-template.md
0 → 100644
_pl_staging/pl_skills/erp-cross-module-log/templates/cross-module-log-template.md
0 → 100644
_pl_staging/pl_skills/erp-downstream-gen/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-downstream-gen/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-downstream-gen | ||
| 3 | +description: Plan-phase step A5. Generate docs/02 + docs/05 + docs/06 五节 + docs/08 + docs/10 + sql/seed-data.sql in one pass, derived from docs/01 and docs/03. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-downstream-gen | ||
| 7 | + | ||
| 8 | +## Pre-conditions | ||
| 9 | + | ||
| 10 | +- `docs/01-需求清单/*.md` full REQ cards present. | ||
| 11 | +- `docs/03-数据库设计文档.md` present. | ||
| 12 | +- Human has reviewed 01 and 03 (ask user to confirm before proceeding). | ||
| 13 | + | ||
| 14 | +## Procedure | ||
| 15 | + | ||
| 16 | +### A. docs/02 — 开发计划 | ||
| 17 | +1. Build module dependency DAG from: | ||
| 18 | + - FKs in docs/03 (table A → table B ⇒ A's module depends on B's module) | ||
| 19 | + - Explicit `depends_on` hints in docs/01 READMEs | ||
| 20 | +2. Topological sort → `order[]`. | ||
| 21 | +3. Read `templates/docs-02-template.md`; fill `modules[]`, `order[]`, `notes`. | ||
| 22 | +4. Write `docs/02-开发计划.md`. | ||
| 23 | + | ||
| 24 | +### B. docs/05 — API 接口契约 | ||
| 25 | +1. Read `templates/docs-05-header-template.md`; write header to `docs/05-API接口契约.md`. | ||
| 26 | +2. For each REQ across all modules: read `templates/docs-05-endpoint-template.md`; infer method / path / auth / permission / request & response schemas (ask user for non-obvious ones); append to `docs/05`. | ||
| 27 | + | ||
| 28 | +### C. docs/06 — 页面清单 | ||
| 29 | +1. For each module with frontend pages: read `templates/docs-06-module-pagelist-template.md`; fill `pages[]` (page_name, route, page_type, req_ids, menu_path, interactions). | ||
| 30 | +2. Append each rendered block to `docs/06-UI交互规范.md` § 五. | ||
| 31 | + | ||
| 32 | +### D. docs/08 — 模块任务管理 | ||
| 33 | +1. Read `templates/docs-08-header-template.md`; write header to `docs/08-模块任务管理.md`. | ||
| 34 | +2. For each module in topological order: read `templates/docs-08-module-row-template.md`; fill `module_id`, `module_name`, `depends_on`, `req_ids`, `path_scopes` (from docs/09 + module code prefix), `confirmed: false`; append. | ||
| 35 | + | ||
| 36 | +### E. docs/10 — 验收清单 | ||
| 37 | +1. Read `templates/docs-10-header-template.md`; write header to `docs/10-验收检查清单.md`. | ||
| 38 | +2. For each module: read `templates/docs-10-module-template.md`; fill `reqs[]`, `data_checks[]`, `ui_checks[]`; append. | ||
| 39 | + | ||
| 40 | +### F. sql/seed-data.sql | ||
| 41 | +1. Read `templates/seed-data-sql-template.sql`. | ||
| 42 | +2. For each module, ask user or infer minimal seed rows (enough for acceptance tests to pass). Fill `module_blocks[]`. | ||
| 43 | +3. Write `sql/seed-data.sql`. | ||
| 44 | + | ||
| 45 | +### G. Validate | ||
| 46 | +- Every REQ in docs/01 appears in docs/05 (as an endpoint if applicable), docs/08 (under its module), docs/10 (as an acceptance item). | ||
| 47 | +- Every module in docs/02 order has a row in docs/08 with `confirmed: false`. | ||
| 48 | +- Run `erp-placeholder-scan` over the 5 files — log residuals. | ||
| 49 | + | ||
| 50 | +Print: `downstream-gen: wrote 5 files + seed. Awaiting human review.` | ||
| 51 | + | ||
| 52 | +## References | ||
| 53 | + | ||
| 54 | +- `templates/docs-02-template.md` | ||
| 55 | +- `templates/docs-05-header-template.md` | ||
| 56 | +- `templates/docs-05-endpoint-template.md` | ||
| 57 | +- `templates/docs-06-module-pagelist-template.md` | ||
| 58 | +- `templates/docs-08-header-template.md` | ||
| 59 | +- `templates/docs-08-module-row-template.md` | ||
| 60 | +- `templates/docs-10-header-template.md` | ||
| 61 | +- `templates/docs-10-module-template.md` | ||
| 62 | +- `templates/seed-data-sql-template.sql` |
_pl_staging/pl_skills/erp-downstream-gen/templates/docs-02-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-downstream-gen/templates/docs-02-template.md | ||
| 1 | +# 02-开发计划 | ||
| 2 | + | ||
| 3 | +模块按**技术依赖**排序,非业务优先级。 | ||
| 4 | + | ||
| 5 | +## 模块依赖表 | ||
| 6 | + | ||
| 7 | +| 模块 ID | 模块名 | 依赖模块 | 依赖表 | 估算天数 | | ||
| 8 | +|---|---|---|---|---| | ||
| 9 | +{{#each modules}} | ||
| 10 | +| {{id}} | {{name}} | {{deps}} | {{tables}} | {{days}} | | ||
| 11 | +{{/each}} | ||
| 12 | + | ||
| 13 | +## 开发顺序(拓扑序) | ||
| 14 | +{{#each order}} | ||
| 15 | +{{index}}. {{module_id}} — {{module_name}} | ||
| 16 | +{{/each}} | ||
| 17 | + | ||
| 18 | +## 关键说明 | ||
| 19 | +{{notes}} |
_pl_staging/pl_skills/erp-downstream-gen/templates/docs-05-endpoint-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-downstream-gen/templates/docs-05-endpoint-template.md | ||
| 1 | +### {{req_id}} {{title}} | ||
| 2 | + | ||
| 3 | +- **Method**: {{method}} | ||
| 4 | +- **Path**: `{{path}}` | ||
| 5 | +- **Auth**: {{auth}} | ||
| 6 | +- **Permission**: {{permission}} | ||
| 7 | + | ||
| 8 | +#### 请求参数 | ||
| 9 | +{{request_params}} | ||
| 10 | + | ||
| 11 | +#### 请求体 | ||
| 12 | +```json | ||
| 13 | +{{request_body_schema}} | ||
| 14 | +``` | ||
| 15 | + | ||
| 16 | +#### 响应体 | ||
| 17 | +```json | ||
| 18 | +{{response_body_schema}} | ||
| 19 | +``` | ||
| 20 | + | ||
| 21 | +#### 错误码 | ||
| 22 | +{{#each errors}} | ||
| 23 | +- `{{code}}` — {{message}} | ||
| 24 | +{{/each}} |
_pl_staging/pl_skills/erp-downstream-gen/templates/docs-05-header-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-downstream-gen/templates/docs-05-header-template.md | ||
| 1 | +# 05-API接口契约 | ||
| 2 | + | ||
| 3 | +BasePath: `{{base_path}}` | ||
| 4 | +端口: `【人工填写:后端端口,默认 8080】` | ||
| 5 | + | ||
| 6 | +## 全局约定 | ||
| 7 | + | ||
| 8 | +### 响应格式 | ||
| 9 | +```json | ||
| 10 | +{"code": 200, "message": "操作成功", "data": {}, "timestamp": 1700000000000} | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +### 错误码 | ||
| 14 | +| 范围 | 含义 | | ||
| 15 | +|---|---| | ||
| 16 | +| 200 | 成功 | | ||
| 17 | +| 400xx | 客户端参数错误 | | ||
| 18 | +| 401xx | 认证/授权错误 | | ||
| 19 | +| 403xx | 权限不足 | | ||
| 20 | +| 404xx | 资源不存在 | | ||
| 21 | +| 500xx | 服务端内部错误 | | ||
| 22 | + | ||
| 23 | +### 鉴权 | ||
| 24 | +{{auth_note}} | ||
| 25 | + | ||
| 26 | +### 分页参数 | ||
| 27 | +{{pagination_note}} | ||
| 28 | + | ||
| 29 | +## 接口清单 | ||
| 30 | +(各模块接口段落见下方,由 `erp-downstream-gen` 按 REQ 填入) |
_pl_staging/pl_skills/erp-downstream-gen/templates/docs-06-module-pagelist-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-downstream-gen/templates/docs-06-module-pagelist-template.md | ||
| 1 | +### {{module_id}} {{module_name}} | ||
| 2 | + | ||
| 3 | +{{#each pages}} | ||
| 4 | +- **{{page_name}}** (`{{route}}`) | ||
| 5 | + - 类型: {{page_type}} (列表页 / 表单页 / 详情页 / 树形管理页) | ||
| 6 | + - 对应 REQ: {{req_ids}} | ||
| 7 | + - 入口菜单: {{menu_path}} | ||
| 8 | + - 主要交互: {{interactions}} | ||
| 9 | +{{/each}} |
_pl_staging/pl_skills/erp-downstream-gen/templates/docs-08-header-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-downstream-gen/templates/docs-08-header-template.md | ||
| 1 | +# 08-模块任务管理 | ||
| 2 | + | ||
| 3 | +`confirmed` 语义(权威定义在 `CLAUDE.md`): | ||
| 4 | +- `false` → 模块待完成或被重开,CC 在此模块工作 | ||
| 5 | +- `true` → 已 MR Approve + Merge,CC 进入下一 `false` 模块 | ||
| 6 | + | ||
| 7 | +CC 修改 `false → true` 需 MR 已 merged 证据(hook `guard-confirmed-flip.sh` 强制)。 | ||
| 8 | + | ||
| 9 | +## 模块列表 |
_pl_staging/pl_skills/erp-downstream-gen/templates/docs-08-module-row-template.md
0 → 100644
_pl_staging/pl_skills/erp-downstream-gen/templates/docs-10-header-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-downstream-gen/templates/docs-10-header-template.md | ||
| 1 | +# 10-验收检查清单 | ||
| 2 | + | ||
| 3 | +通用验收项(全项目适用): | ||
| 4 | + | ||
| 5 | +- [ ] `scripts/test.sh` 本地全绿 | ||
| 6 | +- [ ] schema 与 `docs/superpowers/schema-baseline.sql` 一致(无未回撤 DDL) | ||
| 7 | +- [ ] 所有新接口在 `docs/05` 中有契约定义 | ||
| 8 | +- [ ] 所有新功能代码注释含 REQ-XXX-NNN | ||
| 9 | +- [ ] 统一响应格式 `{code, message, data, timestamp}` | ||
| 10 | +- [ ] 异常走全局处理器,不暴露堆栈到前端 | ||
| 11 | +- [ ] 前端不存敏感信息到 localStorage | ||
| 12 | + | ||
| 13 | +## 模块专项 | ||
| 14 | +(各模块验收段落见下方,由 `erp-downstream-gen` 按模块填入) |
_pl_staging/pl_skills/erp-downstream-gen/templates/docs-10-module-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-downstream-gen/templates/docs-10-module-template.md | ||
| 1 | +### {{module_id}} {{module_name}} | ||
| 2 | + | ||
| 3 | +#### 功能级验收(每个 REQ 对应可执行用例) | ||
| 4 | +{{#each reqs}} | ||
| 5 | +- [ ] {{req_id}} {{title}} | ||
| 6 | + - 自动化用例: `{{test_file}}::{{test_name}}` | ||
| 7 | + - 手动验收: {{manual_check}} | ||
| 8 | +{{/each}} | ||
| 9 | + | ||
| 10 | +#### 数据级验收 | ||
| 11 | +{{#each data_checks}} | ||
| 12 | +- [ ] {{check}} | ||
| 13 | +{{/each}} | ||
| 14 | + | ||
| 15 | +#### UI 级验收(若含前端) | ||
| 16 | +{{#each ui_checks}} | ||
| 17 | +- [ ] {{check}} | ||
| 18 | +{{/each}} |
_pl_staging/pl_skills/erp-downstream-gen/templates/seed-data-sql-template.sql
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-downstream-gen/templates/seed-data-sql-template.sql | ||
| 1 | +-- seed-data.sql — 本地测试数据 | ||
| 2 | +-- Reloaded on every scripts/setup-test-db.sh run. | ||
| 3 | +-- Never mutate schema here; data only. | ||
| 4 | + | ||
| 5 | +SET FOREIGN_KEY_CHECKS = 0; | ||
| 6 | + | ||
| 7 | +{{#each module_blocks}} | ||
| 8 | +-- ========================================================== | ||
| 9 | +-- {{module_id}} {{module_name}} | ||
| 10 | +-- ========================================================== | ||
| 11 | +{{sql_block}} | ||
| 12 | + | ||
| 13 | +{{/each}} | ||
| 14 | + | ||
| 15 | +SET FOREIGN_KEY_CHECKS = 1; |
_pl_staging/pl_skills/erp-feature-brainstorm/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-feature-brainstorm/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-feature-brainstorm | ||
| 3 | +description: Feature-loop step 1. Thin wrapper over superpowers:brainstorming for a single REQ-XXX-NNN. Produces a spec file at docs/superpowers/specs/YYYY-MM-DD-<REQ>.md using the feature-spec-template, after interactive brainstorming with the user. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-feature-brainstorm | ||
| 7 | + | ||
| 8 | +## What | ||
| 9 | + | ||
| 10 | +Produce a ≤1-page spec for one REQ-XXX-NNN by delegating to `superpowers:brainstorming`, then pack the output into the standard spec template. | ||
| 11 | + | ||
| 12 | +## Procedure | ||
| 13 | + | ||
| 14 | +1. **Red-flag gate**: invoke `erp-red-flag-check`. If it halts → stop. | ||
| 15 | +2. Resolve inputs: | ||
| 16 | + - Current REQ-XXX-NNN (from conversation, or the next unfulfilled REQ in `docs/08` current module). | ||
| 17 | + - REQ card: `docs/01-需求清单/<module>.md` § REQ-XXX-NNN. | ||
| 18 | + - Relevant schema tables (from `docs/03` or live MCP query). | ||
| 19 | +3. Delegate to `superpowers:brainstorming` with the REQ card + schema refs as context. | ||
| 20 | +4. Derive path: `docs/superpowers/specs/$(date +%F)-<REQ-id>.md`. If already exists, overwrite with user confirmation. | ||
| 21 | +5. Read `templates/feature-spec-template.md`; fill slots from brainstorm output: | ||
| 22 | + - `goal`, `input`, `output`, `rules`, `constraints`, `schema_refs`, `api_refs`, `acceptance` | ||
| 23 | +6. Write the filled spec to the derived path. | ||
| 24 | +7. **Validate**: every top-level section in the template must be non-empty. If any slot is TBD, loop back to brainstorming for that slot. | ||
| 25 | +8. Print `feature-brainstorm: <REQ> → <path>` to session. | ||
| 26 | + | ||
| 27 | +## References | ||
| 28 | + | ||
| 29 | +- `templates/feature-spec-template.md` | ||
| 30 | +- Delegates: `superpowers:brainstorming` | ||
| 31 | +- Guard: `erp-red-flag-check` |
_pl_staging/pl_skills/erp-feature-brainstorm/templates/feature-spec-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-feature-brainstorm/templates/feature-spec-template.md | ||
| 1 | +--- | ||
| 2 | +req_id: {{req_id}} | ||
| 3 | +date: {{date}} | ||
| 4 | +module: {{module}} | ||
| 5 | +--- | ||
| 6 | + | ||
| 7 | +# Spec: {{req_id}} — {{title}} | ||
| 8 | + | ||
| 9 | +## 目标 | ||
| 10 | +{{goal}} | ||
| 11 | + | ||
| 12 | +## 输入 / 触发 | ||
| 13 | +{{input}} | ||
| 14 | + | ||
| 15 | +## 输出 / 结果 | ||
| 16 | +{{output}} | ||
| 17 | + | ||
| 18 | +## 业务规则 | ||
| 19 | +{{rules}} | ||
| 20 | + | ||
| 21 | +## 边界与约束 | ||
| 22 | +{{constraints}} | ||
| 23 | + | ||
| 24 | +## 依赖的 schema 表 / 字段 | ||
| 25 | +{{schema_refs}} | ||
| 26 | + | ||
| 27 | +## 依赖的接口 | ||
| 28 | +{{api_refs}} | ||
| 29 | + | ||
| 30 | +## 验收标准 | ||
| 31 | +{{acceptance}} |
_pl_staging/pl_skills/erp-feature-plan/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-feature-plan/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-feature-plan | ||
| 3 | +description: Feature-loop step 2. Thin wrapper over superpowers:writing-plans. Turns a spec into a task-level plan (2–5 min per task, with file paths and full code) at docs/superpowers/plans/YYYY-MM-DD-<REQ>.md. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-feature-plan | ||
| 7 | + | ||
| 8 | +## Procedure | ||
| 9 | + | ||
| 10 | +1. **Red-flag gate**: `erp-red-flag-check`. | ||
| 11 | +2. Resolve inputs: | ||
| 12 | + - Current REQ-XXX-NNN and the spec at `docs/superpowers/specs/YYYY-MM-DD-<REQ>.md` (fail if spec missing). | ||
| 13 | + - Relevant code pointers (existing files to touch, discoverable via Grep). | ||
| 14 | + - `docs/04-技术规范.md` and `docs/09-项目目录结构.md` (编码规范 + 目录规范). | ||
| 15 | +3. Delegate to `superpowers:writing-plans` with spec + code pointers + conventions. | ||
| 16 | +4. Derive path: `docs/superpowers/plans/$(date +%F)-<REQ-id>.md`. | ||
| 17 | +5. Read `templates/feature-plan-template.md`; fill `files[]`, `tasks[]`, `commits[]`. | ||
| 18 | +6. Enforce: each task must be 2–5 min, have a failing test identifier, an impl path, and a done_when criterion. | ||
| 19 | +7. Write the plan. | ||
| 20 | +8. Print `feature-plan: <REQ> → <path>` to session. | ||
| 21 | + | ||
| 22 | +## References | ||
| 23 | + | ||
| 24 | +- `templates/feature-plan-template.md` | ||
| 25 | +- Delegates: `superpowers:writing-plans` | ||
| 26 | +- Guard: `erp-red-flag-check` |
_pl_staging/pl_skills/erp-feature-plan/templates/feature-plan-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-feature-plan/templates/feature-plan-template.md | ||
| 1 | +--- | ||
| 2 | +req_id: {{req_id}} | ||
| 3 | +date: {{date}} | ||
| 4 | +spec_ref: docs/superpowers/specs/{{date}}-{{req_id}}.md | ||
| 5 | +--- | ||
| 6 | + | ||
| 7 | +# Plan: {{req_id}} | ||
| 8 | + | ||
| 9 | +## 文件变更清单 | ||
| 10 | +{{#each files}} | ||
| 11 | +- `{{path}}` — {{action}}({{rationale}}) | ||
| 12 | +{{/each}} | ||
| 13 | + | ||
| 14 | +## 任务步骤(每步 2–5 分钟) | ||
| 15 | +{{#each tasks}} | ||
| 16 | +### Task {{index}}: {{title}} | ||
| 17 | +- 失败测试: `{{test_file}}::{{test_name}}` — {{test_intent}} | ||
| 18 | +- 实现路径: `{{impl_file}}` | ||
| 19 | +- 完成判据: {{done_when}} | ||
| 20 | +{{/each}} | ||
| 21 | + | ||
| 22 | +## 提交计划 | ||
| 23 | +{{#each commits}} | ||
| 24 | +- `{{message}}`(覆盖 Task {{task_index}}) | ||
| 25 | +{{/each}} |
_pl_staging/pl_skills/erp-feature-review/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-feature-review/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-feature-review | ||
| 3 | +description: Feature-loop step 5. Thin wrapper over superpowers:code-reviewer. Writes review report at docs/superpowers/reviews/YYYY-MM-DD-<REQ>.md. Self-fix loop capped at 3 rounds. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-feature-review | ||
| 7 | + | ||
| 8 | +## Procedure | ||
| 9 | + | ||
| 10 | +1. Delegate to `superpowers:code-reviewer` with the REQ's diff (`git diff <feature-start>..HEAD`) and the spec. | ||
| 11 | +2. Derive path: `docs/superpowers/reviews/$(date +%F)-<REQ-id>.md`. | ||
| 12 | +3. Read `templates/feature-review-template.md`; fill `round`, `verdict`, `must_fix[]`, `nice_to_have[]`, `gaps`. | ||
| 13 | +4. Write the report. | ||
| 14 | +5. Dispatch logic: | ||
| 15 | + - `verdict = approve` → print `feature-review: <REQ> APPROVED` and exit. | ||
| 16 | + - `verdict = request-changes` → fix Must-fix items, re-run `erp-feature-verify`, then re-review as round N+1. | ||
| 17 | +6. Cap: **3 rounds**. If still `request-changes` after round 3 → stop and print a summary; escalate to user. (Red flag #9 was removed from the strict halt list — use judgement, but don't loop forever.) | ||
| 18 | + | ||
| 19 | +## References | ||
| 20 | + | ||
| 21 | +- `templates/feature-review-template.md` | ||
| 22 | +- Delegates: `superpowers:code-reviewer` |
_pl_staging/pl_skills/erp-feature-review/templates/feature-review-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-feature-review/templates/feature-review-template.md | ||
| 1 | +--- | ||
| 2 | +req_id: {{req_id}} | ||
| 3 | +date: {{date}} | ||
| 4 | +round: {{round}} | ||
| 5 | +reviewer: superpowers:code-reviewer | ||
| 6 | +--- | ||
| 7 | + | ||
| 8 | +# Review: {{req_id}} — round {{round}} | ||
| 9 | + | ||
| 10 | +## 结论 | ||
| 11 | +{{verdict}} (approve / request-changes) | ||
| 12 | + | ||
| 13 | +## Must-fix | ||
| 14 | +{{#each must_fix}} | ||
| 15 | +- [{{severity}}] {{file}}:{{line}} — {{issue}}(建议:{{suggestion}}) | ||
| 16 | +{{/each}} | ||
| 17 | + | ||
| 18 | +## Nice-to-have | ||
| 19 | +{{#each nice_to_have}} | ||
| 20 | +- {{file}}:{{line}} — {{suggestion}} | ||
| 21 | +{{/each}} | ||
| 22 | + | ||
| 23 | +## 反例 / 测试覆盖缺口 | ||
| 24 | +{{gaps}} |
_pl_staging/pl_skills/erp-feature-tdd/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-feature-tdd/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-feature-tdd | ||
| 3 | +description: Feature-loop step 3. Thin wrapper over superpowers:test-driven-development. Executes tasks from the plan one by one, each commit follows the commit-message-template. CRITICAL: every red→green test run is dispatched to a fresh subagent per design principle #7. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-feature-tdd | ||
| 7 | + | ||
| 8 | +## Procedure | ||
| 9 | + | ||
| 10 | +1. **Red-flag gate**: `erp-red-flag-check`. | ||
| 11 | +2. Load the plan at `docs/superpowers/plans/YYYY-MM-DD-<REQ>.md`. | ||
| 12 | +3. For each task in order: | ||
| 13 | + a. Write the failing test(s) at `test_file::test_name`. | ||
| 14 | + b. **Dispatch a fresh subagent via `Agent` (general-purpose) to run the test and confirm it fails**; the subagent returns `{command, exit_code, failing_assertion}` only. Main session does NOT run the test directly. | ||
| 15 | + c. Implement the minimum code at `impl_file` to satisfy the test. | ||
| 16 | + d. **Dispatch another fresh subagent to run the test and confirm it passes**. | ||
| 17 | + e. On persistent failure (>5 attempts on the same test) → invoke `erp-red-flag-check` with flag #4. | ||
| 18 | + f. Stage changes and commit using `templates/commit-message-template.md`; `scope` matches the task's module, `subject` short (≤50 chars), `req_id` mandatory. | ||
| 19 | +4. After all tasks done → hand off to `erp-feature-verify`. | ||
| 20 | + | ||
| 21 | +## Guardrails | ||
| 22 | + | ||
| 23 | +- Never run `mvn test` / `pnpm test` / `scripts/test.sh` directly in the main session. Always via subagent. | ||
| 24 | +- Every commit must include the REQ-XXX-NNN tag. | ||
| 25 | +- Never batch unrelated changes into one commit. | ||
| 26 | + | ||
| 27 | +## References | ||
| 28 | + | ||
| 29 | +- `templates/commit-message-template.md` | ||
| 30 | +- Delegates: `superpowers:test-driven-development` | ||
| 31 | +- Guard: `erp-red-flag-check` |
_pl_staging/pl_skills/erp-feature-tdd/templates/commit-message-template.md
0 → 100644
_pl_staging/pl_skills/erp-feature-verify/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-feature-verify/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-feature-verify | ||
| 3 | +description: Feature-loop step 4. Thin wrapper over superpowers:verification-before-completion. Dispatches the REQ's test suite to a fresh subagent and renders the result through feature-verify-evidence-template. No "done" claim is allowed without this evidence. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-feature-verify | ||
| 7 | + | ||
| 8 | +## Procedure | ||
| 9 | + | ||
| 10 | +1. Determine the feature's test target (Maven profile / pnpm script / pytest path) from the plan or the project's standard commands. | ||
| 11 | +2. **Dispatch a fresh subagent via `Agent` (general-purpose)** with a prompt like: | ||
| 12 | + | ||
| 13 | + ``` | ||
| 14 | + Task: run the feature's test target and report back. Do NOT modify code. Steps: | ||
| 15 | + 1. Run: <command> (e.g., mvn -pl user-module test -Dtest=REQ* ) | ||
| 16 | + 2. Report ONLY structured JSON: {"command":"<cmd>","exit_code":<int>,"passed":<int>,"failed":<int>,"failed_list":["<test>", ...],"stdout_excerpt":"<last 30 lines or most-relevant failure excerpt>"} | ||
| 17 | + No prose. | ||
| 18 | + ``` | ||
| 19 | + | ||
| 20 | +3. Parse the JSON; read `templates/feature-verify-evidence-template.md`; fill slots including `subagent_id` and `conclusion`. | ||
| 21 | +4. If `exit_code != 0` or `failed > 0` → print the filled evidence to session and **stop**. Do not proceed to review. | ||
| 22 | +5. On pass → print the evidence; hand off to `erp-feature-review`. | ||
| 23 | + | ||
| 24 | +## Guardrails | ||
| 25 | + | ||
| 26 | +- Never paste raw test stdout into main session beyond the 30-line `stdout_excerpt`. | ||
| 27 | +- Evidence must be rendered from the template, never freely written. | ||
| 28 | + | ||
| 29 | +## References | ||
| 30 | + | ||
| 31 | +- `templates/feature-verify-evidence-template.md` | ||
| 32 | +- Delegates: `superpowers:verification-before-completion` |
_pl_staging/pl_skills/erp-feature-verify/templates/feature-verify-evidence-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-feature-verify/templates/feature-verify-evidence-template.md | ||
| 1 | +## Verify evidence — {{req_id}} | ||
| 2 | + | ||
| 3 | +- 命令: `{{command}}` | ||
| 4 | +- 子会话: {{subagent_id}} | ||
| 5 | +- 退出码: {{exit_code}} | ||
| 6 | +- 通过用例数: {{passed}} | ||
| 7 | +- 失败用例数: {{failed}} | ||
| 8 | +- 失败列表: {{failed_list}} | ||
| 9 | + | ||
| 10 | +关键 stdout 片段 (≤30 行): | ||
| 11 | + | ||
| 12 | +``` | ||
| 13 | +{{stdout_excerpt}} | ||
| 14 | +``` | ||
| 15 | + | ||
| 16 | +结论: {{conclusion}} (pass / fail) |
_pl_staging/pl_skills/erp-local-test-gate/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-local-test-gate/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-local-test-gate | ||
| 3 | +description: The only hard gate before MR creation. Runs schema-baseline-check + placeholder-scan + scripts/test.sh. scripts/test.sh is dispatched to a fresh subagent (design principle #7). Non-zero on any check = stop. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-local-test-gate | ||
| 7 | + | ||
| 8 | +## Procedure | ||
| 9 | + | ||
| 10 | +1. Invoke `erp-schema-baseline-check`. | ||
| 11 | + - Dirty → flag #1 raised by the skill, stop. | ||
| 12 | +2. Invoke `erp-placeholder-scan` over `docs/**`, `.env*`, `scripts/**`, `CLAUDE.md`. | ||
| 13 | + - Non-empty hits → stop. | ||
| 14 | +3. **Dispatch a fresh subagent (general-purpose)** to run `./scripts/test.sh`: | ||
| 15 | + | ||
| 16 | + ``` | ||
| 17 | + Task: run the project's local test gate. Do NOT modify any code or data. Steps: | ||
| 18 | + 1. cd to the repo root. | ||
| 19 | + 2. Run: ./scripts/test.sh | ||
| 20 | + 3. Report ONLY JSON: {"command":"./scripts/test.sh","exit_code":<int>,"passed":<int>,"failed":<int>,"stdout_excerpt":"<last 30 lines; include any FAIL summary>"} | ||
| 21 | + No prose. | ||
| 22 | + ``` | ||
| 23 | + | ||
| 24 | +4. Read `templates/test-gate-result-template.md`; fill ① ② ③ slots with the three check results. | ||
| 25 | +5. Write the rendered result to `docs/superpowers/module-reports/<module_id>-test-gate.md`. | ||
| 26 | +6. If `exit_code = 0` and both prior checks green → hand off to `erp-module-report` (print `local-test-gate: GREEN`). | ||
| 27 | +7. Otherwise print `local-test-gate: RED (<reason>)` and stop. | ||
| 28 | + | ||
| 29 | +## Guardrails | ||
| 30 | + | ||
| 31 | +- **Never** invoke `./scripts/test.sh` directly from the main session. | ||
| 32 | +- **Never** bypass via `git push --no-verify` (hook `deny-no-verify.sh` enforces). | ||
| 33 | + | ||
| 34 | +## References | ||
| 35 | + | ||
| 36 | +- `templates/test-gate-result-template.md` | ||
| 37 | +- Upstream guards: `erp-schema-baseline-check`, `erp-placeholder-scan` |
_pl_staging/pl_skills/erp-local-test-gate/templates/test-gate-result-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-local-test-gate/templates/test-gate-result-template.md | ||
| 1 | +## Local test gate — {{module_id}} | ||
| 2 | + | ||
| 3 | +执行时间: {{timestamp}} | ||
| 4 | + | ||
| 5 | +### ① Schema 基线比对 | ||
| 6 | +{{schema_baseline_result}} | ||
| 7 | + | ||
| 8 | +### ② 占位扫描 | ||
| 9 | +{{placeholder_scan_result}} | ||
| 10 | + | ||
| 11 | +### ③ scripts/test.sh (subagent) | ||
| 12 | +- 子会话: {{subagent_id}} | ||
| 13 | +- 命令: {{command}} | ||
| 14 | +- 退出码: {{exit_code}} | ||
| 15 | +- 通过: {{passed}} / 失败: {{failed}} | ||
| 16 | +- 关键 stdout (≤30 行): | ||
| 17 | + | ||
| 18 | +``` | ||
| 19 | +{{stdout_excerpt}} | ||
| 20 | +``` | ||
| 21 | + | ||
| 22 | +结论: {{conclusion}} (green / red) |
_pl_staging/pl_skills/erp-module-report/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-module-report/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-module-report | ||
| 3 | +description: After the local test gate is green, produce the standardized 12-section module completion report at docs/superpowers/module-reports/YYYY-MM-DD-<module_id>.md. Embeds schema-scratch and cross-module logs verbatim. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-module-report | ||
| 7 | + | ||
| 8 | +## Procedure | ||
| 9 | + | ||
| 10 | +1. Verify upstream: `erp-local-test-gate` returned GREEN. Otherwise stop. | ||
| 11 | +2. Collect inputs (by globs + git): | ||
| 12 | + - `git diff <module-start-commit>..HEAD` → file changes (§ ③) | ||
| 13 | + - `docs/superpowers/specs|plans|reviews/<date>-<module's REQs>.md` → § ②, § ⑨ | ||
| 14 | + - `docs/superpowers/module-reports/<module_id>-schema-scratch.md` → § ⑥ | ||
| 15 | + - `docs/superpowers/module-reports/<module_id>-cross-module.md` → § ⑦ | ||
| 16 | + - `docs/superpowers/module-reports/<module_id>-test-gate.md` → § ⑤ | ||
| 17 | + - `docs/03` + actual code (grep) → § ④ (tables read/written) | ||
| 18 | +3. Read `templates/module-report-template.md`; fill all 12 sections. | ||
| 19 | +4. **Validation (hard)**: | ||
| 20 | + - § ⑥: if schema-scratch has any row with TBD → stop, ask user (via erp-schema-scratch-log) to fill. | ||
| 21 | + - § ⑦: if cross-module has any row with TBD → stop (erp-cross-module-log). | ||
| 22 | + - § ⑦: if non-empty but no 影响评估 per row → stop. | ||
| 23 | + - § ⑧ must enumerate every deviation from spec; if empty, explicitly write "无偏离". | ||
| 24 | +5. Write `docs/superpowers/module-reports/$(date +%F)-<module_id>.md`. | ||
| 25 | +6. Hand off to `erp-mr-create`. | ||
| 26 | + | ||
| 27 | +## References | ||
| 28 | + | ||
| 29 | +- `templates/module-report-template.md` (12 sections) | ||
| 30 | +- Upstream: `erp-local-test-gate` | ||
| 31 | +- Downstream: `erp-mr-create` |
_pl_staging/pl_skills/erp-module-report/templates/module-report-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-module-report/templates/module-report-template.md | ||
| 1 | +--- | ||
| 2 | +module_id: {{module_id}} | ||
| 3 | +date: {{date}} | ||
| 4 | +git_range: {{git_range}} | ||
| 5 | +--- | ||
| 6 | + | ||
| 7 | +# 模块完成报告 — {{module_id}} {{module_name}} | ||
| 8 | + | ||
| 9 | +## ① 模块信息 | ||
| 10 | +- 模块 ID: {{module_id}} | ||
| 11 | +- 模块名: {{module_name}} | ||
| 12 | +- 开发区间: {{git_range}} | ||
| 13 | +- 开发天数: {{duration_days}} | ||
| 14 | + | ||
| 15 | +## ② REQ 完成清单 | ||
| 16 | +{{#each reqs}} | ||
| 17 | +- [{{status}}] {{req_id}} — {{title}} | ||
| 18 | + - spec: docs/superpowers/specs/{{date}}-{{req_id}}.md | ||
| 19 | + - plan: docs/superpowers/plans/{{date}}-{{req_id}}.md | ||
| 20 | + - review: docs/superpowers/reviews/{{date}}-{{req_id}}.md | ||
| 21 | +{{/each}} | ||
| 22 | + | ||
| 23 | +## ③ 文件变更表 | ||
| 24 | +| 文件 | 操作 | 说明 | | ||
| 25 | +|---|---|---| | ||
| 26 | +{{#each file_changes}} | ||
| 27 | +| {{path}} | {{action}} | {{note}} | | ||
| 28 | +{{/each}} | ||
| 29 | + | ||
| 30 | +## ④ 数据库使用表 | ||
| 31 | +- 读: {{tables_read}} | ||
| 32 | +- 写: {{tables_written}} | ||
| 33 | + | ||
| 34 | +## ⑤ 测试结果 | ||
| 35 | +- `scripts/test.sh` 最终:{{test_conclusion}} | ||
| 36 | +- 通过: {{passed}} / 失败: {{failed}} / 跳过: {{skipped}} | ||
| 37 | +- 覆盖率: {{coverage}} | ||
| 38 | + | ||
| 39 | +## ⑥ Schema 临时改动清单(软规则 S1) | ||
| 40 | + | ||
| 41 | +{{schema_scratch_contents}} | ||
| 42 | + | ||
| 43 | +回撤验证: {{rollback_verified}} (见 erp-schema-baseline-check 结果) | ||
| 44 | + | ||
| 45 | +## ⑦ 跨模块改动清单(软规则 S2) | ||
| 46 | + | ||
| 47 | +{{cross_module_contents}} | ||
| 48 | + | ||
| 49 | +## ⑧ 偏离 spec 清单 | ||
| 50 | +{{#each deviations}} | ||
| 51 | +- {{req_id}}: {{deviation}} (原因: {{reason}}) | ||
| 52 | +{{/each}} | ||
| 53 | + | ||
| 54 | +## ⑨ AI reviewer 报告汇总 | ||
| 55 | +{{#each reviews}} | ||
| 56 | +- {{req_id}}: round {{round}} — {{verdict}}(link: docs/superpowers/reviews/{{date}}-{{req_id}}.md) | ||
| 57 | +{{/each}} | ||
| 58 | + | ||
| 59 | +## ⑩ 已知问题 | ||
| 60 | +{{known_issues}} | ||
| 61 | + | ||
| 62 | +## ⑪ 下一模块预览 | ||
| 63 | +{{next_module}} | ||
| 64 | + | ||
| 65 | +## ⑫ MR 链接 | ||
| 66 | +{{mr_url}} |
_pl_staging/pl_skills/erp-module-start/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-module-start/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-module-start | ||
| 3 | +description: Start the module loop. Locate the first `confirmed: false` module in docs/08, initialize schema-scratch & cross-module log files, print a module banner, and drive the feature loop over each REQ in order. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-module-start | ||
| 7 | + | ||
| 8 | +## Procedure | ||
| 9 | + | ||
| 10 | +1. Read `docs/08-模块任务管理.md`. Locate the first `confirmed: false` module; extract `module_id`, `module_name`, REQ list, dependencies. | ||
| 11 | +2. If no such module → all modules done; print a completion summary and stop. | ||
| 12 | +3. Initialize logs (idempotent): | ||
| 13 | + - `docs/superpowers/module-reports/<module_id>-schema-scratch.md` — if missing, write from `templates/schema-scratch-log-template.md` with `module_name` slot. | ||
| 14 | + - `docs/superpowers/module-reports/<module_id>-cross-module.md` — if missing, write from `templates/cross-module-log-template.md`. | ||
| 15 | +4. Read `templates/module-start-banner-template.md`; fill slots and print to session. | ||
| 16 | +5. For each REQ in order: | ||
| 17 | + a. `erp-red-flag-check` → stop if hit. | ||
| 18 | + b. `erp-feature-brainstorm` | ||
| 19 | + c. `erp-feature-plan` | ||
| 20 | + d. `erp-feature-tdd` | ||
| 21 | + e. `erp-feature-verify` | ||
| 22 | + f. `erp-feature-review` | ||
| 23 | + g. Any halt → stop the module; do not skip to the next REQ silently. | ||
| 24 | +6. After all REQs done → invoke `erp-local-test-gate`. | ||
| 25 | + | ||
| 26 | +## References | ||
| 27 | + | ||
| 28 | +- `templates/module-start-banner-template.md` | ||
| 29 | +- `templates/schema-scratch-log-template.md` | ||
| 30 | +- `templates/cross-module-log-template.md` | ||
| 31 | +- Downstream: `erp-feature-*`, `erp-local-test-gate` |
_pl_staging/pl_skills/erp-module-start/templates/cross-module-log-template.md
0 → 100644
_pl_staging/pl_skills/erp-module-start/templates/module-start-banner-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-module-start/templates/module-start-banner-template.md | ||
| 1 | +## Module start — {{module_id}} ({{module_name}}) | ||
| 2 | + | ||
| 3 | +- 模块依赖: {{depends_on}} | ||
| 4 | +- 对应需求文件: docs/01-需求清单/{{req_file}} | ||
| 5 | +- 功能清单: | ||
| 6 | +{{#each reqs}} | ||
| 7 | + - [ ] {{req_id}} — {{title}} | ||
| 8 | +{{/each}} | ||
| 9 | + | ||
| 10 | +开始功能循环(Layer 3)依次跑每个 REQ。命中红旗 → 停;完成所有 REQ → 进入模块闸门。 |
_pl_staging/pl_skills/erp-module-start/templates/schema-scratch-log-template.md
0 → 100644
_pl_staging/pl_skills/erp-mr-create/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-mr-create/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-mr-create | ||
| 3 | +description: After the module completion report is written, git push and create a GitLab MR with the module report embedded in the description. The only action that touches the remote. Stops to wait for human review. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-mr-create | ||
| 7 | + | ||
| 8 | +## Pre-conditions | ||
| 9 | + | ||
| 10 | +- `erp-module-report` produced the report file. | ||
| 11 | +- `erp-local-test-gate` returned GREEN (re-check just before push; fail if file mtime older than latest commit). | ||
| 12 | + | ||
| 13 | +## Procedure | ||
| 14 | + | ||
| 15 | +1. Ensure current branch is a feature branch (not main/master). If needed: `git checkout -b module-<id>`. | ||
| 16 | +2. `git push -u origin <branch>` — do NOT use `--no-verify` (hook `deny-no-verify.sh` would block anyway). | ||
| 17 | +3. Read `templates/mr-title-template.md`; fill `module_id`, `module_name`. | ||
| 18 | +4. Read `templates/mr-description-template.md`; fill slots: | ||
| 19 | + - `module_report_contents` = full text of `docs/superpowers/module-reports/<date>-<module_id>.md` | ||
| 20 | + - `test_gate_conclusion`, `test_subagent_id`, `schema_rollback_conclusion`, `placeholder_conclusion` | ||
| 21 | +5. Create the MR: | ||
| 22 | + | ||
| 23 | + ```bash | ||
| 24 | + glab mr create --title "$(<title file)" --description "$(<description file)" | ||
| 25 | + ``` | ||
| 26 | + | ||
| 27 | +6. Parse the returned MR URL and IID. Append to § ⑫ of the module report (edit the file in place). | ||
| 28 | +7. Print the MR URL to session. | ||
| 29 | +8. **Stop — wait for human Approve + Merge**. Do NOT call `erp-confirmed-update` yet. | ||
| 30 | + | ||
| 31 | +## References | ||
| 32 | + | ||
| 33 | +- `templates/mr-title-template.md` | ||
| 34 | +- `templates/mr-description-template.md` |
_pl_staging/pl_skills/erp-mr-create/templates/mr-description-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-mr-create/templates/mr-description-template.md | ||
| 1 | +## 模块完成报告 | ||
| 2 | + | ||
| 3 | +见 `docs/superpowers/module-reports/{{date}}-{{module_id}}.md`(本 MR 仓库内完整贴入下方)。 | ||
| 4 | + | ||
| 5 | +--- | ||
| 6 | + | ||
| 7 | +{{module_report_contents}} | ||
| 8 | + | ||
| 9 | +--- | ||
| 10 | + | ||
| 11 | +## 本地闸门证据 | ||
| 12 | + | ||
| 13 | +- test.sh: {{test_gate_conclusion}}(subagent: {{test_subagent_id}}) | ||
| 14 | +- schema 回撤: {{schema_rollback_conclusion}} | ||
| 15 | +- 占位扫描: {{placeholder_conclusion}} | ||
| 16 | + | ||
| 17 | +## 审核入口 | ||
| 18 | + | ||
| 19 | +- 本 MR = 模块 `{{module_id}}` 的唯一人工介入点 | ||
| 20 | +- Approve + Merge 后告知 CC(或 CC 轮询 `glab mr view` 检测 merged),CC 自动 flip `docs/08` `confirmed: true` |
_pl_staging/pl_skills/erp-mr-create/templates/mr-title-template.md
0 → 100644
_pl_staging/pl_skills/erp-mysql-mcp-setup/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-mysql-mcp-setup/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-mysql-mcp-setup | ||
| 3 | +description: Configure the MySQL MCP server and freeze the live schema as the baseline snapshot for future erp-schema-baseline-check diffs. Never runs DDL. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-mysql-mcp-setup | ||
| 7 | + | ||
| 8 | +## Pre-conditions | ||
| 9 | + | ||
| 10 | +- `.env.local` populated with DB_HOST / DB_PORT / DB_USER / DB_PASSWORD / DB_SCHEMA (no `【人工填写:` residuals). | ||
| 11 | +- MySQL instance exists and the schema is already created by a human (not by CC). | ||
| 12 | + | ||
| 13 | +## Procedure | ||
| 14 | + | ||
| 15 | +### A. Write .mcp.json | ||
| 16 | +1. Read `templates/mcp-json-template.json`. | ||
| 17 | +2. Fill slots from `.env.local`. | ||
| 18 | +3. Write `.mcp.json` at project root. | ||
| 19 | +4. If CC's MCP server is not yet loaded, ask user to restart the Claude Code session to pick up the MCP server. | ||
| 20 | + | ||
| 21 | +### B. Verify connectivity (subagent) | ||
| 22 | +**Dispatch a fresh subagent** to run a trivial `mcp__mcp_server_mysql__mysql_query` like `SHOW TABLES;` and return: | ||
| 23 | +```json | ||
| 24 | +{"connected": <bool>, "tables_count": <int>, "error": "<if any>"} | ||
| 25 | +``` | ||
| 26 | + | ||
| 27 | +If `connected: false` → stop, surface error to user. | ||
| 28 | + | ||
| 29 | +### C. Freeze baseline (subagent) | ||
| 30 | +**Dispatch a fresh subagent** to run: | ||
| 31 | +``` | ||
| 32 | +mysqldump --no-data --skip-comments -h<host> -P<port> -u<user> -p<password> <schema> | ||
| 33 | +``` | ||
| 34 | +and return the full dump body (as a text block). | ||
| 35 | + | ||
| 36 | +The subagent must NOT modify the DB. Only mysqldump. | ||
| 37 | + | ||
| 38 | +### D. Write baseline file | ||
| 39 | +1. Read `templates/schema-baseline-header-template.sql`. | ||
| 40 | +2. Fill slots: `project_name`, `timestamp`, `schema_name`, `dump_body` (from subagent). | ||
| 41 | +3. Write `docs/superpowers/schema-baseline.sql`. | ||
| 42 | + | ||
| 43 | +### E. Validate | ||
| 44 | +Read back `docs/superpowers/schema-baseline.sql` — must contain `CREATE TABLE` statements for the tables listed in step B. | ||
| 45 | + | ||
| 46 | +Print: `mysql-mcp-setup: DONE (schema=<name>, tables=<n>, baseline=docs/superpowers/schema-baseline.sql)`. | ||
| 47 | + | ||
| 48 | +## Invariants | ||
| 49 | + | ||
| 50 | +- CC never runs DDL during setup. | ||
| 51 | +- Subagent prompts must explicitly forbid mutations. | ||
| 52 | + | ||
| 53 | +## References | ||
| 54 | + | ||
| 55 | +- `templates/mcp-json-template.json` | ||
| 56 | +- `templates/schema-baseline-header-template.sql` |
_pl_staging/pl_skills/erp-mysql-mcp-setup/templates/mcp-json-template.json
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-mysql-mcp-setup/templates/mcp-json-template.json | ||
| 1 | +{ | ||
| 2 | + "mcpServers": { | ||
| 3 | + "mysql": { | ||
| 4 | + "command": "npx", | ||
| 5 | + "args": ["-y", "@benborla29/mcp-server-mysql"], | ||
| 6 | + "env": { | ||
| 7 | + "MYSQL_HOST": "{{db_host}}", | ||
| 8 | + "MYSQL_PORT": "{{db_port}}", | ||
| 9 | + "MYSQL_USER": "{{db_user}}", | ||
| 10 | + "MYSQL_PASS": "{{db_password}}", | ||
| 11 | + "MYSQL_DB": "{{db_schema}}" | ||
| 12 | + } | ||
| 13 | + } | ||
| 14 | + } | ||
| 15 | +} |
_pl_staging/pl_skills/erp-placeholder-scan/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-placeholder-scan/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-placeholder-scan | ||
| 3 | +description: Scan for 占位符 residuals (`【人工填写:...】`, `your_password`, `your-secret-key`, `N.x` 版本号) in docs/, .env files, scripts/. Invoke after any Write to these locations and always before the module local-test-gate. Produces a scan result following a fixed template. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-placeholder-scan | ||
| 7 | + | ||
| 8 | +## What | ||
| 9 | + | ||
| 10 | +Detect unfilled placeholders. Any hit in a release-blocking scope (module gate) → stop and list residuals for user to fill. | ||
| 11 | + | ||
| 12 | +## Patterns (all case-sensitive unless noted) | ||
| 13 | + | ||
| 14 | +- `【人工填写:` — primary placeholder marker | ||
| 15 | +- `your_password`, `your-secret-key` — generic naked placeholders | ||
| 16 | +- `^\d+\.x$` or `^\d+\.\d+\.x$` — unlocked tech-stack minor versions | ||
| 17 | + | ||
| 18 | +## Scope | ||
| 19 | + | ||
| 20 | +- `docs/**` | ||
| 21 | +- `.env*` (not `.env.local` if the user has intentionally committed secrets? no — still scan; user decides) | ||
| 22 | +- `scripts/**` | ||
| 23 | +- `CLAUDE.md` (header section only) | ||
| 24 | + | ||
| 25 | +## Procedure | ||
| 26 | + | ||
| 27 | +1. Run ripgrep (via Grep tool) for each pattern across scope. | ||
| 28 | +2. Aggregate hits into a list of `(file, line, match)`. | ||
| 29 | +3. Read `templates/placeholder-scan-result-template.md`; fill slots. | ||
| 30 | +4. If hits found in module-gate context: stop the caller, print the filled template to session. | ||
| 31 | +5. If no hits: print `placeholder-scan: PASS` to session only. | ||
| 32 | + | ||
| 33 | +## When called by `erp-local-test-gate` | ||
| 34 | + | ||
| 35 | +A non-empty result fails the gate — caller must stop. | ||
| 36 | + | ||
| 37 | +## References | ||
| 38 | + | ||
| 39 | +- `templates/placeholder-scan-result-template.md` | ||
| 40 | +- `CLAUDE.md` § 🏷️ 占位符统一约定 |
_pl_staging/pl_skills/erp-placeholder-scan/templates/placeholder-scan-result-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-placeholder-scan/templates/placeholder-scan-result-template.md | ||
| 1 | +## 占位符扫描结果 | ||
| 2 | + | ||
| 3 | +扫描时间: {{timestamp}} | ||
| 4 | +扫描范围: {{scan_globs}} | ||
| 5 | +命中总数: {{hit_count}} | ||
| 6 | + | ||
| 7 | +| 文件 | 行号 | 命中串 | | ||
| 8 | +|---|---|---| | ||
| 9 | +{{#each hits}} | ||
| 10 | +| {{file}} | {{line}} | `{{match}}` | | ||
| 11 | +{{/each}} | ||
| 12 | + | ||
| 13 | +结论: {{conclusion}} (pass=无残留 / fail=需人工补齐) |
_pl_staging/pl_skills/erp-red-flag-check/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-red-flag-check/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-red-flag-check | ||
| 3 | +description: Use before each feature-loop step (Brainstorm/Plan/TDD/Verify/Review) and before generating any major artifact. Runs the 6-item red-flag checklist from CLAUDE.md; on any hit, appends a Blocker block to the current plan file and stops silent execution. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-red-flag-check | ||
| 7 | + | ||
| 8 | +## What | ||
| 9 | + | ||
| 10 | +Verify none of the 6 red flags from `CLAUDE.md` § 🚩 静默执行红旗清单 are active. Halt on any hit. | ||
| 11 | + | ||
| 12 | +## When to invoke | ||
| 13 | + | ||
| 14 | +- Before starting any feature-loop step (3.1-3.5) | ||
| 15 | +- Before generating a module-level artifact (module report, MR description) | ||
| 16 | +- Any time the user's request implies a schema conflict, tech-stack boundary, or external dependency | ||
| 17 | + | ||
| 18 | +## Checklist (6 items — source of truth: CLAUDE.md) | ||
| 19 | + | ||
| 20 | +1. **需求与 schema 冲突** — needed fields/tables missing in live schema | ||
| 21 | +2. **需求本身歧义** — two or more reasonable interpretations | ||
| 22 | +3. **超技术栈边界** — requires framework/middleware outside CLAUDE.md 技术栈表 | ||
| 23 | +4. **测试反复失败** — same test failing after 5 consecutive fix attempts in the current feature | ||
| 24 | +5. **要改密钥 / 账密 / 包名** — touching placeholders in `docs/07-环境配置.md` | ||
| 25 | +6. **外部接口不可达** — third-party API / cert / network issue | ||
| 26 | + | ||
| 27 | +## Procedure | ||
| 28 | + | ||
| 29 | +1. Read the current feature's spec/plan path (from conversation or `docs/08`). | ||
| 30 | +2. For each of the 6 flags, check explicitly. If none hit → print `red-flag-check: PASS` to session, exit. | ||
| 31 | +3. On hit: | ||
| 32 | + - Read `templates/red-flag-block-template.md` | ||
| 33 | + - Fill slots (flag_number, flag_name, description, affected_scope, recommendation, decision_needed) | ||
| 34 | + - Append the rendered block to the current plan file: `docs/superpowers/plans/YYYY-MM-DD-<REQ-id>.md` | ||
| 35 | + - Print a 1-sentence session summary pointing to the plan file | ||
| 36 | + - **Stop** — do not invoke any further skill until the user decides | ||
| 37 | + | ||
| 38 | +## Output | ||
| 39 | + | ||
| 40 | +Either `red-flag-check: PASS` (session only), or a `## 🚩 Blocker` block appended to the feature plan file. | ||
| 41 | + | ||
| 42 | +## References | ||
| 43 | + | ||
| 44 | +- `templates/red-flag-block-template.md` | ||
| 45 | +- `CLAUDE.md` § 🚩 静默执行红旗清单(权威 6 条) | ||
| 46 | +- `CLAUDE.md` § 🟡 软规则(S1/S2,不触发红旗但需留痕) |
_pl_staging/pl_skills/erp-red-flag-check/templates/red-flag-block-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-red-flag-check/templates/red-flag-block-template.md | ||
| 1 | +## 🚩 Blocker | ||
| 2 | + | ||
| 3 | +**红旗编号**: {{flag_number}} (1-6,对应 CLAUDE.md 🚩 静默执行红旗清单) | ||
| 4 | +**红旗名称**: {{flag_name}} | ||
| 5 | +**问题描述**: {{description}} | ||
| 6 | +**影响范围**: {{affected_scope}} | ||
| 7 | +**我的建议**: {{recommendation}} | ||
| 8 | +**等待决策**: {{decision_needed}} |
_pl_staging/pl_skills/erp-requirements-gen/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-requirements-gen/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-requirements-gen | ||
| 3 | +description: From the human-authored requirement outline in docs/01-需求清单/README.md and the live MySQL schema, generate full REQ-XXX-NNN cards under docs/01 and the DB design doc docs/03. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-requirements-gen | ||
| 7 | + | ||
| 8 | +## Pre-conditions | ||
| 9 | + | ||
| 10 | +- `docs/01-需求清单/README.md` exists with per-module bullet outlines (author: human). | ||
| 11 | +- MCP + baseline ready (`erp-mysql-mcp-setup` done). | ||
| 12 | + | ||
| 13 | +## Procedure | ||
| 14 | + | ||
| 15 | +### A. Parse README outline | ||
| 16 | +For each module bullet, extract: `module_code` (SYS / PUR / INV / ...), `module_name`, function bullets. | ||
| 17 | + | ||
| 18 | +Ask user via `AskUserQuestion` to clarify any ambiguous mapping. | ||
| 19 | + | ||
| 20 | +### B. Generate REQ cards | ||
| 21 | +For each function bullet: | ||
| 22 | +1. Assign `REQ-<MOD>-<NNN>` (increment per module). | ||
| 23 | +2. Interactively fill the card via `AskUserQuestion` + inference from context: | ||
| 24 | + - 目标 / 输入 / 输出 / 业务规则 / 边界 / 依赖表(验证存在)/ 依赖接口(先占位)/ 验收 | ||
| 25 | +3. Read `templates/req-card-template.md`; render. | ||
| 26 | + | ||
| 27 | +### C. Assemble per-module files | ||
| 28 | +For each module, read `templates/docs-01-module-template.md`, fill with `reqs[]`, write `docs/01-需求清单/<module_code>-<module_name>.md`. | ||
| 29 | + | ||
| 30 | +### D. Generate docs/03 | ||
| 31 | +1. **Dispatch subagent** to query the live schema via MCP and return a structured list: tables + columns + indexes + FKs + types. | ||
| 32 | +2. Read `templates/docs-03-header-template.md`; fill `schema_name`, `er_overview`, `tables[]`. | ||
| 33 | +3. For each table, read `templates/docs-03-table-template.md`; fill and append. | ||
| 34 | +4. Business meaning of each column: infer from REQ cards or ask user. | ||
| 35 | +5. Write `docs/03-数据库设计文档.md`. | ||
| 36 | + | ||
| 37 | +### E. Sanity checks | ||
| 38 | +- Every REQ must reference at least one table that exists in docs/03. | ||
| 39 | +- Every table in docs/03 must appear in at least one REQ (else print a warning; may be an unused table or a missing requirement). | ||
| 40 | + | ||
| 41 | +Print: `requirements-gen: <M> modules, <N> REQs, <T> tables. Awaiting human review of 01/03.` | ||
| 42 | + | ||
| 43 | +## References | ||
| 44 | + | ||
| 45 | +- `templates/req-card-template.md` | ||
| 46 | +- `templates/docs-01-module-template.md` | ||
| 47 | +- `templates/docs-03-header-template.md` | ||
| 48 | +- `templates/docs-03-table-template.md` |
_pl_staging/pl_skills/erp-requirements-gen/templates/docs-01-module-template.md
0 → 100644
_pl_staging/pl_skills/erp-requirements-gen/templates/docs-03-header-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-requirements-gen/templates/docs-03-header-template.md | ||
| 1 | +# 03-数据库设计文档 | ||
| 2 | + | ||
| 3 | +Schema: `{{schema_name}}` | ||
| 4 | +基线快照: `docs/superpowers/schema-baseline.sql` | ||
| 5 | +生成方式: 通过 MCP (`mcp__mcp_server_mysql__mysql_query`) 从 live schema 反查生成。 | ||
| 6 | + | ||
| 7 | +## ER 关系概览 | ||
| 8 | + | ||
| 9 | +{{er_overview}} | ||
| 10 | + | ||
| 11 | +## 表清单 | ||
| 12 | +{{#each tables}} | ||
| 13 | +- `{{table_name}}` — {{purpose}} | ||
| 14 | +{{/each}} |
_pl_staging/pl_skills/erp-requirements-gen/templates/docs-03-table-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-requirements-gen/templates/docs-03-table-template.md | ||
| 1 | +## `{{table_name}}` — {{purpose}} | ||
| 2 | + | ||
| 3 | +### 字段 | ||
| 4 | + | ||
| 5 | +| 字段 | 类型 | Nullable | 默认 | 业务含义 | | ||
| 6 | +|---|---|---|---|---| | ||
| 7 | +{{#each columns}} | ||
| 8 | +| {{name}} | {{type}} | {{nullable}} | {{default}} | {{business_meaning}} | | ||
| 9 | +{{/each}} | ||
| 10 | + | ||
| 11 | +### 索引 | ||
| 12 | +{{#each indexes}} | ||
| 13 | +- `{{name}}` ({{type}}): {{columns}} | ||
| 14 | +{{/each}} | ||
| 15 | + | ||
| 16 | +### 外键 | ||
| 17 | +{{#each foreign_keys}} | ||
| 18 | +- `{{name}}`: {{from_col}} → {{to_table}}.{{to_col}} ({{on_delete}}) | ||
| 19 | +{{/each}} | ||
| 20 | + | ||
| 21 | +### 业务注记 | ||
| 22 | +{{notes}} |
_pl_staging/pl_skills/erp-requirements-gen/templates/req-card-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-requirements-gen/templates/req-card-template.md | ||
| 1 | +### {{req_id}} {{title}} | ||
| 2 | + | ||
| 3 | +- **目标**: {{goal}} | ||
| 4 | +- **输入**: {{input}} | ||
| 5 | +- **输出**: {{output}} | ||
| 6 | +- **业务规则**: {{rules}} | ||
| 7 | +- **边界**: {{constraints}} | ||
| 8 | +- **依赖表**: {{schema_refs}} | ||
| 9 | +- **依赖接口**: {{api_refs}} | ||
| 10 | +- **验收**: {{acceptance}} |
_pl_staging/pl_skills/erp-schema-baseline-check/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-schema-baseline-check/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-schema-baseline-check | ||
| 3 | +description: Verify the live MySQL schema matches the frozen baseline (`docs/superpowers/schema-baseline.sql`). Invoke before the module local-test-gate and before any `confirmed` flip. Any diff = 软规则 S1 未回撤 → 升级为红旗 #1. Execution is delegated to a fresh subagent per design principle #7. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-schema-baseline-check | ||
| 7 | + | ||
| 8 | +## What | ||
| 9 | + | ||
| 10 | +Confirm schema has been rolled back to baseline before declaring a module done. | ||
| 11 | + | ||
| 12 | +## Procedure | ||
| 13 | + | ||
| 14 | +1. Locate baseline file: `docs/superpowers/schema-baseline.sql`. If missing → stop with error "baseline not initialized; run erp-mysql-mcp-setup first". | ||
| 15 | +2. Read env: `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_SCHEMA` from `.env.local` (or prompt user). | ||
| 16 | +3. **Dispatch a fresh subagent via `Agent` tool (subagent_type: general-purpose)** with this prompt: | ||
| 17 | + | ||
| 18 | + ``` | ||
| 19 | + Task: verify MySQL schema matches a frozen baseline. Do NOT make any changes. Steps: | ||
| 20 | + 1. Run: mysqldump --no-data --skip-comments -h<host> -P<port> -u<user> -p<password> <schema> > /tmp/current-schema.sql | ||
| 21 | + 2. Diff against: <absolute path to baseline> | ||
| 22 | + 3. Report back ONLY a structured JSON object (no prose): {"diff_lines": <int>, "deviations": [{"type": "added_table|dropped_column|...", "object": "<name>", "change": "<one-line>"}], "conclusion": "clean|dirty"} | ||
| 23 | + Limit: if the diff exceeds 200 lines, truncate deviations to the first 20 and note "truncated". | ||
| 24 | + ``` | ||
| 25 | + | ||
| 26 | +4. Read the subagent's JSON result. | ||
| 27 | +5. Read `templates/schema-baseline-diff-template.md`; fill slots including `subagent_id` = the agent description/ID. | ||
| 28 | +6. If `conclusion = dirty` → invoke `erp-red-flag-check` with flag #1 and stop the caller. | ||
| 29 | +7. If `conclusion = clean` → print `schema-baseline-check: PASS` to session. | ||
| 30 | + | ||
| 31 | +## References | ||
| 32 | + | ||
| 33 | +- `templates/schema-baseline-diff-template.md` | ||
| 34 | +- `CLAUDE.md` § 🟡 软规则 S1 |
_pl_staging/pl_skills/erp-schema-baseline-check/templates/schema-baseline-diff-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-schema-baseline-check/templates/schema-baseline-diff-template.md | ||
| 1 | +## Schema 基线比对结果 | ||
| 2 | + | ||
| 3 | +比对时间: {{timestamp}} | ||
| 4 | +基线文件: docs/superpowers/schema-baseline.sql | ||
| 5 | +当前 schema: {{schema_name}} @ {{db_host}} | ||
| 6 | +执行方式: subagent ({{subagent_id}}) | ||
| 7 | + | ||
| 8 | +diff 行数: {{diff_lines}} | ||
| 9 | + | ||
| 10 | +### 偏离清单 | ||
| 11 | + | ||
| 12 | +{{#each deviations}} | ||
| 13 | +- {{type}}: {{object}} — {{change}} | ||
| 14 | +{{/each}} | ||
| 15 | + | ||
| 16 | +结论: {{conclusion}} (clean=已回撤 / dirty=未回撤,升级红旗 #1) |
_pl_staging/pl_skills/erp-schema-scratch-log/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-schema-scratch-log/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-schema-scratch-log | ||
| 3 | +description: Fill in 原因 and 预计回撤时机 for DDL stub rows that the `log-ddl.sh` hook auto-appended to `docs/superpowers/module-reports/<current>-schema-scratch.md`. Triggered by the hook's PostToolUse notification or invoked directly before running DDL. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-schema-scratch-log | ||
| 7 | + | ||
| 8 | +## What | ||
| 9 | + | ||
| 10 | +Soft-rule S1 enforcement: every DDL during debug must be logged with reason + rollback plan. | ||
| 11 | + | ||
| 12 | +## Procedure | ||
| 13 | + | ||
| 14 | +1. Identify the current module (first `confirmed: false` entry in `docs/08-模块任务管理.md`). | ||
| 15 | +2. Open `docs/superpowers/module-reports/<current>-schema-scratch.md`. | ||
| 16 | +3. If file does not exist → initialize it by reading `templates/schema-scratch-log-template.md` and writing with `module_name` slot filled. | ||
| 17 | +4. Find rows with `TBD(待填)` in 原因 or 预计回撤时机 columns. | ||
| 18 | +5. For each TBD row, ask the user (AskUserQuestion) or infer from recent conversation context: | ||
| 19 | + - **原因**: what was the debug goal? | ||
| 20 | + - **预计回撤时机**: 本功能结束前 / 本模块 gate 前 / 其他 | ||
| 21 | +6. Edit the row (keep the same timestamp + SQL columns). | ||
| 22 | +7. Print a one-line confirmation: `schema-scratch-log: N rows updated`. | ||
| 23 | + | ||
| 24 | +## Invariants | ||
| 25 | + | ||
| 26 | +- Never mutate the 时间戳 or SQL columns of existing rows. | ||
| 27 | +- Never remove rows; rollback is tracked by `erp-schema-baseline-check`, not by deletion here. | ||
| 28 | + | ||
| 29 | +## References | ||
| 30 | + | ||
| 31 | +- `templates/schema-scratch-log-template.md` (file header) | ||
| 32 | +- `templates/schema-scratch-log-row-template.md` (single row) | ||
| 33 | +- `CLAUDE.md` § 🟡 软规则 S1 |
_pl_staging/pl_skills/erp-schema-scratch-log/templates/schema-scratch-log-row-template.md
0 → 100644
_pl_staging/pl_skills/erp-schema-scratch-log/templates/schema-scratch-log-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-schema-scratch-log/templates/schema-scratch-log-template.md | ||
| 1 | +# Schema 临时改动日志 — {{module_name}} | ||
| 2 | + | ||
| 3 | +软规则 S1:本模块开发期间对 schema 的所有临时 DDL 都应记录在此;模块闸门前必须全部回撤到基线(`docs/superpowers/schema-baseline.sql`)。未回撤 → 升级为红旗。 | ||
| 4 | + | ||
| 5 | +| 时间戳 | SQL | 原因 | 预计回撤时机 | | ||
| 6 | +|---|---|---|---| |
_pl_staging/pl_skills/erp-session-start/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-session-start/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-session-start | ||
| 3 | +description: Top-level orchestrator. Run at the start of any ERP-project session (or manually via /erp-session-start). Detects the current project phase and dispatches to the next skill. Never generates files directly. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-session-start | ||
| 7 | + | ||
| 8 | +## 整体流程(给用户看) | ||
| 9 | + | ||
| 10 | +本项目分两大阶段:**先规划,再编码**。CC 自动探测当前位置、打印阶段横幅、分发到下一步。你只在 ⏸ 卡点处介入。 | ||
| 11 | + | ||
| 12 | +``` | ||
| 13 | +┌──────────────────────────────────────────────────────┐ | ||
| 14 | +│ 📋 阶段 A:规划(一次性) │ | ||
| 15 | +│ │ | ||
| 16 | +│ 锁技术栈 → 生项目骨架 → 接数据库 → 生需求/DB文档 │ | ||
| 17 | +│ ↓ │ | ||
| 18 | +│ 输出「理解确认报告」 │ | ||
| 19 | +│ ↓ │ | ||
| 20 | +│ ⏸ 等你回复「理解正确」 才进入阶段 B │ | ||
| 21 | +└──────────────────────────────────────────────────────┘ | ||
| 22 | + ↓ | ||
| 23 | +┌──────────────────────────────────────────────────────┐ | ||
| 24 | +│ 🔁 阶段 B:编码(按模块循环,每模块包含多个功能) │ | ||
| 25 | +│ │ | ||
| 26 | +│ 一个模块 = 多个功能(REQ-XXX-NNN): │ | ||
| 27 | +│ │ | ||
| 28 | +│ ┌─ 功能循环(每个 REQ 跑一遍)────────────────┐ │ | ||
| 29 | +│ │ Brainstorm → Plan → TDD → Verify → Review │ │ | ||
| 30 | +│ └────────────────────────────────────────────┘ │ | ||
| 31 | +│ ↓ 本模块全部功能完成 │ | ||
| 32 | +│ 本地测试闸门 → 写模块报告 → 建 GitLab MR │ | ||
| 33 | +│ ↓ │ | ||
| 34 | +│ ⏸ 等你 Approve + Merge MR │ | ||
| 35 | +│ ↓ │ | ||
| 36 | +│ 标记模块完成 → 自动进入下一个模块 │ | ||
| 37 | +└──────────────────────────────────────────────────────┘ | ||
| 38 | + | ||
| 39 | +⚙️ 后台守门(任意阶段命中即停下问你,不会静默继续): | ||
| 40 | + • 文档/配置里有未填的【人工填写:】占位符 | ||
| 41 | + • 命中红旗清单(schema 冲突 / 需求歧义 / 超技术栈 等 6 项) | ||
| 42 | + • 数据库 schema 偏离已冻结的基线 | ||
| 43 | + • 调试期间临时 DDL 未在模块结束前回撤 | ||
| 44 | + • 改了已完成模块的代码但没记录原因和影响 | ||
| 45 | +``` | ||
| 46 | + | ||
| 47 | +## 分发梯(按优先级,首条命中即停) | ||
| 48 | + | ||
| 49 | +**A 阶段 · 计划(一次性)** | ||
| 50 | + | ||
| 51 | +1. **A1 技术栈未锁定** — `CLAUDE.md` 顶部 4 meta slots(项目名称/简述/目标用户/部署方式)或技术栈表含 `【人工填写:` | ||
| 52 | + → `erp-tech-stack-lock` | ||
| 53 | +2. **A2 骨架文件缺失** — `docs/04-技术规范.md` / `docs/07-环境配置.md` / `docs/09-项目目录结构.md` / `scripts/test.sh` / `scripts/setup-test-db.sh` / `.githooks/pre-push` / `.env.local.example` 任一缺失 | ||
| 54 | + → `erp-skeleton-gen` | ||
| 55 | +3. **A3 MCP + schema 基线未建立** — `.mcp.json` 或 `docs/superpowers/schema-baseline.sql` 缺失 | ||
| 56 | + → `erp-mysql-mcp-setup` | ||
| 57 | +4. **A4 需求 & DB 文档缺失** — `docs/01-需求清单/` 只有 README 或 `docs/03-数据库设计文档.md` 没有生成的表 | ||
| 58 | + → `erp-requirements-gen` | ||
| 59 | +5. **A5 下游文档缺失** — `docs/02-开发计划.md` / `docs/05-API接口契约.md` / `docs/08-模块任务管理.md` / `docs/10-验收检查清单.md` / `sql/seed-data.sql` 任一缺失 | ||
| 60 | + → `erp-downstream-gen` | ||
| 61 | +6. **A6 未输出过理解确认报告**(且人工未回复「理解正确」) | ||
| 62 | + → `erp-understanding-report` | ||
| 63 | + | ||
| 64 | +**横切守门** | ||
| 65 | + | ||
| 66 | +7. **X1 占位残留** — 内联跑 `erp-placeholder-scan`,结果非空 | ||
| 67 | + → 停下打印清单,等人填 | ||
| 68 | + | ||
| 69 | +**B 阶段 · 编码(按模块循环)** | ||
| 70 | + | ||
| 71 | +8. **B5 待翻 confirmed** — `docs/08` 当前 `confirmed:false` 模块对应的 MR 已 Merged(`glab mr view` 或用户告知) | ||
| 72 | + → `erp-confirmed-update` | ||
| 73 | +9. **B1 默认** — 进入或继续模块循环 | ||
| 74 | + → `erp-module-start` | ||
| 75 | + | ||
| 76 | +## 执行步骤 | ||
| 77 | + | ||
| 78 | +1. **收集状态** | ||
| 79 | + - 读 `CLAUDE.md` 头部 | ||
| 80 | + - Glob `docs/**`、`scripts/**`、`.githooks/**`、`.mcp.json`、`docs/superpowers/schema-baseline.sql` | ||
| 81 | + - 读 `docs/08-模块任务管理.md` | ||
| 82 | + - `git log -1`;若 `glab` 可用则 `glab mr list --state=opened` | ||
| 83 | + | ||
| 84 | +2. **打印阶段横幅(必须输出给用户看)** | ||
| 85 | + | ||
| 86 | + ``` | ||
| 87 | + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | ||
| 88 | + [erp-session-start] | ||
| 89 | + 阶段:<A 计划 | B 编码 | 横切守门> | ||
| 90 | + 命中:<编号> <label> (例:A1 技术栈未锁定) | ||
| 91 | + 当前模块:<module_id 或 —> (B 阶段才填) | ||
| 92 | + 下一步:invoke <skill> | ||
| 93 | + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | ||
| 94 | + ``` | ||
| 95 | + | ||
| 96 | +3. **红旗联动** — 分发目标属于 B 阶段(`erp-module-*` / `erp-feature-*`)时,先调 `erp-red-flag-check`;命中红旗则停在此不分发。 | ||
| 97 | + | ||
| 98 | +4. **分发** — 通过 `Skill` 工具调用选中的下游 skill。本 skill 不直接产出任何制品。 | ||
| 99 | + | ||
| 100 | +## References | ||
| 101 | + | ||
| 102 | +- `CLAUDE.md`(项目指令) | ||
| 103 | +- `docs/08-模块任务管理.md`(confirmed 状态) | ||
| 104 | +- `.claude/skills/erp-*`(下游 skills) |
_pl_staging/pl_skills/erp-skeleton-gen/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-skeleton-gen/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-skeleton-gen | ||
| 3 | +description: Generate the technical skeleton files (docs/04, docs/06 一~四节, docs/07, docs/09) and scripts/ + .githooks/ + .env.local.example. Reads the locked tech stack from CLAUDE.md; emits files from dedicated templates. All sensitive values left as `【人工填写:...】`. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-skeleton-gen | ||
| 7 | + | ||
| 8 | +## Pre-conditions | ||
| 9 | + | ||
| 10 | +- CLAUDE.md header is locked (`erp-tech-stack-lock` has run; no `【人工填写:` in the 4 meta slots). | ||
| 11 | + | ||
| 12 | +## Procedure | ||
| 13 | + | ||
| 14 | +### A. Read tech stack | ||
| 15 | +From CLAUDE.md § 🏗️ 技术栈, parse rows into memory. | ||
| 16 | + | ||
| 17 | +### B. Emit docs/ | ||
| 18 | +For each target below, read the named template, fill stack-derived slots, Write to target path. Files that already exist → stop and ask (`overwrite? skip?`); do not silently clobber. | ||
| 19 | + | ||
| 20 | +| Target | Template | | ||
| 21 | +|---|---| | ||
| 22 | +| `docs/04-技术规范.md` | `templates/docs-04-skeleton-template.md` | | ||
| 23 | +| `docs/06-UI交互规范.md` | `templates/docs-06-static-template.md` | | ||
| 24 | +| `docs/07-环境配置.md` | `templates/docs-07-env-template.md` | | ||
| 25 | +| `docs/09-项目目录结构.md` | `templates/docs-09-structure-template.md` | | ||
| 26 | + | ||
| 27 | +Slot examples: `backend_layering`, `backend_package_convention`, `backend_class_convention`, `frontend_layout`, `controller_rule`, etc. | ||
| 28 | + | ||
| 29 | +- Where a value is project-specific (root package name / namespace), keep the placeholder `【人工填写:<说明>】` and register it in the `zero-section placeholder table` of `docs/07`. | ||
| 30 | + | ||
| 31 | +### C. Emit scripts/ and .githooks/ and .env example | ||
| 32 | + | ||
| 33 | +| Target | Template | | ||
| 34 | +|---|---| | ||
| 35 | +| `scripts/test.sh` | `templates/scripts-test-sh-template.sh` | | ||
| 36 | +| `scripts/setup-test-db.sh` | `templates/scripts-setup-test-db-template.sh` | | ||
| 37 | +| `.githooks/pre-push` | `templates/githooks-pre-push-template.sh` | | ||
| 38 | +| `.env.local.example` | `templates/env-local-example-template` | | ||
| 39 | + | ||
| 40 | +After writing, `chmod +x scripts/*.sh .githooks/pre-push`. | ||
| 41 | + | ||
| 42 | +Run: `git config core.hooksPath .githooks` (ask user confirmation before changing git config — this touches shared state). | ||
| 43 | + | ||
| 44 | +### D. Validate | ||
| 45 | + | ||
| 46 | +- `erp-placeholder-scan` over newly written files: hits are expected (we want them registered in § 零, speed-table). | ||
| 47 | +- Print summary: `skeleton-gen: wrote N files. Placeholders to fill: M (see docs/07 § 零、人工占位速查表).` | ||
| 48 | + | ||
| 49 | +## References | ||
| 50 | + | ||
| 51 | +- `templates/docs-04-skeleton-template.md` | ||
| 52 | +- `templates/docs-06-static-template.md` | ||
| 53 | +- `templates/docs-07-env-template.md` | ||
| 54 | +- `templates/docs-09-structure-template.md` | ||
| 55 | +- `templates/scripts-test-sh-template.sh` | ||
| 56 | +- `templates/scripts-setup-test-db-template.sh` | ||
| 57 | +- `templates/githooks-pre-push-template.sh` | ||
| 58 | +- `templates/env-local-example-template` |
_pl_staging/pl_skills/erp-skeleton-gen/templates/docs-04-skeleton-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-skeleton-gen/templates/docs-04-skeleton-template.md | ||
| 1 | +# 04-技术规范 | ||
| 2 | + | ||
| 3 | +## 一、后端规范 | ||
| 4 | + | ||
| 5 | +### 1.1 分层结构 | ||
| 6 | +{{backend_layering}} | ||
| 7 | + | ||
| 8 | +### 1.2 命名约定 | ||
| 9 | +- 包名: {{backend_package_convention}} | ||
| 10 | +- 类名: {{backend_class_convention}} | ||
| 11 | +- 方法名: {{backend_method_convention}} | ||
| 12 | + | ||
| 13 | +### 1.3 统一响应格式 | ||
| 14 | +```json | ||
| 15 | +{"code": 200, "message": "", "data": {}, "timestamp": 0} | ||
| 16 | +``` | ||
| 17 | + | ||
| 18 | +### 1.4 异常处理 | ||
| 19 | +{{backend_exception_strategy}} | ||
| 20 | + | ||
| 21 | +### 1.5 事务 | ||
| 22 | +{{backend_tx_strategy}} | ||
| 23 | + | ||
| 24 | +### 1.6 JWT 认证 | ||
| 25 | +{{backend_jwt}} | ||
| 26 | + | ||
| 27 | +## 二、前端规范 | ||
| 28 | + | ||
| 29 | +### 2.1 目录约定 | ||
| 30 | +{{frontend_layout}} | ||
| 31 | + | ||
| 32 | +### 2.2 状态管理 | ||
| 33 | +{{frontend_state}} | ||
| 34 | + | ||
| 35 | +### 2.3 请求封装 | ||
| 36 | +{{frontend_http}} | ||
| 37 | + | ||
| 38 | +### 2.4 错误处理 | ||
| 39 | +{{frontend_error}} | ||
| 40 | + | ||
| 41 | +## 三、共同约定 | ||
| 42 | + | ||
| 43 | +### 3.1 Git 提交 | ||
| 44 | +`<type>(<scope>): <subject> REQ-XXX-NNN` | ||
| 45 | + | ||
| 46 | +### 3.2 分页查询 | ||
| 47 | +{{pagination_rule}} | ||
| 48 | + | ||
| 49 | +### 3.3 日期与金额 | ||
| 50 | +{{datetime_money_rule}} |
_pl_staging/pl_skills/erp-skeleton-gen/templates/docs-06-static-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-skeleton-gen/templates/docs-06-static-template.md | ||
| 1 | +# 06-UI交互规范 | ||
| 2 | + | ||
| 3 | +## 一、整体布局 | ||
| 4 | + | ||
| 5 | +### 1.1 页面框架 | ||
| 6 | +{{layout_frame}} | ||
| 7 | + | ||
| 8 | +### 1.2 布局参数 | ||
| 9 | +| 参数 | 值 | 说明 | | ||
| 10 | +|---|---|---| | ||
| 11 | +| Header高度 | 64px | 固定定位 | | ||
| 12 | +| Sidebar宽度 | 220px(展开)/ 64px(折叠) | 可手动切换 | | ||
| 13 | +| 内容区内边距 | 24px | 四周 | | ||
| 14 | +| 最小支持宽度 | 1280px | 不做移动端适配 | | ||
| 15 | + | ||
| 16 | +## 二、标准页面类型 | ||
| 17 | + | ||
| 18 | +### 2.1 列表页 | ||
| 19 | +{{list_page}} | ||
| 20 | + | ||
| 21 | +### 2.2 表单页 | ||
| 22 | +{{form_page}} | ||
| 23 | + | ||
| 24 | +### 2.3 详情页 | ||
| 25 | +{{detail_page}} | ||
| 26 | + | ||
| 27 | +### 2.4 树形管理页 | ||
| 28 | +{{tree_page}} | ||
| 29 | + | ||
| 30 | +## 三、通用交互规则 | ||
| 31 | + | ||
| 32 | +### 3.1 操作反馈 | ||
| 33 | +{{feedback_rules}} | ||
| 34 | + | ||
| 35 | +### 3.2 数据展示 | ||
| 36 | +{{display_rules}} | ||
| 37 | + | ||
| 38 | +### 3.3 权限控制(前端) | ||
| 39 | +{{permission_rules}} | ||
| 40 | + | ||
| 41 | +## 四、主题与颜色 | ||
| 42 | +{{theme_rules}} | ||
| 43 | + | ||
| 44 | +## 五、页面清单(CC 生成) | ||
| 45 | +(由 `erp-downstream-gen` 按模块追加段落) |
_pl_staging/pl_skills/erp-skeleton-gen/templates/docs-07-env-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-skeleton-gen/templates/docs-07-env-template.md | ||
| 1 | +# 07-环境配置 | ||
| 2 | + | ||
| 3 | +## 零、人工占位速查表 | ||
| 4 | + | ||
| 5 | +| 占位符 | 位置 | 说明 | | ||
| 6 | +|---|---|---| | ||
| 7 | +{{#each placeholders}} | ||
| 8 | +| {{marker}} | {{location}} | {{note}} | | ||
| 9 | +{{/each}} | ||
| 10 | + | ||
| 11 | +## 一、依赖清单 | ||
| 12 | +{{#each deps}} | ||
| 13 | +- {{name}} {{version}} — {{purpose}} | ||
| 14 | +{{/each}} | ||
| 15 | + | ||
| 16 | +## 二、端口约定 | ||
| 17 | +| 服务 | 端口 | | ||
| 18 | +|---|---| | ||
| 19 | +{{#each ports}} | ||
| 20 | +| {{service}} | {{port}} | | ||
| 21 | +{{/each}} | ||
| 22 | + | ||
| 23 | +## 三、环境变量(.env.local.example) | ||
| 24 | +见 `.env.local.example`。敏感值 `【人工填写:...】` 由人工替换。 | ||
| 25 | + | ||
| 26 | +## 四、数据库连接 | ||
| 27 | +- Host: `【人工填写:MySQL host】` | ||
| 28 | +- Port: `【人工填写:MySQL port,默认 3306】` | ||
| 29 | +- Schema: `【人工填写:schema 名】` | ||
| 30 | +- 字符集: `【人工填写,例如 utf8mb4】` | ||
| 31 | +- 账号: `【人工填写:只读/读写账号】` | ||
| 32 | +- 密码: `【人工填写:对应密码】` | ||
| 33 | + | ||
| 34 | +## 五、常用命令 | ||
| 35 | +{{#each commands}} | ||
| 36 | +- `{{command}}` — {{description}} | ||
| 37 | +{{/each}} |
_pl_staging/pl_skills/erp-skeleton-gen/templates/docs-09-structure-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-skeleton-gen/templates/docs-09-structure-template.md | ||
| 1 | +# 09-项目目录结构 | ||
| 2 | + | ||
| 3 | +## 一、仓库顶层 | ||
| 4 | +``` | ||
| 5 | +{{repo_root_tree}} | ||
| 6 | +``` | ||
| 7 | + | ||
| 8 | +## 二、后端目录 | ||
| 9 | +``` | ||
| 10 | +{{backend_tree}} | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## 三、前端目录 | ||
| 14 | +``` | ||
| 15 | +{{frontend_tree}} | ||
| 16 | +``` | ||
| 17 | + | ||
| 18 | +## 四、命名与放置约定 | ||
| 19 | +- 根包: `【人工填写:Java 根包名 / C# 命名空间 / Python 顶层模块】` | ||
| 20 | +- Controller: {{controller_rule}} | ||
| 21 | +- Service: {{service_rule}} | ||
| 22 | +- Mapper/Repository: {{mapper_rule}} | ||
| 23 | +- DTO/VO: {{dto_rule}} | ||
| 24 | +- 前端组件: {{component_rule}} | ||
| 25 | +- 前端页面: {{page_rule}} |
_pl_staging/pl_skills/erp-skeleton-gen/templates/env-local-example-template
0 → 100644
_pl_staging/pl_skills/erp-skeleton-gen/templates/githooks-pre-push-template.sh
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-skeleton-gen/templates/githooks-pre-push-template.sh | ||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# .githooks/pre-push — run scripts/test.sh before every push. | ||
| 3 | +# No --no-verify: the claude-code hook deny-no-verify.sh also blocks it. | ||
| 4 | + | ||
| 5 | +set -euo pipefail | ||
| 6 | + | ||
| 7 | +cd "$(git rev-parse --show-toplevel)" | ||
| 8 | + | ||
| 9 | +./scripts/test.sh |
_pl_staging/pl_skills/erp-skeleton-gen/templates/scripts-setup-test-db-template.sh
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-skeleton-gen/templates/scripts-setup-test-db-template.sh | ||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# scripts/setup-test-db.sh — truncate + reseed only. NEVER runs DDL. | ||
| 3 | +# Schema is human-owned; this script only clears data and reloads seed-data.sql. | ||
| 4 | + | ||
| 5 | +set -euo pipefail | ||
| 6 | + | ||
| 7 | +source "$(dirname "$0")/../.env.local" | ||
| 8 | + | ||
| 9 | +echo "[setup-test-db] truncate tables in ${DB_SCHEMA}" | ||
| 10 | +mysql -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASSWORD}" "${DB_SCHEMA}" <<'SQL' | ||
| 11 | +SET FOREIGN_KEY_CHECKS = 0; | ||
| 12 | +{{truncate_block}} | ||
| 13 | +SET FOREIGN_KEY_CHECKS = 1; | ||
| 14 | +SQL | ||
| 15 | + | ||
| 16 | +echo "[setup-test-db] reseed" | ||
| 17 | +mysql -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASSWORD}" "${DB_SCHEMA}" < sql/seed-data.sql | ||
| 18 | + | ||
| 19 | +echo "[setup-test-db] done" |
_pl_staging/pl_skills/erp-skeleton-gen/templates/scripts-test-sh-template.sh
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-skeleton-gen/templates/scripts-test-sh-template.sh | ||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# scripts/test.sh — the only hard gate before merging to main. | ||
| 3 | +# Runs build + lint + unit + integration + E2E. | ||
| 4 | +# Called by .githooks/pre-push and by the erp-local-test-gate skill (via subagent). | ||
| 5 | + | ||
| 6 | +set -euo pipefail | ||
| 7 | + | ||
| 8 | +PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" | ||
| 9 | +cd "$PROJECT_ROOT" | ||
| 10 | + | ||
| 11 | +echo "[test.sh] 1/5 setup test db" | ||
| 12 | +./scripts/setup-test-db.sh | ||
| 13 | + | ||
| 14 | +echo "[test.sh] 2/5 build" | ||
| 15 | +{{build_command}} | ||
| 16 | + | ||
| 17 | +echo "[test.sh] 3/5 lint" | ||
| 18 | +{{lint_command}} | ||
| 19 | + | ||
| 20 | +echo "[test.sh] 4/5 unit + integration" | ||
| 21 | +{{unit_integration_command}} | ||
| 22 | + | ||
| 23 | +echo "[test.sh] 5/5 E2E" | ||
| 24 | +{{e2e_command}} | ||
| 25 | + | ||
| 26 | +echo "[test.sh] GREEN" |
_pl_staging/pl_skills/erp-tech-stack-lock/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-tech-stack-lock/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-tech-stack-lock | ||
| 3 | +description: Interactively collect project metadata (name / brief / target users / deployment) and confirm-or-edit the tech stack table, then write into CLAUDE.md header via claude-md-header-template. Invoke at project start or whenever CLAUDE.md header slots are still `【人工填写:...】`. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-tech-stack-lock | ||
| 7 | + | ||
| 8 | +## Procedure | ||
| 9 | + | ||
| 10 | +### A. Collect 4 metadata slots | ||
| 11 | + | ||
| 12 | +Ask the user via `AskUserQuestion` (one question per slot; use multiSelect=false; provide reasonable options where possible): | ||
| 13 | + | ||
| 14 | +1. **项目名称** — open-ended (no options; use "Other") | ||
| 15 | +2. **项目简述** — open-ended, one sentence | ||
| 16 | +3. **目标用户** — open-ended (examples: 企业内部管理人员 / 面向 C 端客户 / ...) | ||
| 17 | +4. **部署方式** — options: `私有化部署` / `云部署` / `Docker 容器化` / `混合` | ||
| 18 | + | ||
| 19 | +### B. Tech-stack table | ||
| 20 | + | ||
| 21 | +Default table (11 rows): | ||
| 22 | + | ||
| 23 | +| 层级 | 技术 | 版本要求 | | ||
| 24 | +|---|---|---| | ||
| 25 | +| 前端框架 | React | 18.x | | ||
| 26 | +| 前端UI库 | Ant Design | 5.x | | ||
| 27 | +| 前端状态管理 | Redux Toolkit | 最新稳定版 | | ||
| 28 | +| 前端路由 | React Router | v6 | | ||
| 29 | +| 前端构建 | Vite | 最新稳定版 | | ||
| 30 | +| 前端HTTP | Axios | 最新稳定版 | | ||
| 31 | +| 后端框架 | Spring Boot | 3.x | | ||
| 32 | +| 后端ORM | MyBatis-Plus | 最新稳定版 | | ||
| 33 | +| 数据库 | MySQL | 8.x | | ||
| 34 | +| 认证方案 | JWT | — | | ||
| 35 | +| API风格 | RESTful | — | | ||
| 36 | + | ||
| 37 | +**Ask one question per row, in order.** For each row, use `AskUserQuestion` with: | ||
| 38 | +- **header**: the 层级 name (e.g. "前端框架") | ||
| 39 | +- **question**: `<层级>:沿用 <默认技术 默认版本>,还是替换?` | ||
| 40 | +- **options** (exactly 3): | ||
| 41 | + 1. `沿用 <默认技术> <默认版本>` — keep default | ||
| 42 | + 2. `替换为其它技术` — user picks "Other" and types the replacement (format: `技术名 版本`, e.g. `Vue 3.x`) | ||
| 43 | + 3. `当前技术栈不需要` — drop this row entirely (e.g. 纯后端项目可移除前端各行) | ||
| 44 | +- **multiSelect**: false | ||
| 45 | + | ||
| 46 | +One row = one `question` entry. Batch as many rows as possible into each `AskUserQuestion` call (the tool's own `maxItems` caps how many fit per call; don't add artificial limits beyond that). Do NOT collapse multiple rows into one question with rows-as-options. | ||
| 47 | + | ||
| 48 | +**After all 11 rows are collected**, ask a final question: | ||
| 49 | +- **question**: `以上 11 项已确认。是否需要新增技术栈条目?(例如消息队列/缓存/搜索引擎)` | ||
| 50 | +- **options** (exactly 2): | ||
| 51 | + 1. `不新增` | ||
| 52 | + 2. `新增条目` — if picked, follow up: ask the user to list additions in free text, format: `层级 | 技术 | 版本` per line | ||
| 53 | +- **multiSelect**: false | ||
| 54 | + | ||
| 55 | +Collect the final stack_rows list (11 base rows, each either kept or replaced, plus any additions). | ||
| 56 | + | ||
| 57 | +### C. Render and write | ||
| 58 | + | ||
| 59 | +1. Read `templates/claude-md-header-template.md`. | ||
| 60 | +2. Fill slots: `project_name`, `project_brief`, `target_users`, `deployment`, `stack_rows[]`. | ||
| 61 | +3. Locate the target block in `CLAUDE.md` (§ 🎯 项目概述 + § 🏗️ 技术栈) and replace with the rendered content. Preserve all other CLAUDE.md sections verbatim. | ||
| 62 | +4. Verify with `erp-placeholder-scan` over `CLAUDE.md` header — must have no `【人工填写:` residuals in the 4 collected slots. | ||
| 63 | +5. Print `tech-stack-lock: DONE (<project_name>)`. | ||
| 64 | + | ||
| 65 | +## References | ||
| 66 | + | ||
| 67 | +- `templates/claude-md-header-template.md` |
_pl_staging/pl_skills/erp-tech-stack-lock/templates/claude-md-header-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-tech-stack-lock/templates/claude-md-header-template.md | ||
| 1 | +## 🎯 项目概述 | ||
| 2 | + | ||
| 3 | +- **项目名称**: {{project_name}} | ||
| 4 | +- **项目简述**: {{project_brief}} | ||
| 5 | +- **目标用户**: {{target_users}} | ||
| 6 | +- **部署方式**: {{deployment}} | ||
| 7 | + | ||
| 8 | +--- | ||
| 9 | + | ||
| 10 | +## 🏗️ 技术栈(不可更改) | ||
| 11 | + | ||
| 12 | +| 层级 | 技术 | 版本要求 | | ||
| 13 | +|---|---|---| | ||
| 14 | +{{#each stack_rows}} | ||
| 15 | +| {{layer}} | {{tech}} | {{version}} | | ||
| 16 | +{{/each}} |
_pl_staging/pl_skills/erp-understanding-report/SKILL.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-understanding-report/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-understanding-report | ||
| 3 | +description: Output the 6-section understanding confirmation report and stop to wait for the user's "理解正确" before any coding starts. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# erp-understanding-report | ||
| 7 | + | ||
| 8 | +## Pre-conditions | ||
| 9 | + | ||
| 10 | +All planning docs present: `docs/01-需求清单/**`, `docs/02` through `docs/10`, `sql/seed-data.sql`. | ||
| 11 | + | ||
| 12 | +## Procedure | ||
| 13 | + | ||
| 14 | +1. Read (one-time, comprehensive): | ||
| 15 | + - CLAUDE.md | ||
| 16 | + - docs/01-需求清单/README.md and all module files | ||
| 17 | + - docs/02 through 10 | ||
| 18 | + - docs/superpowers/schema-baseline.sql header (not body) | ||
| 19 | +2. Read `templates/understanding-report-template.md`. | ||
| 20 | +3. Fill slots: | ||
| 21 | + - `project_goal` — derived from CLAUDE.md 项目概述 | ||
| 22 | + - `modules[]` — from docs/08 in topological order | ||
| 23 | + - `data_model` — key entity relations summarized from docs/03 (3–5 sentences) | ||
| 24 | + - `tech_approach` — key architectural choices from docs/04 | ||
| 25 | + - `questions` — any ambiguity / conflict / gap you spotted; explicit list, not "no questions" | ||
| 26 | + - `next_module` — first `confirmed: false` in docs/08 | ||
| 27 | +4. Print the rendered report **to the main session** (do NOT write a file — this is a conversation artifact). | ||
| 28 | +5. Stop. Do not invoke any downstream skill. Wait for the user to reply "理解正确" or equivalent. | ||
| 29 | + | ||
| 30 | +## After user confirms | ||
| 31 | + | ||
| 32 | +- Hand off to `erp-session-start` (which will detect state and dispatch to `erp-module-start`). | ||
| 33 | + | ||
| 34 | +## References | ||
| 35 | + | ||
| 36 | +- `templates/understanding-report-template.md` |
_pl_staging/pl_skills/erp-understanding-report/templates/understanding-report-template.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_skills/erp-understanding-report/templates/understanding-report-template.md | ||
| 1 | +## 📝 理解确认报告 | ||
| 2 | + | ||
| 3 | +### 1. 项目目标理解 | ||
| 4 | +{{project_goal}} | ||
| 5 | + | ||
| 6 | +### 2. 模块拆解理解 | ||
| 7 | +{{#each modules}} | ||
| 8 | +- **{{module_id}} {{module_name}}** — {{core_functions}} | ||
| 9 | +{{/each}} | ||
| 10 | + | ||
| 11 | +### 3. 数据模型理解 | ||
| 12 | +{{data_model}} | ||
| 13 | + | ||
| 14 | +### 4. 技术方案理解 | ||
| 15 | +{{tech_approach}} | ||
| 16 | + | ||
| 17 | +### 5. 存在的疑问 | ||
| 18 | +{{questions}} | ||
| 19 | + | ||
| 20 | +### 6. 开发计划确认 | ||
| 21 | +按 `docs/02-开发计划.md` 拓扑序开发,首个待推进模块: **{{next_module}}**。 | ||
| 22 | + | ||
| 23 | +--- | ||
| 24 | + | ||
| 25 | +⚠️ 等待人工回复"理解正确"后才开始编码。 |
_pl_staging/pl_指南.md
0 → 100644
| 1 | +++ a/_pl_staging/pl_指南.md | ||
| 1 | +# ERP项目 — 文档总览与使用指南 | ||
| 2 | + | ||
| 3 | +> 本文件是整个文档体系的入口。先读这里,再按流程操作。 | ||
| 4 | +> 核心思路:**人工只填"机器不可能知道的东西",其余交给 Claude Code 生成后人工审阅。** | ||
| 5 | +> | ||
| 6 | +> **阅读顺序**:建议先通读一到四节(文档目录 / 分工 / 配套机制 / 关键原则),建立整体认知;然后按第五节"完整使用流程"逐步上手。 | ||
| 7 | + | ||
| 8 | +--- | ||
| 9 | + | ||
| 10 | +## 一、文档目录 | ||
| 11 | + | ||
| 12 | +``` | ||
| 13 | +项目根目录/ | ||
| 14 | +├── CLAUDE.md ← ★ Claude Code 的主指令文件(顶部需人工填项目概述) | ||
| 15 | +├── 指南.md ← 本文件 | ||
| 16 | +├── docs/ ← 所有项目文档 | ||
| 17 | +│ ├── 01-需求清单/ ← 功能需求全集(按模块分文件,模块可自由增删) | ||
| 18 | +│ │ ├── README.md ← 纲要 + 模块索引(人工写) | ||
| 19 | +│ │ ├── SYS-系统管理.md ← REQ-SYS-* 用户/角色/权限/部门/字典 | ||
| 20 | +│ │ └── <其他模块>.md ← 如 PUR-采购 / SAL-销售 / HR-人事 等,按业务增删,详见 README | ||
| 21 | +│ ├── 02-开发计划.md ← 分模块开发路线图(CC 基于需求**按技术依赖重排**) | ||
| 22 | +│ ├── 03-数据库设计文档.md ← 表结构业务含义(CC 通过 MySQL MCP 查询 live DB 生成) | ||
| 23 | +│ ├── 04-技术规范.md ← 通用规范 + 技术栈衍生编码规范(骨架由 CC 按技术栈生成) | ||
| 24 | +│ ├── 05-API接口契约.md ← 前后端接口契约(CC 基于需求+表结构生成) | ||
| 25 | +│ ├── 06-UI交互规范.md ← 页面布局与交互规则(模板已完整) | ||
| 26 | +│ ├── 07-环境配置.md ← 骨架由 CC 按技术栈生成;人工填账密/密钥/包名等占位 | ||
| 27 | +│ ├── 08-模块任务管理.md ← ★ 人机协作控制中枢(CC 与 02 对齐) | ||
| 28 | +│ ├── 09-项目目录结构.md ← 骨架由 CC 按技术栈生成(前后端目录名与层级) | ||
| 29 | +│ └── 10-验收检查清单.md ← 每个模块的质量门(CC 基于需求生成) | ||
| 30 | +├── scripts/ | ||
| 31 | +│ ├── setup-test-db.sh ← truncate 当前 schema + reseed(CC 按技术栈生成;3.3) | ||
| 32 | +│ └── test.sh ← 一键全量测试脚本(CC 按技术栈生成;3.3) | ||
| 33 | +├── .githooks/ | ||
| 34 | +│ └── pre-push ← Git hook:push 前自动跑 test.sh(3.3) | ||
| 35 | +├── .env.local ← 每人独立的数据库连接(schema 名),不入 git | ||
| 36 | +└── <代码目录> ← 由 Step 1 技术栈决定,CC 在 Step 10 开发时生成 | ||
| 37 | + 具体目录名与层级参见 docs/09-项目目录结构.md | ||
| 38 | +``` | ||
| 39 | + | ||
| 40 | +--- | ||
| 41 | + | ||
| 42 | +## 二、文档分工:谁来填? | ||
| 43 | + | ||
| 44 | +| 类别 | 文档 | 负责人 | 说明 | | ||
| 45 | +| ---------- | --------------------------------- | ----------- | ----------------------------------------------------------------------- | | ||
| 46 | +| **A 必填** | `CLAUDE.md` 顶部项目概述(4 处) | 👤 人工 | 项目名、简述、目标用户、部署方式 | | ||
| 47 | +| **A 必填** | `docs/01-需求清单/README.md` **纲要** | 👤 人工 | 模块列表 + 每模块核心功能点 + 关键业务数字 | | ||
| 48 | +| **A 必填** | `docs/07-环境配置.md` 敏感/专属占位 | 👤 人工 | 数据库账密、JWT secret、包名、上传路径、小版本号等 | | ||
| 49 | +| **A 必填** | MySQL schema + 表 DDL + MCP 连接 | 👤 人工 | 在现有 MySQL 中新建项目专用 schema 并建齐所有表;在仓库 `.mcp.json` 配置 MCP 指向该 schema | | ||
| 50 | +| **B 生成+审** | `docs/01-需求清单/<模块>.md` 完整版 | 🤖 CC → 人工审 | 逐模块一个文件,基于纲要扩展成 REQ-XXX-NNN 标准卡片 | | ||
| 51 | +| **B 生成+审** | `docs/02-开发计划.md` | 🤖 CC → 人工审 | 基于 01 需求按技术依赖拆分模块 0~N | | ||
| 52 | +| **B 生成+审** | `docs/03-数据库设计文档.md` | 🤖 CC → 人工审 | 通过 MySQL MCP 查 live DB 自动填字段业务说明、ER 关系 | | ||
| 53 | +| **B 生成+审** | `docs/04-技术规范.md` 骨架 | 🤖 CC → 人工审 | 按 `CLAUDE.md` 技术栈表推导后端 / 前端编码规范与认证实现(通用规范章节保留不变) | | ||
| 54 | +| **B 生成+审** | `docs/05-API接口契约.md` | 🤖 CC → 人工审 | 基于 01+03 生成 RESTful 契约 | | ||
| 55 | +| **B 生成+审** | `docs/07-环境配置.md` 骨架 & 依赖 | 🤖 CC → 人工审 | 按 `CLAUDE.md` 技术栈表推导主配置文件 / 依赖清单 / 端口规划 | | ||
| 56 | +| **B 生成+审** | `docs/08-模块任务管理.md` | 🤖 CC → 人工审 | 与 02 对齐生成任务表格 | | ||
| 57 | +| **B 生成+审** | `docs/09-项目目录结构.md` | 🤖 CC → 人工审 | 按 `CLAUDE.md` 技术栈表推导前后端目录名与层级 | | ||
| 58 | +| **B 生成+审** | `docs/10-验收检查清单.md` | 🤖 CC → 人工审 | 基于 01+08 生成验收项 | | ||
| 59 | +| **B 生成+审** | `sql/seed-data.sql` | 🤖 CC → 人工审 | 基于 MCP 查到的 schema 扩充业务测试数据 | | ||
| 60 | +| **C 模板齐全** | `docs/06-UI交互规范.md` | — | 通用规范,无需填写 | | ||
| 61 | + | ||
| 62 | +**判断标准**:只有你知道 / 涉及密钥 / 体现业务意图 → A 类必填;能从需求或 schema 推导 → B 类交给 CC。 | ||
| 63 | + | ||
| 64 | +### 占位符统一约定 | ||
| 65 | + | ||
| 66 | +所有"需要人工填"的位置,全部用下面这种**可见、可搜索** 的标记: | ||
| 67 | + | ||
| 68 | +``` | ||
| 69 | +【人工填写:<简短说明>】 | ||
| 70 | +``` | ||
| 71 | + | ||
| 72 | +示例: | ||
| 73 | + | ||
| 74 | +```markdown | ||
| 75 | +- **项目名称**: 【人工填写:公司+项目名,例如:无锡五彩印务 ERP】 | ||
| 76 | +- **数据库密码**: 【人工填写:生产库密码,走环境变量不要入库】 | ||
| 77 | +- **销售(SAL)**: 【人工填写:客户管理、报价单、销售订单、出库 等核心功能点】 | ||
| 78 | +``` | ||
| 79 | + | ||
| 80 | +**规则:** | ||
| 81 | + | ||
| 82 | +- **填写时把整个 `【人工填写:...】` 连带中文方括号一起替换为实际值**,不要保留方括号 | ||
| 83 | + (示例:`【人工填写:数据库密码】` → `Abc@123`,不是 `【Abc@123】`) | ||
| 84 | +- Step 6 启动时 CC 扫描 `【人工填写:` 作为残留占位的首选特征字符串;兜底还扫通用的裸占位值:`your_password` / `your-secret-key`(技术栈特有的占位值不纳入,统一靠 `【人工填写:`) | ||
| 85 | + | ||
| 86 | +--- | ||
| 87 | + | ||
| 88 | +## 三、配套机制(跨步骤生效,非顺序步骤) | ||
| 89 | + | ||
| 90 | +五节的 9 步是"从零到开发"的顺序动作;本节三条**不是步骤**,而是始终在后台生效的规则 / 闸门 / 工具。 | ||
| 91 | + | ||
| 92 | +### 3.1 confirmed 完成确认标记(模块完成清单) | ||
| 93 | + | ||
| 94 | +`confirmed` 是**模块完成清单**:标记哪些模块已通过人工审核、可视为已交付,从而让 CC 知道该在哪个模块上继续工作。定义在 `docs/08-模块任务管理.md`。 | ||
| 95 | + | ||
| 96 | +```yaml | ||
| 97 | +module_1: | ||
| 98 | + confirmed: false # false = 待完成(CC 在此模块上开发) | ||
| 99 | + # true = 已完成(MR 已合入,CC 进入下一模块) | ||
| 100 | +``` | ||
| 101 | + | ||
| 102 | +| 操作 | 触发方 | 触发条件 | | ||
| 103 | +| -- | -- | -- | | ||
| 104 | +| 默认 `confirmed: false` | — | 新模块生成时 | | ||
| 105 | +| `false` → `true` | **CC** | MR 已 Approved + Merged(人工告知 或 `glab mr view` 验证 merged 状态) | | ||
| 106 | +| `true` → `false`(重新开启) | **人工 或 CC** | 发现已确认模块有 bug / 需打回重做 | | ||
| 107 | + | ||
| 108 | +**授权边界:** | ||
| 109 | + | ||
| 110 | +- CC 可以改 `false` → `true`,**但前置条件是 MR 已合入**(人工 review 是唯一审核点;CC 只是把"MR 合入"这个事实同步到清单里) | ||
| 111 | +- CC **不得**在 MR 未 merged 时改 `true`(等于跳过人工审核) | ||
| 112 | +- CC **可以**把 `true` 改回 `false`(发现已确认模块有 bug 时,把该模块重新开启) | ||
| 113 | + | ||
| 114 | +### 3.2 红旗中断机制(CC 行为规则) | ||
| 115 | + | ||
| 116 | +功能循环默认静默执行,只有命中"红旗"才打断等人决策。**具体的 10 条红旗清单 + CC 命中后的固定动作都定义在 `CLAUDE.md` 的「🚩 静默执行红旗清单」一节**——CC 启动时已自动加载,开发者无需在此重复学习。 | ||
| 117 | + | ||
| 118 | +本节在指南中保留只是为了让阅读流程的开发者知道这个机制存在;**运行态的权威来源是 CLAUDE.md**。 | ||
| 119 | + | ||
| 120 | +### 3.3 本地测试闸门(本项目唯一的硬闸门) | ||
| 121 | + | ||
| 122 | +> **设计**:本项目**不使用 GitLab CI/CD**,所有测试集中在本地完整跑(单元 + 集成 + E2E + lint + 构建);闸门由一键脚本 + `pre-push` Git hook + CC 自动创建 MR + 人工审核合入**协同**实现。 | ||
| 123 | + | ||
| 124 | +#### 数据库架构 | ||
| 125 | + | ||
| 126 | +- **单 MySQL 实例 + 单 schema**(复用现有 MySQL 服务器,不用 Docker) | ||
| 127 | +- schema 命名由人工定(例如 `erp_dev`),由人工在 Step 4 建好所有表 | ||
| 128 | +- **CC 的 MCP 连接**指向该 schema,作为 live 真实源供文档生成与字段核对 | ||
| 129 | +- 本项目**单开发者场景**,`test.sh` 跑时 truncate + reseed 同一 schema,不存在并发问题 | ||
| 130 | + | ||
| 131 | +#### 仓库里放三个产物(CC 在 Step 2 按技术栈生成) | ||
| 132 | + | ||
| 133 | +``` | ||
| 134 | +<项目根>/ | ||
| 135 | +├── scripts/ | ||
| 136 | +│ ├── setup-test-db.sh ← truncate 当前 schema 所有表 + 导入 seed-data.sql | ||
| 137 | +│ └── test.sh ← 一键全量测试:单元 + 集成 + E2E + lint + 构建 | ||
| 138 | +└── .githooks/ | ||
| 139 | + └── pre-push ← Git hook:push 前自动跑 test.sh,失败则拒绝 push | ||
| 140 | +``` | ||
| 141 | + | ||
| 142 | +> **不使用 Docker**、不使用 `docker-compose.test.yml`;复用现有 MySQL。 | ||
| 143 | + | ||
| 144 | +**各文件职责:** | ||
| 145 | + | ||
| 146 | +- **`scripts/setup-test-db.sh`**:读 `.env.local` 取 DB 连接 → 连 MySQL → 对当前 schema 内所有表 `TRUNCATE`(禁用 FK 检查)→ `mysql < sql/seed-data.sql`。**不建表不删表**(DDL 归人工) | ||
| 147 | +- **`scripts/test.sh`**:按技术栈串起来——先调 `setup-test-db.sh` 重置数据 → 后端单元 / 集成测试、前端单元测试、E2E(Playwright / Cypress)、lint、构建验证。退出码非 0 即失败 | ||
| 148 | +- **`.githooks/pre-push`**:bash 脚本,`git push` 前自动触发 `scripts/test.sh`;非 0 退出码会让 `git push` 被拒绝 | ||
| 149 | + | ||
| 150 | +#### 一次性 Dev Setup(每个开发者克隆后跑一次) | ||
| 151 | + | ||
| 152 | +```bash | ||
| 153 | +# 1. 启用仓库自带 hooks(不在 .git/hooks 里,在 .githooks/ 方便入版本控制) | ||
| 154 | +git config core.hooksPath .githooks | ||
| 155 | + | ||
| 156 | +# 2. 复制 .env.local.example → .env.local,填入 MySQL 连接 | ||
| 157 | +cp .env.local.example .env.local | ||
| 158 | +# 编辑:DB_HOST / DB_PORT / DB_USER / DB_PASSWORD / DB_SCHEMA(项目专用 schema 名) | ||
| 159 | + | ||
| 160 | +# 3. 试跑一遍(会对当前 schema 做 truncate + reseed) | ||
| 161 | +./scripts/setup-test-db.sh | ||
| 162 | +./scripts/test.sh | ||
| 163 | + | ||
| 164 | +# 4. 配置 glab CLI(CC 自动创建 MR 用) | ||
| 165 | +glab auth login # 按提示填自建 GitLab 实例 URL + PAT | ||
| 166 | +``` | ||
| 167 | + | ||
| 168 | +> **前提**:MySQL 中已建好项目专用 schema 并用 DDL 建齐所有表(见 Step 4)。 | ||
| 169 | +> | ||
| 170 | +> **CC 需要**:`glab` CLI + GitLab PAT(scope: `api` / `write_repository`);token 存 `~/.config/glab-cli/config.yml`,不入版本控制。MySQL MCP 连接在 `.mcp.json` 配置(指向项目 schema)。 | ||
| 171 | + | ||
| 172 | +**约定写在 `docs/07-环境配置.md` 的七节"启动 / 构建命令"**,由 CC 在 Step 2 生成时同步登记。 | ||
| 173 | + | ||
| 174 | +#### MR 创建与合并流程(合并前置仅 2 项) | ||
| 175 | + | ||
| 176 | +1. **本地 `scripts/test.sh` 全绿** —— `.githooks/pre-push` 自动触发,失败则 push 被拒;**禁止** `--no-verify` 绕过 | ||
| 177 | +2. **CC 自动 `git push` + `glab mr create`** —— 将《模块完成报告》审阅包贴入 MR 描述(含通过用例数、耗时、`test.sh` 输出结尾作为跑过测试的书面证据);CC 输出 MR 链接后**停下**等人工 | ||
| 178 | +3. **模块末人工审核(唯一人工介入点)** —— 你 review 通过后: | ||
| 179 | + - 点 MR "Approve" + Merge | ||
| 180 | + - 对 CC 说"MR 已 approve + merge"(或 "继续") | ||
| 181 | +4. **CC 自行同步 confirmed 并进入下一模块**: | ||
| 182 | + - CC 用 `glab mr view <mr-iid>` 验证 MR 确实已 merged | ||
| 183 | + - 验证通过后,在 `docs/08-模块任务管理.md` 把当前模块 `confirmed` 改为 `true` | ||
| 184 | + - 进入下一个 `false` 模块开始工作 | ||
| 185 | + | ||
| 186 | +> 人工只做"审 + Approve + Merge + 告知 CC"四件事;`confirmed` 字段的实际写入由 CC 完成,但**必须以 MR merged 为前提**——CC 若在未 merged 状态下写 `true`,等于跳过人工审核,属于严重违规。 | ||
| 187 | + | ||
| 188 | +#### GitLab 仓库设置(Ops 一次性配置) | ||
| 189 | + | ||
| 190 | +- Project → Settings → Repository → Protected Branches | ||
| 191 | + - `main`:Allowed to push = **No one**(强制走 MR) | ||
| 192 | + - Allowed to merge = Developers + Maintainers | ||
| 193 | +- Project → Settings → Merge Requests | ||
| 194 | + - ☑ All threads must be resolved | ||
| 195 | + - Approvals → 至少 1 人 | ||
| 196 | + | ||
| 197 | +> 本项目**不启用** "Pipelines must succeed",也不配置 CI/CD Runner;本地 `scripts/test.sh` + `pre-push` hook 是唯一硬闸门。 | ||
| 198 | + | ||
| 199 | +--- | ||
| 200 | + | ||
| 201 | +## 四、关键原则 | ||
| 202 | + | ||
| 203 | +1. **schema 是只读权威(MySQL MCP live 查询)** — 项目专用 schema 是唯一权威来源,CC 通过 MCP 只读查询;需求围绕既有表结构展开;CC 禁止 `CREATE TABLE / ALTER TABLE / DROP TABLE`(DDL 归人工,在 MySQL 中直接执行) | ||
| 204 | +2. **需求与 schema 冲突必须停下来** — 若某需求在表里找不到落脚点,CC 须报告由你决策:改需求 or 人工改库 | ||
| 205 | +3. **人工只填机器不可能知道的东西** — 意图、密钥、密码等 | ||
| 206 | +4. **文档越精确,AI 输出越准确** — A 类纲要写得越详细,B 类生成越准 | ||
| 207 | +5. **先确认理解,再动手编码** — CC 必须先输出《理解确认报告》 | ||
| 208 | +6. **每份文档生成后立即审阅** — 不要积压到最后一起审 | ||
| 209 | +7. **按模块推进,每个模块可控** — 不跳模块,不并行,逐个确认完成 | ||
| 210 | +8. **静默执行,命中红旗才停** — 功能循环默认不打扰人;CC 仅在 `CLAUDE.md` 🚩 红旗清单 10 条之一成立时才打断主会话等人决策 | ||
| 211 | +9. **技术栈分工:版本号单一来源** — `CLAUDE.md` 的技术栈表只做大版本锁定(`18.x` / `3.x`),作为"禁止更换技术"的约束;所有小版本号、依赖清单、具体配置模板(application.yml / pom.xml / vite.config.ts / package.json)只写在 `docs/07-环境配置.md`。两处不要重复小版本,避免漂移。 | ||
| 212 | +10. **Spec 是 source of truth** — 所有代码必须能回溯到某份 spec(01 需求卡 / superpowers spec);代码跑偏 spec 时,以 spec 为准,先改 spec 再改码。 | ||
| 213 | +11. **验收必须可执行** — `docs/10-验收检查清单.md` 不是人工 checklist,而是**可自动运行的测试用例清单**(JUnit + Playwright / Vitest)。`confirmed: true` 的前提是所有用例本地 `./scripts/test.sh` 全绿。 | ||
| 214 | +12. **AI 产物必须逐行 review,但人工只在模块末做一次** — 每个功能强制跑 `superpowers:code-reviewer` 子代理审查并修复;人工 review 在模块末统一进行,依据《模块完成报告》的审阅包。 | ||
| 215 | +13. **本地测试脚本是唯一硬闸门** — `scripts/test.sh` 跑完整测试(单元 + 集成 + E2E + lint + 构建);`pre-push` hook 失败即拒 push;测试绿后 CC 自动 `git push + glab mr create`;**本项目不配置 CI/CD**;禁止 `--no-verify` 绕过。 | ||
| 216 | +14. **业务顺序 ≠ 执行顺序** — `01-需求清单/` 按业务模块分组,顺序无所谓;`02-开发计划.md` 才是执行顺序,由 CC 按技术依赖(基础设施 → 认证 → 系统管理 → 基础资料 → 业务主流程)重排。人工不要试图在 01 里排开发顺序。 | ||
| 217 | +15. **计划阶段 vs 开发阶段** — Step 1–9 是**计划阶段**,**不写业务代码**,通过人机反复对话把所有不确定性消解在文档里(需求卡、表结构、API 契约、任务清单、验收用例等都越厚越好)。Step 10 是**开发阶段**,CC 在充分的文档基础上**尽可能自主推进**(功能循环默认静默),人工只在模块末 review MR。**文档越厚,开发越能自主;开发越自主,文档越要在计划阶段打磨**——宁可在前者多花时间,也不让后者被追问打断。 | ||
| 218 | + | ||
| 219 | +--- | ||
| 220 | + | ||
| 221 | +## 五、完整使用流程 | ||
| 222 | + | ||
| 223 | +本流程分为两个阶段,**严格单向推进,不回头**: | ||
| 224 | + | ||
| 225 | +| 阶段 | 步骤 | 核心原则 | 交互密度 | | ||
| 226 | +|------|------|--------|--------| | ||
| 227 | +| 🗂️ **计划阶段** | Step 1–9 | **不写业务代码**,通过人机反复对话沉淀尽量丰富的文档 | 高(每步都有人工审核 / 输入) | | ||
| 228 | +| 🏗️ **开发阶段** | Step 10 | **文档驱动自主开发**,功能循环默认静默,人工只在模块末 review MR | 低(每个模块唯一一次人工介入点) | | ||
| 229 | + | ||
| 230 | +> **设计意图**:把所有模糊、歧义、决策压力都挪到计划阶段解决;进入开发阶段后 CC 能一气呵成地推进功能循环,不被反复打断。**文档质量 = 开发自主度的上限。** | ||
| 231 | + | ||
| 232 | +> **总原则**:通用开发项目都应遵循"**锁定技术栈 → 生成环境配置 → 填占位 → 提供业务输入 → 生成需求文档 → 分模块开发**"的单向依赖链。 | ||
| 233 | +> ⚠️ 本项目额外约束:数据库是**现有的**,schema 是既定事实不可变,所以业务需求必须后于 schema。 | ||
| 234 | +> | ||
| 235 | +> **动手前**先读完一到四节,建立整体认知;本节是具体操作步骤。 | ||
| 236 | + | ||
| 237 | +--- | ||
| 238 | + | ||
| 239 | +## 🗂️ 计划阶段(Step 1–9):文档厚过天 | ||
| 240 | + | ||
| 241 | +> 本阶段**不写任何业务代码**(Step 2 生成的 scripts / 配置骨架属于开发工装,不是产品代码)。 | ||
| 242 | +> 每一步产出都要**立刻人工审阅**,宁可在这里多对话几轮。 | ||
| 243 | +> 计划阶段走完后,`docs/` 应该能回答 CC 在开发中可能遇到的 95% 以上问题。 | ||
| 244 | + | ||
| 245 | +### Step 1 — 确定技术栈(人工) | ||
| 246 | + | ||
| 247 | +1. **填 `CLAUDE.md` 顶部 4 处**:项目名 / 简述 / 目标用户 / 部署方式。 | ||
| 248 | +2. **确认或调整 `CLAUDE.md` 的「🏗️ 技术栈」表**。默认是 `Spring Boot 3.x + MyBatis-Plus + React 18 + Vite + Ant Design + JWT + MySQL 8`,保留或替换为你的技术选型。**此表只写大版本**,小版本号留到 Step 3(配置运行环境)填。 | ||
| 249 | + | ||
| 250 | +> 这一步决定了 Step 2 能生成什么;变动技术栈必须回到这一步重走。 | ||
| 251 | + | ||
| 252 | +### Step 2 — 生成技术骨架(CC) | ||
| 253 | + | ||
| 254 | +基于 `CLAUDE.md` 技术栈表,由 CC 一次性生成 **04 / 07 / 09** 的**骨架部分**(凡是技术栈变动就需要重生成的内容)。 | ||
| 255 | + | ||
| 256 | +**对 CC 说(复制粘贴即可):** | ||
| 257 | + | ||
| 258 | +``` | ||
| 259 | +请读 CLAUDE.md(不需要读 指南.md),基于 CLAUDE.md 的「🏗️ 技术栈」表,一次性生成下列骨架。 | ||
| 260 | +前三份是 docs/ 下的纯模板文件;第四项是**本地测试闸门**的四件套(仓库根与 scripts/ / .githooks/ 下)。 | ||
| 261 | +你的任务是把每一节 / 每个文件填成技术栈对应的实际内容。 | ||
| 262 | + | ||
| 263 | +1. docs/07-环境配置.md —— 保留文件头与节标题不变,按技术栈填入各节内容: | ||
| 264 | + - 一、基础环境:列出运行时 / 包管理器 / 构建工具的大版本要求 | ||
| 265 | + - 二、后端运行配置:给出主配置文件(如 application.yml / appsettings.json / settings.py / …)的完整结构 | ||
| 266 | + - 三、前端构建配置:给出构建与路径配置(如 vite.config.* / next.config.* / tsconfig.json 等) | ||
| 267 | + - 四、后端依赖清单:按包管理器格式(pom.xml / build.gradle / requirements.txt / *.csproj / go.mod / package.json …)列核心依赖 | ||
| 268 | + - 五、前端依赖清单:按包管理器格式列依赖 | ||
| 269 | + - 六、端口规划:填表 | ||
| 270 | + - 七、启动 / 构建命令:填表 | ||
| 271 | + | ||
| 272 | +2. docs/09-项目目录结构.md —— 保留文件头与节标题不变,按技术栈填入: | ||
| 273 | + - 一、顶层结构(固定项 CLAUDE.md / 指南.md / docs / sql + 技术栈相关代码目录) | ||
| 274 | + - 二、后端目录结构(分层结构树) | ||
| 275 | + - 三、前端目录结构 | ||
| 276 | + - 四、命名约定(表格) | ||
| 277 | + | ||
| 278 | +3. docs/04-技术规范.md —— 保留文件头与节标题不变,**三节(通用规范)不要改**;只填: | ||
| 279 | + - 一、后端编码规范(1.1 命名约定表 / 1.2 包 / 模块结构树 / 1.3 分层职责 / 1.4 代码模板) | ||
| 280 | + - 二、前端编码规范(2.1 命名约定表 / 2.2 目录结构 / 2.3 组件编写规范 / 2.4 API 调用规范) | ||
| 281 | + - 四节只填 4.6 认证实现(其余 4.1–4.5 是跨栈策略,不要改) | ||
| 282 | + | ||
| 283 | +4. 本地测试闸门三件套 + 一个环境文件(项目**不配置 CI/CD**;闸门完全在本地;**不使用 Docker**;单开发者复用现有 MySQL 中的单 schema): | ||
| 284 | + - `scripts/setup-test-db.sh` —— 读 `.env.local` 取 DB 连接 → 连 MySQL → 对当前 schema 内所有表 TRUNCATE(SET FOREIGN_KEY_CHECKS=0)→ `mysql < sql/seed-data.sql`;**不做 DDL**(建表归人工) | ||
| 285 | + - `scripts/test.sh` —— 先调 `setup-test-db.sh` 重置数据 → 后端单元+集成测试 + 前端单元测试 + **E2E**(Playwright / Cypress,按栈选)+ lint + 前后端构建;任一失败即退出非 0 | ||
| 286 | + - `.githooks/pre-push` —— `#!/usr/bin/env bash` + `set -e` + 调用 `./scripts/test.sh` | ||
| 287 | + - 根目录 `.env.local.example` —— 占位模板,列 `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_PASSWORD` / `DB_SCHEMA`,值用 `【人工填写:...】`;真实 `.env.local` 入 `.gitignore` | ||
| 288 | + - `docs/07-环境配置.md` 需额外登记:MySQL 连接信息(host / port / 账密 / schema 名占位)+ MCP 配置说明;`glab` CLI 工具要求 + GitLab PAT 占位;E2E 测试依赖(Playwright browser install 等) | ||
| 289 | + - **不生成** `docker-compose.test.yml`(本项目不用 Docker) | ||
| 290 | + | ||
| 291 | +【强制规则】 | ||
| 292 | +- 所有敏感值 / 项目专属值 / 小版本号一律用 【人工填写:<简短说明>】 标记,不要填实际值 | ||
| 293 | +- 凡是"只有人工能决定"的地方(密钥、账密、命名约定等)一律用这个标记,不要自行编值 | ||
| 294 | +- 占位标记必须用纯文本 `【人工填写:…】`,**不要用 HTML 注释**(`<!-- ... -->`),因为后者在 Obsidian 渲染视图会被隐藏,开发者会漏填 | ||
| 295 | +- 每个【人工填写:...】 必须带**简短说明**,让填写的人立刻知道这里要写什么(例如"【人工填写:JWT 签名密钥,256+ bit 随机串】",不是"【人工填写】") | ||
| 296 | +- 项目专属标识(Java 根包名 / C# 命名空间 / Python 顶层模块等)**不要在本次引入新的 【人工填写】**, | ||
| 297 | + 统一引用 docs/07-环境配置.md 中已登记的占位(如在 07 里叫 `type-aliases-package`,本次生成 04 时也用该值引用) | ||
| 298 | +- 每插入一处 新的 【人工填写:...】 标记,同步把它的位置登记到所在文件的「零、人工占位速查表」 | ||
| 299 | + (04 没有零节,如果确需引入新占位,同步在 04 顶部新建一个与 07 同结构的零节;能复用 07 占位就不要新建) | ||
| 300 | +- 三份文件的文件头说明、节标题不要改,只填充表格行 / 章节内容 | ||
| 301 | + | ||
| 302 | +四份可以连续生成,不用中间停下来确认。全部完成后统一输出: | ||
| 303 | + - 四份文件的绝对路径 | ||
| 304 | + - 四份各自引入的 【人工填写:...】 标记总数 | ||
| 305 | + - 07 / 09 占位速查表的最终行数(04 和测试闸门四件套若无新增占位则报"无") | ||
| 306 | + - 生成过程中遇到的任何疑点 | ||
| 307 | + | ||
| 308 | +然后停下等我一次性人工审核,之后进入 Step 3(配置运行环境)。不要触碰其他文件。 | ||
| 309 | +``` | ||
| 310 | + | ||
| 311 | +**CC 会生成的内容参考:** | ||
| 312 | + | ||
| 313 | +- **2a. `docs/07-环境配置.md` 骨架** —— 七节:基础环境 / 后端运行配置 / 前端构建配置 / 后端依赖 / 前端依赖 / 端口规划 / 启动命令 | ||
| 314 | +- **2b. `docs/09-项目目录结构.md` 骨架** —— 四节:顶层结构 / 后端目录 / 前端目录 / 命名约定 | ||
| 315 | +- **2c. `docs/04-技术规范.md` 骨架** —— 技术栈相关部分(一、后端规范 / 二、前端规范 / 4.6 认证实现),三节通用规范和 4.1–4.5 策略不动 | ||
| 316 | +- **2d. 本地测试闸门三件套 + `.env.local.example`** —— `scripts/setup-test-db.sh` + `scripts/test.sh` + `.githooks/pre-push` + `.env.local.example`;**不生成** `docker-compose.test.yml`(本项目不用 Docker);详见 3.3 | ||
| 317 | + | ||
| 318 | +**CC 不填任何敏感值**,一律用 `【人工填写:...】` 标记(详见第二节「占位符统一约定」)。 | ||
| 319 | + | ||
| 320 | +### Step 3 — 配置运行环境(人工) | ||
| 321 | + | ||
| 322 | +分别打开 `docs/07-环境配置.md` 和 `docs/09-项目目录结构.md` 顶部的「零、人工占位速查表」,按速查表逐行定位到正文里的 `【人工填写:...】` 标记,连同方括号一起替换为实际值。 | ||
| 323 | + | ||
| 324 | +> 速查表的每一行由 Step 2 生成时自动登记,内容随所选技术栈而异(Java 栈里会有 Java 包名、JWT secret;.NET 栈里则可能是命名空间、appsettings.json 密钥等)。**以你这份项目的速查表为准**,不要参考其他项目的清单。 | ||
| 325 | +> | ||
| 326 | +> 是否填完由 Step 6 启动时 CC 自动搜索 `【人工填写:` 来核对。 | ||
| 327 | +> 小版本号**只写在此处**;`CLAUDE.md` 技术栈表只锁大版本。两处重复必然漂移。 | ||
| 328 | + | ||
| 329 | +### Step 4 — 建 schema 建表 + 配置 MCP(人工) | ||
| 330 | + | ||
| 331 | +本项目**不使用 `sql/schema.sql` 文件**;MySQL live DB 本身就是 schema 的唯一权威来源,CC 通过 MySQL MCP 查询获取。 | ||
| 332 | + | ||
| 333 | +**操作步骤:** | ||
| 334 | + | ||
| 335 | +1. **在现有 MySQL 中建项目专用 schema**(如 `erp_dev`,名字由你定;大版本需与 `CLAUDE.md` 技术栈表一致) | ||
| 336 | +2. **在该 schema 内建齐所有表**: | ||
| 337 | + - 若是全新项目:人工手写 DDL 一次性建好 | ||
| 338 | + - 若有参考库:`mysqldump --no-data <source> | mysql <erp_dev>` | ||
| 339 | +3. **配置 CC 的 MCP 连接**:在仓库根 `.mcp.json` 里填 `mcp_server_mysql` 的 host / port / user / password / database(指向项目 schema),账密用 `【人工填写:...】` 占位 + 实际值走环境变量 | ||
| 340 | +4. **配置 `.env.local`**:`cp .env.local.example .env.local` 填入 DB 连接与 schema 名 | ||
| 341 | +5. **验证**:跑 `./scripts/setup-test-db.sh` 能正常 truncate + reseed;CC 启动时能通过 MCP `SHOW TABLES` 查到所有表 | ||
| 342 | + | ||
| 343 | +> ⚠️ **CC 禁止 `CREATE / ALTER / DROP TABLE`**(见 CLAUDE.md 红旗 #1 + #6)。schema 改动永远由人工在 MySQL 中直接执行。 | ||
| 344 | +> | ||
| 345 | +> ⚠️ DDL 文件请版本化管理(可另存库外,如团队知识库),但**不要放 `sql/schema.sql`**——那会被误当作 CC 的输入源。 | ||
| 346 | + | ||
| 347 | +### Step 5 — 确定需求纲要(人工) | ||
| 348 | + | ||
| 349 | +在 `docs/01-需求清单/README.md` 中填写"模块 + 核心功能点"的 bullet 纲要。 | ||
| 350 | + | ||
| 351 | +> ⚠️ 写之前先通过 MySQL MCP `SHOW TABLES` 看一遍库里有哪些表,确保每条需求在表里有落脚点。 | ||
| 352 | +> ⚠️ 模块顺序**不代表开发顺序**——开发顺序由 CC 生成 `02` 时按技术依赖重排。 | ||
| 353 | + | ||
| 354 | +示例: | ||
| 355 | +- 系统管理(SYS):用户登录、用户 CRUD、角色权限、部门管理 | ||
| 356 | +- 销售(SAL):客户管理、报价单、销售订单、出库 | ||
| 357 | +- 采购(PUR):供应商管理、采购申请、采购订单、入库 | ||
| 358 | +- ……(按业务实际增删模块) | ||
| 359 | + | ||
| 360 | +### Step 6 — 生成需求与数据库文档(CC) | ||
| 361 | + | ||
| 362 | +本步只生成 **需求卡(01)+ 数据库设计文档(03)**。完成后**停下等人工审核**(可能需要修改),审核通过后再进入 Step 7 生成依赖它们的下游文档。 | ||
| 363 | + | ||
| 364 | +**对 CC 说(复制粘贴即可):** | ||
| 365 | + | ||
| 366 | +``` | ||
| 367 | +请先读 CLAUDE.md(不需要读 指南.md)。 | ||
| 368 | + | ||
| 369 | +【第 0 步:占位核对】在生成任何 B 类文档前,先扫描 docs/07-环境配置.md、 | ||
| 370 | +docs/09-项目目录结构.md 以及其他所有 A 类文档,匹配以下任一特征字符串视为未填: | ||
| 371 | + - "【人工填写:" (统一标记,详见 CLAUDE.md「🏷️ 占位符统一约定」) | ||
| 372 | + - "your_password" / "your-secret-key" (兜底:通用配置裸占位值) | ||
| 373 | + - 版本号仍为大版本占位(匹配形如 "N.x" 或 "N.N.x" 的正则,未锁定到具体小版本) | ||
| 374 | + | ||
| 375 | +如发现残留占位:停下来输出残留位置清单,等我补完 07 再重新触发本 prompt,不要进入下一步。 | ||
| 376 | +如全部已替换:继续下面的生成流程。 | ||
| 377 | + | ||
| 378 | +【生成流程:一次性生成两份文档,不用逐份停下等我确认,默认静默执行】 | ||
| 379 | + | ||
| 380 | +1. 基于 docs/01-需求清单/README.md 的纲要,按模块逐个生成 | ||
| 381 | + docs/01-需求清单/<模块缩写>-<模块名>.md(SYS / SAL / PUR / INV / …), | ||
| 382 | + 每个模块一个文件 | ||
| 383 | + | ||
| 384 | +2. 通过 MySQL MCP 查 live DB(`SHOW TABLES` / `SHOW CREATE TABLE` / `INFORMATION_SCHEMA.COLUMNS`)填 docs/03-数据库设计文档.md 表结构业务说明 | ||
| 385 | + | ||
| 386 | +全部生成完毕后【统一输出一份汇总】: | ||
| 387 | + - 每份文件的绝对路径 | ||
| 388 | + - 每份的关键体量指标(01 每模块多少个功能 / 03 多少张表多少字段) | ||
| 389 | + - 生成过程中遇到的任何疑点(与 schema 对不上、纲要不够等) | ||
| 390 | + | ||
| 391 | +然后停下来等我做【一次性人工审核】。中途不要提问、不要等"下一份"; | ||
| 392 | +仅当出现以下阻塞时才中断并报告: | ||
| 393 | + - 需求纲要里提到的字段在 schema 中找不到 | ||
| 394 | + - 需求本身出现无法自行消解的歧义 | ||
| 395 | + - MySQL MCP 连接不可达(host 不通 / 账密错 / schema 为空表 0 张) | ||
| 396 | + | ||
| 397 | +**严禁**生成 02 / 05 / 08 / 10 / seed-data.sql——那是 Step 7 的范围,必须在 01 / 03 审核通过后才能动。 | ||
| 398 | +``` | ||
| 399 | + | ||
| 400 | +**人工审核要点**: | ||
| 401 | +- 01 需求卡是否覆盖纲要每一条 bullet?字段引用在 schema 里能否找到? | ||
| 402 | +- 03 表结构业务含义是否准确?ER 关系是否漏写? | ||
| 403 | +- 发现问题直接改文档,或让 CC 针对性重生成某模块 / 某表。审核通过后进入 Step 7。 | ||
| 404 | + | ||
| 405 | +--- | ||
| 406 | + | ||
| 407 | +### Step 7 — 生成下游文档(CC) | ||
| 408 | + | ||
| 409 | +**前置**:Step 6 的 01 + 03 已通过人工审核。本步基于它们生成所有依赖文档。 | ||
| 410 | + | ||
| 411 | +**对 CC 说(复制粘贴即可):** | ||
| 412 | + | ||
| 413 | +``` | ||
| 414 | +Step 6 的 01 + 03 已通过人工审核。请基于它们【一次性】生成下游文档,默认静默执行: | ||
| 415 | + | ||
| 416 | +1. 基于 01 + 03 生成 docs/02-开发计划.md | ||
| 417 | + —— 必须按技术依赖重排(先基础设施 / 认证 / 系统管理,再业务模块按依赖顺序), | ||
| 418 | + 不要沿用 01 的业务分组顺序 | ||
| 419 | + | ||
| 420 | +2. 基于 01 + 03 生成 docs/05-API接口契约.md | ||
| 421 | + | ||
| 422 | +3. 与 02 对齐生成 docs/08-模块任务管理.md | ||
| 423 | + | ||
| 424 | +4. 基于 01 + 08 生成 docs/10-验收检查清单.md | ||
| 425 | + | ||
| 426 | +5. 基于 MCP 查到的 schema 扩充 sql/seed-data.sql | ||
| 427 | + | ||
| 428 | +全部生成完毕后【统一输出一份汇总】: | ||
| 429 | + - 每份文件的绝对路径 | ||
| 430 | + - 每份的关键体量指标(02 多少模块 / 05 多少个 Endpoint / 08 多少 Task / | ||
| 431 | + 10 多少验收用例 / seed 多少行) | ||
| 432 | + - 生成过程中遇到的任何疑点 | ||
| 433 | + | ||
| 434 | +然后停下来等我做【一次性人工审核】。中途不要提问。 | ||
| 435 | +仅当出现以下阻塞时才中断并报告: | ||
| 436 | + - 01 / 03 中的需求/表在生成 02/05/08/10 时出现无法消解的歧义 | ||
| 437 | + - MySQL MCP 连接不可达 | ||
| 438 | +``` | ||
| 439 | + | ||
| 440 | +### Step 8 — 确认 CC 理解(CC) | ||
| 441 | + | ||
| 442 | +全部文档就绪后,CC 需输出 6 节式确认报告。你回复"理解正确"后才能进入 Step 9。 | ||
| 443 | + | ||
| 444 | +**对 CC 说(复制粘贴即可):** | ||
| 445 | + | ||
| 446 | +``` | ||
| 447 | +所有文档已生成完毕。请按依赖顺序完整读一遍(**不要读 指南.md**): | ||
| 448 | + CLAUDE.md → | ||
| 449 | + docs/01-需求清单/README.md → docs/01-需求清单/<各模块>.md → | ||
| 450 | + docs/02 → docs/03 → docs/04 → docs/05 → docs/06 → | ||
| 451 | + docs/07 → docs/08 → docs/09 → docs/10 | ||
| 452 | + | ||
| 453 | +然后输出《理解确认报告》,严格 6 节: | ||
| 454 | + | ||
| 455 | +### 1. 项目目标理解(≤ 3 句话复述项目目标) | ||
| 456 | +### 2. 模块拆解理解(列出所有业务模块及其核心功能) | ||
| 457 | +### 3. 数据模型理解(核心实体之间的关系) | ||
| 458 | +### 4. 模块规划理解(模块 1 / 2 / …,每个模块做什么、依赖什么) | ||
| 459 | +### 5. 技术栈与约束理解(CLAUDE.md 技术栈表 + 认证 + 只读 schema 等约束) | ||
| 460 | +### 6. 风险与歧义清单(读文档过程中发现的矛盾、歧义、待确认项) | ||
| 461 | + | ||
| 462 | +报告输完停下,等我回复"理解正确"再做任何后续动作。 | ||
| 463 | +``` | ||
| 464 | + | ||
| 465 | +### Step 9 — 固化文档为 CC 参考(CC 一次性清理) | ||
| 466 | + | ||
| 467 | +Step 8 通过后,`docs/` 进入**"事实只读"状态**:人工不再手动改 docs,所有 docs 作为 CC 写代码时的纯参考。此步由 CC 一次性扫描并删除面向人工的流程 / 指引性内容,让文档只剩业务 / 技术事实。 | ||
| 468 | + | ||
| 469 | +**对 CC 说(复制粘贴即可):** | ||
| 470 | + | ||
| 471 | +``` | ||
| 472 | +《理解确认报告》已通过我批准。现在进行一次性"文档固化"清理:把 docs/ 下所有文档 | ||
| 473 | +转为"纯 CC 参考"状态。 | ||
| 474 | + | ||
| 475 | +【不要动的文件】 | ||
| 476 | + - docs/08-模块任务管理.md(人机协作控制中枢,CC 在每个模块末 MR 合入后改 confirmed) | ||
| 477 | + - 根目录 指南.md(流程文档,本身就面向人) | ||
| 478 | + - 根目录 CLAUDE.md(保留顶部「项目概述」4 条即可,其他已是规范型内容可留) | ||
| 479 | + | ||
| 480 | +【其他所有 docs/*.md、docs/01-需求清单/*.md 执行删除规则】 | ||
| 481 | + | ||
| 482 | +删除以下内容: | ||
| 483 | + 1. 文件头部"本文档由 Claude Code 在 Step X 自动生成…" / "初始状态:空模板…" 等 | ||
| 484 | + 生命周期说明(CC 读过指南知道来源,无需每份文档重复) | ||
| 485 | + 2. 所有明确面向人工的操作指引 blockquote,例如: | ||
| 486 | + - "新增模块只需两步…" | ||
| 487 | + - "改名规则" | ||
| 488 | + - "填写方式" / "核对由 Step 6 CC 自动执行" | ||
| 489 | + - "⚠️ 写之前先…" / "⚠️ 顺序不代表开发顺序…" | ||
| 490 | + 3. 章节标题里的"(人工填写)" / "(CC 自动填)" / "(CC 参考)" 等人机角色标记, | ||
| 491 | + 只保留章节主标题 | ||
| 492 | + 4. 「零、人工占位速查表」整节(此时占位已全部填完,索引表已失去用途) | ||
| 493 | + 5. 各节开头 "由 CC 在 Step X 基于 XX 生成" 一类节内生命周期引导 blockquote | ||
| 494 | + (章节内容已填妥,引导文字已完成使命) | ||
| 495 | + 6. "示例见 SYS-系统管理.md" / "示例见下" 等面向人的阅读引导 | ||
| 496 | + | ||
| 497 | +【保留】 | ||
| 498 | + - 所有实际业务 / 技术事实:功能卡片(REQ-XXX)、表结构、字段说明、ER 关系、API 契约、 | ||
| 499 | + 模块规划、任务表、代码规范、依赖清单、目录结构、验收用例、seed 数据、配置值 | ||
| 500 | + - 章节主标题(去掉括号里的角色标记) | ||
| 501 | + - 文档头 H1 标题 | ||
| 502 | + | ||
| 503 | +【执行方式】 | ||
| 504 | + - 先给我一份「清理前 vs 清理后」的预览 diff(每份文件列出将删除的段落摘要 + 行数变化) | ||
| 505 | + - 我确认"执行"后你再真正下手 | ||
| 506 | + - 执行后再次输出每份文件的前后行数对比 + 分类删除统计 | ||
| 507 | + | ||
| 508 | +执行完之后,docs/ 进入 Step 10(分模块开发)的只读参考态。 | ||
| 509 | +``` | ||
| 510 | + | ||
| 511 | +--- | ||
| 512 | + | ||
| 513 | +## 🏗️ 开发阶段(Step 10):文档即 spec,CC 自主推进 | ||
| 514 | + | ||
| 515 | +> 进入本阶段时,`docs/` 已固化为只读参考态(Step 9 已清理),所有业务 / 技术事实都在文档里。 | ||
| 516 | +> 功能循环(Brainstorm → Plan → TDD → Verify → AI 自审)**默认静默**,CC 遇到不确定性只在命中 🚩 红旗清单时才打断人工。 | ||
| 517 | +> 人工在本阶段的**唯一介入点**是模块末 review MR(一个模块一次)。 | ||
| 518 | +> 如果此阶段 CC 频繁打断问问题,说明计划阶段文档打磨得不够,应回头补文档(必要时 Step 6/7 重生成 + 人工审核)而不是让开发"边开发边定义"。 | ||
| 519 | + | ||
| 520 | +### Step 10 — 分模块开发(模块循环 + 功能循环) | ||
| 521 | + | ||
| 522 | +> **术语提示** | ||
| 523 | +> - **模块** = 一组紧密相关、能整体交付的功能集合,对应 `docs/02-开发计划.md` 里的一个模块。**模块循环**就是开发一个模块。 | ||
| 524 | +> - **功能** = 一条具体的功能需求,编号格式 `REQ-<模块缩写>-<三位序号>`(如 `REQ-SYS-001` 用户登录)。**功能循环**就是开发一个功能。 | ||
| 525 | +> - **confirmed** = 模块完成确认标记,详见 3.1。 | ||
| 526 | + | ||
| 527 | +**启动新模块时对 CC 说(复制粘贴即可):** | ||
| 528 | + | ||
| 529 | +``` | ||
| 530 | +请按 CLAUDE.md「🔄 模块循环 + 功能循环」开发下一个模块。 | ||
| 531 | + | ||
| 532 | +1. 打开 docs/08-模块任务管理.md,找到第一个 confirmed: false 的模块 | ||
| 533 | +2. 对该模块内每个功能(REQ-XXX)依次跑功能循环 5 步: | ||
| 534 | + Brainstorm → Plan → TDD → Verify → AI 自审 | ||
| 535 | + 所有产物归档到 docs/superpowers/{specs,plans,reviews}/YYYY-MM-DD-<REQ-id>.md | ||
| 536 | +3. 命中 CLAUDE.md「🚩 静默执行红旗清单」任一条 → 立即停下、写 🚩 Blocker 节、一句话告警 | ||
| 537 | +4. 该模块全部功能完成后产出《模块完成报告》审阅包: | ||
| 538 | + - 每个功能的 spec + plan + diff | ||
| 539 | + - 每个功能的 AI reviewer 报告 | ||
| 540 | + - 测试总数 / 通过率 / 覆盖率 / `scripts/test.sh` 最后一次输出结尾 | ||
| 541 | + - schema 改动清单(应为 0) | ||
| 542 | + - 偏离 spec 清单 | ||
| 543 | +5. `scripts/test.sh` 本地全绿后,自动 `git push` + `glab mr create`,把审阅包贴入 MR 描述,输出 MR 链接后**停下**等人工审核。 | ||
| 544 | + **此时严禁改 `confirmed`**——必须等人工 Approve + Merge 后才能改(见步骤 6)。 | ||
| 545 | + | ||
| 546 | +默认静默执行。除红旗场景外,不要向我提问或确认。 | ||
| 547 | +``` | ||
| 548 | + | ||
| 549 | +**模块末人工 review 通过后对 CC 说(复制粘贴即可):** | ||
| 550 | + | ||
| 551 | +``` | ||
| 552 | +MR 已 Approve + Merge。请: | ||
| 553 | +1. 用 glab mr view <mr-iid> 验证 MR 状态为 merged | ||
| 554 | +2. 验证通过后,把 docs/08-模块任务管理.md 里当前模块的 confirmed 改为 true(commit 消息格式:chore(module): confirm module_N as completed) | ||
| 555 | +3. 基于指南开始下一个模块(重复上面的启动 prompt) | ||
| 556 | + | ||
| 557 | +若 glab mr view 显示未 merged(opened / closed),立即停下告警,不要改 confirmed。 | ||
| 558 | +``` | ||
| 559 | + | ||
| 560 | +--- | ||
| 561 | + | ||
| 562 | +**流程详解:** | ||
| 563 | + | ||
| 564 | +每个模块走一次**模块循环**,模块内每个**功能**(REQ-XXX)走一次**功能循环**。 | ||
| 565 | + | ||
| 566 | +**模块循环:** | ||
| 567 | + | ||
| 568 | +``` | ||
| 569 | +找 docs/08 中第一个 confirmed: false 的模块 | ||
| 570 | + ↓ | ||
| 571 | +对模块内每个功能(REQ-XXX)依次跑功能循环(CC 静默执行,不打扰人) | ||
| 572 | + ↓ | ||
| 573 | +CC 输出《模块完成报告》,打包附件(见下方"审阅包") | ||
| 574 | + ↓ | ||
| 575 | +自动化闸门:本地 `./scripts/test.sh` 全绿(见 3.3) | ||
| 576 | + ↓ | ||
| 577 | +CC 自动 `git push` + `glab mr create`(审阅包贴入 MR 描述) | ||
| 578 | + ↓ | ||
| 579 | +**人工审核 MR**(一个模块唯一一次人工介入点) | ||
| 580 | + ↓ | ||
| 581 | +全部通过 → 你点 Approve + Merge | ||
| 582 | + ↓ | ||
| 583 | +你对 CC 说"MR 已合入" → CC 验证 merged 状态 → CC 把 `confirmed` 改为 true → 进入下一个模块 | ||
| 584 | +``` | ||
| 585 | + | ||
| 586 | +**《模块完成报告》审阅包必须包含:** | ||
| 587 | + | ||
| 588 | +- 本模块所有功能的 spec、plan、diff(`git diff <module-start>..HEAD`) | ||
| 589 | +- 每个功能的 AI reviewer 报告(`docs/superpowers/reviews/`) | ||
| 590 | +- 测试结果:总用例数、通过率、覆盖率、`scripts/test.sh` 最后一次运行输出结尾(证据) | ||
| 591 | +- schema 改动清单(应为 0,若非 0 必须额外解释) | ||
| 592 | +- 偏离 spec 清单(实现中与 spec 不一致的地方,一处都不能漏报) | ||
| 593 | + | ||
| 594 | +**功能循环(单个功能 REQ-XXX 级)— 静默执行,无人工打断:** | ||
| 595 | + | ||
| 596 | +``` | ||
| 597 | +1. Brainstorm (可调用 superpowers:brainstorming) | ||
| 598 | + 产出:≤ 1 页 spec,写入 docs/superpowers/specs/YYYY-MM-DD-<REQ-id>.md | ||
| 599 | + 内容:目标 / 接口 / 数据流 / 边界条件 / 测试标准 | ||
| 600 | + | ||
| 601 | +2. Plan (可调用 superpowers:writing-plans) | ||
| 602 | + 产出:Task 级步骤,每步 2–5 分钟,含文件路径与完整代码 | ||
| 603 | + 写入 docs/superpowers/plans/YYYY-MM-DD-<REQ-id>.md | ||
| 604 | + | ||
| 605 | +3. TDD 执行 (可调用 superpowers:test-driven-development) | ||
| 606 | + 写失败测试 → 跑 → 实现最小代码 → 测试通过 → 提交 | ||
| 607 | + 频繁小提交,每个 task 一个 commit | ||
| 608 | + | ||
| 609 | +4. Verify (可调用 superpowers:verification-before-completion) | ||
| 610 | + 声称"完成"前,必须贴出 mvn test / pnpm test 的实际输出 | ||
| 611 | + | ||
| 612 | +5. AI 自审 (superpowers:code-reviewer 子代理,强制) | ||
| 613 | + 产出:审查报告写入 docs/superpowers/reviews/YYYY-MM-DD-<REQ-id>.md | ||
| 614 | + CC 自行修复 reviewer 发现的问题,直到 reviewer 通过 | ||
| 615 | +``` | ||
| 616 | + | ||
| 617 | +> **人工 review 不在此发生**,移到模块末统一进行(模块循环倒数第 2 步)。 |
hooks/hooks.json
0 → 100644
| 1 | +++ a/hooks/hooks.json | ||
| 1 | +{ | ||
| 2 | + "hooks": { | ||
| 3 | + "PreToolUse": [ | ||
| 4 | + { | ||
| 5 | + "matcher": "Bash", | ||
| 6 | + "hooks": [ | ||
| 7 | + { "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/scripts/deny-no-verify.sh" } | ||
| 8 | + ] | ||
| 9 | + } | ||
| 10 | + ], | ||
| 11 | + "PostToolUse": [ | ||
| 12 | + { | ||
| 13 | + "matcher": "Edit|Write", | ||
| 14 | + "hooks": [ | ||
| 15 | + { "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/scripts/log-cross-module.sh" } | ||
| 16 | + ] | ||
| 17 | + } | ||
| 18 | + ] | ||
| 19 | + } | ||
| 20 | +} |
hooks/scripts/deny-no-verify.sh
0 → 100755
| 1 | +++ a/hooks/scripts/deny-no-verify.sh | ||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# PreToolUse hook: block any `git push --no-verify` — the local test.sh gate is the only hard gate. | ||
| 3 | + | ||
| 4 | +set -euo pipefail | ||
| 5 | + | ||
| 6 | +input="$(cat)" | ||
| 7 | +tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty')" | ||
| 8 | +[ "$tool_name" = "Bash" ] || exit 0 | ||
| 9 | + | ||
| 10 | +cmd="$(printf '%s' "$input" | jq -r '.tool_input.command // empty')" | ||
| 11 | +[ -n "$cmd" ] || exit 0 | ||
| 12 | + | ||
| 13 | +if printf '%s' "$cmd" | grep -qE '\bgit[[:space:]]+push\b.*--no-verify\b'; then | ||
| 14 | + echo "BLOCKED: --no-verify bypasses the local test.sh gate (唯一硬闸门). If test.sh is failing, fix the root cause; do not skip the gate. Use /erp-local-test-gate to run the gate properly." >&2 | ||
| 15 | + exit 2 | ||
| 16 | +fi | ||
| 17 | + | ||
| 18 | +exit 0 |
hooks/scripts/log-cross-module.sh
0 → 100755
| 1 | +++ a/hooks/scripts/log-cross-module.sh | ||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# PostToolUse hook: 检测 Edit/Write 是否触及"当前模块以外"的模块路径,若是则在当前模块的跨模块日志中留痕(软规则 S2)。 | ||
| 3 | +# 注:原设计基于"已勾 [x] 模块"触发,但 docs/08 § 二 的 checkbox 永远保持 `- [ ]`(完成由 MR merged state 判定); | ||
| 4 | +# 新判定按"非当前模块"触发——CC 在当前模块开发期间改动其他模块(无论是否已 merged)都应留痕。 | ||
| 5 | + | ||
| 6 | +set -euo pipefail | ||
| 7 | + | ||
| 8 | +input="$(cat)" | ||
| 9 | +tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty')" | ||
| 10 | +case "$tool_name" in Edit|Write) ;; *) exit 0 ;; esac | ||
| 11 | + | ||
| 12 | +file_path="$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')" | ||
| 13 | +[ -n "$file_path" ] || exit 0 | ||
| 14 | + | ||
| 15 | +project_dir="${CLAUDE_PROJECT_DIR:-$(pwd)}" | ||
| 16 | +docs08="$project_dir/docs/08-模块任务管理.md" | ||
| 17 | +[ -f "$docs08" ] || exit 0 | ||
| 18 | + | ||
| 19 | +# 跳过 docs/08 自身的改动(元数据文件编辑不是代码跨模块改动,不触发 S2) | ||
| 20 | +case "$file_path" in *"/docs/08-模块任务管理.md") exit 0 ;; esac | ||
| 21 | + | ||
| 22 | +# 当前模块 = 当前 git 分支名去掉 `module-` 前缀。 | ||
| 23 | +# erp-module-start 步骤 3 保证模块循环期间处于 module-<id> 分支; | ||
| 24 | +# 非 module-* 分支(如 main、feature/*、docs/*)不在模块循环内,不触发 S2 留痕。 | ||
| 25 | +current_branch="$(cd "$project_dir" 2>/dev/null && git branch --show-current 2>/dev/null || echo '')" | ||
| 26 | +case "$current_branch" in | ||
| 27 | + module-*) current_module="${current_branch#module-}" ;; | ||
| 28 | + *) exit 0 ;; | ||
| 29 | +esac | ||
| 30 | +[ -n "$current_module" ] || exit 0 | ||
| 31 | + | ||
| 32 | +# 遍历所有 `- module_X` 行(docs/08 § 二 的所有模块,纯 bullet 无 checkbox), | ||
| 33 | +# 提取 module_id 和其下的"路径:"行。 | ||
| 34 | +# docs/08 § 二 的模块块结构: | ||
| 35 | +# - module_0 <name> | ||
| 36 | +# - 依赖: ... | ||
| 37 | +# - 路径: backend/module/xxx/, frontend/pages/xxx/ | ||
| 38 | +# - MR: !N 或 — | ||
| 39 | +hit_module="" | ||
| 40 | +# 用 awk 逐模块解析:每碰到 `- module_` 记录 module_id($2),然后在其下找第一个 `- 路径:` 行 | ||
| 41 | +# current_module 已在上文计算,在外层循环被排除 → 只会命中"非当前模块"的路径 | ||
| 42 | +while IFS=$'\t' read -r mod paths; do | ||
| 43 | + [ "$mod" = "$current_module" ] && continue | ||
| 44 | + IFS=',' read -ra scope_arr <<< "$paths" | ||
| 45 | + for s in "${scope_arr[@]}"; do | ||
| 46 | + s="$(echo "$s" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//; s:/$::')" | ||
| 47 | + [ -z "$s" ] && continue | ||
| 48 | + case "$file_path" in *"$s"*) hit_module="$mod"; break 2;; esac | ||
| 49 | + done | ||
| 50 | +done < <(awk ' | ||
| 51 | + /^- module_/ { | ||
| 52 | + # `- module_xxx <name>` awk 默认分词:$1=-、$2=module_xxx、$3=<name> | ||
| 53 | + mod=$2 | ||
| 54 | + next | ||
| 55 | + } | ||
| 56 | + mod && /^[[:space:]]*- 路径:/ { | ||
| 57 | + sub(/^[[:space:]]*- 路径:[[:space:]]*/,"") | ||
| 58 | + print mod "\t" $0 | ||
| 59 | + mod="" | ||
| 60 | + } | ||
| 61 | + /^- module_/ && mod { mod="" } | ||
| 62 | +' "$docs08") | ||
| 63 | + | ||
| 64 | +[ -n "$hit_module" ] || exit 0 | ||
| 65 | + | ||
| 66 | +log_dir="$project_dir/docs/superpowers/module-reports" | ||
| 67 | +mkdir -p "$log_dir" | ||
| 68 | +log_file="$log_dir/${current_module}-cross-module.md" | ||
| 69 | +if [ ! -f "$log_file" ]; then | ||
| 70 | + { | ||
| 71 | + echo "# 跨模块改动日志 — ${current_module}" | ||
| 72 | + echo "" | ||
| 73 | + echo "| 时间戳 | 目标模块 | 文件 | 改动摘要 | 原因 | 影响评估 |" | ||
| 74 | + echo "|---|---|---|---|---|---|" | ||
| 75 | + } > "$log_file" | ||
| 76 | +fi | ||
| 77 | + | ||
| 78 | +ts="$(date -u +%FT%TZ)" | ||
| 79 | +rel_path="${file_path#$project_dir/}" | ||
| 80 | +echo "| ${ts} | ${hit_module} | ${rel_path} | ${tool_name} | TBD(CC 补) | TBD(CC 补) |" >> "$log_file" | ||
| 81 | + | ||
| 82 | +jq -n --arg m "$hit_module" --arg f "$log_file" --arg p "$rel_path" \ | ||
| 83 | + '{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:("跨模块改动检测:\($p) 属于模块 [\($m)](非当前模块)。存根已写入 \($f),含 TBD(CC 补) 占位。请由 CC 调用 erp-cross-module-log skill 自主推断并补填原因与影响评估(软规则 S2,CC 自主维护,非人工填写)。")}}' |
skills/coding/erp-feature-brainstorm/SKILL.md
0 → 100644
| 1 | +++ a/skills/coding/erp-feature-brainstorm/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-feature-brainstorm | ||
| 3 | +description: 功能循环第 1 步。针对单个 REQ-XXX-NNN 进行交互式头脑风暴,产出功能规格文件到 docs/superpowers/specs/。 | ||
| 4 | +user-invocable: false | ||
| 5 | +allowed-tools: Read Write Skill Bash(mysql *) | ||
| 6 | +--- | ||
| 7 | + | ||
| 8 | +**所有输出必须使用中文。** | ||
| 9 | + | ||
| 10 | +# erp-feature-brainstorm | ||
| 11 | + | ||
| 12 | +## 说明 | ||
| 13 | + | ||
| 14 | +针对一个 REQ-XXX-NNN,委托 `superpowers:brainstorming` 进行头脑风暴,然后将输出打包到标准规格模板中,产出 ≤1 页的功能规格。 | ||
| 15 | + | ||
| 16 | +## 执行步骤 | ||
| 17 | + | ||
| 18 | +1. **红旗检查**:调用 `erp-red-flag-check`。如果命中 → 停止。 | ||
| 19 | +2. 确定输入: | ||
| 20 | + - 当前 REQ-XXX-NNN(从对话中获取,或 `docs/08` 当前模块下一个未完成的 REQ)。 | ||
| 21 | + - REQ 卡片:`docs/01-需求清单/<module>.md` 中对应的 REQ-XXX-NNN 节。 | ||
| 22 | + - 相关数据表(从 `docs/03` 或实时 mysql 命令行查询)。 | ||
| 23 | +3. 委托 `superpowers:brainstorming`,以 REQ 卡片 + schema 引用作为上下文。 | ||
| 24 | +4. 推导路径:`docs/superpowers/specs/$(date +%F)-<REQ-id>.md`。如已存在,征求用户确认后覆盖。 | ||
| 25 | +5. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/feature-spec-template.md`,从头脑风暴输出填充槽位: | ||
| 26 | + - `goal`、`input`、`output`、`rules`、`constraints`、`schema_refs`、`api_refs`、`acceptance` | ||
| 27 | +6. 将填充后的规格写入推导路径。 | ||
| 28 | +7. **验证**:模板中每个顶级节必须非空。如有槽位为 TBD,回到头脑风暴补充该槽位。 | ||
| 29 | +8. 输出 `feature-brainstorm: <REQ> → <path>`。 | ||
| 30 | + | ||
| 31 | +## 衔接 | ||
| 32 | + | ||
| 33 | +立即调用 `Skill(erp-feature-plan)` 进入下一步。 | ||
| 34 | + | ||
| 35 | +## 参考 | ||
| 36 | + | ||
| 37 | +- `${CLAUDE_SKILL_DIR}/templates/feature-spec-template.md` | ||
| 38 | +- 委托:`superpowers:brainstorming` | ||
| 39 | +- 守门:`erp-red-flag-check` |
skills/coding/erp-feature-brainstorm/templates/feature-spec-template.md
0 → 100644
| 1 | +++ a/skills/coding/erp-feature-brainstorm/templates/feature-spec-template.md | ||
| 1 | +--- | ||
| 2 | +req_id: {{req_id}} | ||
| 3 | +date: {{date}} | ||
| 4 | +module: {{module}} | ||
| 5 | +--- | ||
| 6 | + | ||
| 7 | +# Spec: {{req_id}} — {{title}} | ||
| 8 | + | ||
| 9 | +## 目标 | ||
| 10 | +{{goal}} | ||
| 11 | + | ||
| 12 | +## 输入 / 触发 | ||
| 13 | +{{input}} | ||
| 14 | + | ||
| 15 | +## 输出 / 结果 | ||
| 16 | +{{output}} | ||
| 17 | + | ||
| 18 | +## 业务规则 | ||
| 19 | +{{rules}} | ||
| 20 | + | ||
| 21 | +## 边界与约束 | ||
| 22 | +{{constraints}} | ||
| 23 | + | ||
| 24 | +## 依赖的 schema 表 / 字段 | ||
| 25 | +{{schema_refs}} | ||
| 26 | + | ||
| 27 | +## 依赖的接口 | ||
| 28 | +{{api_refs}} | ||
| 29 | + | ||
| 30 | +## 验收标准 | ||
| 31 | +{{acceptance}} |
skills/coding/erp-feature-plan/SKILL.md
0 → 100644
| 1 | +++ a/skills/coding/erp-feature-plan/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-feature-plan | ||
| 3 | +description: 功能循环第 2 步。将规格转化为任务级计划(每任务 2-5 分钟,含文件路径和完整代码),输出到 docs/superpowers/plans/。 | ||
| 4 | +user-invocable: false | ||
| 5 | +allowed-tools: Read Write Grep Skill | ||
| 6 | +--- | ||
| 7 | + | ||
| 8 | +**所有输出必须使用中文。** | ||
| 9 | + | ||
| 10 | +# erp-feature-plan | ||
| 11 | + | ||
| 12 | +## 执行步骤 | ||
| 13 | + | ||
| 14 | +1. **红旗检查**:调用 `erp-red-flag-check`。 | ||
| 15 | +2. 确定输入: | ||
| 16 | + - 当前 REQ-XXX-NNN 及其规格文件 `docs/superpowers/specs/YYYY-MM-DD-<REQ>.md`(规格不存在则报错)。 | ||
| 17 | + - 相关代码指针(已有的待修改文件,通过 Grep 发现)。 | ||
| 18 | + - `docs/04-技术规范.md` 和 `docs/09-项目目录结构.md`(编码规范 + 目录规范)。 | ||
| 19 | +3. 委托 `superpowers:writing-plans`,以规格 + 代码指针 + 规范作为上下文。 | ||
| 20 | +4. 推导路径:`docs/superpowers/plans/$(date +%F)-<REQ-id>.md`。 | ||
| 21 | +5. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/feature-plan-template.md`,填充 `files[]`、`tasks[]`、`commits[]`。 | ||
| 22 | +6. 强制要求:每个任务有失败测试标识、实现路径和完成标准。 | ||
| 23 | +7. 写入计划文件。 | ||
| 24 | +8. 输出 `feature-plan: <REQ> → <path>`。 | ||
| 25 | + | ||
| 26 | +## 衔接 | ||
| 27 | + | ||
| 28 | +立即调用 `Skill(erp-feature-tdd)` 进入下一步。 | ||
| 29 | + | ||
| 30 | +## 参考 | ||
| 31 | + | ||
| 32 | +- `${CLAUDE_SKILL_DIR}/templates/feature-plan-template.md` | ||
| 33 | +- 委托:`superpowers:writing-plans` | ||
| 34 | +- 守门:`erp-red-flag-check` |
skills/coding/erp-feature-plan/templates/feature-plan-template.md
0 → 100644
| 1 | +++ a/skills/coding/erp-feature-plan/templates/feature-plan-template.md | ||
| 1 | +--- | ||
| 2 | +req_id: {{req_id}} | ||
| 3 | +date: {{date}} | ||
| 4 | +spec_ref: docs/superpowers/specs/{{date}}-{{req_id}}.md | ||
| 5 | +--- | ||
| 6 | + | ||
| 7 | +# Plan: {{req_id}} | ||
| 8 | + | ||
| 9 | +## Schema 改动 | ||
| 10 | +{{schema_change_decision}} <!-- "无" 或 "需要 migration:V<n>__<snake_case>.sql,作用:<一行描述>" --> | ||
| 11 | + | ||
| 12 | +## 文件变更清单 | ||
| 13 | +{{#each files}} | ||
| 14 | +- `{{path}}` — {{action}}({{rationale}}) | ||
| 15 | +{{/each}} | ||
| 16 | + | ||
| 17 | +## 任务步骤 | ||
| 18 | +{{#each tasks}} | ||
| 19 | +### Task {{index}}: {{title}} | ||
| 20 | +- 失败测试: `{{test_file}}::{{test_name}}` — {{test_intent}} | ||
| 21 | +- 实现路径: `{{impl_file}}` | ||
| 22 | +- 完成判据: {{done_when}} | ||
| 23 | +{{/each}} | ||
| 24 | + | ||
| 25 | +## 提交计划 | ||
| 26 | +{{#each commits}} | ||
| 27 | +- `{{message}}`(覆盖 Task {{task_index}}) | ||
| 28 | +{{/each}} |
skills/coding/erp-feature-review/SKILL.md
0 → 100644
| 1 | +++ a/skills/coding/erp-feature-review/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-feature-review | ||
| 3 | +description: 功能循环第 5 步。AI 自审,输出审阅报告到 docs/superpowers/reviews/。approve 回调 erp-module-start;request-changes 则编辑代码并 fix commit,重跑 verify。自修复循环上限 5 轮。 | ||
| 4 | +user-invocable: false | ||
| 5 | +allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *) | ||
| 6 | +--- | ||
| 7 | + | ||
| 8 | +**所有输出必须使用中文。** | ||
| 9 | + | ||
| 10 | +# erp-feature-review | ||
| 11 | + | ||
| 12 | +## 执行步骤 | ||
| 13 | + | ||
| 14 | +1. 委托 `superpowers:code-reviewer`,以该 REQ 的 diff(`git diff <feature-start>..HEAD`)和规格作为输入。 | ||
| 15 | +2. 推导路径:`docs/superpowers/reviews/$(date +%F)-<REQ-id>.md`。 | ||
| 16 | +3. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md`,填充 `round`、`verdict`、`must_fix[]`、`nice_to_have[]`、`gaps`。verdict 必须是 `approve` 或 `request-changes`。 | ||
| 17 | +4. 写入报告。 | ||
| 18 | + | ||
| 19 | +5. 分发: | ||
| 20 | + - **`verdict = approve`** → 输出 `feature-review: <REQ> round <N> 通过`,然后调用 `Skill(erp-module-start)` 回模块主循环(module-start 会自动把本 REQ 识别为 done 并推进下一个 REQ)。 | ||
| 21 | + - **`verdict = request-changes`** → 执行"自修复子流程": | ||
| 22 | + - 逐项处理 `must_fix[]`:对每个条目用 `Edit` 修改其指向的代码文件。 | ||
| 23 | + - 所有 Must-fix 修复后,拼 commit 消息(格式与 `erp-feature-tdd` 一致,单行):`fix(<module_id>): 修复 review round <N> must-fix <REQ-id>`。 | ||
| 24 | + - `Bash`: `git add <修改的代码文件>` + `git commit -m "<上一步拼出的消息>"`。 | ||
| 25 | + - 调用 `Skill(erp-feature-verify)` 重跑验证;verify 通过后会再次链到本 skill,作为 round `<N+1>` 重审。 | ||
| 26 | + | ||
| 27 | +6. 上限:**5 轮**。第 5 轮仍为 `request-changes` → 停止并打印摘要(升级给用户手工介入),不再自动修复,不回调 module-start。 | ||
| 28 | + | ||
| 29 | +## 衔接 | ||
| 30 | + | ||
| 31 | +- `approve` → `Skill(erp-module-start)` 回主循环。 | ||
| 32 | +- `request-changes`(round < 5)→ `Skill(erp-feature-verify)` 重跑。 | ||
| 33 | +- `request-changes`(round == 5)→ 停止。 | ||
| 34 | + | ||
| 35 | +## 参考 | ||
| 36 | + | ||
| 37 | +- `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md` | ||
| 38 | +- Fix commit 格式与 `erp-feature-tdd` 的 `commit-message-template.md` 对齐(`fix(<scope>): <subject> <req_id>`) | ||
| 39 | +- 委托:`superpowers:code-reviewer` | ||
| 40 | +- 上游:`erp-feature-verify` | ||
| 41 | +- 下游:`erp-module-start`(approve)或 `erp-feature-verify`(request-changes) |
skills/coding/erp-feature-review/templates/feature-review-template.md
0 → 100644
| 1 | +++ a/skills/coding/erp-feature-review/templates/feature-review-template.md | ||
| 1 | +--- | ||
| 2 | +req_id: {{req_id}} | ||
| 3 | +date: {{date}} | ||
| 4 | +round: {{round}} | ||
| 5 | +reviewer: superpowers:code-reviewer | ||
| 6 | +--- | ||
| 7 | + | ||
| 8 | +# Review: {{req_id}} — round {{round}} | ||
| 9 | + | ||
| 10 | +## 结论 | ||
| 11 | +{{verdict}} (approve / request-changes) | ||
| 12 | + | ||
| 13 | +## Must-fix | ||
| 14 | +{{#each must_fix}} | ||
| 15 | +- [{{severity}}] {{file}}:{{line}} — {{issue}}(建议:{{suggestion}}) | ||
| 16 | +{{/each}} | ||
| 17 | + | ||
| 18 | +## Nice-to-have | ||
| 19 | +{{#each nice_to_have}} | ||
| 20 | +- {{file}}:{{line}} — {{suggestion}} | ||
| 21 | +{{/each}} | ||
| 22 | + | ||
| 23 | +## 反例 / 测试覆盖缺口 | ||
| 24 | +{{gaps}} |
skills/coding/erp-feature-tdd/SKILL.md
0 → 100644
| 1 | +++ a/skills/coding/erp-feature-tdd/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-feature-tdd | ||
| 3 | +description: 功能循环第 3 步。逐任务执行计划:写失败测试 → 实现代码 → 测试通过 → 提交。所有测试运行均派发到子会话执行。 | ||
| 4 | +user-invocable: false | ||
| 5 | +allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *) | ||
| 6 | +--- | ||
| 7 | + | ||
| 8 | +**所有输出必须使用中文。** | ||
| 9 | + | ||
| 10 | +# erp-feature-tdd | ||
| 11 | + | ||
| 12 | +## 执行步骤 | ||
| 13 | + | ||
| 14 | +1. **红旗检查**:调用 `erp-red-flag-check`。 | ||
| 15 | +2. 加载计划文件 `docs/superpowers/plans/YYYY-MM-DD-<REQ>.md`。 | ||
| 16 | +3. **Schema 改动优先(如果计划声明了需要)**:若 plan 标注 "本 REQ 需要 schema 改动",**第一个任务必须是写 migration 文件**: | ||
| 17 | + - `ls sql/migrations/V*.sql` 得最大版本号 n_max,新文件版本号 = n_max + 1 | ||
| 18 | + - 文件名格式 `V<n>__<snake_case_desc>.sql`,例 `V5__add_user_email.sql` | ||
| 19 | + - `Write` 该文件(只含 DDL:`ALTER TABLE ... ADD COLUMN ...` / `CREATE TABLE ...` 等),commit | ||
| 20 | + - 之后的代码任务(entity / DAO / service / 测试)在此之后做;测试跑时 Spring Boot 启动会让 Flyway 自动 apply 这个新 migration(`scripts/setup-test-db.sh` 只负责清空库) | ||
| 21 | +4. 按顺序处理每个(代码类)任务: | ||
| 22 | + a. 在 `test_file::test_name` 处编写失败测试。 | ||
| 23 | + b. **派发子会话**(通过 `Agent`,general-purpose)运行测试并确认失败;子会话只返回 `{command, exit_code, failing_assertion}`。主会话**不直接**运行测试。 | ||
| 24 | + c. 在 `impl_file` 处实现最小代码使测试通过。 | ||
| 25 | + d. **再次派发子会话**运行测试并确认通过。 | ||
| 26 | + e. 持续失败(同一测试 >10 次修复尝试)→ 调用 `erp-red-flag-check`(红旗 #4)。 | ||
| 27 | + f. 暂存变更并使用 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 提交;`scope` 匹配任务的模块,`subject` ≤50 字符,`req_id` 必填。 | ||
| 28 | +5. 所有任务完成后 → 交接给 `erp-feature-verify`。 | ||
| 29 | + | ||
| 30 | +## 护栏 | ||
| 31 | + | ||
| 32 | +- **绝不**在主会话直接运行 `mvn test` / `pnpm test` / `scripts/test.sh`,必须通过子会话。 | ||
| 33 | +- 每次提交必须包含 REQ-XXX-NNN 标签。 | ||
| 34 | +- 不要将不相关的变更合并到一次提交中。 | ||
| 35 | +- **禁止**在主会话直接 `mysql -e "ALTER ..."` 跑业务 DDL;所有业务 schema 变更必须走 `sql/migrations/V_n__<desc>.sql` 文件(只读查询 / 临时调试探索除外)。 | ||
| 36 | + | ||
| 37 | +## 衔接 | ||
| 38 | + | ||
| 39 | +立即调用 `Skill(erp-feature-verify)` 进入下一步。 | ||
| 40 | + | ||
| 41 | +## 参考 | ||
| 42 | + | ||
| 43 | +- `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` | ||
| 44 | +- 委托:`superpowers:test-driven-development` | ||
| 45 | +- 守门:`erp-red-flag-check` |
skills/coding/erp-feature-tdd/templates/commit-message-template.md
0 → 100644
skills/coding/erp-feature-verify/SKILL.md
0 → 100644
| 1 | +++ a/skills/coding/erp-feature-verify/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-feature-verify | ||
| 3 | +description: 功能循环第 4 步。将功能的测试套件派发到子会话执行,用模板渲染验证证据。无证据不得声称完成。 | ||
| 4 | +user-invocable: false | ||
| 5 | +allowed-tools: Skill Read Write Agent | ||
| 6 | +--- | ||
| 7 | + | ||
| 8 | +**所有输出必须使用中文。** | ||
| 9 | + | ||
| 10 | +# erp-feature-verify | ||
| 11 | + | ||
| 12 | +## 执行步骤 | ||
| 13 | + | ||
| 14 | +1. 从计划文件或项目标准命令中确定功能的测试目标(Maven profile / pnpm script / pytest path)。 | ||
| 15 | +2. **派发子会话**(通过 `Agent`,general-purpose),prompt 类似: | ||
| 16 | + | ||
| 17 | + ``` | ||
| 18 | + 任务:运行功能测试目标并报告结果。不要修改任何代码。步骤: | ||
| 19 | + 1. 执行:<command>(例如 mvn -pl user-module test -Dtest=REQ*) | ||
| 20 | + 2. 仅返回结构化 JSON:{"command":"<cmd>","exit_code":<int>,"passed":<int>,"failed":<int>,"failed_list":["<test>", ...],"stdout_excerpt":"<最后 30 行或最相关的失败摘录>"} | ||
| 21 | + 不要输出任何描述性文字。 | ||
| 22 | + ``` | ||
| 23 | + | ||
| 24 | +3. 解析 JSON;用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/feature-verify-evidence-template.md`,填充槽位(包括 `subagent_id` 和 `conclusion`)。 | ||
| 25 | +4. 如果 `exit_code != 0` 或 `failed > 0` → 打印填充后的证据到会话并**停止**,不进入审阅。 | ||
| 26 | +5. 通过 → 打印证据,交接给 `erp-feature-review`。 | ||
| 27 | + | ||
| 28 | +## 护栏 | ||
| 29 | + | ||
| 30 | +- 不要将原始测试 stdout 粘贴到主会话(超过 30 行的 `stdout_excerpt`)。 | ||
| 31 | +- 证据必须从模板渲染,不能自由编写。 | ||
| 32 | + | ||
| 33 | +## 衔接 | ||
| 34 | + | ||
| 35 | +立即调用 `Skill(erp-feature-review)` 进入下一步。 | ||
| 36 | + | ||
| 37 | +## 参考 | ||
| 38 | + | ||
| 39 | +- `${CLAUDE_SKILL_DIR}/templates/feature-verify-evidence-template.md` | ||
| 40 | +- 委托:`superpowers:verification-before-completion` |
skills/coding/erp-feature-verify/templates/feature-verify-evidence-template.md
0 → 100644
| 1 | +++ a/skills/coding/erp-feature-verify/templates/feature-verify-evidence-template.md | ||
| 1 | +## Verify evidence — {{req_id}} | ||
| 2 | + | ||
| 3 | +- 命令: `{{command}}` | ||
| 4 | +- 子会话: {{subagent_id}} | ||
| 5 | +- 退出码: {{exit_code}} | ||
| 6 | +- 通过用例数: {{passed}} | ||
| 7 | +- 失败用例数: {{failed}} | ||
| 8 | +- 失败列表: {{failed_list}} | ||
| 9 | + | ||
| 10 | +关键 stdout 片段 (≤30 行): | ||
| 11 | + | ||
| 12 | +``` | ||
| 13 | +{{stdout_excerpt}} | ||
| 14 | +``` | ||
| 15 | + | ||
| 16 | +结论: {{conclusion}} (pass / fail) |
skills/coding/erp-local-test-gate/SKILL.md
0 → 100644
| 1 | +++ a/skills/coding/erp-local-test-gate/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-local-test-gate | ||
| 3 | +description: MR 创建前的唯一硬闸门。子会话跑 scripts/test.sh(setup-test-db.sh 清库后,Spring Boot 启动让 Flyway apply 当前 sql/migrations/V*.sql),任一失败则停止。 | ||
| 4 | +user-invocable: false | ||
| 5 | +allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *) | ||
| 6 | +--- | ||
| 7 | + | ||
| 8 | +**所有输出必须使用中文。** | ||
| 9 | + | ||
| 10 | +# erp-local-test-gate | ||
| 11 | + | ||
| 12 | +## 执行步骤 | ||
| 13 | + | ||
| 14 | +1. **派发子会话**(`Agent`,general-purpose)运行 `./scripts/test.sh`: | ||
| 15 | + | ||
| 16 | + ``` | ||
| 17 | + 任务:运行项目本地测试闸门。不要修改任何代码或数据。步骤: | ||
| 18 | + 1. cd 到仓库根目录。 | ||
| 19 | + 2. 执行:./scripts/test.sh | ||
| 20 | + 3. 仅返回 JSON:{"command":"./scripts/test.sh","exit_code":<int>,"passed":<int>,"failed":<int>,"stdout_excerpt":"<最后 30 行,包含 FAIL 摘要>"} | ||
| 21 | + 不要输出任何描述性文字。 | ||
| 22 | + ``` | ||
| 23 | + | ||
| 24 | +2. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/test-gate-result-template.md`,用结果填充槽位。 | ||
| 25 | + | ||
| 26 | +3. 写入 `docs/superpowers/module-reports/<module_id>-test-gate.md`。 | ||
| 27 | + | ||
| 28 | +3b. **commit evidence 到 module 分支**(确保 test-gate.md 随 MR 合并进 main,审计可追溯): | ||
| 29 | + | ||
| 30 | + ```bash | ||
| 31 | + git add docs/superpowers/module-reports/<module_id>-test-gate.md | ||
| 32 | + git commit -m "chore(<module_id>): add local test-gate evidence" | ||
| 33 | + ``` | ||
| 34 | + | ||
| 35 | +4. 如果 `exit_code = 0` → 交接给 `erp-module-report`(输出 `local-test-gate: 通过`)。 | ||
| 36 | + | ||
| 37 | +5. 否则打印以下横幅并**停下**(不自动重试、不自动修复——失败分类需人工判断): | ||
| 38 | + | ||
| 39 | + ``` | ||
| 40 | + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | ||
| 41 | + [erp-local-test-gate] ⚠️ 未通过 | ||
| 42 | + | ||
| 43 | + 失败清单: <失败测试清单(来自子会话 JSON)> | ||
| 44 | + stdout 摘录: <最后 30 行 / FAIL 摘要> | ||
| 45 | + 详细证据: docs/superpowers/module-reports/<module_id>-test-gate.md | ||
| 46 | + | ||
| 47 | + 请根据失败类型选择下一步: | ||
| 48 | + | ||
| 49 | + ① 测试脆弱(flakey,偶发) | ||
| 50 | + → 再跑 /erp-workflow:erp-coding-start | ||
| 51 | + (module-start 幂等:reviews 已全 approve 会跳过功能循环,直接重跑本闸门) | ||
| 52 | + | ||
| 53 | + ② 真有回归(某个 REQ 破坏了其他 REQ/已合并模块) | ||
| 54 | + → 定位到具体 REQ,删除其 review 记录: | ||
| 55 | + rm docs/superpowers/reviews/*-<REQ-id>.md | ||
| 56 | + → 再跑 /erp-workflow:erp-coding-start | ||
| 57 | + (module-start 把该 REQ 视为未完成,重走 brainstorm→...→review 循环修复) | ||
| 58 | + | ||
| 59 | + ③ 环境/依赖问题(DB 连不上、外部 API 失败、证书失效) | ||
| 60 | + → 命中红旗 #6(外部接口不可达) | ||
| 61 | + → 调用 Skill(erp-red-flag-check) 追加 Blocker 到本模块任一 plan 文件 | ||
| 62 | + → 修好环境后再跑 /erp-workflow:erp-coding-start | ||
| 63 | + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | ||
| 64 | + ``` | ||
| 65 | + | ||
| 66 | + 然后**停止**,不调用下游 skill(module-report / mr-create)。 | ||
| 67 | + | ||
| 68 | +## 护栏 | ||
| 69 | + | ||
| 70 | +- **绝不**在主会话直接执行 `./scripts/test.sh`。 | ||
| 71 | +- **绝不**通过 `git push --no-verify` 绕过(hook `deny-no-verify.sh` 会拦截)。 | ||
| 72 | + | ||
| 73 | +## 衔接 | ||
| 74 | + | ||
| 75 | +立即调用 `Skill(erp-module-report)` 生成模块报告。 | ||
| 76 | + | ||
| 77 | +## 参考 | ||
| 78 | + | ||
| 79 | +- `${CLAUDE_SKILL_DIR}/templates/test-gate-result-template.md` |
skills/coding/erp-local-test-gate/templates/test-gate-result-template.md
0 → 100644
| 1 | +++ a/skills/coding/erp-local-test-gate/templates/test-gate-result-template.md | ||
| 1 | +## Local test gate — {{module_id}} | ||
| 2 | + | ||
| 3 | +执行时间: {{timestamp}} | ||
| 4 | + | ||
| 5 | +### scripts/test.sh (subagent) | ||
| 6 | +- 子会话: {{subagent_id}} | ||
| 7 | +- 命令: {{command}} | ||
| 8 | +- 退出码: {{exit_code}} | ||
| 9 | +- 通过: {{passed}} / 失败: {{failed}} | ||
| 10 | +- 关键 stdout (≤30 行): | ||
| 11 | + | ||
| 12 | +``` | ||
| 13 | +{{stdout_excerpt}} | ||
| 14 | +``` | ||
| 15 | + | ||
| 16 | +结论: {{conclusion}} (green / red) |
skills/coding/erp-module-report/SKILL.md
0 → 100644
| 1 | +++ a/skills/coding/erp-module-report/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-module-report | ||
| 3 | +description: 本地测试闸门通过后,生成标准化 12 节模块完成报告,嵌入本模块新增的 migration 清单和跨模块改动日志。 | ||
| 4 | +user-invocable: false | ||
| 5 | +allowed-tools: Read Write Glob Grep Skill Bash(git diff *) Bash(git log *) Bash(git add *) Bash(git commit *) | ||
| 6 | +--- | ||
| 7 | + | ||
| 8 | +**所有输出必须使用中文。** | ||
| 9 | + | ||
| 10 | +# erp-module-report | ||
| 11 | + | ||
| 12 | +## 执行步骤 | ||
| 13 | + | ||
| 14 | +0. **红旗检查**:调用 `Skill(erp-red-flag-check)` → 命中则停止(与 `erp-red-flag-check` SKILL 描述"生成模块级制品前"对齐)。 | ||
| 15 | + | ||
| 16 | +1. 验证上游:`erp-local-test-gate` 返回了绿色。否则停止。 | ||
| 17 | +2. 收集输入(优先 shell 摘要,避免把 diff 正文读进上下文): | ||
| 18 | + - **文件变更 § ③** — 只用摘要,**不**读 diff 正文: | ||
| 19 | + - `git diff --stat <module-start-commit>..HEAD` → 每文件增减行数 | ||
| 20 | + - `git diff --name-status <module-start-commit>..HEAD` → A/M/D 状态 | ||
| 21 | + - `git log --oneline <module-start-commit>..HEAD` → commit 列表 | ||
| 22 | + - `docs/superpowers/specs|plans|reviews/<date>-<本模块的 REQ>.md` → § ②、§ ⑨(正常 Read,一般不大) | ||
| 23 | + - **§ ⑥ 本模块新增 migration**:用 `git diff --name-only --diff-filter=A <module-start-commit>..HEAD -- 'sql/migrations/V*.sql'` 列出本模块提交的新 migration 文件;每个文件 Read 第一行(V_n 描述)作为说明 | ||
| 24 | + - `docs/superpowers/module-reports/<module_id>-cross-module.md` → § ⑦ | ||
| 25 | + - `docs/superpowers/module-reports/<module_id>-test-gate.md` → § ⑤ | ||
| 26 | + - § ④(读写的表):**用 `grep -rlE "(SELECT|INSERT|UPDATE|DELETE).*FROM|INTO"` 定位涉及 SQL 的文件,再按需 Read 片段**。不要全量读 docs/03。 | ||
| 27 | +3. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/module-report-template.md`,填充全部 12 节。 | ||
| 28 | +4. **硬性验证**: | ||
| 29 | + - § ⑦:如果 cross-module 有任何行含 `TBD(CC 补)` → **停止**,调用 `Skill(erp-cross-module-log)` 让 CC **自主推断**补齐,补完再回本步骤重验。 | ||
| 30 | + - § ⑦:如果非空但某行缺少影响评估(被填成空/敷衍)→ 同样调 `erp-cross-module-log` 重补。 | ||
| 31 | + - § ⑧ 必须列举所有偏离规格之处;如果没有,明确写"无偏离"。 | ||
| 32 | +5. 写入 `docs/superpowers/module-reports/$(date +%F)-<module_id>.md`。 | ||
| 33 | + | ||
| 34 | +5b. **commit 模块报告 + cross-module 日志到 module 分支**(确保审计证据随 MR 合并进 main;erp-mr-create 的 worktree clean 前置条件依赖此步): | ||
| 35 | + | ||
| 36 | + ```bash | ||
| 37 | + git add docs/superpowers/module-reports/$(date +%F)-<module_id>.md | ||
| 38 | + # cross-module log 若存在且有改动(erp-cross-module-log 补齐过 TBD)也一并提交 | ||
| 39 | + [ -f "docs/superpowers/module-reports/<module_id>-cross-module.md" ] && \ | ||
| 40 | + git add docs/superpowers/module-reports/<module_id>-cross-module.md | ||
| 41 | + git commit -m "docs(<module_id>): add module completion report + cross-module log" | ||
| 42 | + ``` | ||
| 43 | + | ||
| 44 | +6. 交接给 `erp-mr-create`。 | ||
| 45 | + | ||
| 46 | +## 衔接 | ||
| 47 | + | ||
| 48 | +立即调用 `Skill(erp-mr-create)` 推送并创建 MR。 | ||
| 49 | + | ||
| 50 | +## 参考 | ||
| 51 | + | ||
| 52 | +- `${CLAUDE_SKILL_DIR}/templates/module-report-template.md`(12 节) | ||
| 53 | +- 上游:`erp-local-test-gate` | ||
| 54 | +- 下游:`erp-mr-create` |
skills/coding/erp-module-report/templates/module-report-template.md
0 → 100644
| 1 | +++ a/skills/coding/erp-module-report/templates/module-report-template.md | ||
| 1 | +--- | ||
| 2 | +module_id: {{module_id}} | ||
| 3 | +date: {{date}} | ||
| 4 | +git_range: {{git_range}} | ||
| 5 | +--- | ||
| 6 | + | ||
| 7 | +# 模块完成报告 — {{module_id}} {{module_name}} | ||
| 8 | + | ||
| 9 | +## ① 模块信息 | ||
| 10 | +- 模块 ID: {{module_id}} | ||
| 11 | +- 模块名: {{module_name}} | ||
| 12 | +- 开发区间: {{git_range}} | ||
| 13 | + | ||
| 14 | +## ② REQ 完成清单 | ||
| 15 | +{{#each reqs}} | ||
| 16 | +- [{{status}}] {{req_id}} — {{title}} | ||
| 17 | + - spec: docs/superpowers/specs/{{date}}-{{req_id}}.md | ||
| 18 | + - plan: docs/superpowers/plans/{{date}}-{{req_id}}.md | ||
| 19 | + - review: docs/superpowers/reviews/{{date}}-{{req_id}}.md | ||
| 20 | +{{/each}} | ||
| 21 | + | ||
| 22 | +## ③ 文件变更表 | ||
| 23 | +| 文件 | 操作 | 说明 | | ||
| 24 | +|---|---|---| | ||
| 25 | +{{#each file_changes}} | ||
| 26 | +| {{path}} | {{action}} | {{note}} | | ||
| 27 | +{{/each}} | ||
| 28 | + | ||
| 29 | +## ④ 数据库使用表 | ||
| 30 | +- 读: {{tables_read}} | ||
| 31 | +- 写: {{tables_written}} | ||
| 32 | + | ||
| 33 | +## ⑤ 测试结果 | ||
| 34 | +- `scripts/test.sh` 最终:{{test_conclusion}} | ||
| 35 | +- 通过: {{passed}} / 失败: {{failed}} / 跳过: {{skipped}} | ||
| 36 | +- 覆盖率: {{coverage}} | ||
| 37 | + | ||
| 38 | +## ⑥ 本模块新增 Migration | ||
| 39 | + | ||
| 40 | +{{#each migrations}} | ||
| 41 | +- `sql/migrations/{{filename}}` — {{desc}} | ||
| 42 | +{{/each}} | ||
| 43 | + | ||
| 44 | +(若本模块无 schema 改动,写 "—") | ||
| 45 | + | ||
| 46 | +## ⑦ 跨模块改动清单(软规则 S2) | ||
| 47 | + | ||
| 48 | +{{cross_module_contents}} | ||
| 49 | + | ||
| 50 | +## ⑧ 偏离 spec 清单 | ||
| 51 | +{{#each deviations}} | ||
| 52 | +- {{req_id}}: {{deviation}} (原因: {{reason}}) | ||
| 53 | +{{/each}} | ||
| 54 | + | ||
| 55 | +## ⑨ AI reviewer 报告汇总 | ||
| 56 | +{{#each reviews}} | ||
| 57 | +- {{req_id}}: round {{round}} — {{verdict}}(link: docs/superpowers/reviews/{{date}}-{{req_id}}.md) | ||
| 58 | +{{/each}} | ||
| 59 | + | ||
| 60 | +## ⑩ 已知问题 | ||
| 61 | +{{known_issues}} | ||
| 62 | + | ||
| 63 | +## ⑪ 下一模块预览 | ||
| 64 | +{{next_module}} | ||
| 65 | + | ||
| 66 | +## ⑫ MR 链接 | ||
| 67 | +{{mr_url}} |
skills/coding/erp-module-start/SKILL.md
0 → 100644
| 1 | +++ a/skills/coding/erp-module-start/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-module-start | ||
| 3 | +description: 启动/恢复模块循环。按 docs/02 § 二 REQ 清单定位当前模块及其 REQ 序列,确保处于模块分支,扫 docs/superpowers/reviews/ 计算已完成 REQ,驱动第一个未完成 REQ 的功能循环;全部完成则调 erp-local-test-gate。幂等可重入。 | ||
| 4 | +user-invocable: false | ||
| 5 | +allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout *) Bash(git rev-parse *) Bash(glab mr *) | ||
| 6 | +--- | ||
| 7 | + | ||
| 8 | +**所有输出必须使用中文。** | ||
| 9 | + | ||
| 10 | +# erp-module-start | ||
| 11 | + | ||
| 12 | +## 执行步骤 | ||
| 13 | + | ||
| 14 | +### 步骤 1:按 `docs/02 § 二` REQ 序 + MR state 定位当前模块 + 本模块 REQ 列表 | ||
| 15 | + | ||
| 16 | +与 `erp-coding-start` 步骤 3 同构(完成判定权威是 `MR:` 字段 + `glab mr view state`,不看 checkbox): | ||
| 17 | + | ||
| 18 | +- 用 `Read` 读取 `docs/02-开发计划.md`,用 `Grep`(pattern `^\|\s*[0-9]+\s*\|\s*\*\*(REQ-[A-Z0-9]+-[0-9]+)\*\*\s*\|\s*(module_\w+)`)抽取 § 二 表格数据行,按行号升序得 `req_order[]`。 | ||
| 19 | +- 若 `req_order` 为空 → 打印"⚠️ docs/02 § 二 REQ 开发顺序清单为空或无法解析,请检查"并停止。 | ||
| 20 | +- 初始化 `module_merged[module_id → bool]` 空缓存。按序遍历 `req_order[]`: | ||
| 21 | + - `module_merged[module_id]` 已缓存为 `true` → 跳过本 REQ。 | ||
| 22 | + - `module_merged[module_id]` 已缓存为 `false` → `current_module = module_id`,结束遍历。 | ||
| 23 | + - 未缓存 → 读 docs/08 § 二 该模块条目的 ` - MR:` 字段: | ||
| 24 | + - `MR: —` → `module_merged[module_id] = false`,`current_module = module_id`,结束遍历。 | ||
| 25 | + - `MR: !<iid>` → `Bash`: `glab mr view <iid> -F json 2>/dev/null`,取 `.state`: | ||
| 26 | + - `merged` → 缓存 `true`,跳过本 REQ。 | ||
| 27 | + - 其他 → 缓存 `false`,`current_module = module_id`,结束遍历。 | ||
| 28 | +- **抽取本模块 REQ 序列 `req_list[]`**:从 `req_order[]` 取出所有 `module_id == current_module` 的项,按原序组成(同模块 REQ 必须连续,见 A5 约束)。 | ||
| 29 | +- 用 `Read` 读取 docs/08 § 二 该模块行 + 后续缩进行,提取 `module_name` / `depends_on`(REQ 列表以 docs/02 为权威,不再读 docs/08)。 | ||
| 30 | + | ||
| 31 | +### 步骤 2:所有模块已完成短路 | ||
| 32 | + | ||
| 33 | +如果 `req_order[]` 全部遍历完 `current_module` 仍未赋值(即所有模块都 merged)→ 打印"所有模块已完成"摘要并停止。 | ||
| 34 | + | ||
| 35 | +### 步骤 3:确保处于模块分支 | ||
| 36 | + | ||
| 37 | +- `target_branch = module-<module_id>`(例 `module-module_sys`)。 | ||
| 38 | +- 用 `Bash` 执行 `git branch --show-current` 得 `current_branch`。 | ||
| 39 | +- `current_branch == target_branch` → 继续步骤 4。 | ||
| 40 | +- 否则用 `Bash` 执行 `git rev-parse --verify <target_branch> 2>/dev/null`: | ||
| 41 | + - 存在 → `git checkout <target_branch>` | ||
| 42 | + - 不存在 → `git checkout -b <target_branch>` | ||
| 43 | +- 若当前工作区有未提交改动且 checkout 失败 → 打印错误并停止(请用户手工处理 dirty state)。 | ||
| 44 | + | ||
| 45 | +### 步骤 4:初始化跨模块日志(幂等) | ||
| 46 | + | ||
| 47 | +`docs/superpowers/module-reports/<module_id>-cross-module.md` — 不存在则从 `${CLAUDE_SKILL_DIR}/templates/cross-module-log-template.md` 创建。 | ||
| 48 | + | ||
| 49 | +### 步骤 5:计算已完成 REQ 集合 `done_reqs[]`(幂等断点恢复关键) | ||
| 50 | + | ||
| 51 | +- 对 `req_list[]` 每个 `req_id`,用 `Glob` 查 `docs/superpowers/reviews/*-<req_id>.md`。 | ||
| 52 | +- 命中后用 `Grep`(pattern `^verdict:\s*approve`,`-i` 不敏感)检查首部 verdict。 | ||
| 53 | +- 两者都命中 → 加入 `done_reqs[]`。 | ||
| 54 | + | ||
| 55 | +### 步骤 6:渲染并打印模块横幅 | ||
| 56 | + | ||
| 57 | +`Read ${CLAUDE_SKILL_DIR}/templates/module-start-banner-template.md`,填充槽位;`reqs[]` 每项的 `status` 字段根据 `done_reqs[]` 填 `x`(已完成)或空格(未完成)。 | ||
| 58 | + | ||
| 59 | +### 步骤 7:推进主循环 | ||
| 60 | + | ||
| 61 | +- 从 `req_list[]` 取第一个不在 `done_reqs[]` 中的 REQ 作为 `next_req`。 | ||
| 62 | +- **没有 `next_req`**(全部完成)→ 调用 `Skill(erp-local-test-gate)` 进入模块闸门。 | ||
| 63 | +- **有 `next_req`** → 调用 `Skill(erp-feature-brainstorm)` 启动该 REQ 的功能循环。功能循环链(brainstorm → plan → tdd → verify → review)完成后,`erp-feature-review` 在 `verdict=approve` 分支会回调 `Skill(erp-module-start)` —— 再次进入本 skill 时,步骤 5 会把刚通过的 REQ 加入 `done_reqs[]`,步骤 7 自动取下一 REQ,形成可重入推进。 | ||
| 64 | +- 任何中断(红旗 / 测试持续失败 / review 5 轮仍 request-changes)→ 停止本模块,不要静默跳下一 REQ。 | ||
| 65 | + | ||
| 66 | +## 参考 | ||
| 67 | + | ||
| 68 | +- `docs/02-开发计划.md § 二 开发顺序清单`(分发权威) | ||
| 69 | +- `docs/08-模块任务管理.md § 二`(模块元数据 + `MR:` 字段;每模块行是 `- module_id ...` bullet,无 checkbox;完成判定权威是 MR state) | ||
| 70 | +- `docs/superpowers/reviews/*.md`(REQ 级进度事实——verdict=approve 即完成) | ||
| 71 | +- `${CLAUDE_SKILL_DIR}/templates/module-start-banner-template.md` | ||
| 72 | +- `${CLAUDE_SKILL_DIR}/templates/cross-module-log-template.md` | ||
| 73 | +- 下游:`erp-feature-*`、`erp-local-test-gate` |
skills/coding/erp-module-start/templates/cross-module-log-template.md
0 → 100644
| 1 | +++ a/skills/coding/erp-module-start/templates/cross-module-log-template.md | ||
| 1 | +# 跨模块改动日志 — {{module_name}} | ||
| 2 | + | ||
| 3 | +软规则 S2:本模块开发期间对**非当前模块**代码的改动(无论目标模块是否已 MR merged)记录在此;模块完成报告必须单列「跨模块改动」节完整贴入。漏留痕或未评估影响 → 升级为红旗。 | ||
| 4 | + | ||
| 5 | +**本日志由 CC 自主维护**——hook `log-cross-module.sh` 自动落存根(含 `TBD(CC 补)` 占位),CC 调 `erp-cross-module-log` skill 自主推断补「原因 / 影响评估」两列。**不需要人工填写**。 | ||
| 6 | + | ||
| 7 | +| 时间戳 | 目标模块 | 文件 | 改动摘要 | 原因 | 影响评估 | | ||
| 8 | +|---|---|---|---|---|---| |
skills/coding/erp-module-start/templates/module-start-banner-template.md
0 → 100644
| 1 | +++ a/skills/coding/erp-module-start/templates/module-start-banner-template.md | ||
| 1 | +## Module start — {{module_id}} ({{module_name}}) | ||
| 2 | + | ||
| 3 | +- 模块依赖: {{depends_on}} | ||
| 4 | +- 对应需求文件: docs/01-需求清单/{{req_file}} | ||
| 5 | +- 分支: module-{{module_id}} | ||
| 6 | +- 功能清单(`x` = 已完成 review approve): | ||
| 7 | +{{#each reqs}} | ||
| 8 | + - [{{status}}] {{req_id}} — {{title}} | ||
| 9 | +{{/each}} | ||
| 10 | + | ||
| 11 | +开始/恢复功能循环(Layer 3),本次处理清单中第一个未完成 REQ。命中红旗 → 停;所有 REQ 完成 → 进入模块闸门。 |
skills/coding/erp-mr-create/SKILL.md
0 → 100644
| 1 | +++ a/skills/coding/erp-mr-create/SKILL.md | ||
| 1 | +--- | ||
| 2 | +name: erp-mr-create | ||
| 3 | +description: 模块报告完成后,验证当前分支为 module-<id> + worktree 干净,push 推代码和所有 evidence,创建 GitLab MR(报告嵌入描述),把 MR URL 追加到模块报告 § ⑫ 并 commit,把 MR iid 回写到 docs/08 该模块 `MR:` 字段并 commit,再次 push 同步。完成信号由 MR merged state 判定(docs/08 无 checkbox)。停下等待人工审核。 | ||
| 4 | +user-invocable: false | ||
| 5 | +allowed-tools: Read Write Edit Skill Bash(git *) Bash(glab *) Bash(sed *) Bash(awk *) Bash(cat *) Bash(echo *) Bash(mkdir -p .tmp) Bash(mv .tmp/*) Bash(rm -f .tmp/*) | ||
| 6 | +--- | ||
| 7 | + | ||
| 8 | +**所有输出必须使用中文。** | ||
| 9 | + | ||
| 10 | +# erp-mr-create | ||
| 11 | + | ||
| 12 | +## 前置条件 | ||
| 13 | + | ||
| 14 | +- `erp-module-report` 已生成报告文件并 commit 到 module 分支。 | ||
| 15 | +- `erp-local-test-gate` 返回了绿色,test-gate.md 已 commit 到 module 分支。 | ||
| 16 | +- 当前分支 = `module-<module_id>`(由 `erp-module-start` 步骤 3 负责切入)。 | ||
| 17 | + | ||
| 18 | +## 执行步骤 | ||
| 19 | + | ||
| 20 | +### 步骤 0:红旗检查 | ||
| 21 | + | ||
| 22 | +调用 `Skill(erp-red-flag-check)` → 命中则停止。 | ||
| 23 | + | ||
| 24 | +### 步骤 1:验证当前分支 | ||
| 25 | + | ||
| 26 | +- `Bash`: `git branch --show-current` → `current_branch`。 | ||
| 27 | +- `current_branch` 必须匹配 `module-*`;否则打印错误并**停止**(不自动建分支——分支职责在 `erp-module-start` 步骤 3)。 | ||
| 28 | +- 从 `current_branch` 取 `module_id = current_branch` 去掉 `"module-"` 前缀。 | ||
| 29 | + | ||
| 30 | +### 步骤 2:验证 worktree 干净(防止 evidence 文件漏 commit) | ||
| 31 | + | ||
| 32 | +- `Bash`: `git status --porcelain` | ||
| 33 | +- 输出非空 → 打印 dirty 文件清单并**停止**: | ||
| 34 | + ``` | ||
| 35 | + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | ||
| 36 | + [erp-mr-create] ⚠️ worktree 不干净,无法 push | ||
| 37 | + | ||
| 38 | + 以下文件有未提交改动: | ||
| 39 | + <git status 输出> | ||
| 40 | + | ||
| 41 | + push 前所有 evidence 必须已 commit 到 module 分支。检查点: | ||
| 42 | + - erp-local-test-gate 步骤 3b 是否已 commit test-gate.md? | ||
| 43 | + - erp-module-report 步骤 5b 是否已 commit 模块报告 + cross-module log? | ||
| 44 | + - 本 skill 前没人跑过额外的 Edit/Write? | ||
| 45 | + | ||
| 46 | + 修复方式:`git add <files> && git commit -m "..."`,然后重跑 /erp-workflow:erp-coding-start。 | ||
| 47 | + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | ||
| 48 | + ``` | ||
| 49 | + | ||
| 50 | +### 步骤 3:push 推送全部已 commit 内容 | ||
| 51 | + | ||
| 52 | +`git push -u origin <current_branch>` — **不要**使用 `--no-verify`(hook `deny-no-verify.sh` 会拦截)。 | ||
| 53 | + | ||
| 54 | +此 push 包含:代码 commit(erp-feature-tdd 产出)+ 模块 review fix commit(erp-feature-review 产出)+ test-gate evidence commit(erp-local-test-gate 产出)+ 模块完成报告 commit(erp-module-report 产出)。 | ||
| 55 | + | ||
| 56 | +### 步骤 4:读取 MR 标题模板 | ||
| 57 | + | ||
| 58 | +用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/mr-title-template.md`,填充 `module_id`、`module_name`,得到 MR 标题字符串(一行,较短,进上下文 OK)。 | ||
| 59 | + | ||
| 60 | +### 步骤 5:生成 MR 描述文件(纯 shell,不读模块报告内容进上下文) | ||
| 61 | + | ||
| 62 | +```bash | ||
| 63 | +mkdir -p .tmp | ||
| 64 | +DESC_FILE=.tmp/mr-desc.md | ||
| 65 | +REPORT="docs/superpowers/module-reports/<date>-<module_id>.md" | ||
| 66 | + | ||
| 67 | +# 先用 sed 替换 description 模板的简单槽位 | ||
| 68 | +sed -e "s|{{test_gate_conclusion}}|<值>|g" \ | ||
| 69 | + -e "s|{{test_subagent_id}}|<值>|g" \ | ||
| 70 | + -e "s|{{module_id}}|<值>|g" \ | ||
| 71 | + -e "s|{{date}}|<值>|g" \ | ||
| 72 | + "${CLAUDE_SKILL_DIR}/templates/mr-description-template.md" > "$DESC_FILE" | ||
| 73 | + | ||
| 74 | +# 把模块报告完整内容直接管道注入,替换 {{module_report_contents}} 所在行 | ||
| 75 | +awk -v report="$REPORT" ' | ||
| 76 | + /\{\{module_report_contents\}\}/ { while ((getline line < report) > 0) print line; close(report); next } | ||
| 77 | + { print } | ||
| 78 | +' "$DESC_FILE" > .tmp/mr-desc.final | ||
| 79 | +mv .tmp/mr-desc.final "$DESC_FILE" | ||
| 80 | +``` | ||
| 81 | + | ||
| 82 | +关键:**模块报告内容只经 awk 管道流过**,从不进入 LLM 上下文。 | ||
| 83 | + | ||
| 84 | +### 步骤 6:创建 MR | ||
| 85 | + | ||
| 86 | +```bash | ||
| 87 | +TITLE_FILE=.tmp/mr-title.txt | ||
| 88 | +echo "<步骤 4 得到的标题>" > "$TITLE_FILE" | ||
| 89 | +glab mr create --title "$(cat "$TITLE_FILE")" --description "$(cat "$DESC_FILE")" | ||
| 90 | +rm -f .tmp/mr-title.txt .tmp/mr-desc.md | ||
| 91 | +``` | ||
| 92 | + | ||
| 93 | +### 步骤 7:追加 MR URL 到模块报告 § ⑫ 并 commit | ||
| 94 | + | ||
| 95 | +- 解析返回的 MR URL 和 IID(`<iid>`)。 | ||
| 96 | +- `Edit docs/superpowers/module-reports/<date>-<module_id>.md` 的 § ⑫:把 `{{mr_url}}` 占位替换为实际 URL(若已替换过,追加一行)。 | ||
| 97 | +- `Bash`: `git add docs/superpowers/module-reports/<date>-<module_id>.md && git commit -m "docs(<module_id>): record MR !<iid> link in module report"`。 | ||
| 98 | + | ||
| 99 | +### 步骤 8:回写 docs/08 的 MR 字段并 commit | ||
| 100 | + | ||
| 101 | +- `Edit docs/08-模块任务管理.md`:把当前模块条目的 ` - MR: —` 改为 ` - MR: !<iid>`(只改一行)。docs/08 § 二每模块是 bullet(`- module_id ...`,无 checkbox),`MR:` 字段是唯一动态字段。 | ||
| 102 | +- `Bash`: `git add docs/08-模块任务管理.md && git commit -m "chore(<module_id>): record MR !<iid> in docs/08"`。 | ||
| 103 | + | ||
| 104 | +### 步骤 9:再次 push | ||
| 105 | + | ||
| 106 | +步骤 3 的 push 之后,步骤 7 和 8 又产生了两个新 commit(MR link + docs/08 MR iid)。必须再次 push 让 MR 自动更新 commit 列表 + diff: | ||
| 107 | + | ||
| 108 | +`Bash`: `git push origin <current_branch>` | ||
| 109 | + | ||
| 110 | +### 步骤 10:向会话打印 MR URL | ||
| 111 | + | ||
| 112 | +### 步骤 11:停止 — 等待人工 Approve + Merge | ||
| 113 | + | ||
| 114 | +用户合并后再跑 `/erp-workflow:erp-coding-start`,入口会自动检测 MR merged → `git checkout main` + `git pull --ff-only` 同步远程 + 派发下一模块。 | ||
| 115 | + | ||
| 116 | +## 设计要点 | ||
| 117 | + | ||
| 118 | +- **main 是 protected branch**,只能通过 MR 修改。MR diff 包含:代码 + 模块报告 + test-gate evidence + cross-module log + docs/08 的 `MR: !<iid>` 字段。 | ||
| 119 | +- **完成信号由 MR state 判定**——docs/08 § 二每模块是 bullet(无 checkbox),没有可翻勾的地方。从结构上消除"用户抢跑 coding-start 跳过未合并模块"的 ordering bug。仅 `MR:` 字段在 `—` / `!<iid>` 之间变化。 | ||
| 120 | +- **worktree 干净前置**(步骤 2):保证 test-gate.md、module-report.md、cross-module log.md 都已进 repo,审计证据完整;防止下次 coding-start `git checkout main` 遇到 dirty state。 | ||
| 121 | + | ||
| 122 | +## 参考 | ||
| 123 | + | ||
| 124 | +- `${CLAUDE_SKILL_DIR}/templates/mr-title-template.md` | ||
| 125 | +- `${CLAUDE_SKILL_DIR}/templates/mr-description-template.md` | ||
| 126 | +- 上游:`erp-module-report` | ||
| 127 | +- 守门:`erp-red-flag-check` | ||
| 128 | +- 下游闸门:用户手工 MR Approve + Merge |