erp-workflow
Claude Code 插件:ERP / 后端管理系统全流程开发框架。
把"从零到 N 个模块上线 + 前端整体阶段"的整个流程固化成 9 个 skill(Plan 阶段,交互式)+ 1 个 Workflow(workflows/coding.mjs,Coding 阶段,全自动静默)+ 1 个 reviewer agent + 4 个跨平台 Node 助手(lib/*.mjs)+ 25 份模板,让 CC 在 schema 演化用 Flyway migration、需求可追溯、纯本地 git 的前提下推进编码。Plan 阶段把全部需求/配置/前端约定问询前移(4 个闸门);Coding 阶段整体是单个 Workflow 脚本,子代理无法弹窗 → 结构性静默,后端按模块循环依次打里程碑 tag,所有后端模块打里程碑后进入前端整体阶段(以项目根 prototype/ 静态 HTML mockup 为页面权威)。
这个插件做什么
📋 阶段 A:规划(一次性,交互式 9 skill,入口 /erp-workflow:plan-start)
A0 project-init → A1 scope-lock(结构化 REQ 卡片 + secrets/commands 锁)
↓
⏸ 审阅 REQ → 重新运行 /plan-start
↓
A2 skeleton-gen → A3 db-design-gen(REQ → docs/03 + 回填依赖表,ERP 约定可确认)
↓
⏸ 审阅 docs/03 → 重新运行 /plan-start
↓
A4 db-init(docs/03 → V1 migration → 自动 apply 到本地 MySQL)
↓
A5 downstream-gen(docs/02 / docs/05 / docs/06 § 三 / docs/10)
↓ ⛔ docs/05 + docs/02 评审闸(必须确认)
A6 frontend-scope-lock(项目级 UI 约定 / design tokens / 组件库;prototype/ 门禁)
↓
⛔ Plan 终结硬闸(全部前移闸门通过才放行)
↓
用户显式 /erp-workflow:coding-start
🔁 阶段 B:编码(单个 Workflow 脚本 workflows/coding.mjs,全自动静默)
coding-start(瘦入口 skill)校验 Plan 终结闸 → 启动 Workflow
coding.mjs Router → 解析 docs/08 § 二/§ 三 + git tag,列出待跑模块
│
├─ B-后端(按模块循环,每模块一个里程碑 tag)
│ featureLoop(后端):spec → plan → tdd → verify → review(有界 5 轮修复)
│ testGate(backend) → 跨模块记录 → 模块报告 → milestone(本地 merge --no-ff + tag)
│
└─ B-前端(后端全部打里程碑后,整体 1 个里程碑 tag)
featureLoop(前端,FE-NN,路径限 frontend/) → testGate(frontend) → milestone
子代理无法弹窗 → 缺值即写阻塞点并 halt(终止态,非对话框);fail-fast 后等人工修复重跑 coding-start
首次使用
-
进入空项目目录并启动 Claude Code:
mkdir my-erp && cd my-erp claude --plugin-dir /path/to/erp-workflow-plugin -
Plan 阶段入口(一次性规划):
/erp-workflow:plan-startPlan 阶段三段式执行,中间有两个人工审阅断点:
-
第一段(首次运行):执行 A0 → A1(创建骨架 / 锁技术栈 / 填需求 / 生成 REQ 卡片骨架)后停下,等你审阅并补全
docs/01-需求清单/<module>/REQ-*.md(CC 已起草 req_id / title / goal / rules / constraints / acceptance;输入 / 输出 各含一句简述 + N 张示例字段表,模板原样复制由你按业务编辑;依赖表 / 依赖接口保留TBD(A3/A5 自动补)由后续 skill 回填——Plan 阶段第一个人工关口:业务范围) -
第二段(REQ 审阅完重新运行):继续 A2 → A3(生成骨架 / 从 REQ 正向设计
docs/03-数据库设计文档.md并回填 REQ 依赖表)后再次停下,等你审阅 docs/03 的表 / 字段 / 索引 / 外键(第二个人工关口:数据库 schema —— A4 会基于它翻译 DDL 并 apply 到 MySQL,所以这关口与 REQ 审阅同等重要) -
第三段(docs/03 审阅完重新运行):执行 A4 → A5 → A6(解析 docs/03 → 生成 V1 migration → 自动
DROP+CREATE本地 schema 并 apply → 生成下游文档 → docs/05 + docs/02 评审闸 → A6frontend-scope-lock锁定项目级前端约定 / design tokens / 组件库 + prototype/ 门禁),通过 Plan 终结硬闸 后再次停下
每次运行都会自动接上次停下的地方继续;中途可以随时关闭 CC,下次运行同样的命令即可恢复。Plan 阶段把全部需求/配置/前端约定问询前移:A1 锁结构化 REQ 字段 + secrets/account/包名/命名 + 各 stack 的 build/lint/unit/e2e 命令;A5 后强制评审 docs/05 + docs/02;A6 锁前端约定。这些闸门全过,Plan 终结硬闸 才放行。Plan 完成后不会自动进入编码,需要你手动运行 /erp-workflow:coding-start。
两个审阅断点的处理方式一致:A1 / A3 完成时 skill 已自动勾选
docs/08-模块任务管理.md § 一该阶段的全部子项 + 顶层;审阅是隐式的——你看完 REQ 卡片 / docs/03 后直接重新运行/plan-start,下次入口就会派发到下一阶段。如果审阅时发现需要修订,直接编辑 docs/01 / docs/03 即可,不依赖 docs/08 的勾选状态。
-
Coding 阶段入口(单个 Workflow,后端模块循环 → 前端整体阶段,全自动静默):
/erp-workflow:coding-startPlan 全部完成后由你显式触发。coding-start是一个瘦入口 skill:校验 Plan 终结闸(docs/08 § 一 全勾、git 在默认分支、工作树干净)后,调用Workflow({scriptPath:"${CLAUDE_PLUGIN_ROOT}/workflows/coding.mjs", ...})启动整个编码阶段,然后告知"已在后台启动,跑完或 halt 时通知"。所有编码逻辑都在coding.mjs里,不再有 B 阶段 skill 链。
coding.mjs 的阶段(子代理执行,无弹窗):
-
Router:扫描 docs/08 § 二/§ 三 里程碑字段 + 本地
git tag -l,产出结构化模块清单({id, done, reqs[], feItems[]}),过滤出待跑模块。docs/08 字段与 git tag 不一致 → halt 报错(绝不静默假设完成状态)。 -
后端模块循环(顶层
for module,fail-fast):每模块依次featureLoop(reqs, 'backend')→(spec → plan → tdd → verify → review,有界 5 轮修复,第 5 轮仍 request-changes 即 halt)→testGate(backend)(红色自动重试 1 次防 flaky,仍红则 halt)→ 跨模块改动记录 → 模块报告 → milestone(本地git merge --no-ff进默认分支 + 打milestone/<id>tag + 回写 docs/08 § 二)。 -
前端阶段(后端全部打里程碑后):
featureLoop(feItems, 'frontend')(FE-NN,路径限frontend/,review 调统一code-revieweragent 附加前端 7 维 checklist)→testGate(frontend)→ milestone(docs/08 § 三 整体里程碑)。 -
halt 终止态:子代理缺值不弹窗 → 写阻塞点并抛错;整阶段 fail-fast,halt 后停下等人工修复,修好重跑
/erp-workflow:coding-start从断点续跑。
docs/08 § 二 每后端模块占一行 bullet,§ 三 是前端阶段整体段,完成信号统一由本地 git tag -l 'milestone/<id>' 判定。
-
中途恢复:任何时候重跑
/erp-workflow:coding-start——coding.mjs的 Router 根据 docs/08 § 二/§ 三 里程碑字段 + 本地 git tag 跳到当前该做的模块/阶段。
目录结构
erp-workflow-plugin/
├── .claude-plugin/
│ └── plugin.json # 插件清单,声明 ./skills(9 skill)
├── README.md # 本文档
├── workflows/
│ └── coding.mjs # 阶段 B:整个编码阶段编排为单个静默 Workflow
├── lib/ # 跨平台 Node 助手(ESM,node:test 单测)
│ ├── merge-gitignore.mjs # .gitignore 逐行判重合并(替代 merge-gitignore.sh)
│ ├── render.mjs # 字面量安全模板渲染(替代 render.sh)
│ ├── validate-ddl.mjs # docs/03 ↔ DDL 5 维校验(替代 validate.sh)
│ ├── apply-ddl.mjs # 安全 env 解析 + mysql apply(替代内联 mysql bash)
│ └── *.test.mjs # 各助手的 node:test 单测
├── agents/
│ └── code-reviewer.md # 统一 reviewer(coding.mjs review stage 调用,phase 选维度集)
└── skills/ # 阶段 A:9 个 skill(扁平,无中间层)
├── plan-start/ # A 阶段入口 + Plan 终结硬闸
├── project-init/ # A0
├── scope-lock/ # A1
├── skeleton-gen/ # A2
├── db-design-gen/ # A3
├── db-init/ # A4
├── downstream-gen/ # A5
├── frontend-scope-lock/ # A6
└── coding-start/ # B 阶段瘦入口(启动 coding.mjs)
Hook 清单(0 个)
本插件不再注册任何 hook。原"跨模块改动留痕"hook(log-cross-module.sh)已删除,其职责由 workflows/coding.mjs 的 cross-module stage 在模块循环内承担。
Skill 清单(9 个,扁平于 skills/)
入口(2 个)
| Skill | 作用 | 谁调用 |
|---|---|---|
plan-start |
A 阶段入口 + Plan 终结硬闸。读 docs/08 § 一 找第一个未勾 A 子项 → 派发对应 A skill(含 A6 → frontend-scope-lock);A 全部完成时校验全部前移闸门(REQ 真实数据、docs/07 secrets 全锁、docs/04 § 零 命令齐、docs/05+02 已评审、A6 前端 scope 已锁),全过才提示运行 /erp-workflow:coding-start,否则指出缺口不放行 |
用户手动 /erp-workflow:plan-start
|
coding-start |
B 阶段瘦入口(allowed-tools: Read Glob Workflow)。校验 Plan 终结闸(docs/08 § 一 全勾、git 在默认分支、工作树干净)→ 读 docs/08 § 二/§ 三 + git tag -l 'milestone/*' 概述进度 → 调用 Workflow({scriptPath:"${CLAUDE_PLUGIN_ROOT}/workflows/coding.mjs", args:{projectRoot}}) 启动整个编码阶段 → 告知"已在后台启动" |
用户手动 /erp-workflow:coding-start
|
Plan 阶段 A skill(7 个 = A0~A6,均由 plan-start 按 docs/08 § 一 顺序派发)
| # | Skill | 作用 | 流程中谁调用 |
|---|---|---|---|
| A0 | project-init |
• 依赖检查:检测 git / mysql / node 是否在 PATH,缺失则按 OS(darwin/win32/linux)打印安装指引并 halt(不自动 brew/apt 安装) • 空目录初始化:用 Read/Write/Glob 工具拷模板创建 CLAUDE.md / docs/01/index.md / docs/08 • git init
|
plan-start |
| A1 | scope-lock |
• 引导填项目概述 / 技术栈 / 需求索引 • 按 docs/01-需求清单/<module>/{_module.md, REQ-*.md} 子目录结构生成结构化 REQ 卡片(每字段一行:字段名/类型/必填/校验/业务规则/示例值,示例值必须替换为真实约束)• A1 终结校验:REQ 字段非空且非占位、docs/07 secret/account/包名/namespace 字段清单已锁、各 stack 的 build/lint/unit/e2e 命令写入 docs/04 § 零;缺失则在此(Plan 期)用 AskUserQuestion 问清• 用 node ${CLAUDE_PLUGIN_ROOT}/lib/render.mjs 渲染模板• 停下等人工审阅,审阅完毕用 /plan-start 续进 A2 |
A0 |
| A2 | skeleton-gen |
• 生成架构文档:docs/04 § 一+ / docs/06 / docs/07 / docs/09 • 生成跨平台工具脚本: scripts/*.mjs、.env.local(无 chmod)• 创建 sql/migrations/ 空目录(Flyway 准备)• 用 node ${CLAUDE_PLUGIN_ROOT}/lib/merge-gitignore.mjs 合并 .gitignore(逐行判重) |
plan-start |
| A3 | db-design-gen |
• A3 起始用 AskUserQuestion 确认 ERP 约定(主键策略 / 租户列 / 列前缀规则,默认值可覆盖),结果写 docs/04 + CLAUDE.md• 从 docs/01 REQ 卡片正向设计 docs/03-数据库设计文档.md(schema SSoT)• 回填 REQ 卡片依赖表( TBD(A3 自动补) → 实际表名)• 停下等人工审阅 docs/03,审阅完毕用 /plan-start 续进 A4 |
A2 |
| A4 | db-init |
• LLM 解析 docs/03 → sql/migrations/V1__initial_schema.sql(DDL only)• node ${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs 校验 DDL ↔ docs/03(5 维:表/列名/列类型/索引/FK),fail-closed• node ${CLAUDE_PLUGIN_ROOT}/lib/apply-ddl.mjs .env.local V1.sql(安全 env 解析 + mysql2 apply,无 shell-source) |
A3 |
| A5 | downstream-gen |
• 一次性生成 docs/02 / docs/05 / docs/06 § 三 / docs/10 • 回填 REQ 卡片依赖接口( TBD(A5 自动补) → 实际 endpoint)• 追加模块清单到 docs/08 § 二 • docs/05 + docs/02 评审闸:用 AskUserQuestion 让用户确认 API 端点/字段无误 + 构建顺序可接受,未确认不勾 A5• 最终占位符 + 结构残留扫描 |
A4 |
| A6 | frontend-scope-lock |
• user-invocable:false,由 plan-start 在 A5 后派发• prototype/ 门禁:项目根 prototype/*.html 缺失则 AskUserQuestion 要求补齐(Plan 期可问)• 从 prototype + docs/01 + docs/05/06 提炼项目级 UI 约定 / design tokens / 组件库选型,逐一 AskUserQuestion 确认• 写入 docs/06(UI 交互规范)+ docs/04(前端栈) |
plan-start |
Coding 阶段(1 个 Workflow,非 skill)
整个编码阶段不再是 skill 链,而是单个 Workflow 脚本 workflows/coding.mjs(由瘦入口 skill coding-start 启动)。子代理无法弹窗 → 缺值即写阻塞点并 halt(结构性静默)。
coding-start(skill)校验 Plan 终结闸 → Workflow({scriptPath:"…/workflows/coding.mjs"})
│
▼ coding.mjs(各 stage 派 agent 子代理执行,无弹窗)
Router ── 解析 docs/08 § 二/§ 三 + git tag → 结构化模块清单(schema 校验)
│ docs/08 字段与 git tag 不一致 → halt
│
顶层 for module(fail-fast,halt 后 break):
│
├─ 后端:featureLoop(module.reqs, 'backend')
│ spec → plan → tdd → verify → reviewWithFixLoop(有界 5 轮:
│ review(code-reviewer) approve → 过;request-changes → fix → 重审;
│ 第 5 轮仍未过 → throw HALT)
│ → testGate(backend)(红色自动重试 1 次防 flaky,仍红 → HALT)
│ → 跨模块改动记录 → 模块报告
│ → milestone(git merge --no-ff 进默认分支 + tag milestone/<id> + 回写 docs/08 § 二)
│
└─ 前端(module.feItems 非空时,后端全部打里程碑后):
featureLoop(feItems, 'frontend')(FE-NN,路径限 frontend/,
review 调 code-reviewer + 前端 7 维 checklist)
→ testGate(frontend) → milestone(docs/08 § 三 整体里程碑)
coding.mjs 内部用 pipeline 把后端/前端功能链同构为一个 featureLoop(items, phase)(替代旧 10 个克隆 skill);reviewWithFixLoop 有界 5 轮;testGate 失败自动重试 1 次。完成信号统一由本地 git tag -l 'milestone/<id>' 判定,不依赖任何远程仓库 / push。
旧 B 阶段的 15 个 skill(
module-start/feature-*/frontend-start/fe-feature-*/test-gate/module-report/milestone-tag)与 2 个横切 skill(interrupt-check/cross-module-log)已删除,其意图融入coding.mjs的各 stage prompt 与lib/助手;中断/跨模块留痕由 workflow 的 halt 终止态 +crossModulePromptstage 承担(替代被删 hook)。
Agent 清单(1 个)
| Agent | 用途 | 谁调用 |
|---|---|---|
code-reviewer |
统一 reviewer。phase=backend 跑通用代码审查维度;phase=frontend 附加前端 7 维 checklist(prototype 一致性 / design tokens / a11y / 响应式 / 业务校验前端复刻 / API 一致性 / 状态机覆盖,主观维度仅标记明显问题不触发 request-changes)。非交互,返回结构化 verdict,绝不弹窗 |
workflows/coding.mjs 的 review stage:agent(..., {agentType:'code-reviewer'})
|
Templates 清单(25 份)
| 所属 Skill | 模板文件 | 用途 |
|---|---|---|
| project-init | CLAUDE-template.md |
项目根的 CLAUDE.md(4 条通用准则 + ERP 专属约定) |
| project-init | docs-01-index-template.md |
需求清单索引骨架,等用户填模块表 |
| project-init | docs-04-stack-template.md |
docs/04 § 零 默认技术栈总览(零槽位,拷即可) |
| project-init | docs-08-initial-template.md |
工作流进度文件骨架(Plan A0~A6 checkbox) |
| scope-lock | req-card-template.md |
单张 REQ-XXX-NNN 卡片骨架(结构化字段表:字段名/类型/必填/校验/业务规则/示例值,示例值须替换为真实约束) |
| scope-lock | _module-template.md |
模块子目录的 _module.md 模块头(模块代码-名 / 简述 / 依赖模块 TBD / 涉及表 TBD) |
| scope-lock | config-vars-template.yaml |
仓库根 config-vars.yaml 骨架(跨栈中立):非敏感项目级配置(包名/端口/前端包名/初始账号)+ secrets_ref 键名引用 .env.local;A1 E.2 锁定 |
| skeleton-gen | docs-04-skeleton-template.md |
docs/04 § 一+ 编码规范大纲(HTML 注释引导 LLM) |
| skeleton-gen | docs-06-static-template.md |
docs/06 § 一~二 大纲(通用交互 + Design Tokens;布局以 prototype/ 为权威) |
| skeleton-gen | docs-07-env-template.md |
docs/07 环境配置大纲(只记规则/约定,不记具体值;配置值指向 config-vars.yaml + .env.local) |
| skeleton-gen | docs-09-structure-template.md |
docs/09 目录结构大纲 |
| skeleton-gen | scripts-setup-test-db-template.mjs |
跨平台 drop + create 空库脚本(安全 env 解析,无 shell-source);schema apply 交给 Flyway |
| skeleton-gen | scripts-test-template.mjs |
test.mjs 骨架(命令槽位 {{TEST_CMD}} / {{E2E_CMD}},spawnSync(shell:true) 跨平台执行) |
| skeleton-gen | env-local-template |
凭据模板(DB_* + JWT_SECRET);A2 据 config-vars.yaml secrets_ref 追加项目专属 secret 键 |
| skeleton-gen | gitignore-append-template |
插件推荐忽略项(.env.local、.tmp/、构建产物等) |
| skeleton-gen | styles-tokens-template.css |
前端 design tokens CSS 变量骨架 |
| db-design-gen | docs-03-header-template.md |
docs/03 数据库设计头部 |
| db-design-gen | docs-03-table-template.md |
docs/03 单表小节模板 |
| downstream-gen | docs-02-template.md |
docs/02 开发计划 |
| downstream-gen | docs-05-header-template.md |
docs/05 API 契约头部 |
| downstream-gen | docs-05-endpoint-template.md |
docs/05 单接口小节 |
| downstream-gen | docs-06-module-pagelist-template.md |
docs/06 § 三 单模块页面清单 |
| downstream-gen | docs-08-module-row-template.md |
docs/08 § 二 单模块 bullet 行 |
| downstream-gen | docs-10-header-template.md |
docs/10 验收清单(项目级 SOP,零槽位 + 引用指针) |
| frontend-scope-lock | fe-scope-template.md |
A6 前端 scope:UI 约定 / design tokens / 组件库 / 每个 FE-NN 设计决策表 |
流程使用情况:所有模板都被对应 skill 的 SKILL.md 引用,没有孤儿模板。Coding 阶段的渲染/校验逻辑改由 lib/*.mjs 助手承担,不再用 skill 模板。
前置依赖
-
Node.js ≥ 18:
lib/*.mjs助手 +workflows/coding.mjs+ 生成进目标项目的scripts/*.mjs均为 ESM;CC 运行时自带。A0project-init检测 git / mysql / node 在 PATH,缺失则按 OS 打印安装指引并 halt(不自动安装) -
MySQL 8.x 实例已就绪(推荐本地 /
*.localhost;A4db-init的安全守护要求 host 在白名单且 schema 名含test/dev/local,避免误删生产库) -
mysql2(目标项目侧):A4db-init经lib/apply-ddl.mjs用 mysql2 连接 + 安全 env 解析 apply V1;生成的scripts/setup-test-db.mjs在测试闸门前后 drop+create 空库 -
Spring Boot + Flyway(必需):pom.xml 声明
flyway-core+flyway-mysql;Spring 启动时自动 applysql/migrations/V*.sql。本插件生成的setup-test-db.mjs只清库,schema 必须由 Flyway 应用 -
本地 git 仓库(纯本地,无需远程):A0
project-init执行git init;B 阶段每模块由coding.mjs的 milestone stage 本地git merge --no-ff进默认分支并git tag -a milestone/<id>,完成信号由git tag -l判定。不依赖任何远程仓库 / push / GitLab -
本地可运行
mvn test/pnpm test:测试命令由 A1 写入 docs/04 § 零,生成的scripts/test.mjs由skeleton-gen产出,coding.mjs的 testGate stage 调用
设计原则
参见 project-init/templates/CLAUDE-template.md 末尾的「🧭 通用工作准则」4 条:① Think Before Coding ② Simplicity First ③ Surgical Changes ④ Goal-Driven Execution。
最关键的 1 条:"所有测试与验证派发到全新子会话执行,主会话只接收结构化结论"——避免主会话被测试输出污染,并让测试结果作为独立证据存档。