Commit 18d6d2922771cf5f37c4ec7ba14dc92e62c7fe08

Authored by zichun
0 parents

init

Showing 138 changed files with 6277 additions and 0 deletions
.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
  1 +++ a/_pl_staging/pl_commands/erp-session-start.md
  1 +---
  2 +description: ERP 项目会话入口 — 自动探测当前阶段并分发到下一步 skill
  3 +---
  4 +
  5 +Invoke the `erp-session-start` skill via the Skill tool to detect the current ERP-project phase and dispatch to the next skill. Do not read `指南.md`. Follow CLAUDE.md.
... ...
_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
  1 +++ a/_pl_staging/pl_skills/erp-confirmed-update/templates/confirmed-flip-commit-template.md
  1 +chore({{module_id}}): mark confirmed (MR !{{mr_iid}} merged)
... ...
_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
  1 +++ a/_pl_staging/pl_skills/erp-cross-module-log/templates/cross-module-log-row-template.md
  1 +| {{timestamp}} | {{target_module}} | {{file_path}} | {{change_summary}} | {{reason}} | {{impact}} |
... ...
_pl_staging/pl_skills/erp-cross-module-log/templates/cross-module-log-template.md 0 → 100644
  1 +++ a/_pl_staging/pl_skills/erp-cross-module-log/templates/cross-module-log-template.md
  1 +# 跨模块改动日志 — {{module_name}}
  2 +
  3 +软规则 S2:本模块开发期间对其他 `confirmed: true` 模块代码的改动记录在此;模块完成报告必须单列「跨模块改动」节完整贴入。漏留痕或未评估影响 → 升级为红旗。
  4 +
  5 +| 时间戳 | 目标模块 | 文件 | 改动摘要 | 原因 | 影响评估 |
  6 +|---|---|---|---|---|---|
... ...
_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
  1 +++ a/_pl_staging/pl_skills/erp-downstream-gen/templates/docs-08-module-row-template.md
  1 +{{module_id}}:
  2 + name: {{module_name}}
  3 + depends_on: {{depends_on}}
  4 + reqs: {{req_ids}}
  5 + paths: [{{path_scopes}}]
  6 + confirmed: false
... ...
_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
  1 +++ a/_pl_staging/pl_skills/erp-feature-tdd/templates/commit-message-template.md
  1 +{{type}}({{scope}}): {{subject}} {{req_id}}
... ...
_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
  1 +++ a/_pl_staging/pl_skills/erp-module-start/templates/cross-module-log-template.md
  1 +# 跨模块改动日志 — {{module_name}}
  2 +
  3 +软规则 S2:本模块开发期间对其他 `confirmed: true` 模块代码的改动记录在此;模块完成报告必须单列「跨模块改动」节完整贴入。漏留痕或未评估影响 → 升级为红旗。
  4 +
  5 +| 时间戳 | 目标模块 | 文件 | 改动摘要 | 原因 | 影响评估 |
  6 +|---|---|---|---|---|---|
... ...
_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
  1 +++ a/_pl_staging/pl_skills/erp-module-start/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-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
  1 +++ a/_pl_staging/pl_skills/erp-mr-create/templates/mr-title-template.md
  1 +feat({{module_id}}): {{module_name}}
... ...
_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
  1 +++ a/_pl_staging/pl_skills/erp-requirements-gen/templates/docs-01-module-template.md
  1 +# {{module_code}}-{{module_name}}
  2 +
  3 +模块简述: {{module_brief}}
  4 +依赖模块: {{depends_on}}
  5 +涉及表: {{tables}}
  6 +
  7 +## 功能清单
  8 +
  9 +{{#each reqs}}
  10 +{{req_card}}
  11 +{{/each}}
... ...
_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
  1 +++ a/_pl_staging/pl_skills/erp-schema-scratch-log/templates/schema-scratch-log-row-template.md
  1 +| {{timestamp}} | `{{sql}}` | {{reason}} | {{rollback_plan}} |
... ...
_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
  1 +++ a/_pl_staging/pl_skills/erp-skeleton-gen/templates/env-local-example-template
  1 +DB_HOST=【人工填写:MySQL host,例如 localhost】
  2 +DB_PORT=【人工填写:MySQL port,默认 3306】
  3 +DB_USER=【人工填写:开发账号名】
  4 +DB_PASSWORD=【人工填写:对应密码】
  5 +DB_SCHEMA=【人工填写:schema 名,例如 erp_dev】
  6 +JWT_SECRET=【人工填写:JWT 签名密钥,256+ bit 随机串】
... ...
_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
  1 +++ a/skills/coding/erp-feature-tdd/templates/commit-message-template.md
  1 +{{type}}({{scope}}): {{subject}} {{req_id}}
... ...
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
... ...
skills/coding/erp-mr-create/templates/mr-description-template.md 0 → 100644
  1 +++ a/skills/coding/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 +
  15 +## 审核入口
  16 +
  17 +- 本 MR = 模块 `{{module_id}}` 的唯一人工介入点
  18 +- Approve + Merge 后,下次用户跑 `/erp-workflow:erp-coding-start` 时入口会自动扫到 `glab mr view state=merged`,`git pull --ff-only` 同步 main 并推进下一模块。docs/08 § 二每模块是 bullet(无 checkbox),完成由 MR state 判定
... ...
skills/coding/erp-mr-create/templates/mr-title-template.md 0 → 100644
  1 +++ a/skills/coding/erp-mr-create/templates/mr-title-template.md
  1 +feat({{module_id}}): {{module_name}}
... ...
skills/crosscut/erp-coding-start/SKILL.md 0 → 100644
  1 +++ a/skills/crosscut/erp-coding-start/SKILL.md
  1 +---
  2 +name: erp-coding-start
  3 +description: B 阶段(Coding)入口。先验证 Plan 已完成;按 docs/02 § 二 REQ 开发顺序清单扫,对每个 REQ 所属模块用 docs/08 的 `MR:` 字段 + `glab mr view state` 判完成——merged 跳过,`—` 或 opened/closed 选为当前模块并派发到 erp-module-start。派发前先 git checkout main + pull --ff-only 保持 base 最新。docs/08 § 二 每模块是 bullet(无 checkbox),完成由 MR state 判定。
  4 +user-invocable: true
  5 +allowed-tools: Skill Read Glob Grep Bash(glab mr *) Bash(git branch *) Bash(git checkout *) Bash(git pull *) Bash(git status *)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +B 阶段(Coding)的入口分发器。职责:**验证 Plan 已完成 → 按 docs/02 § 二 REQ 序 + MR state 找当前模块 → 切回 main 同步 remote → 派发 erp-module-start**。不直接生成任何文件。开发顺序权威是 `docs/02 § 二`;完成判定权威是 `docs/08 条目的 MR: 字段 + glab mr view state`(docs/08 § 二每模块是 bullet,无 checkbox)。
  11 +
  12 +## 执行步骤
  13 +
  14 +### 步骤 1:确认 docs/08 存在
  15 +
  16 +用 `Glob` 检查 `docs/08-模块任务管理.md`。
  17 +- 不存在 → 打印"⚠️ 项目尚未初始化,请先运行 `/erp-workflow:erp-plan-start`"并停下。
  18 +
  19 +### 步骤 2:Plan 完成性检查
  20 +
  21 +用 `Grep` 在 `docs/08-模块任务管理.md` 搜 `^- \[ \] A[0-5]`(pattern 可以直接匹配父项未勾的情况;也可以更宽地搜 `^[[:space:]]*- \[ \].*A[0-5]` 涵盖子项)。
  22 +
  23 +- **命中任一 A 未勾** → 打印:
  24 + ```
  25 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  26 + [erp-coding-start] ⚠️ Plan 尚未完成
  27 +
  28 + docs/08 § 一 还有未勾选项,请先运行:
  29 + /erp-workflow:erp-plan-start
  30 +
  31 + 继续 Plan 阶段直到 A5 下游文档生成完成,再回来运行 coding-start。
  32 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  33 + ```
  34 + **停下**。
  35 +
  36 +- 无命中 → Plan 已完成,进入步骤 3。
  37 +
  38 +### 步骤 3:按 docs/02 REQ 序 + MR state 找当前模块
  39 +
  40 +1. 用 `Read` 读取 `docs/02-开发计划.md` 的 § 二;用 `Grep`(pattern `^\|\s*[0-9]+\s*\|\s*\*\*(REQ-[A-Z0-9]+-[0-9]+)\*\*\s*\|\s*(module_\w+)`,`-n`)抽取所有表格数据行,按行号升序得 `req_order[]`,每项含 `req_id` + `module_id`。
  41 +2. 若 `req_order` 为空 → 打印错误并**停下**(与原逻辑相同,略)。
  42 +3. **初始化模块完成缓存 `module_merged[module_id → bool]`**(空)。
  43 +4. 按序遍历 `req_order[]`:
  44 + - 若 `module_merged[module_id]` 已有缓存:
  45 + - `true` → 跳过本 REQ,继续下一个
  46 + - `false` → `current_module = module_id`,结束遍历,进入步骤 4
  47 + - 未缓存 → 读 docs/08 § 二 该模块条目的 ` - MR:` 字段:
  48 + - `MR: —` → `module_merged[module_id] = false`;`current_module = module_id`,结束遍历
  49 + - `MR: !<iid>` → `Bash`: `glab mr view <iid> -F json 2>/dev/null`,解析 `.state`:
  50 + - `merged` → `module_merged[module_id] = true`,跳过本 REQ
  51 + - 其他(`opened` / `closed` / 查不到)→ `module_merged[module_id] = false`;`current_module = module_id`,结束遍历
  52 +5. 全遍历完仍无命中(所有模块都 merged) → 打印:
  53 + ```
  54 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  55 + [erp-coding-start] ✅ 所有模块已完成
  56 +
  57 + docs/02 § 二 清单中每个 REQ 所属模块的 MR 都已 merged。项目结束。
  58 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  59 + ```
  60 + 并**停下**。
  61 +6. 命中后:记录 `current_module` 的 `MR:` 字段值(`—` / `!<iid>-opened` / `!<iid>-closed` / `!<iid>-查不到`,用于步骤 5 横幅展示)。
  62 +
  63 +### 步骤 4:切回 main + 同步远程(准备 module-start 切新分支的干净 base)
  64 +
  65 +- `Bash`: `git branch --show-current` → `current_branch`。
  66 +- 若 `current_branch != main`:
  67 + - `Bash`: `git status --porcelain`;非空 → 打印:
  68 + ```
  69 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  70 + [erp-coding-start] ⚠️ 当前分支 <current_branch> 有未提交改动,无法切换到 main
  71 +
  72 + <git status 输出>
  73 +
  74 + 请手工处理后重跑 /erp-workflow:erp-coding-start。
  75 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  76 + ```
  77 + 并**停下**。
  78 + - `Bash`: `git checkout main`。
  79 +- `Bash`: `git pull --ff-only origin main`。
  80 + - 失败(非 fast-forward / 网络 / 冲突)→ 打印错误横幅:
  81 + ```
  82 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  83 + [erp-coding-start] ⚠️ 同步 main 失败
  84 +
  85 + 本地 main 无法 fast-forward 到 remote。请手工处理:
  86 + git status
  87 + git log main..origin/main # 远程领先的 commit
  88 + git log origin/main..main # 本地未推的 commit
  89 + 修复后重跑 /erp-workflow:erp-coding-start。
  90 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  91 + ```
  92 + 并**停下**。
  93 +
  94 +### 步骤 5:打印横幅并分发
  95 +
  96 +```
  97 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  98 + [erp-coding-start]
  99 + 阶段:B 编码
  100 + 当前模块:<current_module>
  101 + MR 状态:<未建 | opened | closed | 查不到>
  102 + 下一步:invoke erp-module-start
  103 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  104 +```
  105 +
  106 +然后立即用 `Skill` 工具调用 `erp-module-start`。
  107 +
  108 +> 分发前先调 `erp-red-flag-check`;命中红旗则停在此不分发。
  109 +
  110 +## 设计要点
  111 +
  112 +- **完成判定直接读 `MR:` 字段 + `glab mr view state`**:docs/08 § 二 每模块是 bullet(无 checkbox),没有可翻勾的地方。这从结构上消除了 Codex adversarial review Finding 1 描述的"用户抢跑 coding-start 跳过未合并模块"的 ordering bug:
  113 + - MR 未 merge 前本地 docs/08 没有任何"已完成"标记
  114 + - 即使用户抢跑 coding-start,步骤 3 扫到 MR opened 仍会选中当前模块(不是跳到下一模块)
  115 + - module-start 会 `git checkout module-<id>` 回到原分支,用户看到"继续在当前模块"而非"开始下一模块"
  116 +- **pull main 时机**:原设计里 pull main 是 merged 分支特有动作;新设计里每次派发前都 pull main(代码同步 + module-start 切新分支时 base 新鲜)。
  117 +
  118 +## 参考
  119 +
  120 +- `docs/02-开发计划.md § 二 开发顺序清单`(分发权威)
  121 +- `docs/08-模块任务管理.md § 二`(模块元数据 + `MR:` 字段;每模块行是 `- module_id ...` bullet,无 checkbox)
  122 +- `CLAUDE.md`(项目指令)
  123 +- `erp-plan-start`(姊妹入口,A 阶段)
... ...
skills/crosscut/erp-cross-module-log/SKILL.md 0 → 100644
  1 +++ a/skills/crosscut/erp-cross-module-log/SKILL.md
  1 +---
  2 +name: erp-cross-module-log
  3 +description: 为 log-cross-module.sh hook 自动追加到跨模块改动日志中的条目补填「原因」和「影响评估」。覆盖对"非当前模块"文件的编辑(无论目标模块是否已 MR merged)。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Edit Bash(git branch *)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# erp-cross-module-log
  11 +
  12 +## 说明
  13 +
  14 +软规则 S2 执行:对**非当前模块**文件的每次编辑(无论目标模块是否已 MR merged)必须记录原因 + 影响评估。
  15 +
  16 +**本日志由 CC 自主维护**——hook 自动落存根、CC 自主推断补齐两列,**不需要人工填写**。人工只在最终看 MR 描述时复核。
  17 +
  18 +## 执行步骤
  19 +
  20 +1. 确定当前模块(从当前 git 分支名推导:`git branch --show-current` → `module-<module_id>` → 取 `module_id`。`erp-module-start` 步骤 3 保证本 skill 执行时一定处于 `module-*` 分支)。
  21 +2. 打开 `docs/superpowers/module-reports/<current>-cross-module.md`(不存在则从 `${CLAUDE_SKILL_DIR}/templates/cross-module-log-template.md` 初始化)。
  22 +3. 找到「原因」或「影响评估」列中含 `TBD(CC 补)` 的行。
  23 +4. 对每个 TBD 行,CC **自主推断**填写以下两列(基于当前 session 的改动上下文 + REQ 卡片 + 目标模块的代码):
  24 + - **原因**:为什么要修改目标模块的代码?当前模块的哪个需求迫使这样做?
  25 + - **影响评估**:目标模块的哪些 API / 行为 / 调用方可能受影响?其现有测试是否仍然有效?是否需要新测试?(1-3 句话)
  26 +5. 编辑该行;保持时间戳 / 目标模块 / 文件 / 改动摘要列不变。
  27 +6. 输出确认:`cross-module-log: 更新了 N 行`。
  28 +
  29 +## 下游
  30 +
  31 +填充后的日志会被 `erp-module-report` 原文嵌入到 `module-report-template.md` § ⑦。
  32 +
  33 +## 参考
  34 +
  35 +- `${CLAUDE_SKILL_DIR}/templates/cross-module-log-template.md`
  36 +- `${CLAUDE_SKILL_DIR}/templates/cross-module-log-row-template.md`
  37 +- `CLAUDE.md` § 🟡 软规则 S2
... ...
skills/crosscut/erp-cross-module-log/templates/cross-module-log-row-template.md 0 → 100644
  1 +++ a/skills/crosscut/erp-cross-module-log/templates/cross-module-log-row-template.md
  1 +| {{timestamp}} | {{target_module}} | {{file_path}} | {{change_summary}} | {{reason}} | {{impact}} |
... ...
skills/crosscut/erp-cross-module-log/templates/cross-module-log-template.md 0 → 100644
  1 +++ a/skills/crosscut/erp-cross-module-log/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/crosscut/erp-plan-start/SKILL.md 0 → 100644
  1 +++ a/skills/crosscut/erp-plan-start/SKILL.md
  1 +---
  2 +name: erp-plan-start
  3 +description: A 阶段(Plan)入口与分发器。根据 docs/08 § 一 的 checkbox 状态派发到 A0~A5 对应 skill(§ 二是 B 阶段模块元数据,本 skill 不读)。Plan 全部完成(A5 已勾)时打印提示让用户运行 /erp-workflow:erp-coding-start 进入 B 阶段。
  4 +allowed-tools: Skill Read Glob Grep
  5 +---
  6 +
  7 +**所有输出必须使用中文。** 用户是中文用户,所有对话、横幅、提示、报告一律用中文。
  8 +
  9 +你是 ERP 项目**规划阶段的编排器**。你**只派发 A 阶段(A0~A5)的 skill**;docs/08 § 一 全部勾选后即停下,提示用户显式运行 `/erp-workflow:erp-coding-start` 进入 B 阶段,**不直接派发任何 B 阶段 skill**。你不直接生成任何文件。
  10 +
  11 +## 第一步:读取 docs/08 + 决定分发目标 + `mark_line`
  12 +
  13 +docs/08 § 一 是**Plan 阶段进度权威**(A0~A5 的 checkbox)。不做其他文件存在性检查——文件在不等于做完,只有 checkbox 是做完的证据。§ 二的模块元数据由 erp-coding-start 消费,本 skill 不读。
  14 +
  15 +### 分发判定
  16 +
  17 +1. **docs/08 是否存在**
  18 + 用 `Glob` 检查 `docs/08-模块任务管理.md`。
  19 + - 不存在 → `target=erp-project-init`、`mark_line=A0`、`unchecked_line=""`(流程开始)。
  20 +
  21 +2. **找 § 一 第一个未勾的 A 子项**
  22 + 用 `Grep`(pattern `^[[:space:]]*- \[ \].*A[0-5]`,`-n`)在 `docs/08-模块任务管理.md` 的 § 一 Plan 段搜索,取**最小行号**那一行作为 `unchecked_line`。
  23 + 注:§ 二 的模块行是纯 bullet(`- module_id ...`,无 checkbox),不会被此 pattern 匹配。
  24 +
  25 +3. **把 `unchecked_line` 映射到 `target_skill` + `mark_line`**:
  26 +
  27 +| `unchecked_line` 特征 | `target_skill` | `mark_line` |
  28 +|---|---|---|
  29 +| 无 docs/08 | `erp-project-init` | `A0` |
  30 +| 含 `A0` / A0 子项 | `erp-project-init` | `A0` |
  31 +| 含 `A1` / A1 子项 | `erp-scope-lock` | `A1` |
  32 +| 含 `A2` / A2 子项 | `erp-skeleton-gen` | `A2` |
  33 +| 含 `A3` / A3 子项 | `erp-db-init` | `A3` |
  34 +| 含 `A4` / A4 子项 | `erp-db-design-gen` | `A4` |
  35 +| 含 `A5` / A5 子项 | `erp-downstream-gen` | `A5` |
  36 +| 无命中(A 全勾,Plan 阶段结束) | **无分发** | `plan-done` |
  37 +
  38 +项目完成状态(B 阶段所有模块 MR merged)由 `erp-coding-start` 扫 MR state 判定并打印,本 skill 不处理。
  39 +
  40 +## 第二步:分发通知 + 调用目标 skill
  41 +
  42 +本入口**不画完整流程图**——目标 A skill 会在自己的步骤 0 打印带 `▶` 当前位置的流程图。本步骤只做分发决策与通知。
  43 +
  44 +### 2.1 Plan 已完成(`mark_line=plan-done`)
  45 +
  46 +A 阶段所有 checkbox 均 `[x]`。因无下游 A skill 接手,本步骤**自己打印流程图**(`▶` 标在"规划阶段到此结束")+ 提示,**停下**;项目整体完成状态由 `erp-coding-start` 扫 MR state 判定,本 skill 不负责:
  47 +
  48 +```
  49 +┌──────────────────────────────────────────────────────┐
  50 +│ 📋 阶段 A:规划(一次性) │
  51 +│ │
  52 +│ A0 初始化项目 → A1 锁范围(REQ 卡片) │
  53 +│ ↓ │
  54 +│ ⏸ 等你审阅 REQ,重跑 /erp-plan-start 续 │
  55 +│ ↓ │
  56 +│ A2 生骨架 → A3 初始化 DB → A4 生 DB 设计 → A5 生下游文档│
  57 +│ ↓ │
  58 +│ ▶ 规划阶段到此结束 │
  59 +└──────────────────────────────────────────────────────┘
  60 +
  61 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  62 + [erp-plan-start] ✅ Plan 阶段全部完成
  63 +
  64 + 请运行 /erp-workflow:erp-coding-start 进入 B 阶段模块循环。
  65 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  66 +```
  67 +
  68 +不调任何下游 skill。
  69 +
  70 +### 2.2 正常派发(`target_skill` 非空)
  71 +
  72 +打印简短分发通知:
  73 +
  74 +```
  75 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  76 + [erp-plan-start] → 派发到 <target_skill>
  77 + 未勾项:<docs/08 中第一个 - [ ] 行内容>
  78 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  79 +```
  80 +
  81 +立即用 `Skill` 工具调用 `target_skill`。
  82 +
  83 +## 参考
  84 +
  85 +- `docs/08-模块任务管理.md`(唯一进度权威)
  86 +- `CLAUDE.md`(项目指令)
  87 +- 下游 skills(通过 `Skill` 工具按名称调用)
... ...
skills/crosscut/erp-red-flag-check/SKILL.md 0 → 100644
  1 +++ a/skills/crosscut/erp-red-flag-check/SKILL.md
  1 +---
  2 +name: erp-red-flag-check
  3 +description: 在每个功能循环步骤和生成重要制品前运行。检查 CLAUDE.md 中的 6 项红旗清单,命中任一项则追加 Blocker 到计划文件并停止。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Bash(mysql *)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# erp-red-flag-check
  11 +
  12 +## 说明
  13 +
  14 +验证 CLAUDE.md § 🚩 静默执行红旗清单中的 6 项均未触发。命中任一项则中断。
  15 +
  16 +## 调用时机
  17 +
  18 +- 每个功能循环步骤开始前(3.1-3.5)
  19 +- 生成模块级制品前(模块报告、MR 描述)
  20 +- 用户请求涉及 schema 冲突、技术栈边界或外部依赖时
  21 +
  22 +## 检查清单(6 项 — 权威来源:CLAUDE.md)
  23 +
  24 +1. **需求与 schema 冲突** — 所需字段/表在实时 schema 中不存在
  25 +2. **需求本身歧义** — 存在两种或以上合理解读
  26 +3. **超技术栈边界** — 需要 CLAUDE.md 技术栈表以外的框架/中间件
  27 +4. **测试反复失败** — 同一功能中同一测试连续 10 次修复失败
  28 +5. **要改密钥/账密/包名** — 涉及 `docs/07-环境配置.md` 中的人工填写字段
  29 +6. **外部接口不可达** — 第三方 API / 证书 / 网络问题
  30 +
  31 +## 执行步骤
  32 +
  33 +1. 读取当前功能的规格/计划文件路径(从对话或 `docs/08` 获取)。
  34 +2. 逐项检查 6 个红旗。如果全部未命中 → 输出 `red-flag-check: 通过`,退出。
  35 +3. 命中时:
  36 + - 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/red-flag-block-template.md`
  37 + - 填充槽位(flag_number、flag_name、description、affected_scope、recommendation、decision_needed)
  38 + - 将渲染后的块追加到当前计划文件:`docs/superpowers/plans/YYYY-MM-DD-<REQ-id>.md`
  39 + - 向会话打印一句话摘要 + 指向计划文件的路径
  40 + - **停止** — 在用户决策前不调用任何后续 skill
  41 +
  42 +## 输出
  43 +
  44 +`red-flag-check: 通过`(仅会话),或一个 `## 🚩 Blocker` 块追加到功能计划文件。
  45 +
  46 +## 参考
  47 +
  48 +- `${CLAUDE_SKILL_DIR}/templates/red-flag-block-template.md`
  49 +- `CLAUDE.md` § 🚩 静默执行红旗清单(权威 6 条)
  50 +- `CLAUDE.md` § 🟡 软规则(S2 跨模块改动,不触发红旗但需留痕)
... ...
skills/crosscut/erp-red-flag-check/templates/red-flag-block-template.md 0 → 100644
  1 +++ a/skills/crosscut/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}}
