Name Last Update
.claude-plugin Loading commit data...
agents Loading commit data...
docs Loading commit data...
hooks Loading commit data...
lib Loading commit data...
skills Loading commit data...
workflows Loading commit data...
.gitattributes Loading commit data...
.gitignore Loading commit data...
README.md Loading commit data...

README.md

erp-workflow

Claude Code 插件:ERP / 后端管理系统全流程开发框架。

从零到 N 模块上线的 ERP 全流程开发框架:Plan 阶段交互、Coding 阶段静默 Workflow。

这个插件做什么

📋 阶段 A:规划(一次性,交互式;入口 /erp-workflow:plan-start 派发 A0~A5 共 6 个 skill)

   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/08 § 三 FE 清单;prototype/ 门禁)
                          ↓ ⛔ docs/05 + docs/02 评审闸(必须确认)
              ⛔ Plan 终结硬闸(全部前移闸门通过才放行)
                          ↓
                  用户显式 /erp-workflow:coding-start

🔁 阶段 B:编码(单个 Workflow 脚本 workflows/coding.mjs,全自动静默)

   coding-start(瘦入口 skill)校验 Plan 终结闸 → 启动 Workflow

   coding.mjs Router → 解析 docs/08 § 二/§ 三 + milestone/* / req-done/* git tag,列出待跑模块
     │
     ├─ B-后端(按依赖波次推进模块,每模块一个里程碑 tag;模块内功能链仍顺序 for-await)
     │    · 调度:LLM 只输出模块间依赖边(fk/api/seed/order…,宁串勿并、证据可查),
     │      JS 做确定性拓扑波次(Kahn);同波次 ≥2 模块才启用并行机器,宽 1 波次走现行主根路径
     │    · lane 隔离:并行模块各占 lane worktree(独立 index,commit 不争锁)+ lane 测试库
     │      (ERP_TEST_DB_SCHEMA 打穿到 Spring)+ 专属 migration 版本段(版本号只保唯一、
     │      不保连续不保合并序,Flyway 须 out-of-order: true);milestone/RESUME 与起栈类 stage 全局互斥
     │    · 降级:任何并行机制失败(调度违例/环/lane DB 不支持/worktree 建失败)一律 fail-open
     │      回现行串行路径,绝不因并行机制 halt;args.parallel 缺省或 modules:false 即全串行
     │    runBranchSetup(module-<id>)  ← JS 编排:detect default → wt clean → exists? →
     │                                   checkout/create → confirm HEAD(5 微 agent)
     │    → featureLoop(后端):spec → plan → tdd → verify → review(有界 5 轮修复,
     │      throw 自然冒泡到模块主循环 try → fail-fast)
     │    → testGate(backend)
     │    → Seed stage(testGate green 后:生成 sql/seed/NN__<module>.sql 演示种子
     │      + 冷起栈真跑验证:复制源库→副本→Flyway apply 新迁移→seed-demo-data.mjs 注入
     │      →按 -- expect: 行对账→drop-test-db.mjs 删副本)
     │    → runCrossModule(JS 编排:diff → 分类 → 写日志)
     │    → reportPrompt(LLM 12 节叙述)
     │    → runMilestone(JS 编排:wt → default → 已合入? → merge → 字段当前值?
     │                  → 写字段 → tag 已存在? → 打 tag → 报告 § ⑫ 当前值? → 替换占位;
     │                  10+ 微 agent,全部跳过/分支条件由 JS 判定,幂等)
     │
     └─ B-前端(后端全部打里程碑后,整体 1 个里程碑 tag)
          runBranchSetup(frontend-phase)
          → 静态原型渲染门 preview(前端段开头:Playwright headless 逐页渲染 prototype/**/*.html 本身
            → 截图归档为可视化基线 + 跑原型自带交互点击冒烟 + 捕获 JS/console 错误。与行为门正交——
            前者测静态原型、后者测实现。硬门:原型渲染失败 / 脚本未捕获异常(jsErrors)→仲裁(只许 retry/halt),
            halt 即停下等人工回 plan/add-req 修原型后重跑(coding 不改原型源码);console.error 仅 advisory;
            唯环境未就绪(Playwright/浏览器缺失)才 retry→仲裁降级。无 prototype/ 则跳过)
          → 前端骨架占位阶段(router 全量 lazy 路由表 + FeStub 占位,保证中途任意时刻可构建可起;
            含 e2e 基线脚手架:Playwright globalSetup 按注入时序注种子 + admin 登录 storageState;
            含单测基线:vitest include 限定 tests/**/*.test.*——单测一律 frontend/tests/ 镜像 src/,
            交付源码 frontend/src/ 内禁测试文件,同后端 src/main↔src/test 物理分离)
          → featureLoop(前端,FE-NN,路径限 frontend/):spec → plan → tdd → verify →
            review 循环(静态验收,approve 即打 req-done/<FE>)
          → 阶段级行为门 behavior(整个前端阶段只跑一次:起全栈+演示种子+sentinel,
            按全部 FE spec 聚合的作用域并集枚举路由,交互/文字/样式三层断言;交互失效
            /sentinel 错/样式违规(非 token 色、横向溢出、控件重叠等)转可 fix must-fix
            →fix→单测复验→重跑门(≤3 轮),软文字按来源仲裁,green 才放行)
          → testGate(frontend,全量回归 vitest+playwright,兜底行为 fix 引入的回归)
          → runMilestone(milestone/frontend-phase)

          · 前端 jsdom-only 重叠(可选,parallel.frontendOverlap,缺省关):前端**不依赖后端**的部分
            (骨架 + spec/plan + tdd 的 jsdom 任务 + vitest verify)在独立前端 worktree 与后端波次**并发**,
            打中间 tag fe-code-done/<FE>;后端全部 done 后 reconcile(合 default→frontend-phase)+ phase2
            (e2e 任务 + review + req-done + 行为门 + 测试闸 + 里程碑,主根全栈)。重叠期前端无栈/无固定
            端口/无 DB,端口与 lane 不变量全保住;缺省关 / phase1 失败 / 后端未全 done 回退现行终波路径。
            设计:docs/superpowers/plans/2026-06-15-frontend-overlap-jsdom.md

   子代理无法弹窗 → 缺值即写阻塞点并 halt(终止态,非对话框);fail-fast 后等人工修复重跑 coding-start

   续跑 handoff:主循环结束(halt 或全完成)时 best-effort 追加 docs/superpowers/RESUME.md
     (上次 halt 原因 + 本次自主默认假设 + 待跑模块),供下次 coding-start 步骤 3.5 复盘;
     进度真值仍是 git tag,RESUME.md 仅定向,写失败绝不阻断主流程