... ...
skills/plan/erp-db-design-gen/SKILL.md 0 → 100644
  1 +++ a/skills/plan/erp-db-design-gen/SKILL.md
  1 +---
  2 +name: erp-db-design-gen
  3 +description: A4 DB 设计生成 + REQ 回填——用 mysql CLI 反查 schema 生成 docs/03-数据库设计文档.md;然后用 Grep 在 docs/01-需求清单/*.md 定位 TBD(A4 自动补) 替换为实际表/字段引用。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Edit Grep Glob Skill Bash(mysql *) Bash(source *)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# erp-db-design-gen
  11 +
  12 +## 前置条件
  13 +
  14 +- `erp-db-init` 已完成:`.env.local` 凭据已填,`sql/migrations/V1__initial_schema.sql` 和 `sql/seed-data.sql` 都已生成。
  15 +- `erp-scope-lock` 已完成:`docs/01-需求清单/<module>-*.md` REQ 卡片存在,含 `TBD(A4 自动补)` 占位。
  16 +
  17 +## 执行步骤
  18 +
  19 +### 步骤 0:打印当前位置流程图
  20 +
  21 +向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A4):
  22 +
  23 +```
  24 +┌──────────────────────────────────────────────────────┐
  25 +│ 📋 阶段 A:规划(一次性) │
  26 +│ │
  27 +│ A0 初始化项目 → A1 锁范围(REQ 卡片) │
  28 +│ ↓ │
  29 +│ ⏸ 等你审阅 REQ,重跑 /erp-plan-start 续 │
  30 +│ ↓ │
  31 +│ A2 生骨架 → A3 初始化 DB → ▶ A4 生 DB 设计 → A5 生下游文档│
  32 +│ ↓ │
  33 +│ 规划阶段到此结束 │
  34 +└──────────────────────────────────────────────────────┘
  35 +```
  36 +
  37 +### A. 查询实时 schema
  38 +
  39 +用 `Bash` source `.env.local` 后查询:
  40 +
  41 +```bash
  42 +source .env.local
  43 +MYSQL_CMD="mysql -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD} -N -B"
  44 +
  45 +# 表列表 + 注释
  46 +$MYSQL_CMD -e "SELECT table_name, table_comment FROM information_schema.tables WHERE table_schema='${DB_SCHEMA}' AND table_type='BASE TABLE' ORDER BY table_name;"
  47 +
  48 +# 字段详情
  49 +$MYSQL_CMD -e "SELECT table_name, column_name, column_type, is_nullable, column_default, column_comment FROM information_schema.columns WHERE table_schema='${DB_SCHEMA}' ORDER BY table_name, ordinal_position;"
  50 +
  51 +# 外键
  52 +$MYSQL_CMD -e "SELECT table_name, column_name, referenced_table_name, referenced_column_name FROM information_schema.key_column_usage WHERE table_schema='${DB_SCHEMA}' AND referenced_table_name IS NOT NULL;"
  53 +
  54 +# 索引
  55 +$MYSQL_CMD -e "SELECT table_name, index_name, GROUP_CONCAT(column_name ORDER BY seq_in_index) AS cols, non_unique FROM information_schema.statistics WHERE table_schema='${DB_SCHEMA}' GROUP BY table_name, index_name, non_unique;"
  56 +```
  57 +
  58 +将结果解析为结构化列表(内存中)。**不把查询结果完整写入会话上下文**——只保留表名 + 字段名 + 关键元信息。
  59 +
  60 +### B. 生成 docs/03
  61 +
  62 +1. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md`,填充 `schema_name`、`er_overview`、`tables[]`。
  63 +2. 对每张表,用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-03-table-template.md`,填充并追加。
  64 +3. 每个字段的业务含义:
  65 + - 如果 `column_comment` 非空,直接用
  66 + - 否则从 A1 生成的 REQ 卡片上下文推断
  67 +4. 用 `Write` 写入 `docs/03-数据库设计文档.md`。
  68 +
  69 +### C. 回填 REQ 卡片的 TBD 字段
  70 +
  71 +1. 用 `Glob` 列出 `docs/01-需求清单/*.md`(排除 `README.md`)。
  72 +2. 用 `Grep` 在这些文件中搜索 `TBD(A4 自动补)` 的**行号**(不读全文)。
  73 +3. 对每个命中的 REQ:
  74 + - 用 `Read` 仅读取该 REQ 卡片所在的片段(REQ 标题行前后 20 行)
  75 + - 根据 `goal` / `input` / `output` 推断引用的表
  76 + - 用 `Edit`:`依赖表: TBD(A4 自动补)` → `依赖表: <table1>, <table2>`(具体表名)
  77 + - **不动** `依赖接口: TBD(A5 自动补)`——那行由 A5 `erp-downstream-gen` 生成 docs/05 后回填
  78 +4. 打印回填统计:`A4 回填 N 处 schema_refs`。
  79 +
  80 +### D. 一致性检查
  81 +
  82 +1. 用 `Grep` 在 `docs/01-需求清单/*.md` 搜索 `依赖表:`,抽取所有表名。
  83 +2. 用 `Grep` 在 `docs/03-数据库设计文档.md` 搜索表标题(每张表一行 `### table_name`)。
  84 +3. 比对:
  85 + - REQ 提到但 docs/03 没有的表 → 报错停下(schema 与需求不一致;请确认是 REQ 理解错误还是需要新增 migration)
  86 + - docs/03 有但没 REQ 引用 → 警告但不停下(可能是未使用表)
  87 +4. 用 `Grep` 搜 `TBD(A4 自动补)` 在 `docs/01-需求清单/*.md`:应 0 命中(A4 已把所有 schema_refs 回填完);若仍有,打印残留 REQ 清单并停下。
  88 +
  89 +### E. 勾选 docs/08 进度 + 进入 A5
  90 +
  91 +用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 4 个 checkbox(A4 的 3 个子项 + A4 父项):
  92 +- ` - [ ] docs/03 数据库设计已生成` → `[x]`
  93 +- ` - [ ] REQ 卡片依赖表已回填` → `[x]`
  94 +- ` - [ ] schema 一致性检查通过` → `[x]`
  95 +- `- [ ] A4 DB 设计 + REQ 回填 — erp-db-design-gen` → `[x]`
  96 +
  97 +输出 `db-design-gen: 完成(<T> 张表, <R> 个 REQ 已回填依赖表;依赖接口留给 A5)`。
  98 +
  99 +立即调用 `Skill(erp-downstream-gen)` 进入 A5,不等用户手动输入。
  100 +
  101 +## 不变量
  102 +
  103 +- REQ 卡片的 `依赖接口` 字段不在此处填充,留给 A5 erp-downstream-gen(它会先生成 docs/05 API 契约,再按 `TBD(A5 自动补)` 回填)。
  104 +
  105 +## 参考
  106 +
  107 +- `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md`
  108 +- `${CLAUDE_SKILL_DIR}/templates/docs-03-table-template.md`
  109 +- `.env.local`(DB 凭据)
  110 +- `docs/01-需求清单/*.md`(回填目标)
... ...
skills/plan/erp-db-design-gen/templates/docs-03-header-template.md 0 → 100644
  1 +++ a/skills/plan/erp-db-design-gen/templates/docs-03-header-template.md
  1 +# 03-数据库设计文档
  2 +
  3 +Schema: `{{schema_name}}`
  4 +Migration 清单: `sql/migrations/V*.sql`(由 Flyway 顺序 apply)
  5 +生成方式: 通过 `mysql` 命令行从 live schema 反查生成。
  6 +
  7 +## ER 关系概览
  8 +
  9 +{{er_overview}}
  10 +
  11 +## 表清单
  12 +{{#each tables}}
  13 +- `{{table_name}}` — {{purpose}}
  14 +{{/each}}
... ...
skills/plan/erp-db-design-gen/templates/docs-03-table-template.md 0 → 100644
  1 +++ a/skills/plan/erp-db-design-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}}
... ...
skills/plan/erp-db-init/SKILL.md 0 → 100644
  1 +++ a/skills/plan/erp-db-init/SKILL.md
  1 +---
  2 +name: erp-db-init
  3 +description: A3 验证 MySQL 连接 + 导出当前 schema 为 `sql/migrations/V1__initial_schema.sql`(Flyway 初始 migration,DDL only)+ 导出当前数据为 `sql/seed-data.sql`(INSERT only)。不执行任何 DDL。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Edit Glob Skill Bash(mkdir *) Bash(mysql *) Bash(mysqldump *) Bash(source *) Bash(sed *) Bash(cat *) Bash(rm sql/migrations/*.raw) Bash(rm sql/*.raw) Bash(grep *)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# erp-db-init
  11 +
  12 +## 执行步骤
  13 +
  14 +### 步骤 0:打印当前位置流程图
  15 +
  16 +向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A3):
  17 +
  18 +```
  19 +┌──────────────────────────────────────────────────────┐
  20 +│ 📋 阶段 A:规划(一次性) │
  21 +│ │
  22 +│ A0 初始化项目 → A1 锁范围(REQ 卡片) │
  23 +│ ↓ │
  24 +│ ⏸ 等你审阅 REQ,重跑 /erp-plan-start 续 │
  25 +│ ↓ │
  26 +│ A2 生骨架 → ▶ A3 初始化 DB → A4 生 DB 设计 → A5 生下游文档│
  27 +│ ↓ │
  28 +│ 规划阶段到此结束 │
  29 +└──────────────────────────────────────────────────────┘
  30 +```
  31 +
  32 +### A. 防御性检查 .env.local
  33 +
  34 +用 `Glob` 检查 `.env.local` 是否存在。
  35 +
  36 +- **存在** → 进入步骤 B。
  37 +- **不存在** → 向用户输出:
  38 +
  39 + ```
  40 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  41 + [erp-db-init] ⚠️ .env.local 缺失
  42 +
  43 + 可能是被误删。请先重新运行 erp-skeleton-gen 重建,
  44 + 或手动从 .env.local.example 复制并填写 DB_HOST / DB_PORT / DB_USER / DB_PASSWORD / DB_SCHEMA。
  45 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  46 + ```
  47 +
  48 +### B. 验证 MySQL 连接
  49 +
  50 +用 `Bash` 执行(先 `source .env.local` 加载变量):
  51 +
  52 +```bash
  53 +source .env.local && mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" -e "USE \`$DB_SCHEMA\`; SHOW TABLES;"
  54 +```
  55 +
  56 +- **成功** → 记录表列表,继续步骤 C。
  57 +- **失败** → 向用户输出具体错误(认证失败 / schema 不存在 / 主机不可达等),提示检查 `.env.local`,**停下**。
  58 +
  59 +### C. 导出当前 schema 为 V1 initial migration
  60 +
  61 +用 `Bash` 执行 mysqldump(**仅 DDL,不含数据**):
  62 +
  63 +```bash
  64 +mkdir -p sql/migrations && source .env.local && mysqldump --no-data --skip-comments -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" "$DB_SCHEMA" > sql/migrations/V1__initial_schema.sql.raw
  65 +```
  66 +
  67 +如果 `mysqldump` 命令不存在,向用户输出具体错误(提示安装 `mysql-client` / `brew install mysql-client` 等)并**停下**(mysql 和 mysqldump 是 A0 `erp-project-init` 的前置依赖,正常情况下应已就绪)。
  68 +
  69 +### D. 加头部写入 V1 最终 migration 文件
  70 +
  71 +**严禁**用 `Read` 读取 `.sql.raw`(dump 可能有几千行,会撑爆上下文)。用纯 shell 拼接:
  72 +
  73 +```bash
  74 +PROJECT="<从 CLAUDE.md 读到的项目名称>"
  75 +TS="$(date -u +%FT%TZ)"
  76 +source .env.local
  77 +{
  78 + sed -e "s|{{project_name}}|$PROJECT|g" \
  79 + -e "s|{{timestamp}}|$TS|g" \
  80 + -e "s|{{schema_name}}|$DB_SCHEMA|g" \
  81 + "${CLAUDE_SKILL_DIR}/templates/migration-v1-header-template.sql"
  82 + cat sql/migrations/V1__initial_schema.sql.raw
  83 +} > sql/migrations/V1__initial_schema.sql
  84 +rm sql/migrations/V1__initial_schema.sql.raw
  85 +```
  86 +
  87 +说明:
  88 +- `sed` 替换 header 模板里的 3 个槽位
  89 +- `cat` 追加 dump 内容
  90 +- 全程不经过 LLM 上下文
  91 +
  92 +### E. 导出当前数据为 seed-data.sql
  93 +
  94 +用 `Bash` 执行 mysqldump(**仅数据,INSERT only**):
  95 +
  96 +```bash
  97 +source .env.local && mysqldump --no-create-info --complete-insert --skip-comments --skip-extended-insert \
  98 + -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" "$DB_SCHEMA" > sql/seed-data.sql.raw
  99 +```
  100 +
  101 +拼接 header 模板 + raw:
  102 +
  103 +```bash
  104 +PROJECT="<从 CLAUDE.md 读到的项目名称>"
  105 +TS="$(date -u +%FT%TZ)"
  106 +source .env.local
  107 +{
  108 + sed -e "s|{{project_name}}|$PROJECT|g" \
  109 + -e "s|{{timestamp}}|$TS|g" \
  110 + -e "s|{{schema_name}}|$DB_SCHEMA|g" \
  111 + "${CLAUDE_SKILL_DIR}/templates/seed-data-sql-template.sql"
  112 + echo ""
  113 + echo "SET FOREIGN_KEY_CHECKS = 0;"
  114 + echo ""
  115 + cat sql/seed-data.sql.raw
  116 + echo ""
  117 + echo "SET FOREIGN_KEY_CHECKS = 1;"
  118 +} > sql/seed-data.sql
  119 +rm sql/seed-data.sql.raw
  120 +```
  121 +
  122 +说明:
  123 +- 本地 MySQL 里已有的数据就是测试数据集,直接 dump 下来
  124 +- `--complete-insert` 让 INSERT 含列名,schema 演化后仍可读
  125 +- `--skip-extended-insert` 让每行一条 INSERT,diff 友好
  126 +- 全程不经过 LLM 上下文
  127 +
  128 +### F. 验证 + 勾选 docs/08 进度 + 进入 A4
  129 +
  130 +1. 用 `Bash` 执行 `grep -c "CREATE TABLE" sql/migrations/V1__initial_schema.sql` 统计表数量,与步骤 B 记录的表数对比。不一致 → 报错停下。
  131 +
  132 +2. 用 `Bash` 执行 `grep -c "INSERT INTO" sql/seed-data.sql` 统计数据行数:
  133 + - > 0:正常
  134 + - = 0:提示"本地 DB 无数据,seed-data.sql 为空(只有 header 注释);如需测试数据,请在本地 MySQL 插入后重跑 A3",允许继续
  135 +
  136 +3. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 5 个 checkbox(A3 的 4 个子项 + A3 父项):
  137 + - ` - [ ] .env.local 凭据验证通过` → `[x]`
  138 + - ` - [ ] MySQL 连接验证通过` → `[x]`
  139 + - ` - [ ] V1 initial migration 已生成(sql/migrations/V1__initial_schema.sql,DDL only)` → `[x]`
  140 + - ` - [ ] sql/seed-data.sql 已导出(本地数据快照,INSERT only)` → `[x]`
  141 + - `- [ ] A3 DB 初始化 — erp-db-init` → `[x]`
  142 +
  143 +4. 输出 `db-init: 完成(schema=<名称>, tables=<T>, V1 migration ✓, seed rows=<R>)`。
  144 +
  145 +5. 立即调用 `Skill(erp-db-design-gen)` 进入 A4,不等用户手动输入。
  146 +
  147 +## 不变量
  148 +
  149 +- 密码通过 `.env.local` 经 `source` 注入,不硬编码在命令里。
  150 +- 本 skill **只** 产生 V1 initial migration 和 seed-data.sql 快照;后续 V2/V3 及业务数据变化由 B 阶段 `erp-feature-tdd` 在 REQ 实现时写入。
  151 +
  152 +## 参考
  153 +
  154 +- `${CLAUDE_SKILL_DIR}/templates/migration-v1-header-template.sql`
  155 +- `${CLAUDE_SKILL_DIR}/templates/seed-data-sql-template.sql`
  156 +- 产物 1:`sql/migrations/V1__initial_schema.sql`(由 Flyway 在 Spring Boot 启动时自动 apply)
  157 +- 产物 2:`sql/seed-data.sql`(由开发者选一种方式装载:@Sql / R__seed / data.sql)
... ...
skills/plan/erp-downstream-gen/SKILL.md 0 → 100644
  1 +++ a/skills/plan/erp-downstream-gen/SKILL.md
  1 +---
  2 +name: erp-downstream-gen
  3 +description: A5 下游文档生成——基于 docs/01 和 docs/03 推导,一次性生成 docs/02 + docs/05 + docs/06 § 五 + docs/10,回填 REQ 卡片依赖接口,把模块清单追加到 docs/08 § 二。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# erp-downstream-gen
  11 +
  12 +## 前置条件
  13 +
  14 +- `docs/01-需求清单/*.md` 完整 REQ 卡片已就绪(A1 生成 + 人工审阅过)。
  15 +- `docs/03-数据库设计文档.md` 已就绪(A4 生成)。
  16 +- `docs/05` / `docs/06` / `docs/10` / `sql/seed-data.sql` 等下游文件尚不存在(本 skill 创建)。
  17 +
  18 +## 执行步骤
  19 +
  20 +### 步骤 0:打印当前位置流程图
  21 +
  22 +向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A5):
  23 +
  24 +```
  25 +┌──────────────────────────────────────────────────────┐
  26 +│ 📋 阶段 A:规划(一次性) │
  27 +│ │
  28 +│ A0 初始化项目 → A1 锁范围(REQ 卡片) │
  29 +│ ↓ │
  30 +│ ⏸ 等你审阅 REQ,重跑 /erp-plan-start 续 │
  31 +│ ↓ │
  32 +│ A2 生骨架 → A3 初始化 DB → A4 生 DB 设计 → ▶ A5 生下游文档│
  33 +│ ↓ │
  34 +│ 规划阶段到此结束 │
  35 +└──────────────────────────────────────────────────────┘
  36 +```
  37 +
  38 +### A. docs/02 — 开发计划(含 REQ 级开发顺序清单,CC 分发权威)
  39 +
  40 +**清单粒度**:每行一个 REQ(功能),不是模块。同一模块的 REQ 必须**连续排列**。
  41 +
  42 +1. 构建**模块依赖 DAG**:
  43 + - docs/03 中的外键(表 A → 表 B ⇒ A 的模块依赖 B 的模块)
  44 + - docs/01 README 中的显式 `depends_on` 提示
  45 +2. 对模块 DAG 做拓扑排序得 `module_topo_order[]`。
  46 +3. 对**每个模块内部**构建 REQ 间依赖(从 REQ 卡片 `goal` / `rules` / `依赖表` 推断 REQ-A 是 REQ-B 的前置),得到模块内 REQ 顺序。
  47 +4. 合成 `req_order[]`:按 `module_topo_order[]` 依次铺开每个模块内的 REQ 序列(**同模块 REQ 连续**)。
  48 +5. **环依赖打破**:
  49 + - **模块级**:若模块 DAG 存在环(module_A ↔ module_B),按启发式(字母序 / 被依赖次数多者先)破环排出 `module_topo_order`,并在**参与环的模块里第一个 REQ** 的 `note` 字段填入原因(如 "A↔B 互依赖:先做 A 的骨架")。
  50 + - **REQ 级(同模块内)**:若模块内 REQ 互依赖,同样破环,`note` 填原因。
  51 + - 非环 REQ `note` 留 `—`。
  52 +6. 为 `req_order[]` 每项生成字段:
  53 + - `index`:行号(从 1 开始)
  54 + - `req_id`:如 `REQ-SYS-001`
  55 + - `module_id`:该 REQ 所属模块,如 `module_sys`
  56 + - `rationale`(一行**选中理由**):依赖驱动的简短描述,如 `所属模块无依赖,基础模块` / `依赖 REQ-SYS-001 已在前` / `所属模块依赖 module_sys 已在前`
  57 + - `note`(一行**备注**):默认 `—`;仅环依赖打破场景填原因
  58 +7. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-02-template.md`,填充 `modules[]`(含 `id` / `name` / `deps` / `tables`)/ `req_order[]`(每项含 `index` / `req_id` / `module_id` / `rationale` / `note`)/ `notes`。
  59 +8. 写入 `docs/02-开发计划.md`。
  60 +
  61 +### B. docs/05 — API 接口契约
  62 +
  63 +1. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-05-header-template.md`,写入 `docs/05-API接口契约.md` 头部。
  64 +2. 对所有模块的每个 REQ:用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-05-endpoint-template.md`,推断 method / path / auth / permission / 请求和响应 schema(不明确的询问用户),追加到 docs/05。
  65 +
  66 +### B2. 回填 REQ 卡片 依赖接口
  67 +
  68 +1. 用 `Glob` 列出 `docs/01-需求清单/*.md`(排除 `README.md`)。
  69 +2. 用 `Grep` 在这些文件中搜索 `TBD(A5 自动补)` 的行号(不读全文)。
  70 +3. 对每个命中的 REQ:
  71 + - 用 `Read` 仅读取该 REQ 卡片所在的片段(REQ 标题行前后 20 行),提取 `req_id`。
  72 + - 在步骤 B 刚生成的 `docs/05-API接口契约.md` 里 Grep 属于该 REQ 的 endpoint(通过 REQ 标签或 req_id 关联)。
  73 + - 用 `Edit`:`依赖接口: TBD(A5 自动补)` → `依赖接口: POST /api/xxx, GET /api/yyy`(具体 method + path 列表,多个用 `,` 分隔)。
  74 +4. 打印回填统计:`A5 回填 N 处 api_refs`。
  75 +
  76 +### C. docs/06 — 页面清单
  77 +
  78 +1. 对每个有前端页面的模块:用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-06-module-pagelist-template.md`,填充 `pages[]`(page_name、route、page_type、req_ids、menu_path、interactions)。
  79 +2. 将每个渲染块追加到 `docs/06-UI交互规范.md` § 五。
  80 +
  81 +### D. docs/08 § 二 — 追加模块清单
  82 +
  83 +docs/08 已由 A0 erp-project-init 创建(含 Plan 进度骨架)。本步骤只往 § 二 追加模块行,**不重写整个文件**。
  84 +
  85 +1. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-08-module-row-template.md`(单模块 bullet 行模板)。
  86 +2. **按 `module_id` 字母序**对每个模块:渲染一行 bullet(`- ` 开头,无 checkbox),填充 `module_id` / `module_name` / `depends_on` / `path_scopes`(不含 REQ 列表——REQ 级顺序由 docs/02 § 二 权威维护;模块完成信号由 `MR:` 字段 + `glab mr view state` 判定)。
  87 +
  88 + > 注意:docs/08 § 二 的行序**不决定分发顺序**——分发权威在 docs/02 § 二 REQ 开发顺序清单。本步骤按字母序排只是便于人类肉眼查找。
  89 +3. 所有模块行拼成一段文本,用 `Edit` 在 `docs/08-模块任务管理.md` 的 `## 二、Coding 阶段(按模块循环)` 标题后插入(定位用下一行注释"(A5 填入后..."作为锚,把模块清单插到该注释之前)。
  90 +
  91 +### E. docs/10 — 验收清单
  92 +
  93 +1. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-10-header-template.md`,写入 `docs/10-验收检查清单.md` 头部。
  94 +2. 对每个模块:用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-10-module-template.md`,填充 `reqs[]`、`data_checks[]`、`ui_checks[]`,追加。
  95 +
  96 +### F. 验证 + 勾选 docs/08 进度 + 终止 Plan 阶段
  97 +
  98 +1. 一致性检查:
  99 + - docs/01 的每个 REQ 都出现在 docs/05(作为接口,如适用)、docs/10(作为验收项)。
  100 + - `docs/02 § 二` 开发顺序清单的 `module_id` 集合 = `docs/08 § 二` 的 `module_id` 集合(数量、ID 全等);不相等 → 报错停下,列出差集。
  101 +
  102 +2. **最终占位符扫描**(覆盖 Plan 阶段全部产出:`docs/01-需求清单/*.md` + `docs/02` / `docs/05` / `docs/06` / `docs/10` + `sql/seed-data.sql`):
  103 +
  104 + a. **`TBD` → CC 自动补齐**:`Grep` 搜 `TBD(A4 自动补)` 和 `TBD(A5 自动补)`。有命中则按 A4 / B2 同样逻辑就地补填(A4 查 docs/03 填 `依赖表:`;A5 查 docs/05 按 REQ-ID 填 `依赖接口:`),再 Grep 确认 0 命中;仍残留报错停下。
  105 +
  106 + b. **`【人工填写:...】` → QA 循环等用户补**(与 A2 erp-skeleton-gen 步骤 E 同风格):
  107 +
  108 + 循环执行直到两个条件**同时满足**:(1) 扫描 0 命中;(2) 用户选「继续」
  109 +
  110 + - **b.1 扫描**:用 `Grep` 在上述所有文件中搜 `【人工填写:`,得命中数 N 和残留位置清单(`<文件:行号> — <行内容摘要>`)
  111 + - **b.2 打印汇总横幅**:
  112 + ```
  113 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  114 + [erp-downstream-gen] 最终占位符审阅
  115 +
  116 + <N=0 时打印:✅ 全部填完>
  117 + <N>0 时打印:⚠️ 还有 N 处待填:
  118 + <文件:行号> — <行内容摘要>
  119 + ...>
  120 +
  121 + 需要调整 → 直接编辑对应文件
  122 + 填完后 → 回来选「继续」放行完成 Plan
  123 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  124 + ```
  125 + - **b.3 弹 QA**:用 `AskUserQuestion` 询问:
  126 + - **question**: `最终占位符补填完毕?`
  127 + - **options** (每项为对象):
  128 + - `{"label": "继续", "description": "放行完成 Plan 阶段"}`
  129 + - `{"label": "有疑问想先沟通", "description": "需要讨论或修改"}`
  130 + - **b.4 路由**:
  131 + - 选「有疑问想先沟通」→ 回答用户问题后**回 b.1 重扫**
  132 + - 选「继续」→ **回 b.1 重扫验证**:
  133 + - 新 N = 0 → 进步骤 3
  134 + - 新 N > 0 → 用户以为填完其实还有残留,回 b.2 打印新横幅 + 再弹 QA
  135 +
  136 + 关键:**每次弹 QA 前都重扫一次**,用户看到的 N 始终是最新的;只有 N = 0 且选「继续」才放行。
  137 +
  138 +3. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 7 个 checkbox(A5 的 6 个子项 + A5 父项):
  139 + - ` - [ ] docs/02 开发计划已生成` → `[x]`
  140 + - ` - [ ] docs/05 API 契约已生成` → `[x]`
  141 + - ` - [ ] docs/06 § 五 页面清单已填入` → `[x]`
  142 + - ` - [ ] docs/10 验收清单已生成` → `[x]`
  143 + - ` - [ ] 下方模块列表已填入` → `[x]`
  144 + - ` - [ ] REQ 卡片依赖接口已回填` → `[x]`
  145 + - `- [ ] A5 下游文档生成 — erp-downstream-gen` → `[x]`
  146 +
  147 +4. 输出:`downstream-gen: 写入 4 个文件 + <N> 个模块 + <M> 处 REQ 依赖接口回填。`
  148 +
  149 +5. 打印 Plan 阶段终止横幅并**停下**(不自动进入 B 阶段):
  150 +
  151 + ```
  152 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  153 + [erp-downstream-gen] ✅ Plan 阶段(A0~A5)全部完成
  154 +
  155 + 所有规划文档已就绪,docs/08 § 一 全部勾选。
  156 +
  157 + 下一步由你显式触发:
  158 + 运行 /erp-workflow:erp-coding-start 进入 B 阶段模块循环
  159 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  160 + ```
  161 +
  162 +## 参考
  163 +
  164 +- `${CLAUDE_SKILL_DIR}/templates/docs-02-template.md`
  165 +- `${CLAUDE_SKILL_DIR}/templates/docs-05-header-template.md`
  166 +- `${CLAUDE_SKILL_DIR}/templates/docs-05-endpoint-template.md`
  167 +- `${CLAUDE_SKILL_DIR}/templates/docs-06-module-pagelist-template.md`
  168 +- `${CLAUDE_SKILL_DIR}/templates/docs-08-module-row-template.md`(模块 bullet 行模板)
  169 +- `${CLAUDE_SKILL_DIR}/templates/docs-10-header-template.md`
  170 +- `${CLAUDE_SKILL_DIR}/templates/docs-10-module-template.md`
... ...
skills/plan/erp-downstream-gen/templates/docs-02-template.md 0 → 100644
  1 +++ a/skills/plan/erp-downstream-gen/templates/docs-02-template.md
  1 +# 02-开发计划
  2 +
  3 +## 一、模块依赖表
  4 +
  5 +| 模块 ID | 模块名 | 依赖模块 | 依赖表 |
  6 +|---|---|---|---|
  7 +{{#each modules}}
  8 +| {{id}} | {{name}} | {{deps}} | {{tables}} |
  9 +{{/each}}
  10 +
  11 +## 二、开发顺序清单(CC 分发权威)
  12 +
  13 +> 本清单由 A5 `erp-downstream-gen` 一次性生成。**每行是一个 REQ(功能)**,不是模块。CC 按表格行序从上到下扫描,对每个 REQ 所属模块查 `docs/08 § 二` 的 `MR:` 字段 + `glab mr view state`:`merged` 跳过,其他(`—` / opened / closed / 查不到)选为当前模块(`erp-module-start` 会一次性把该模块在本清单里所有 REQ 做完)。`docs/08 § 二` 每模块是 bullet(无 checkbox),完成由 MR state 判定。
  14 +>
  15 +> **约束**:同一模块的所有 REQ 必须**连续排列**。允许打破依赖拓扑(如环依赖、业务必须先做),但必须在「备注」列写明原因。
  16 +
  17 +| # | REQ | 所属模块 | 选中理由 | 备注 |
  18 +|---|-----|---------|---------|------|
  19 +{{#each req_order}}
  20 +| {{index}} | **{{req_id}}** | {{module_id}} | {{rationale}} | {{note}} |
  21 +{{/each}}
  22 +
  23 +## 三、关键说明
  24 +{{notes}}
... ...
skills/plan/erp-downstream-gen/templates/docs-05-endpoint-template.md 0 → 100644
  1 +++ a/skills/plan/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}}
... ...
skills/plan/erp-downstream-gen/templates/docs-05-header-template.md 0 → 100644
  1 +++ a/skills/plan/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 填入)
... ...
skills/plan/erp-downstream-gen/templates/docs-06-module-pagelist-template.md 0 → 100644
  1 +++ a/skills/plan/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}}
... ...
skills/plan/erp-downstream-gen/templates/docs-08-module-row-template.md 0 → 100644
  1 +++ a/skills/plan/erp-downstream-gen/templates/docs-08-module-row-template.md
  1 +- {{module_id}} {{module_name}}
  2 + - 依赖: {{depends_on}}
  3 + - 路径: {{path_scopes}}
  4 + - MR: —
... ...
skills/plan/erp-downstream-gen/templates/docs-10-header-template.md 0 → 100644
  1 +++ a/skills/plan/erp-downstream-gen/templates/docs-10-header-template.md
  1 +# 10-验收检查清单
  2 +
  3 +通用验收项(全项目适用):
  4 +
  5 +- [ ] `scripts/test.sh` 本地全绿
  6 +- [ ] 所有 schema 改动都有对应 `sql/migrations/V_n__<desc>.sql`
  7 +- [ ] 所有新接口在 `docs/05` 中有契约定义
  8 +- [ ] 所有新功能代码注释含 REQ-XXX-NNN
  9 +- [ ] 统一响应格式 `{code, message, data, timestamp}`
  10 +- [ ] 异常走全局处理器,不暴露堆栈到前端
  11 +- [ ] 前端不存敏感信息到 localStorage
  12 +
  13 +## 模块专项
  14 +(各模块验收段落见下方,由 `erp-downstream-gen` 按模块填入)
... ...
skills/plan/erp-downstream-gen/templates/docs-10-module-template.md 0 → 100644
  1 +++ a/skills/plan/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}}
... ...
skills/plan/erp-project-init/SKILL.md 0 → 100644
  1 +++ a/skills/plan/erp-project-init/SKILL.md
  1 +---
  2 +name: erp-project-init
  3 +description: A0 项目初始化——从插件模板幂等地复制 CLAUDE.md / docs/01-需求清单/README.md / docs/08-模块任务管理.md(已存在则跳过),并初始化 Git(如未初始化)。session-start 在 docs/08 缺失时派发本 skill。
  4 +user-invocable: false
  5 +allowed-tools: Glob Edit Skill Bash(mkdir *) Bash(cp -n *) Bash(git init) Bash(command -v *) Bash(uname *) Bash(brew *) Bash(export PATH=*) Bash(echo *)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +你负责在空/半空项目目录中创建初始文件结构。**本 skill 幂等**——已存在的文件不覆盖。
  11 +
  12 +## 执行步骤
  13 +
  14 +### 步骤 0:打印当前位置流程图
  15 +
  16 +向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A0):
  17 +
  18 +```
  19 +┌──────────────────────────────────────────────────────┐
  20 +│ 📋 阶段 A:规划(一次性) │
  21 +│ │
  22 +│ ▶ A0 初始化项目 → A1 锁范围(REQ 卡片) │
  23 +│ ↓ │
  24 +│ ⏸ 等你审阅 REQ,重跑 /erp-plan-start 续 │
  25 +│ ↓ │
  26 +│ A2 生骨架 → A3 初始化 DB → A4 生 DB 设计 → A5 生下游文档│
  27 +│ ↓ │
  28 +│ 规划阶段到此结束 │
  29 +└──────────────────────────────────────────────────────┘
  30 +```
  31 +
  32 +### A. 依赖检查 + 自动安装(命令行工具)
  33 +
  34 +用 `Bash` 检查 `mysql` / `mysqldump` 是否在 PATH 中:
  35 +
  36 +```bash
  37 +for cmd in mysql mysqldump; do
  38 + command -v "$cmd" >/dev/null 2>&1 || echo "MISSING: $cmd"
  39 +done
  40 +```
  41 +
  42 +**全部在 PATH** → 进入 B。
  43 +
  44 +**有缺失** → 尝试自动安装:
  45 +1. 用 `Bash` 探测环境(`uname -s`、是否有 `brew` / `apt` / `yum` / `apk` 等)
  46 +2. 根据当前系统选最合适的包管理器安装 mysql 客户端;若需要 sudo 但 CC 没有权限,打印手动安装命令让用户执行
  47 +3. 装完后,把必要的 bin 路径加入本次会话 PATH(如 macOS 的 keg-only 路径)
  48 +4. 向用户提示如何把路径永久写入 shell 启动脚本
  49 +5. 重新跑开头的 `command -v` 循环验证;仍缺失 → 打印错误并停下,等用户手动解决后重跑入口
  50 +
  51 +### B. 幂等复制模板文件
  52 +
  53 +用 `Bash` 一次性完成。`cp -n` 表示"不覆盖已存在的文件":
  54 +
  55 +```bash
  56 +mkdir -p docs/01-需求清单
  57 +cp -n "${CLAUDE_SKILL_DIR}/templates/CLAUDE-template.md" CLAUDE.md
  58 +cp -n "${CLAUDE_SKILL_DIR}/templates/docs-01-readme-template.md" docs/01-需求清单/README.md
  59 +cp -n "${CLAUDE_SKILL_DIR}/templates/docs-08-initial-template.md" docs/08-模块任务管理.md
  60 +```
  61 +
  62 +故障恢复场景:如果用户之前 init 跑一半中断(CLAUDE.md 已存在但 docs/08 缺失),`cp -n` 会保留 CLAUDE.md 原样,只补齐 docs/08。
  63 +
  64 +### C. 初始化 Git(如尚未初始化)
  65 +
  66 +用 `Glob` 检查 `.git/` 目录是否存在。
  67 +- 不存在 → 用 `Bash` 执行 `git init`。
  68 +- 已存在 → 跳过。
  69 +
  70 +### D. 勾选 docs/08 的 A0 进度
  71 +
  72 +用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选这两行:
  73 +- ` - [ ] 项目文件骨架已创建(CLAUDE.md + docs/01-需求清单/README.md)` → ` - [x] 项目文件骨架已创建(CLAUDE.md + docs/01-需求清单/README.md)`
  74 +- `- [ ] A0 项目初始化 — erp-project-init` → `- [x] A0 项目初始化 — erp-project-init`
  75 +
  76 +### E. 打印完成横幅并进入 A1
  77 +
  78 +向用户输出:
  79 +
  80 +```
  81 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  82 + [erp-project-init] 项目初始化完成
  83 +
  84 + 已创建:
  85 + ✓ CLAUDE.md(从插件模板复制)
  86 + ✓ docs/01-需求清单/README.md(待人工填写模块索引)
  87 + ✓ docs/08-模块任务管理.md(全流程进度跟踪)
  88 + 已勾选:A0 项目初始化
  89 +
  90 + 下一步:A1 erp-scope-lock(填写项目概述 + 技术栈 + 需求索引 + REQ 卡片)
  91 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  92 +```
  93 +
  94 +立即调用 `Skill(erp-scope-lock)` 进入 A1,不等用户手动输入。
... ...
skills/plan/erp-project-init/templates/CLAUDE-template.md 0 → 100644
  1 +++ a/skills/plan/erp-project-init/templates/CLAUDE-template.md
  1 +# CLAUDE.md — ERP项目 Claude Code 主指令文件
  2 +
  3 +> 本文件是 Claude Code 的"操作手册"。Claude Code 启动时会自动读取此文件。
  4 +
  5 +---
  6 +
  7 +## 🎯 项目概述
  8 +
  9 +- **项目名称**: 【人工填写:公司 + 项目名,例如"XX 公司 ERP 管理系统"】
  10 +- **项目简述**: 【人工填写:一句话描述项目目标,例如"面向中小制造企业的全流程 ERP,涵盖采购/库存/生产/销售/财务"】
  11 +- **目标用户**: 【人工填写:谁会用,例如"企业内部管理人员(采购员、仓管员、生产主管、销售员、财务人员、管理层)"】
  12 +- **部署方式**: 【人工填写:私有化部署 / 云部署 / Docker 容器化 等】
  13 +
  14 +---
  15 +
  16 +## ✅ 模块完成判定规则
  17 +
  18 +`docs/08-模块任务管理.md § 二` 是**模块元数据表**——每个模块一行 bullet(无 checkbox),记录依赖 / 路径 / MR iid。**模块完成由 `MR:` 字段 + `glab mr view state=merged` 判定**,不用 checkbox 表达进度。
  19 +
  20 +### 规则定义
  21 +
  22 +每个模块在 docs/08 § 二 中长这样:
  23 +
  24 +```markdown
  25 +- module_0 系统管理
  26 + - 依赖: —
  27 + - 路径: backend/module/sys/, frontend/pages/sys/
  28 + - MR: —
  29 +```
  30 +
  31 +`MR:` 字段由 `erp-mr-create` 在创建 MR 时从 `—` 改为 `!<iid>`。
  32 +
  33 +### 模块状态语义
  34 +
  35 +| `MR:` 字段 | `glab mr view state` | 含义 | 你(Claude Code)的行为 |
  36 +|---|---|---|---|
  37 +| `—` | — | 模块未开始(未建 MR) | ✅ 开始本模块开发 |
  38 +| `!<iid>` | `opened` / `closed` | 模块开发中 / 打回 | ✅ 继续推进该模块 |
  39 +| `!<iid>` | `merged` | 模块**已完成** | 🟢 进入下一未完成模块 |
  40 +
  41 +### 工作流规则
  42 +
  43 +- **开发顺序权威在 `docs/02-开发计划.md § 二 开发顺序清单`**,不是 `docs/08 § 二` 的物理行序
  44 +- **下一个要做的模块** = `docs/02 § 二` 清单中**第一个所属模块 MR 状态非 merged 的 REQ** 的 `module_id`(由 `erp-coding-start` 步骤 3 扫 `docs/08` 的 `MR:` 字段 + `glab mr view` 判定)
  45 +- `docs/02 § 二` 清单由 A5 `erp-downstream-gen` 生成阶段一次性确定(会交互询问业务偏好),之后通常不改;若开发中途需要调整顺序,重新触发 A5 生成阶段而非直接编辑文件
  46 +- **已完成模块**(`MR: !<iid>` + `glab mr view state=merged`):**默认不改**(不是禁止,是已交付无需改)
  47 +- 如果在当前模块开发中发现某个**已完成模块**(MR merged)有 bug:
  48 + - **不停下当前工作**,按软规则 S2 直接修复该模块代码;hook `log-cross-module.sh` 会自动留痕,调用 `erp-cross-module-log` 补「原因 / 影响评估」
  49 + - 修复随当前模块 MR 一起合并——不需要改 `docs/08`(模块已是 merged 状态,本插件不会标记重开;修复是以"当前模块依赖他的代码"的方式进入)
  50 + - 在当前模块的《模块完成报告》第 ⑦ 节「跨模块改动」明确记录:哪个模块、哪个文件、什么问题、修复范围、影响评估
  51 +
  52 +### 模块完成流程
  53 +
  54 +```
  55 +1. 对每个 REQ 跑完整功能循环:
  56 + brainstorm → plan → TDD(红绿循环,每步 commit)→ verify(子会话跑 REQ 级测试)→ 自审
  57 +2. 所有 REQ 完成后,erp-local-test-gate 派子会话按顺序跑:
  58 + a. schema 一致性检查(erp-local-test-gate 步骤 1 内联,schema 未漂移)+ 占位符扫描
  59 + b. scripts/test.sh 全套:build → lint → **unit + integration(全量重跑当前模块所有
  60 + REQ 的功能测试 + 所有已勾模块的回归测试)** → e2e
  61 + 任一失败停下修复再来
  62 +3. 测试全绿 → erp-module-report 输出《模块完成报告》
  63 +4. 自动 git push(.githooks/pre-push 会再跑一遍 scripts/test.sh 作为硬闸门)
  64 + + glab mr create,报告嵌入 MR 描述
  65 +5. 人工 review MR → Approve + Merge(人工动作,唯一人工介入点)
  66 +6. 下次用户跑 `/erp-workflow:erp-coding-start` 时,入口自动检测到本模块 `glab mr view state=merged` → `git checkout main && git pull --ff-only` 同步远程 → 扫下一模块派发
  67 +7. 你**不需要**手工 Edit docs/08(模块元数据不变;下次 coding-start 自动扫 MR state 判完成)
  68 +```
  69 +
  70 +> 两道测试闸门:功能级(`erp-feature-tdd` + `erp-feature-verify`,每 REQ 一遍)+ 模块级(`erp-local-test-gate` + pre-push hook,每模块一遍)。所有测试/验证都派到子会话跑,主会话只收结构化结论。
  71 +
  72 +### 模块完成报告
  73 +
  74 +由 `erp-module-report` skill 产出,模板位于 由 erp-module-report skill 持有(12 节标准化,含跨模块改动等 CLAUDE.md 软规则映射节)。CC 不手写模块报告,仅填模板。
  75 +
  76 +---
  77 +
  78 +## 🏷️ 占位符统一约定(`【人工填写:...】`)
  79 +
  80 +所有"只有人工能决定"的位置(密钥 / 账密 / 包名 / 命名约定 / 小版本号 等)一律使用以下纯文本标记:
  81 +
  82 +```
  83 +【人工填写:<简短说明>】
  84 +```
  85 +
  86 +### CC 行为规则
  87 +
  88 +- **生成文档 / 模板时**:凡是项目专属值、敏感值、技术栈小版本号一律用此标记,不要自行编造
  89 +- **不要用 HTML 注释**(`<!-- ... -->`),因为后者在 Obsidian 渲染视图被隐藏,开发者会漏填
  90 +- **必须带简短说明**:例如 `【人工填写:JWT 签名密钥,256+ bit 随机串】`,而不是空 `【人工填写】`
  91 +- **项目专属标识**(Java 根包名 / C# 命名空间 / Python 顶层模块等)只在 `docs/07-环境配置.md` 引入一次占位,其他文件**复用**已有的占位,不重复创建
  92 +
  93 +---
  94 +
  95 +## 🔄 开发流程(模块循环 + 功能循环)
  96 +
  97 +两层嵌套循环的详细步骤**全部固化到 skills**,CLAUDE.md 不展开。入口调 `/erp-workflow:erp-coding-start`,自动分发:
  98 +
  99 +- **模块循环(外层,Layer 2)** → `erp-module-start` → `erp-local-test-gate`(commit test-gate.md)→ `erp-module-report`(commit 模块报告 + cross-module log)→ `erp-mr-create`(worktree clean 校验 → push → 建 MR → 追 MR URL 到报告 + commit → 写 `MR: !<iid>` 到 docs/08 + commit → 再 push)→ 人工 Approve+Merge → 下次 `/erp-workflow:erp-coding-start` 扫到本模块 `glab mr view merged` → `git pull --ff-only main` → 推进下一模块
  100 +- **功能循环(内层,Layer 3,每个 REQ-XXX-NNN 走一遍)** → `erp-feature-brainstorm` → `erp-feature-plan` → `erp-feature-tdd` → `erp-feature-verify` → `erp-feature-review`
  101 +
  102 +**本地测试闸门**: `erp-local-test-gate` 是 MR 前的唯一硬闸门,子会话跑 `scripts/test.sh`:脚本先让 `setup-test-db.sh` 清空库 → build / lint → 跑测试(Spring Boot 启动时 Flyway 自动 apply `sql/migrations/V*.sql`)→ e2e → 再次清库。详见 § 🧪 自测要求。`.githooks/pre-push` 在 push 时会再跑一次 `scripts/test.sh` 作为兜底;`git push --no-verify` 被 hook `deny-no-verify.sh` 硬拦截。本项目不配置 GitLab CI/CD。
  103 +
  104 +> 占位符扫描 / schema 一致性校验都不在此闸门:前者在 A 阶段 skill 生成期完成;schema 演化通过 Flyway migration 保证一致(每次测试启动,Spring Boot 的 Flyway 从空库按序 apply V1~Vn,不存在"漂移"概念)。hook 产生的 `TBD(CC 补)` 存根由 CC 自主调 `erp-cross-module-log` 补齐,并在 `erp-module-report` § ⑦ 硬验收(非人工填写)。
  105 +
  106 +---
  107 +
  108 +## 📐 编码行为约束
  109 +
  110 +### 你必须做的 ✅
  111 +
  112 +1. **严格遵循** `docs/04-技术规范.md` 中的命名和编码规范
  113 +2. **严格遵循** `docs/09-项目目录结构.md` 中的目录规范,文件放对位置
  114 +3. **每个后端接口** 必须先在 `docs/05-API接口契约.md` 中定义,再编码实现
  115 +4. **每个功能** 必须可追溯到 `docs/01-需求清单.md` 中的需求编号
  116 +5. **代码注释** 必须包含对应的需求编号,如 `// REQ-001: 用户登录`
  117 +6. **数据库 schema 走 migration**:所有业务 schema 改动(CREATE/ALTER/DROP TABLE/INDEX/VIEW)必须写成 `sql/migrations/V_n__<snake_case_desc>.sql` 文件,由 Flyway 顺序 apply;**禁止**在主会话直接 `mysql -e` 跑业务 DDL(只读查询 / 临时本地调试探索除外)。详见 § Schema 演化规约
  118 +7. **提交代码前** 确保无编译错误、无明显运行时错误
  119 +8. **每个Controller方法** 必须有统一的响应格式包装
  120 +9. **异常处理** 使用全局异常处理器,不在业务代码中catch后吞掉异常
  121 +10. **分页查询** 统一使用 MyBatis-Plus 的 Page 对象
  122 +
  123 +### 你禁止做的 🚫
  124 +
  125 +1. **默认禁止** 修改"非当前模块"(其他 REQ 所属模块)的代码;确为实现当前模块所必需时,按软规则 S2 执行(留痕 + 模块报告单列说明)
  126 +2. **禁止** 引入`docs/04-技术规范.md` 技术栈表以外的框架或中间件(如需要必须先报告)
  127 +3. **禁止** 硬编码配置(数据库连接、端口号等必须放在配置文件中)
  128 +4. **禁止** 在前端直接写SQL或直接操作数据库
  129 +5. **禁止** 跳过模块开发(必须按顺序)
  130 +6. **禁止** 删除或覆盖他人代码(如有冲突必须报告)
  131 +7. **禁止** 使用 `SELECT *`,必须显式列出需要的字段
  132 +8. **禁止** 在循环中执行数据库查询(N+1问题)
  133 +9. **禁止** 前端存储敏感信息到 localStorage
  134 +10. **禁止** 返回后端异常堆栈给前端
  135 +
  136 +### Schema 演化规约(Flyway migration)
  137 +
  138 +1. **文件命名**:`sql/migrations/V<n>__<snake_case_desc>.sql`,例:`V5__add_user_email_unique_index.sql`
  139 +2. **版本号分配**:建文件前 `ls sql/migrations/V*.sql` 查当前最大 n,新文件 `n_max + 1`
  140 +3. **Apply 方式**:Spring Boot 启动 / 测试启动时 Flyway 自动 apply(项目必须在 `pom.xml` 声明 `flyway-core` + `flyway-mysql` 依赖)。`scripts/setup-test-db.sh` 只负责清空库,不做 apply
  141 +4. **已合并的 migration 永不修改**:发现错了写一个补救 migration(如 `V7__fix_V5_index_name.sql`),绝不编辑 git 历史里的旧 `V_n.sql`
  142 +5. **临时调试 DDL ≠ 业务 DDL**:临时在本地试字段/索引可手动 `mysql -e`,但不写 migration;下次 `setup-test-db.sh` 会 drop+create 清掉
  143 +6. **A3 生成的 V1**:`V1__initial_schema.sql` 是 A 阶段由 `erp-db-init` 从人工初始化的 schema 导出的初始版本;后续 V2/V3/... 由 B 阶段每个 REQ 按需写入
  144 +
  145 +---
  146 +
  147 +## 🔄 统一响应格式
  148 +
  149 +所有后端接口必须返回以下格式:
  150 +
  151 +```json
  152 +{
  153 + "code": 200,
  154 + "message": "操作成功",
  155 + "data": {},
  156 + "timestamp": 1700000000000
  157 +}
  158 +```
  159 +
  160 +错误响应:
  161 +
  162 +```json
  163 +{
  164 + "code": 40001,
  165 + "message": "用户名或密码错误",
  166 + "data": null,
  167 + "timestamp": 1700000000000
  168 +}
  169 +```
  170 +
  171 +错误码规范:
  172 +
  173 +| 错误码范围 | 含义 |
  174 +|-----------|------|
  175 +| 200 | 成功 |
  176 +| 400xx | 客户端参数错误 |
  177 +| 401xx | 认证/授权错误 |
  178 +| 403xx | 权限不足 |
  179 +| 404xx | 资源不存在 |
  180 +| 500xx | 服务端内部错误 |
  181 +
  182 +---
  183 +
  184 +## 🗂️ Git 提交规范
  185 +
  186 +每次提交必须遵循以下格式:
  187 +
  188 +```
  189 +<type>(<scope>): <subject>
  190 +
  191 +type: feat|fix|refactor|docs|style|test|chore
  192 +scope: 模块名,如 user, inventory, order
  193 +subject: 简短描述,中文可
  194 +
  195 +示例:
  196 +feat(user): 实现用户登录接口 REQ-001
  197 +fix(order): 修复订单金额计算精度问题
  198 +refactor(common): 统一响应格式包装
  199 +```
  200 +
  201 +---
  202 +
  203 +## 🧪 自测要求
  204 +
  205 +- 所有测试与验证(`scripts/test.sh` / `mvn test` / `pnpm test` / DB 测试集 diff 等)**一律派发到全新子会话 via `Agent` 执行**,主会话只接收结构化结论(命令 / 退出码 / 通过数 / 失败项 / 关键 stdout ≤30 行)。不在主会话直跑测试。
  206 +- 由 `erp-feature-verify`(功能级)+ `erp-local-test-gate`(模块级)两道 skill 统一承接。前者每个 REQ 跑一次,后者模块闸门跑一次。
  207 +- 声称"完成"前必须贴出子会话返回的 evidence(模板:由 erp-feature-verify skill 持有)。
  208 +
  209 +---
  210 +
  211 +## 🚩 静默执行红旗清单(中断机制)
  212 +
  213 +功能循环(每个功能 REQ-XXX 的 Brainstorm → Plan → TDD → Verify → AI 自审)默认 **静默跑不打扰人**,但命中以下任何一条必须**立刻停下、记录原因、等人决策**,不得自行绕过:
  214 +
  215 +| # | 红旗 | 例子 |
  216 +| - | --- | --- |
  217 +| 1 | **需求与 schema 不一致** | REQ 提到的字段/表在现有 schema 里不存在 → 先向用户确认「加一个 migration 新增 / 修正 REQ 理解」;得到答复后继续,**不走下方 Blocker 文件流程** |
  218 +| 2 | **需求本身歧义** | spec 中某规则有两种合理解读,CC 无法判断 |
  219 +| 3 | **超技术栈边界** | 需要引入 `docs/tech-stack.md` 以外的框架 / 中间件 |
  220 +| 4 | **测试反复失败** | 同一测试同一功能内连续 **10 次**修复失败 |
  221 +| 5 | **要改密钥 / 账密 / 包名** | `docs/07-环境配置.md` 里由人工标注必须填的字段 |
  222 +| 6 | **外部接口不可达** | 第三方 API 无法连接、证书失效等环境问题 |
  223 +
  224 +**命中红旗时的固定动作:**
  225 +
  226 +1. 在当前功能的 plan 文件里追加一节 `## 🚩 Blocker`,描述红旗编号、现象、初步判断
  227 +2. 停止后续所有功能的静默执行
  228 +3. 在主会话输出一句话摘要 + 指向 blocker 文件的路径,等人回复
  229 +
  230 +**报告格式:**
  231 +
  232 +```markdown
  233 +## ⚠️ 需要人工决策
  234 +
  235 +**红旗编号**: [1–6 中的某一条]
  236 +**问题描述**: [详细描述]
  237 +**影响范围**: [影响哪些模块 / 功能]
  238 +**我的建议**: [初步判断,可选]
  239 +**等待决策**: [需要人工做什么决定]
  240 +```
  241 +
  242 +---
  243 +
  244 +## 🟡 软规则(允许继续,但有强制后续动作)
  245 +
  246 +以下情况 **不触发中断**,CC 可自行继续推进,但必须在约定位置留痕,模块完成时统一审计。漏留痕 = 红旗。
  247 +
  248 +| # | 软规则 | 允许动作 | 强制后续 |
  249 +| - | ----- | ------- | ------- |
  250 +| S2 | **跨模块改动**(动到非当前模块的代码——无论该模块是否已 MR merged) | 允许修改,但范围受限:仅为当前模块实现所必需 | ① 当次修改立即追加到 `docs/superpowers/module-reports/<current>-cross-module.md`(含文件路径、改动原因、对目标模块功能/API 的影响评估)② 《模块完成报告》必须单列「跨模块改动」节完整贴入 ③ 漏留痕或未评估影响 → 升级为红旗 |
  251 +
  252 +---
  253 +
  254 +## 🧭 通用工作准则(General Principles)
  255 +
  256 +### 1. Think Before Coding
  257 +
  258 +**Don't assume. Don't hide confusion. Surface tradeoffs.**
  259 +
  260 +Before implementing:
  261 +- State your assumptions explicitly. If uncertain, ask.
  262 +- If multiple interpretations exist, present them - don't pick silently.
  263 +- If a simpler approach exists, say so. Push back when warranted.
  264 +- If something is unclear, stop. Name what's confusing. Ask.
  265 +
  266 +### 2. Simplicity First
  267 +
  268 +**Minimum code that solves the problem. Nothing speculative.**
  269 +
  270 +- No features beyond what was asked.
  271 +- No abstractions for single-use code.
  272 +- No "flexibility" or "configurability" that wasn't requested.
  273 +- No error handling for impossible scenarios.
  274 +- If you write 200 lines and it could be 50, rewrite it.
  275 +
  276 +Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
  277 +
  278 +### 3. Surgical Changes
  279 +
  280 +**Touch only what you must. Clean up only your own mess.**
  281 +
  282 +When editing existing code:
  283 +- Don't "improve" adjacent code, comments, or formatting.
  284 +- Don't refactor things that aren't broken.
  285 +- Match existing style, even if you'd do it differently.
  286 +- If you notice unrelated dead code, mention it - don't delete it.
  287 +
  288 +When your changes create orphans:
  289 +- Remove imports/variables/functions that YOUR changes made unused.
  290 +- Don't remove pre-existing dead code unless asked.
  291 +
  292 +The test: Every changed line should trace directly to the user's request.
  293 +
  294 +### 4. Goal-Driven Execution
  295 +
  296 +**Define success criteria. Loop until verified.**
  297 +
  298 +Transform tasks into verifiable goals:
  299 +- "Add validation" → "Write tests for invalid inputs, then make them pass"
  300 +- "Fix the bug" → "Write a test that reproduces it, then make it pass"
  301 +- "Refactor X" → "Ensure tests pass before and after"
  302 +
  303 +For multi-step tasks, state a brief plan:
  304 +```
  305 +1. [Step] → verify: [check]
  306 +2. [Step] → verify: [check]
  307 +3. [Step] → verify: [check]
  308 +```
  309 +
  310 +Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
  311 +
  312 +---
  313 +
  314 +## ⚡ Skill & 模板入口索引
  315 +
  316 +CC 会话启动请直接调 **`/erp-plan-start`** —— 顶层编排器会自动探测当前阶段(计划 / 模块循环 / 功能循环 / blocker)并分发到下一个 skill。
  317 +
  318 +### Skills(20 个,详细动作见各 `SKILL.md` 正文)
  319 +
  320 +| Layer | Skill |
  321 +|---|---|
  322 +| **0 入口** | `erp-plan-start` / `erp-project-init` |
  323 +| **1 计划阶段** | `erp-scope-lock` / `erp-skeleton-gen` / `erp-db-init` / `erp-db-design-gen` / `erp-downstream-gen` |
  324 +| **2 模块循环(外)** | `erp-module-start` / `erp-local-test-gate` / `erp-module-report` / `erp-mr-create` |
  325 +| **3 功能循环(内)** | `erp-feature-brainstorm` / `erp-feature-plan` / `erp-feature-tdd` / `erp-feature-verify` / `erp-feature-review` |
  326 +| **4 横切守门** | `erp-red-flag-check` / `erp-cross-module-log`(软规则 S2) |
  327 +
  328 +### Hooks(3 个,由插件 `hooks/hooks.json` + `hooks/scripts/*.sh` 提供)
  329 +
  330 +- `deny-no-verify.sh` — 拒 `git push --no-verify`
  331 +- `log-cross-module.sh` — 跨模块改动自动留痕(S2)
  332 +
  333 +### 模板(分散在各 skill 的 插件 `skills/erp-*/templates/*`)
  334 +
  335 +每个生成文件都对应一个模板(设计原则 #5)。模板保持纯净(原则 #6),帮助文本由 skill 通过 `AskUserQuestion` 交互引导。模板按"谁用谁拥有"原则分散到各自的 skill 目录下,便于打包成 plugin。一份共享模板(`cross-module-log-template.md`)在 `erp-module-start` 与 `erp-cross-module-log` 中各有一份副本。
  336 +
... ...
skills/plan/erp-project-init/templates/docs-01-readme-template.md 0 → 100644
  1 +++ a/skills/plan/erp-project-init/templates/docs-01-readme-template.md
  1 +# 需求清单
  2 +
  3 +> 本目录按模块组织所有功能需求。每个模块一个文件,由 CC 基于下方纲要扩展成 REQ-XXX-NNN 标准卡片。
  4 +
  5 +## 模块索引
  6 +
  7 +| 模块代码 | 模块名称 | 核心功能点(简要) |
  8 +|----------|----------|--------------------|
  9 +| SYS | 系统管理 | 【人工填写:用户/角色/权限/部门/字典 等】 |
  10 +| 【人工填写:模块代码】 | 【人工填写:模块名称】 | 【人工填写:核心功能点】 |
  11 +
  12 +## 填写说明
  13 +
  14 +1. 每个模块占一行,`模块代码` 用大写英文缩写(如 SYS / PUR / INV / SAL / FIN / HR)
  15 +2. `核心功能点` 只需列关键词,CC 会基于此扩展成完整 REQ 卡片
  16 +3. 填完后运行 `/erp-workflow:erp-plan-start`,CC 会自动检测并进入需求生成阶段
... ...
skills/plan/erp-project-init/templates/docs-08-initial-template.md 0 → 100644
  1 +++ a/skills/plan/erp-project-init/templates/docs-08-initial-template.md
  1 +# 08-工作流进度
  2 +
  3 +> 全流程进度跟踪。CC 每完成一项产出就勾选一项。
  4 +> - **§ 一 Plan(A0~A5)**:`erp-plan-start` 找第一个未勾 A 子项分发到对应 skill
  5 +> - **§ 二 Coding(模块)**:分发权威在 `docs/02-开发计划.md § 二 开发顺序清单`;`erp-coding-start` 按 docs/02 顺序扫,对每个 REQ 所属模块查本 § 二的 `MR:` 字段 + `glab mr view state`,找第一个非 merged 模块分发。本 § 二每模块是纯 bullet(无 checkbox),§ 二行序无语义
  6 +
  7 +## 一、Plan 阶段(一次性)
  8 +
  9 +- [ ] A0 项目初始化 — erp-project-init
  10 + - [ ] 项目文件骨架已创建(CLAUDE.md + docs/01-需求清单/README.md)
  11 +
  12 +- [ ] A1 范围锁定 — erp-scope-lock
  13 + - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述)
  14 + - [ ] 技术栈已确认(docs/04 § 零)
  15 + - [ ] 需求清单索引已填写(docs/01-需求清单/README.md)
  16 + - [ ] REQ 卡片已生成(docs/01-需求清单/*.md,schema/api 字段标记为 TBD)
  17 +
  18 +- [ ] A2 骨架生成 — erp-skeleton-gen
  19 + - [ ] 架构文档已生成(docs/04 § 一+、docs/06、docs/07、docs/09)
  20 + - [ ] 工具脚本已生成(scripts/*.sh、.githooks/pre-push、.env.local)
  21 + - [ ] .gitignore 已配置
  22 +
  23 +- [ ] A3 DB 初始化 — erp-db-init
  24 + - [ ] .env.local 凭据验证通过
  25 + - [ ] MySQL 连接验证通过
  26 + - [ ] V1 initial migration 已生成(sql/migrations/V1__initial_schema.sql,DDL only)
  27 + - [ ] sql/seed-data.sql 已导出(本地数据快照,INSERT only)
  28 +
  29 +- [ ] A4 DB 设计 + REQ 回填 — erp-db-design-gen
  30 + - [ ] docs/03 数据库设计已生成
  31 + - [ ] REQ 卡片依赖表已回填
  32 + - [ ] schema 一致性检查通过
  33 +
  34 +- [ ] A5 下游文档生成 — erp-downstream-gen
  35 + - [ ] docs/02 开发计划已生成
  36 + - [ ] docs/05 API 契约已生成
  37 + - [ ] docs/06 § 五 页面清单已填入
  38 + - [ ] docs/10 验收清单已生成
  39 + - [ ] 下方模块列表已填入
  40 + - [ ] REQ 卡片依赖接口已回填
  41 +
  42 +## 二、Coding 阶段(按模块循环)
  43 +
  44 +(A5 填入后,每个模块一行 bullet(`- ` 开头,无 checkbox)。每个模块的 `MR:` 字段在 `—` 和 `!<iid>` 之间变化,完成由 `glab mr view state=merged` 判定。`erp-coding-start` 每次跑时按 docs/02 REQ 序扫描每模块的 MR state 决定派发。)
  45 +
  46 +<!-- 模块格式示例(由 A5 erp-downstream-gen 追加):
  47 +- module_0 系统管理
  48 + - 依赖: —
  49 + - 路径: backend/module/sys/, frontend/pages/sys/
  50 + - MR: —
  51 +-->
... ...
skills/plan/erp-scope-lock/SKILL.md 0 → 100644
  1 +++ a/skills/plan/erp-scope-lock/SKILL.md
  1 +---
  2 +name: erp-scope-lock
  3 +description: A1 计划范围锁定——引导用户填写项目概述 + 技术栈 + 需求索引,并自动扩展 REQ 卡片待人工评审。`schema_refs` 填 `TBD(A4 自动补)`(A4 回填依赖表),`api_refs` 填 `TBD(A5 自动补)`(A5 回填依赖接口)。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Edit Grep Skill AskUserQuestion
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# erp-scope-lock
  11 +
  12 +## 执行步骤
  13 +
  14 +### 步骤 0:打印当前位置流程图
  15 +
  16 +向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A1):
  17 +
  18 +```
  19 +┌──────────────────────────────────────────────────────┐
  20 +│ 📋 阶段 A:规划(一次性) │
  21 +│ │
  22 +│ A0 初始化项目 → ▶ A1 锁范围(REQ 卡片) │
  23 +│ ↓ │
  24 +│ ⏸ 等你审阅 REQ,重跑 /erp-plan-start 续 │
  25 +│ ↓ │
  26 +│ A2 生骨架 → A3 初始化 DB → A4 生 DB 设计 → A5 生下游文档│
  27 +│ ↓ │
  28 +│ 规划阶段到此结束 │
  29 +└──────────────────────────────────────────────────────┘
  30 +```
  31 +
  32 +### A. 提示用户填写项目概述并等待
  33 +
  34 +向用户输出:
  35 +
  36 +```
  37 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  38 + [erp-scope-lock] 请填写项目概述
  39 +
  40 + 📄 文件位置: ./CLAUDE.md
  41 + 📌 编辑位置: § 🎯 项目概述
  42 +
  43 + 请将以下占位符替换为实际值:
  44 + - 项目名称
  45 + - 项目简述
  46 + - 目标用户
  47 + - 部署方式
  48 + 改完后回来选择「继续」。
  49 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  50 +```
  51 +
  52 +用 `AskUserQuestion` 询问:
  53 +- **question**: `项目概述填写完毕了吗?`
  54 +- **options** (每项为对象):
  55 + - `{"label": "继续", "description": "已完成检查"}`
  56 + - `{"label": "有疑问想先沟通", "description": "需要讨论或修改"}`
  57 +
  58 +- 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。
  59 +- 用户选择「继续」→ 进入步骤 B。
  60 +
  61 +### B. 保存默认技术栈到 docs/04
  62 +
  63 +用 `Write` 将以下默认技术栈表写入 `docs/04-技术规范.md`:
  64 +
  65 +```markdown
  66 +# 04-技术规范
  67 +
  68 +## 零、技术栈总览
  69 +
  70 +| 分层模块 | 技术 | 版本要求 | 说明 |
  71 +|---|---|---|---|
  72 +| 前端基础框架 | React | 18.x | 构建前端应用 |
  73 +| 前端 UI 组件 | Ant Design | 5.x | 页面组件与交互控件 |
  74 +| 前端状态管理 | Redux Toolkit | 最新稳定版 | 管理全局状态 |
  75 +| 前端路由管理 | React Router | v6 | 页面路由与导航 |
  76 +| 前端工程化构建 | Vite | 最新稳定版 | 前端开发与打包构建 |
  77 +| 前端接口通信 | Axios | 最新稳定版 | 调用后端 API |
  78 +| 后端基础框架 | Spring Boot | 3.x | 构建后端服务 |
  79 +| 后端数据访问 | MyBatis-Plus | 最新稳定版 | 数据库访问与 ORM 增强 |
  80 +| 工作流引擎 | Activiti | 6.x | 审批流、流程流转 |
  81 +| 缓存服务 | Redis | 最新稳定版 | 缓存、会话、分布式能力 |
  82 +| 报表打印 | JXLS | 2.8.1 | 基于 Excel 模板生成报表 |
  83 +| Excel 导入导出 | EasyExcel | 4.0.3 | Excel 数据导入导出 |
  84 +| 关系型数据库 | MySQL | 8.x | 核心业务数据存储 |
  85 +| 数据库 schema 迁移 | Flyway (`flyway-core` + `flyway-mysql`) | 10.x / 最新稳定版 | `sql/migrations/V_n__*.sql` 顺序 apply;Spring Boot 启动时自动应用 |
  86 +| 接口风格 | RESTful API | 统一规范 | 前后端接口设计规范 |
  87 +| 权限认证 | Spring Security / JWT | 最新稳定版 | 登录认证、权限控制 |
  88 +| API 文档 | OpenAPI / Swagger | 最新稳定版 | 接口文档与调试 |
  89 +| 项目构建管理 | Maven | 3.9.x | Java 项目依赖与构建 |
  90 +| JDK 运行环境 | Java | 17 / 21 | Spring Boot 3 推荐版本 |
  91 +| 部署容器 | Docker | 最新稳定版 | 容器化部署 |
  92 +| Web 服务器 / 反向代理 | Nginx | 最新稳定版 | 前端托管、反向代理、负载分发 |
  93 +| 日志管理 | Logback | 默认集成 / 最新稳定版 | 应用日志输出 |
  94 +| 对象映射工具 | MapStruct | 最新稳定版 | DTO / VO / Entity 转换 |
  95 +| 工具类库 | Hutool / Apache Commons | 最新稳定版 | 常用工具方法支持 |
  96 +
  97 +> 本表由 erp-scope-lock 锁定。后续所有规范基于此表推导。
  98 +```
  99 +
  100 +### C. 提示用户检查并等待
  101 +
  102 +向用户输出:
  103 +
  104 +```
  105 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  106 + [erp-scope-lock] 技术栈已保存
  107 +
  108 + 📄 文件位置: ./docs/04-技术规范.md
  109 + 📌 编辑位置: § 零、技术栈总览
  110 +
  111 + 请检查技术栈表:
  112 + - 不需要的行直接删除(如纯后端项目删前端行)
  113 + - 需要替换的技术直接改
  114 + - 需要新增的条目直接加行
  115 + 改完后回来选择「继续」。
  116 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  117 +```
  118 +
  119 +用 `AskUserQuestion` 询问:
  120 +- **question**: `技术栈检查完毕了吗?`
  121 +- **options** (每项为对象):
  122 + - `{"label": "继续", "description": "已完成检查"}`
  123 + - `{"label": "有疑问想先沟通", "description": "需要讨论或修改"}`
  124 +
  125 +- 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。
  126 +- 用户选择「继续」→ 进入步骤 D。
  127 +
  128 +### D. 提示用户填写需求清单并等待
  129 +
  130 +`docs/01-需求清单/README.md` 已由 `erp-project-init` 写入占位符模板,这里让用户补齐模块清单。
  131 +
  132 +向用户输出:
  133 +
  134 +```
  135 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  136 + [erp-scope-lock] 请填写需求清单模块索引
  137 +
  138 + 📄 文件位置: ./docs/01-需求清单/README.md
  139 + 📌 编辑位置: § 模块索引(表格)
  140 +
  141 + 请按业务列出所有模块:
  142 + - 每行一个模块(如 SYS 系统管理 / PUR 采购 / SAL 销售)
  143 + - 「核心功能点」只需关键词,CC 会扩展为完整 REQ 卡片
  144 + 改完后回来选择「继续」。
  145 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  146 +```
  147 +
  148 +用 `AskUserQuestion` 询问:
  149 +- **question**: `需求清单模块索引填写完毕了吗?`
  150 +- **options** (每项为对象):
  151 + - `{"label": "继续", "description": "已完成检查"}`
  152 + - `{"label": "有疑问想先沟通", "description": "需要讨论或修改"}`
  153 +
  154 +- 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。
  155 +- 用户选择「继续」→ 进入步骤 E。
  156 +
  157 +### E. 生成 REQ 卡片并等用户审阅
  158 +
  159 +先用 `Grep` 在 `docs/01-需求清单/README.md` 搜索 `【人工填写:`,命中 → 提示残留行,回到步骤 D。通过后:
  160 +
  161 +1. 用 `Read` 读取 `docs/01-需求清单/README.md`,解析模块索引表(每行:模块代码 / 模块名 / 核心功能点)。
  162 +2. 用 `Read` 读取两份模板:
  163 + - `${CLAUDE_SKILL_DIR}/templates/req-card-template.md`
  164 + - `${CLAUDE_SKILL_DIR}/templates/docs-01-module-template.md`
  165 +3. 对每个模块:
  166 + - 基于「核心功能点」关键词,LLM 扩展为若干 REQ-XXX-NNN 卡片(编号按模块递增)
  167 + - 每张卡片填充字段:
  168 + - `goal` / `input` / `output` / `rules` / `constraints` / `acceptance` —— LLM 基于功能点推断
  169 + - `schema_refs` —— 填 `TBD(A4 自动补)`(A4 `erp-db-design-gen` 回填依赖表)
  170 + - `api_refs` —— 填 `TBD(A5 自动补)`(A5 `erp-downstream-gen` 回填依赖接口)
  171 + - 用 module 模板包装卡片列表
  172 + - 用 `Write` 写入 `docs/01-需求清单/<module_code>-<module_name>.md`
  173 +4. 向用户输出(只打印,**不弹 QA**,不等待):
  174 +
  175 +```
  176 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  177 + [erp-scope-lock] REQ 卡片已生成
  178 +
  179 + 📄 文件位置: ./docs/01-需求清单/<module>-*.md
  180 + ⚠️ 依赖表 = TBD(A4 自动补)(A4 阶段回填) / 依赖接口 = TBD(A5 自动补)(A5 阶段回填)
  181 +
  182 + 请人工审阅每张 REQ 卡片的功能字段:
  183 + - 目标 / 输入 / 输出
  184 + - 业务规则 / 边界
  185 + - 验收标准
  186 +
  187 + 审阅是 Plan 阶段的关键人工关口,请认真逐张过一遍。
  188 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  189 +```
  190 +
  191 +5. 立即进入步骤 F(不等待用户任何输入)。
  192 +
  193 +### F. 勾选 docs/08 进度 + 停下等人工审阅
  194 +
  195 +1. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 5 个 checkbox(A1 的 4 个子项 + A1 父项):
  196 + - ` - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述)` → `[x]`
  197 + - ` - [ ] 技术栈已确认(docs/04 § 零)` → `[x]`
  198 + - ` - [ ] 需求清单索引已填写(docs/01-需求清单/README.md)` → `[x]`
  199 + - ` - [ ] REQ 卡片已生成(docs/01-需求清单/*.md,schema/api 字段标记为 TBD)` → `[x]`
  200 + - `- [ ] A1 范围锁定 — erp-scope-lock` → `[x]`
  201 +
  202 +2. 输出 `scope-lock: 完成(4 项产出已勾选)`。
  203 +
  204 +3. 打印停下横幅并**停下**(**不调** `Skill(erp-skeleton-gen)`,A2 由用户手动恢复):
  205 +
  206 + ```
  207 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  208 + [erp-scope-lock] ✅ A1 范围锁定完成
  209 +
  210 + 产出:
  211 + ✓ CLAUDE.md § 🎯 项目概述
  212 + ✓ docs/04 § 零 技术栈
  213 + ✓ docs/01-需求清单/README.md 模块索引
  214 + ✓ docs/01-需求清单/<module>-*.md REQ 卡片
  215 +
  216 + ⏸ 现在请你审阅 REQ 卡片(路径:`docs/01-需求清单/<module_code>-<module_name>.md`)。
  217 +
  218 + 审阅完成后,运行以下命令继续进入 A2:
  219 + /erp-workflow:erp-plan-start
  220 +
  221 + (入口会读 docs/08 进度,自动派发到 A2 erp-skeleton-gen)
  222 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  223 + ```
  224 +
  225 + **停止**,不调用任何下游 skill。
  226 +
  227 +## 参考
  228 +
  229 +- `CLAUDE.md` § 🎯 项目概述(写入目标)
  230 +- `docs/04-技术规范.md`(技术栈输出,供 erp-skeleton-gen 读取使用)
  231 +- `docs/01-需求清单/README.md`(模块索引输入)
  232 +- `docs/01-需求清单/<module>-*.md`(REQ 卡片输出,A4 erp-db-design-gen 会回填 TBD 字段)
  233 +- `${CLAUDE_SKILL_DIR}/templates/req-card-template.md`
  234 +- `${CLAUDE_SKILL_DIR}/templates/docs-01-module-template.md`
... ...
skills/plan/erp-scope-lock/templates/docs-01-module-template.md 0 → 100644
  1 +++ a/skills/plan/erp-scope-lock/templates/docs-01-module-template.md
  1 +# {{module_code}}-{{module_name}}
  2 +
  3 +模块简述: {{module_brief}}
  4 +依赖模块: {{depends_on}}
  5 +涉及表: {{tables}}
  6 +
  7 +## 功能清单
  8 +
  9 +{{#each reqs}}
  10 +{{req_card}}
  11 +{{/each}}
... ...
skills/plan/erp-scope-lock/templates/req-card-template.md 0 → 100644
  1 +++ a/skills/plan/erp-scope-lock/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}}
... ...
skills/plan/erp-skeleton-gen/SKILL.md 0 → 100644
  1 +++ a/skills/plan/erp-skeleton-gen/SKILL.md
  1 +---
  2 +name: erp-skeleton-gen
  3 +description: A2 骨架生成——基于 docs/04 § 零 技术栈 + docs/01-需求清单/README.md 模块索引,生成项目专属的架构文档(docs/04 § 一+、docs/06、docs/07、docs/09)和工具脚本。固定工具文件走 cp,架构文档由 LLM 按大纲生成。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Edit Skill Grep Glob AskUserQuestion Bash(mkdir *) Bash(cp *) Bash(touch *) Bash(chmod *) Bash(git config *) Bash(cat *) Bash(bash *)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# erp-skeleton-gen
  11 +
  12 +## 前置条件
  13 +
  14 +本 skill 从 docs/08 进度推进而来。
  15 +
  16 +**输入文件**:
  17 +- `docs/04-技术规范.md § 零`:erp-scope-lock 写入的技术栈表。本 skill 基于它推导 § 一+ 编码规范、docs/07 依赖清单、docs/09 目录结构、scripts/test.sh 的构建/测试命令。
  18 +- `docs/01-需求清单/`:A1 已产出 README.md(模块索引表)+ 每模块一份 REQ 卡片(`<code>-<name>.md`,用户已审阅确认)。A2 只用其中的**模块 ID 列表**生成 docs/09 的后端/前端模块目录树(`module/user/` / `module/order/` 等),REQ 卡片详情不在本 skill 使用(留给 A4 回填 schema、A5 生成 API/验收清单)。
  19 +- `docs/08-模块任务管理.md`:末尾 Edit 勾选 A2 checkbox。
  20 +
  21 +**产出覆盖提醒**:
  22 +- 本 skill 会 `Write` 覆盖以下文件:docs/04(拼接 § 零 + § 一+)、docs/06、docs/07、docs/09、scripts/test.sh、scripts/setup-test-db.sh、.githooks/pre-push、.env.local。
  23 +- 如果之前运行过本 skill 且用户手动改过这些文件,**重跑会覆盖修改**。
  24 +
  25 +## 执行步骤
  26 +
  27 +### 步骤 0:打印当前位置流程图
  28 +
  29 +向用户展示当前在 A 阶段流程中的位置(A-only,`▶` 标在 A2):
  30 +
  31 +```
  32 +┌──────────────────────────────────────────────────────┐
  33 +│ 📋 阶段 A:规划(一次性) │
  34 +│ │
  35 +│ A0 初始化项目 → A1 锁范围(REQ 卡片) │
  36 +│ ↓ │
  37 +│ ⏸ 等你审阅 REQ,重跑 /erp-plan-start 续 │
  38 +│ ↓ │
  39 +│ ▶ A2 生骨架 → A3 初始化 DB → A4 生 DB 设计 → A5 生下游文档│
  40 +│ ↓ │
  41 +│ 规划阶段到此结束 │
  42 +└──────────────────────────────────────────────────────┘
  43 +```
  44 +
  45 +### A. 读取锁定的输入
  46 +
  47 +用 `Read` 读取:
  48 +- `docs/04-技术规范.md` § 零 技术栈表
  49 +- `docs/01-需求清单/README.md` 模块索引
  50 +
  51 +这两份是本次生成的**唯一权威输入**,后续所有内容都基于它们推导。
  52 +
  53 +### B.1 生成 3 个全新架构文档(docs/06 / 07 / 09)
  54 +
  55 +对下表每个目标文件:
  56 +1. 用 `Read` 读取对应的大纲模板(只含 section 标题 + HTML 注释形式的填写提示)
  57 +2. 基于步骤 A 的输入,按大纲生成项目专属内容
  58 +3. **剥掉所有 `<!-- -->` 注释**(注释是给 LLM 的提示,不应出现在最终文档里)
  59 +4. 用 `Write` 写入目标路径
  60 +
  61 +| 目标文件 | 大纲模板 |
  62 +|---|---|
  63 +| `docs/06-UI交互规范.md`(写 § 一 ~ 四,§ 五 占位) | `${CLAUDE_SKILL_DIR}/templates/docs-06-static-template.md` |
  64 +| `docs/07-环境配置.md` | `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md` |
  65 +| `docs/09-项目目录结构.md` | `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md` |
  66 +
  67 +项目专属标识(根包名 / 命名空间)保留 `【人工填写:<说明>】` 占位,等人工在 docs/09 顶部补填一次后,其他文件复用。
  68 +
  69 +### B.2 追加 docs/04 § 一+(保留 § 零 不覆盖)
  70 +
  71 +docs/04 已由 erp-scope-lock 写入 § 零。本步骤追加 § 一 ~ 三。
  72 +
  73 +1. 用 `Read` 读取 `docs/04-技术规范.md`(拿现有 § 零 完整内容)。
  74 +2. 用 `Read` 读取 `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`(§ 一+ 大纲)。
  75 +3. 基于步骤 A 技术栈,按大纲生成 § 一 ~ 三 的项目专属内容,剥掉 HTML 注释。
  76 +4. 拼接 `<§ 零 原文>\n\n<新生成的 § 一+>` → 用 `Write` 写回 `docs/04-技术规范.md`。
  77 +
  78 +### C. 生成工具脚本
  79 +
  80 +#### C.1 零槽位文件:纯 `cp`
  81 +
  82 +```bash
  83 +mkdir -p scripts .githooks sql/migrations
  84 +touch sql/migrations/.gitkeep
  85 +cp "${CLAUDE_SKILL_DIR}/templates/env-local-template" .env.local
  86 +cp "${CLAUDE_SKILL_DIR}/templates/githooks-pre-push-template.sh" .githooks/pre-push
  87 +cp "${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh" scripts/setup-test-db.sh
  88 +```
  89 +
  90 +说明:
  91 +- `sql/migrations/` 是 Flyway migration 目录。A3 `erp-db-init` 会在此生成 `V1__initial_schema.sql`,后续 B 阶段每个 REQ 的业务 DDL 也写在这(`V2__xxx.sql` / `V3__xxx.sql` ...)
  92 +- `setup-test-db.sh` 只做 **drop + create 空库**;schema apply 由 **Flyway 在 Spring Boot 启动时自动处理**
  93 +- **硬依赖**:项目 `pom.xml` 必须包含 `flyway-core` + `flyway-mysql` 依赖(已列入 docs/04 § 零 技术栈);否则 Spring 启动不会 apply migration,测试会因表不存在而失败
  94 +- seed 数据(`sql/seed-data.sql`)由 A3 `erp-db-init` 从本地 MySQL 导出,开发者选一种装载方式(Spring `@Sql` / Flyway `R__seed.sql` / `data.sql`);setup-test-db.sh 只负责清空库
  95 +
  96 +#### C.2 `scripts/test.sh` —— 直接 Write
  97 +
  98 +基于步骤 A 的技术栈推断 4 条命令(build / lint / unit+integration / e2e),直接 `Write` 完整 `scripts/test.sh`。
  99 +
  100 +骨架如下(CC 把 4 个 `<推断的 ... 命令>` 替换成实际值后 Write):
  101 +
  102 +```bash
  103 +#!/usr/bin/env bash
  104 +# scripts/test.sh —— 合并到 main 前的唯一硬闸门。
  105 +# 顺序:setup-db → build → lint → unit+integration → e2e → reset-db
  106 +# 由 .githooks/pre-push 和 erp-local-test-gate skill(通过子会话)调用。
  107 +
  108 +set -euo pipefail
  109 +
  110 +PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
  111 +cd "$PROJECT_ROOT"
  112 +
  113 +echo "[test.sh] 1/6 setup test db"
  114 +./scripts/setup-test-db.sh
  115 +
  116 +echo "[test.sh] 2/6 build"
  117 +<推断的 build 命令,如:(cd backend && mvn -DskipTests clean package) && (cd frontend && pnpm build)>
  118 +
  119 +echo "[test.sh] 3/6 lint"
  120 +<推断的 lint 命令>
  121 +
  122 +echo "[test.sh] 4/6 unit + integration"
  123 +<推断的 unit+integration 命令>
  124 +
  125 +echo "[test.sh] 5/6 E2E"
  126 +<推断的 e2e 命令>
  127 +
  128 +echo "[test.sh] 6/6 reset test db"
  129 +./scripts/setup-test-db.sh
  130 +
  131 +echo "[test.sh] GREEN"
  132 +```
  133 +
  134 +#### C.3 赋权 + 配置 git hooks
  135 +
  136 +```bash
  137 +chmod +x scripts/*.sh .githooks/pre-push
  138 +git config core.hooksPath .githooks
  139 +```
  140 +
  141 +### D. 追加 .gitignore 忽略项
  142 +
  143 +调用脚本完成合并:
  144 +
  145 +```bash
  146 +bash "${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh" "${CLAUDE_SKILL_DIR}/templates/gitignore-append-template"
  147 +```
  148 +
  149 +脚本行为:
  150 +- 若项目根无 `.gitignore` → 直接 `cp` 整份模板
  151 +- 若已有 → 读模板每一行,跳过注释/空行,用 `grep -xF` 整行精确匹配判重(避免 `.env` 误匹配 `.env.local`、通配符 `*.iml` 被当正则),只追加缺失的规则
  152 +
  153 +### E. 占位符智能填充 + `.env.local` 独立提示 + QA 循环验证
  154 +
  155 +目标:减少用户重复编辑。同一"逻辑占位"(如根包名出现多处)只问用户一次,CC 批量填;派生占位(如 Java 路径从根包名派生)由 CC 自己推断。敏感占位(`.env.local` 凭据 / 密钥)不进会话上下文,让用户自己去文件里填。
  156 +
  157 +循环执行直到**两个条件同时满足**:
  158 +(a) 所有占位符已填(重扫命中数 N = 0)
  159 +(b) 用户选「继续」
  160 +
  161 +#### E.1 扫描 + 分组
  162 +
  163 +用 `Grep` 扫 `【人工填写:` 于以下 8 个路径,记录每处命中(文件 + 行号 + 说明文字):
  164 +- `docs/04-技术规范.md`
  165 +- `docs/06-UI交互规范.md`
  166 +- `docs/07-环境配置.md`
  167 +- `docs/09-项目目录结构.md`
  168 +- `scripts/*.sh`
  169 +- `.githooks/pre-push`
  170 +- `.gitignore`
  171 +- `.env.local`
  172 +
  173 +对每个命中提取 `【人工填写:<说明>】` 的 `<说明>`,**分两组**:
  174 +
  175 +- **敏感组**:`.env.local` 路径下的全部命中(密码 / 密钥 / 账号等)。**不**通过 `AskUserQuestion` 问——留给 E.4 提示用户手动编辑。
  176 +- **非敏感组**:其他文件的命中。按语义聚合成"逻辑占位":
  177 + - **说明文字完全相同** → 同一个根占位(多处共用同一值),如"根包名"出现 3 次
  178 + - **说明表达派生关系** → 派生占位,派生自某根占位(如"后端 java 根包路径"派生自"根包名")
  179 + - **无法归类** → 视作独立根占位单独问
  180 +
  181 +若总 N=0(无任何占位)→ 直接跳 E.5 验证。
  182 +
  183 +#### E.2 向用户询问非敏感"根占位"
  184 +
  185 +对每个非派生根占位用 `AskUserQuestion` 询问:
  186 +
  187 +- **question**: `请输入 <说明>(将填充到 <N> 处)`
  188 +- **options**(给**默认值候选 + 自由输入**,供用户快速选择;"Other" 由 CC 运行时自动提供,无需显式列):
  189 + - `{"label": "<合理默认值>", "description": "示例默认值"}`
  190 + - (可选)`{"label": "<第二个常见默认>", "description": "..."}`
  191 +
  192 +示例(根包名):
  193 +```
  194 +question: "请输入 Java 根包名(将填充到 3 处)"
  195 +options:
  196 + - {"label": "com.example.erp", "description": "示例默认"}
  197 +```
  198 +
  199 +- 用户选默认值 → 取该值
  200 +- 用户选 Other → 用户输入的字符串为该值
  201 +
  202 +**派生占位不问用户**——由 CC 在 E.3 自行推断。
  203 +
  204 +#### E.3 CC 批量 Edit 填充
  205 +
  206 +1. 对每个根占位:遍历所有命中位置,用 `Edit` 把 `【人工填写:<说明>】` 替换为 E.2 用户输入的值。
  207 +
  208 +2. 对每个派生占位:CC 基于说明文字 + 根占位值**自行推断**派生值,用 `Edit` 填入。例如:
  209 + - 根 `根包名 = com.xly.erp` → 派生 `后端 java 根包路径 = backend/src/main/java/com/xly/erp/`
  210 + - 根 `根包名 = com.xly.erp` → 派生 `测试 java 根包路径 = backend/src/test/java/com/xly/erp/`
  211 +
  212 +3. 若 CC 对某派生占位无法可靠推断(说明不清 / 上下文不足),**回退**:把该占位当作独立根占位,弹 `AskUserQuestion` 问用户。
  213 +
  214 +#### E.4 `.env.local` 敏感占位提示(不弹 QA)
  215 +
  216 +若敏感组非空,打印提示横幅(只打印,不问):
  217 +
  218 +```
  219 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  220 + [erp-skeleton-gen] ⚠️ 敏感占位需你亲自填
  221 +
  222 + 📄 文件: ./.env.local
  223 + 待填字段(<N> 个):
  224 + <列出实际命中的字段名,如 DB_HOST / DB_PORT / DB_USER / DB_PASSWORD / DB_SCHEMA / JWT_SECRET>
  225 +
  226 + 这些是凭据 / 密钥,CC 不通过会话询问(避免写入聊天记录)。
  227 + 请直接编辑 .env.local 填入实际值。
  228 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  229 +```
  230 +
  231 +#### E.5 验证 + QA 循环
  232 +
  233 +1. 用 `Grep` **重新扫** `【人工填写:` 于所有 8 个路径,得新命中数 N 和残留清单。
  234 +
  235 +2. 打印汇总横幅:
  236 +
  237 + ```
  238 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  239 + [erp-skeleton-gen] 骨架生成完成,请审阅
  240 +
  241 + 📄 架构文档:
  242 + ✓ docs/04-技术规范.md (§ 一 ~ 三)
  243 + ✓ docs/06-UI交互规范.md (§ 一 ~ 四)
  244 + ✓ docs/07-环境配置.md
  245 + ✓ docs/09-项目目录结构.md
  246 +
  247 + 📄 工具文件:
  248 + ✓ scripts/test.sh
  249 + ✓ scripts/setup-test-db.sh
  250 + ✓ .githooks/pre-push
  251 + ✓ .env.local
  252 + ✓ .gitignore(新建 / 追加 / 跳过)
  253 + ✓ sql/migrations/.gitkeep
  254 +
  255 + 占位符状态:
  256 + <N=0 时打印:✅ 全部填完>
  257 + <N>0 时打印:⚠️ 还有 N 处待填:
  258 + <文件:行号> — <行内容摘要>
  259 + ...>
  260 +
  261 + 需要调整 → 直接编辑对应文件(尤其 .env.local 敏感字段)
  262 + 填完后 → 选「继续」放行 A3
  263 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  264 + ```
  265 +
  266 +3. 用 `AskUserQuestion` 询问:
  267 + - **question**: `架构文档审阅 & 占位符补填完毕?`
  268 + - **options**:
  269 + - `{"label": "继续", "description": "进入 A3 数据库配置"}`
  270 + - `{"label": "有疑问想先沟通", "description": "需要讨论或修改"}`
  271 +
  272 +4. 路由:
  273 + - 选「有疑问想先沟通」→ 回答用户问题后**回 E.5.1 重扫**
  274 + - 选「继续」→ **回 E.5.1 重扫验证**:
  275 + - 新 N = 0 → 进入步骤 F(放行 A3)
  276 + - 新 N > 0 → 用户以为填完其实还有残留,回 E.5.2 打印新横幅 + 再弹 QA
  277 +
  278 +关键点:**每次弹 QA 前都重扫一次**,用户看到的 N 始终是最新的;只有 N = 0 且选「继续」才放行。
  279 +
  280 +### F. 勾选 docs/08 进度 + 进入 A3
  281 +
  282 +1. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 4 个 checkbox(A2 的 3 个子项 + A2 父项):
  283 + - ` - [ ] 架构文档已生成(docs/04 § 一+、docs/06、docs/07、docs/09)` → `[x]`
  284 + - ` - [ ] 工具脚本已生成(scripts/*.sh、.githooks/pre-push、.env.local)` → `[x]`
  285 + - ` - [ ] .gitignore 已配置` → `[x]`
  286 + - `- [ ] A2 骨架生成 — erp-skeleton-gen` → `[x]`
  287 +
  288 +2. 输出 `skeleton-gen: 完成(docs/04 § 一+ / docs/06 / docs/07 / docs/09 + scripts/*.sh + .githooks/pre-push + .env.local + .gitignore)`。
  289 +
  290 +3. 立即调用 `Skill(erp-db-init)` 进入 A3,不等用户手动输入。
  291 +
  292 +## 参考
  293 +
  294 +- `docs/04-技术规范.md` § 零(技术栈输入)
  295 +- `docs/01-需求清单/README.md`(模块索引输入)
  296 +- `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`(大纲)
  297 +- `${CLAUDE_SKILL_DIR}/templates/docs-06-static-template.md`(大纲)
  298 +- `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md`(大纲)
  299 +- `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md`(大纲)
  300 +- `${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh`(0 槽位)
  301 +- `${CLAUDE_SKILL_DIR}/templates/githooks-pre-push-template.sh`(0 槽位)
  302 +- `${CLAUDE_SKILL_DIR}/templates/env-local-template`(0 槽位)
  303 +- `${CLAUDE_SKILL_DIR}/templates/gitignore-append-template`(0 槽位)
  304 +- `${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh`(.gitignore 逐行判重合并脚本)
... ...
skills/plan/erp-skeleton-gen/scripts/merge-gitignore.sh 0 → 100755
  1 +++ a/skills/plan/erp-skeleton-gen/scripts/merge-gitignore.sh
  1 +#!/usr/bin/env bash
  2 +# merge-gitignore.sh
  3 +# 把模板里的忽略规则合并到项目根的 .gitignore:
  4 +# - 若 .gitignore 不存在 → 直接 cp 模板(含注释头和结构)
  5 +# - 若已存在 → 逐行判重,只追加模板里缺失的规则行(跳过注释/空行)
  6 +#
  7 +# 用法:merge-gitignore.sh <template_path> [<target_gitignore_path>]
  8 +# template_path 模板文件绝对路径(由 erp-skeleton-gen skill 传入)
  9 +# target_gitignore_path 目标 .gitignore 路径,默认为当前工作目录下的 .gitignore
  10 +#
  11 +# 判重:grep -xF 整行精确匹配 + 字面字符串(非正则),避免 .env 误匹配 .env.local,
  12 +# 也避免 *.class / *.iml 等通配符被当作 regex。
  13 +
  14 +set -euo pipefail
  15 +
  16 +template="${1:?usage: merge-gitignore.sh <template_path> [<target_gitignore_path>]}"
  17 +target="${2:-.gitignore}"
  18 +
  19 +if [ ! -f "$template" ]; then
  20 + echo "[merge-gitignore] ERROR: template not found: $template" >&2
  21 + exit 1
  22 +fi
  23 +
  24 +if [ ! -f "$target" ]; then
  25 + cp "$template" "$target"
  26 + echo "[merge-gitignore] created $target from template"
  27 + exit 0
  28 +fi
  29 +
  30 +added=0
  31 +while IFS= read -r line; do
  32 + case "$line" in ""|"#"*) continue ;; esac
  33 + if ! grep -qxF "$line" "$target"; then
  34 + echo "$line" >> "$target"
  35 + added=$((added + 1))
  36 + fi
  37 +done < "$template"
  38 +
  39 +echo "[merge-gitignore] $target updated (+$added rules)"
... ...
skills/plan/erp-skeleton-gen/templates/docs-04-skeleton-template.md 0 → 100644
  1 +++ a/skills/plan/erp-skeleton-gen/templates/docs-04-skeleton-template.md
  1 +<!--
  2 +本文件是 docs/04-技术规范.md 的 § 一+ 大纲。
  3 +skeleton-gen 读取 docs/04 § 零(技术栈表)和 docs/01-需求清单/README.md(模块索引),
  4 +按下述大纲生成本项目专属的规范内容。LLM 不要原样拷贝提示文字,只保留 section 标题。
  5 +-->
  6 +
  7 +## 一、后端规范
  8 +
  9 +### 1.1 分层结构
  10 +<!-- 按 § 零 的后端框架定层次:controller/service/mapper 等;每层职责一句话。 -->
  11 +
  12 +### 1.2 命名约定
  13 +<!-- 包名(根包用【人工填写:根包名】占位)/ 类名 / 方法名 / 常量的大小写规则,含 2 个示例。 -->
  14 +
  15 +### 1.3 统一响应格式
  16 +<!-- 成功/失败的 JSON 结构,错误码段位划分。 -->
  17 +
  18 +### 1.4 异常处理
  19 +<!-- 全局异常处理器的使用方式;哪些异常要 catch,哪些禁止。 -->
  20 +
  21 +### 1.5 事务
  22 +<!-- 事务边界(通常 service 层);跨服务调用的禁止/替代方案。 -->
  23 +
  24 +### 1.6 认证
  25 +<!-- 基于 § 零 认证方案推导:token 生命周期、刷新机制、密钥管理。 -->
  26 +
  27 +## 二、前端规范
  28 +
  29 +### 2.1 目录约定
  30 +<!-- 基于 § 零 前端框架推导:api/components/pages/store/hooks/utils 的职责。 -->
  31 +
  32 +### 2.2 状态管理
  33 +<!-- 基于 § 零 状态管理技术推导:全局 vs 局部、服务端数据的存放。 -->
  34 +
  35 +### 2.3 请求封装
  36 +<!-- HTTP 客户端的拦截器、超时、错误重试、鉴权注入。 -->
  37 +
  38 +### 2.4 错误处理
  39 +<!-- 网络错误 / 业务错误 / 页面级错误的分层处理。 -->
  40 +
  41 +## 三、共同约定
  42 +
  43 +### 3.1 Git 提交
  44 +`<type>(<scope>): <subject> REQ-XXX-NNN`
  45 +
  46 +### 3.2 分页查询
  47 +<!-- 后端分页对象 + 前端分页组件,入参出参约定。 -->
  48 +
  49 +### 3.3 日期与金额
  50 +<!-- 后端类型(如 LocalDateTime / BigDecimal)+ 前端展示工具;金额精度约定。 -->
... ...
skills/plan/erp-skeleton-gen/templates/docs-06-static-template.md 0 → 100644
  1 +++ a/skills/plan/erp-skeleton-gen/templates/docs-06-static-template.md
  1 +<!--
  2 +本文件是 docs/06-UI交互规范.md 的 § 一~四 大纲(§ 五由 erp-downstream-gen 追加)。
  3 +skeleton-gen 读取 docs/04 § 零 和 docs/01 README,按下述大纲生成项目专属内容。
  4 +UI 细节(布局参数、颜色、组件选型)来自 § 零 前端 UI 组件库。
  5 +-->
  6 +
  7 +# 06-UI交互规范
  8 +
  9 +## 一、整体布局
  10 +
  11 +### 1.1 页面框架
  12 +<!-- 基于 § 零 UI 组件库(如 Ant Design Layout)描述整体骨架:Header / Sider / Content。 -->
  13 +
  14 +### 1.2 布局参数
  15 +<!-- 表格形式:Header 高度 / Sidebar 宽度 / 内边距 / 最小分辨率,给出默认值。 -->
  16 +
  17 +## 二、标准页面类型
  18 +<!-- 根据 docs/01 README 的模块索引推断业务可能出现的页面类型(通常列表/表单/详情/树形 4 类,根据项目裁剪)。 -->
  19 +
  20 +### 2.1 列表页
  21 +<!-- 顶部操作区 + 搜索栏 + 表格 + 分页,关键组件选型。 -->
  22 +
  23 +### 2.2 表单页
  24 +<!-- Drawer 还是独立页;校验时机;提交按钮位置。 -->
  25 +
  26 +### 2.3 详情页
  27 +<!-- Descriptions + Tabs 的组合方式。 -->
  28 +
  29 +### 2.4 树形管理页
  30 +<!-- 如项目有组织架构/权限树/分类树才生成此节,否则删除。 -->
  31 +
  32 +## 三、通用交互规则
  33 +
  34 +### 3.1 操作反馈
  35 +<!-- 成功/失败消息;危险操作二次确认;长耗时按钮 loading 态。 -->
  36 +
  37 +### 3.2 数据展示
  38 +<!-- 空状态 / 加载 / 异常 的统一组件与文案。 -->
  39 +
  40 +### 3.3 权限控制(前端)
  41 +<!-- 菜单级 / 按钮级 / 路由级的控制方式,关联后端 RBAC。 -->
  42 +
  43 +## 四、主题与颜色
  44 +<!-- 基于 § 零 UI 库的主题 token;主色 / 成功 / 警告 / 错误 色值。 -->
  45 +
  46 +## 五、页面清单(CC 生成)
  47 +(由 `erp-downstream-gen` 按模块追加段落)
... ...
skills/plan/erp-skeleton-gen/templates/docs-07-env-template.md 0 → 100644
  1 +++ a/skills/plan/erp-skeleton-gen/templates/docs-07-env-template.md
  1 +<!--
  2 +本文件是 docs/07-环境配置.md 的大纲。
  3 +skeleton-gen 基于 docs/04 § 零 技术栈表推导各节内容:
  4 + § 一 依赖清单 → 从技术栈的每一行技术推导运行时和构建依赖
  5 + § 二 端口约定 → 从后端/前端/数据库/缓存/反向代理 各取默认端口
  6 + § 四 常用命令 → 基于构建工具、包管理器、MR 工具给出开发者最常用命令
  7 +-->
  8 +
  9 +# 07-环境配置
  10 +
  11 +## 一、依赖清单
  12 +
  13 +<!-- 表格:| 层 | 依赖 | 版本 | 说明 |;覆盖 运行时 / 构建 / 容器 / CLI 工具。 -->
  14 +
  15 +## 二、端口约定
  16 +
  17 +<!-- 表格:| 服务 | 端口 | 说明 |;至少列 后端 HTTP / 前端 dev / 数据库 / 缓存 / 反代。 -->
  18 +
  19 +## 三、环境变量
  20 +
  21 +运行时凭据(数据库连接、JWT 密钥等)全部放在仓库根的 `.env.local`,不入 git。
  22 +字段清单与占位符见该文件,真实值由开发者本地填写。
  23 +
  24 +## 四、常用命令
  25 +
  26 +<!-- 表格:| 命令 | 说明 |;包含 启动后端 / 启动前端 / 打包 / 跑测试 / 重置测试数据 / 创建 MR。 -->
... ...
skills/plan/erp-skeleton-gen/templates/docs-09-structure-template.md 0 → 100644
  1 +++ a/skills/plan/erp-skeleton-gen/templates/docs-09-structure-template.md
  1 +<!--
  2 +本文件是 docs/09-项目目录结构.md 的大纲。
  3 +skeleton-gen 基于 docs/04 § 零 技术栈推导目录树:
  4 + § 二 后端目录 → 按后端框架的惯例(如 Spring Boot 的 src/main/java)
  5 + § 三 前端目录 → 按前端框架的惯例(如 Vite + React 的 src/)
  6 + § 四 docs 目录 → 沿用插件标准
  7 + § 五 命名约定 → 按后端语言的包/命名空间习惯
  8 +
  9 +模块划分参考 docs/01-需求清单/README.md 的模块索引,将业务模块落到代码目录。
  10 +-->
  11 +
  12 +# 09-项目目录结构
  13 +
  14 +## 一、仓库顶层
  15 +
  16 +<!-- 用代码块画出顶层目录树,含 CLAUDE.md / README.md / .env.local / .githooks / scripts / docs / sql / backend / frontend 等。 -->
  17 +
  18 +## 二、后端目录
  19 +
  20 +<!-- 基于后端框架的目录树;按 docs/01 README 的模块代码把业务模块列出(module/user/、module/order/ 等)。 -->
  21 +
  22 +## 三、前端目录
  23 +
  24 +<!-- 基于前端框架的目录树;pages/ 下按业务模块建子目录。 -->
  25 +
  26 +## 四、docs/ 结构
  27 +
  28 +```
  29 +docs/
  30 +├── 01-需求清单/ # REQ 卡片按模块分文件
  31 +├── 02-开发计划.md
  32 +├── 03-数据库设计文档.md
  33 +├── 04-技术规范.md
  34 +├── 05-API接口契约.md
  35 +├── 06-UI交互规范.md
  36 +├── 07-环境配置.md
  37 +├── 08-模块任务管理.md
  38 +├── 09-项目目录结构.md
  39 +├── 10-验收检查清单.md
  40 +└── superpowers/ # CC 运行时产物
  41 +```
  42 +
  43 +## 五、命名与放置约定
  44 +
  45 +<!-- 根包 / 命名空间用【人工填写:】占位;Controller / Service / Mapper / DTO / VO / 前端组件 / 前端页面 的放置规则。 -->
... ...
skills/plan/erp-skeleton-gen/templates/env-local-template 0 → 100644
  1 +++ a/skills/plan/erp-skeleton-gen/templates/env-local-template
  1 +DB_HOST=【人工填写:MySQL host,例如 localhost】
  2 +DB_PORT=【人工填写:MySQL port,默认 3306】
  3 +DB_USER=【人工填写:开发账号名】
  4 +DB_PASSWORD=【人工填写:对应密码】
  5 +DB_SCHEMA=【人工填写:schema 名,例如 erp_dev】
  6 +JWT_SECRET=【人工填写:JWT 签名密钥,256+ bit 随机串】
... ...
skills/plan/erp-skeleton-gen/templates/githooks-pre-push-template.sh 0 → 100644
  1 +++ a/skills/plan/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
... ...
skills/plan/erp-skeleton-gen/templates/gitignore-append-template 0 → 100644
  1 +++ a/skills/plan/erp-skeleton-gen/templates/gitignore-append-template
  1 +# ==== ERP 插件推荐忽略项(erp-skeleton-gen 追加) ====
  2 +# 本地运行时配置(含真实凭据,严禁入库)
  3 +.env.local
  4 +.env.*.local
  5 +
  6 +# Java / Maven
  7 +target/
  8 +*.class
  9 +
  10 +# Node / 前端构建产物
  11 +node_modules/
  12 +dist/
  13 +build/
  14 +coverage/
  15 +
  16 +# IDE
  17 +.idea/
  18 +.vscode/
  19 +*.iml
  20 +
  21 +# OS
  22 +.DS_Store
  23 +Thumbs.db
  24 +
  25 +# 日志
  26 +*.log
  27 +logs/
  28 +
  29 +# 插件运行时临时文件
  30 +.tmp/
  31 +*.raw
  32 +# ==== 结束 ====
... ...
skills/plan/erp-skeleton-gen/templates/scripts-setup-test-db-template.sh 0 → 100644
  1 +++ a/skills/plan/erp-skeleton-gen/templates/scripts-setup-test-db-template.sh
  1 +#!/usr/bin/env bash
  2 +# scripts/setup-test-db.sh — 数据库重置脚本:drop + create 空库。
  3 +# schema apply 由 Flyway 在 Spring Boot 启动时自动处理(见 docs/04 技术栈 + sql/migrations/V*.sql)。
  4 +# seed 数据由测试框架负责(Spring @Sql / Flyway R__seed.sql / data.sql)。
  5 +#
  6 +# 使用场景:
  7 +# - scripts/test.sh 开头:清空库,让 Spring 启动时 Flyway 从 V1 开始重放所有 migration
  8 +# - scripts/test.sh 结尾:清空库,避免测试遗留污染下次运行
  9 +# - 手动调试时:reset 到零状态
  10 +
  11 +set -euo pipefail
  12 +
  13 +source "$(dirname "$0")/../.env.local"
  14 +
  15 +MYSQL_CMD="mysql -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD}"
  16 +
  17 +echo "[setup-test-db] drop + create database ${DB_SCHEMA}"
  18 +$MYSQL_CMD -e "DROP DATABASE IF EXISTS \`${DB_SCHEMA}\`; CREATE DATABASE \`${DB_SCHEMA}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
  19 +
  20 +echo "[setup-test-db] done — schema will be applied by Flyway when Spring Boot starts"
... ...