首次使用

  1. 进入空项目目录并启动 Claude Code

    mkdir my-erp && cd my-erp
    claude --plugin-dir /path/to/erp-workflow-plugin
    
  2. Plan 阶段入口(一次性规划):

    /erp-workflow:plan-start
    

    Plan 阶段两段式执行,中间有一个人工审阅断点(docs/03 数据库 schema):

  • 第一段(首次运行):执行 A0 → A1 → A2 → A3(创建骨架 / 锁技术栈 / 填需求 / 生成 REQ 卡片 / 生成项目骨架 / 从 REQ 正向设计 docs/03-数据库设计文档.md 并回填 REQ 依赖表)后停下,等你审阅 docs/03 的表 / 字段 / 索引 / 语义引用关系(人工关口:数据库 schema —— A4 会基于它翻译 DDL 并 apply 到 MySQL)。A1 的 REQ 卡片由 CC 据 index.md 填 6 个占位、字段表按模板原样复制,不再单独停下审阅
  • 第二段(docs/03 审阅完重新运行):执行 A4 → A5(解析 docs/03 → 生成 V1 migration → bootstrap-source-flyway 把源库建立成 Flyway 托管态(建库 + apply V1 + 写 flyway 历史;已托管则幂等跳过)→ 生成下游文档 → docs/05 + docs/02 评审闸 → prototype/ 门禁 + 推导 FE 清单写 docs/08 § 三),通过 Plan 终结硬闸 后再次停下(前端布局/交互以 prototype/ 为权威,不另设 UI 规范文档)

Plan 完成后不会自动进入编码,需手动 /erp-workflow:coding-start。

  1. Coding 阶段入口(单个 Workflow,后端模块循环 → 前端整体阶段,全自动静默):

    /erp-workflow:coding-start
    

    Plan 全部完成后由你显式触发;详细职责见下方 Skill 清单。详细流程见上方阶段 B 流程图。

  2. 中途恢复:任何时候重跑 /erp-workflow:coding-start——coding.mjs 的 Router 根据 docs/08 § 二/§ 三 里程碑字段 + 本地 milestone/* / req-done/* tag 跳到当前该做的模块/阶段。

目录结构

erp-workflow-plugin/
├── .claude-plugin/
│   └── plugin.json                  # 插件清单,显式列出 11 个 skill 路径
├── README.md                        # 本文档
├── workflows/
│   └── coding.mjs                   # 阶段 B:整个编码阶段编排为单个静默 Workflow
├── lib/                             # 跨平台 Node 助手(ESM,node:test 单测)
│   ├── validate-ddl.mjs             # docs/03 ↔ DDL 4 维校验(替代 validate.sh)
│   ├── yaml-config.mjs              # config-vars.yaml 极简 YAML 读取(2 层 map + 标量)
│   ├── apply-ddl.mjs                # 解析 config-vars.yaml database: 段 + mysql2 apply
│   ├── req-ledger.mjs               # 需求台账:docs/01 REQ + docs/08 §三 FE + prototype/ 原型快照 内容哈希,scan/commit 识别新增/变更(add-req 用)
│   └── *.test.mjs                   # 各助手的 node:test 单测
├── agents/
│   └── code-reviewer.md             # 统一 reviewer(coding.mjs review stage 调用,phase 选维度集)
└── skills/                          # 按阶段分组(slug 不变,由 SKILL.md frontmatter name 决定)
    ├── plan/                        # 阶段 A:10 个 skill(入口 + A0~A5 + 增量入口 + 微改通道×2)
    │   ├── plan-start/              # A 阶段入口 + Plan 终结硬闸
    │   ├── project-init/            # A0
    │   ├── scope-lock/              # A1
    │   ├── skeleton-gen/            # A2
    │   ├── db-design-gen/           # A3
    │   ├── db-init/                 # A4
    │   ├── downstream-gen/          # A5(含前端 FE 清单推导,原 A6 已并入)
    │   ├── add-req/                 # 增量需求入口(Plan 完结后追加/修改需求,经 req-ledger 哈希台账只跑增量)
    │   ├── quick-field/             # 字段微改快速通道(加列 + 界面呈现:保 SSoT 跳流程,不作废 tag、不重跑 coding)
    │   └── quick-ui/                # 前端小功能快速通道(已有页面局部小交互,只消费既有端点:直改 frontend/,不作废 tag、不重跑 coding)
    └── coding/                      # 阶段 B:1 个 skill(瘦入口)
        └── coding-start/            # 启动 workflows/coding.mjs

Skill 清单(11 个)

入口(5 个)

Skill 作用 谁调用
plan-start A 阶段入口 + Plan 终结硬闸。读 docs/08 § 一 找第一个未勾 A 子项 → 派发对应 A skill;A 全部完成时校验 4 项前移闸门(REQ 真实数据、config-vars.yaml 全部配置(含 DB 凭据 / 密钥)全锁、docs/04 § 零 命令齐、docs/05+02 已评审),全过才提示运行 /erp-workflow:coding-start,否则指出缺口不放行 用户手动 /erp-workflow:plan-start
coding-start B 阶段瘦入口allowed-tools: Read Glob Workflow Bash(git ...))。校验 Plan 完成态(docs/08 § 一 全勾)+ 取得 projectRoot(git 就绪由 coding.mjs runBranchSetup 在运行时把守)→ 读 docs/08 § 二/§ 三 + git tag -l 'milestone/*' 概述阶段进度(Workflow Router 再用 req-done/* 判定功能级 resume)→ 若有 docs/superpowers/RESUME.md 则读末尾条目复盘上次 halt 原因/待跑模块 → 调用 Workflow({scriptPath:"${CLAUDE_PLUGIN_ROOT}/workflows/coding.mjs", args:{projectRoot}}) 启动整个编码阶段 → 告知"已在后台启动" 用户手动 /erp-workflow:coding-start
add-req 增量需求入口(Plan 完结后追加 / 修改需求时用)。node lib/req-ledger.mjs scan 用内容哈希台账(.req-ledger.json)识别 docs/01 REQ 卡片 + docs/08 §三 FE 行的新增 / 变更;只对增量做 A3-delta(写新 V_n migration + 同步 docs/03,绝不改 V1)+ A5-delta(补 docs/05 端点 / docs/02 顺序 / docs/08 模块行 / FE 行),并 git tag -d 作废变更单元已有的 req-done/*(及所属 milestone/*,复位 docs/08 里程碑字段),使 coding.mjs Router 只重跑增量。首跑无台账则先建基线。 用户手动 /erp-workflow:add-req
quick-field 字段微改快速通道(已完成需求追加纯展示/录入字段时替代 add-req 全流程)。保 schema SSoT 不缩水(V_n ALTER + docs/03 同步 + validate-ddl fail-closed),后端/前端代码由主会话直改(grep 清单 + 轻量编译/lint 自检),台账 req-ledger commit 重基线但绝不作废任何 req-done/milestone tag——Router 视一切已完成,不重跑 coding.mjs(不冷起栈、不跑测试门/行为门)。代价是字段未过行为验收:登记到 docs/08 §四 待验清单,攒批人工验收。仅限追加式 ADD COLUMN(可空/带 DEFAULT)+ 既有链路多带一个字段;超界即停下回落 /add-req 用户手动 /erp-workflow:quick-field
quick-ui 前端小功能快速通道(quick-field 的姊妹通道,已完成页面追加局部小交互时替代 add-req)。代码由主会话直改 frontend/(lint/类型检查 + grep 自检,不起栈、不跑行为门/e2e),可见布局变化同步 prototype/、按需更新 docs/08 §三 FE 行文字,台账 req-ledger commit 重基线但绝不作废任何 tag——前端阶段不重跑。待验条目登记 docs/08 §四。硬边界:纯前端、只消费 docs/05 既有端点、不新增页面/路由/FE 行;超界即停下回落 /add-req 用户手动 /erp-workflow:quick-ui

Plan 阶段 A skill(A0~A5,共 6 个)

# Skill 作用 流程中谁调用
A0 project-init 依赖检查:检测 git / mysql / node 是否在 PATH,缺失则按 OS 自动安装,装不上再停下提示用户
• 空目录初始化:用 Read/Write/Glob 工具拷模板创建 CLAUDE.md / docs/01/index.md / docs/08
git init
plan-start
A1 scope-lock • 引导填项目概述 / 技术栈 / 需求索引
• 按 docs/01-需求清单/<module>/{_module.md, <req_id>.md} 子目录结构生成 REQ 卡片(req_id = <模块代码>-<子模块代码>-<功能名>,如 USR-UserInfo-Login;CC 据 index.md 填 {{req_id/title/goal/rules/constraints/acceptance}} 6 个占位,模板其余内容含输入/输出示例字段表原样复制)
A1 终结校验:REQ 6 个占位均填真实数据、无 {{ 残留、config-vars.yaml 全部配置(包名 / 端口 / 初始账号 + DB 凭据 / 密钥占位)已锁、各 stack 的 build/lint/unit/e2e 命令写入 docs/04 § 零;缺失则在此(Plan 期)用 AskUserQuestion 问清(敏感凭据由用户自填,不进会话)
• 据模板直接 Write 生成 _module.md / <req_id>.md
• 终结校验通过后自动调用 Skill(skeleton-gen) 进入 A2(不停下)
A0
A2 skeleton-gen • 生成架构文档:docs/04 § 一+
• 生成跨平台工具脚本:scripts/*.mjs无 chmod;凭据 / 配置统一在 A1 产出的 config-vars.yaml)
• 据 gitignore-append-template 用 Read/Write 并入项目 .gitignore
plan-start
A3 db-design-gen • 套用固定 ERP 约定(列前缀 i/s/t/b/diIncrement 主键、sBrandsId/sSubsidiaryId 租户列)+ 每表自动补标准列(11 列基础:iIncrement/sId/sBrandsId/sSubsidiaryId/sMakePerson/tCreateDate/tUpdateDate/iOrder/bInvalid/sFormId/sMemo;主表额外加 4 审核列 bCheck/tCheckDate/sCheckPerson/sStatus(共 15 列),从表额外加 sParentId 紧随 sId(共 12 列);其中 sId/sBrandsId/sSubsidiaryId/sMakePerson/sCheckPerson 为 varchar(50) NOT NULL)从 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(4 维:表/列名/列类型/索引),fail-closed
node ${CLAUDE_PLUGIN_ROOT}/lib/apply-ddl.mjs config-vars.yaml V1.sql(读取 config-vars.yaml database: 段 + mysql2 apply)
A3
A5 downstream-gen • 一次性生成 docs/02 / docs/05
• 回填 REQ 卡片依赖接口(TBD(A5 自动补) → 实际 endpoint)
• 追加模块清单到 docs/08 § 二
docs/05 + docs/02 评审闸:用 AskUserQuestion 让用户确认 API 端点/字段无误 + 构建顺序可接受,未确认不勾 A5
prototype/ 门禁 + 推导 FE 清单写 docs/08 § 三(原 A6 已并入;无 prototype 则问「无前端」→ § 三 留空)
• 最终占位符 + 结构残留扫描
A4

Coding 阶段(1 个 Workflow,非 skill)

整个编码阶段不再是 skill 链,而是单个 Workflow 脚本 workflows/coding.mjs(由瘦入口 skill coding-start 启动)。子代理无法弹窗 → 缺值即写阻塞点并 halt(结构性静默)。完整流程见本文档顶部「阶段 B:编码」流程图。

Agent 清单(1 个)

Agent 用途 谁调用
code-reviewer 统一 reviewer。phase=backend 跑通用代码审查维度;phase=frontend 附加前端 8 维 checklist(prototype 一致性 / design tokens / a11y / 响应式 / 业务校验前端复刻 / API 一致性 / 状态机覆盖 / 测试文件隔离,主观维度仅标记明显问题不触发 request-changes)。非交互,返回结构化 verdict,绝不弹窗 workflows/coding.mjs 的 review stage:agent(..., {agentType:'erp-workflow:code-reviewer'})(必须带 erp-workflow: 插件命名空间——裸 code-reviewer 会与其它插件的同名 agent 歧义)

Templates 清单(19 份)

所属 Skill 模板文件 用途
project-init CLAUDE-template.md 项目根的 CLAUDE.md(ERP 专属编码约束 + Schema 演化 + Git 提交规范)
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~A5 checkbox)
scope-lock req-card-template.md 单张 REQ 卡片模板(文件名 == req_id <模块代码>-<子模块代码>-<功能名>{{req_id/title/goal/rules/constraints/acceptance}} 占位 + 输入/输出示例字段表;A1 原样复制,只填这 6 个占位)
scope-lock _module-template.md 模块子目录的 _module.md 模块头(模块代码-名 / 简述 / 依赖模块 TBD / 涉及表 TBD)
scope-lock config-vars-template.yaml 仓库根 config-vars.yaml 骨架(跨栈中立):项目全部配置——非敏感(包名/端口/前端包名/初始账号)+ 敏感凭据(database / admin_init.password / secrets);A1 E.2 锁定,随项目提交
skeleton-gen docs-04-skeleton-template.md docs/04 § 一+ 编码规范大纲(HTML 注释引导 LLM)
skeleton-gen scripts-setup-test-db-template.mjs 跨平台"复制源库→一次性测试副本"脚本(mysqldump 管道;内联极简 YAML 读 config-vars.yaml database: 段;COPY≠SOURCE 守卫,源库绝不被 drop);本轮新迁移的 apply 交给起后端时的 Flyway
skeleton-gen scripts-drop-test-db-template.mjs 测试收尾删副本脚本(幂等 DROP IF EXISTS;硬拒删源库)
skeleton-gen scripts-promote-to-source-template.mjs 测试绿后把副本上已验证的新迁移晋升到源库(移植 flyway 历史行 + 重放迁移 SQL;幂等;跨 lane 由编排层起栈互斥串行)
skeleton-gen scripts-seed-demo-data-template.mjs 演示种子注入脚本(schema 建好后按 sql/seed/<NN>__<module>.sql 文件名升序幂等注入;_demo_seed_history 账本表记已应用文件跳过;同走 mysql;调用方 = 前端 e2e globalSetup / 行为门 / 里程碑后人工验收)
skeleton-gen scripts-test-template.mjs test.mjs 骨架(命令槽位按后端/前端/build/lint/test/e2e 分开,spawnSync(shell:true) 跨平台执行)
skeleton-gen gitignore-append-template 插件推荐忽略项(.tmp/、构建产物等;config-vars.yaml 随项目提交,不忽略)
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-08-module-row-template.md docs/08 § 二 单模块 bullet 行

前置依赖

  • Node.js ≥ 18lib/*.mjs 助手 + 生成进目标项目的 scripts/*.mjs 为 Node ESM;workflows/coding.mjs 是 Claude Workflow 运行时脚本(由 Workflow 工具执行,不作为普通 node CLI 入口)。A0 project-init 检测 git / mysql / node 在 PATH,缺失则按 OS 自动安装,装不上再停下提示用户
  • MySQL 8.x 实例已就绪(host / 库名 / 凭据取自 config-vars.yamldatabase: 段,由你填写并完全信任)。database.schema = 源库(真实持久库):测试永不 drop 它,每次测试由 setup-test-db.mjs 把它 mysqldump 复制成一次性副本(<schema>__test / lane 副本),跑完 drop-test-db.mjs 删副本,绿后 promote-to-source.mjs 把新迁移晋升回源库。这些脚本与 seed-demo-data.mjs 同走 mysql/mysqldump CLI,故两者须在 PATH
  • mysql2(目标项目侧):A4 db-initlib/bootstrap-source-flyway.mjs 用 mysql2 建源库 + apply V1 + 写 checksum 一致的 flyway 历史(源库首次 Flyway 托管化;已托管则幂等跳过)
  • Spring Boot + Flyway必需):build.gradle 声明 flyway-core + flyway-mysql;Spring 启动时自动 apply sql/migrations/V*.sql。副本自带源库 flyway 历史,起后端时 Flyway 只 apply 本轮新迁移到副本
  • 本地 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
  • 本地可运行 ./gradlew test / pnpm test:测试命令由 A1 写入 docs/04 § 零,生成的 scripts/test.mjsskeleton-gen 产出,coding.mjs 的 testGate stage 调用

设计原则

参见 skills/plan/project-init/templates/CLAUDE-template.md 的「📐 编码行为约束」。