From c786feec07a3e64222303da3183d16ff20903c21 Mon Sep 17 00:00:00 2001 From: zichun Date: Mon, 25 May 2026 15:28:00 +0800 Subject: [PATCH] refactor: drop lite branding — rename lite-init/design/build-db → init/design/build-db, de-brand plugin meta/README/banners --- .claude-plugin/plugin.json | 4 ++-- README.md | 82 +++++++++++++++++++++++++++++++++++++++++----------------------------------------- skills/coding/milestone/SKILL.md | 8 ++++---- skills/crosscut/coding-start/SKILL.md | 6 +++--- skills/crosscut/coding-start/banners/flow-lite.txt | 14 -------------- skills/crosscut/coding-start/banners/flow.txt | 14 ++++++++++++++ skills/crosscut/plan-start/SKILL.md | 24 ++++++++++++------------ skills/crosscut/plan-start/banners/flow-lite.txt | 14 -------------- skills/crosscut/plan-start/banners/flow.txt | 14 ++++++++++++++ skills/plan/build-db/SKILL.md | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ skills/plan/build-db/scripts/validate.sh | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ skills/plan/build-db/templates/docs-05-endpoint-template.md | 12 ++++++++++++ skills/plan/build-db/templates/docs-05-header-template.md | 30 ++++++++++++++++++++++++++++++ skills/plan/build-db/templates/docs-08-module-row-template.md | 6 ++++++ skills/plan/design/SKILL.md | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ skills/plan/design/scripts/merge-gitignore.sh | 39 +++++++++++++++++++++++++++++++++++++++ skills/plan/design/templates/docs-03-header-template.md | 28 ++++++++++++++++++++++++++++ skills/plan/design/templates/docs-03-table-template.md | 27 +++++++++++++++++++++++++++ skills/plan/design/templates/docs-04-skeleton-template.md | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ skills/plan/design/templates/env-local-template | 25 +++++++++++++++++++++++++ skills/plan/design/templates/gitignore-append-template | 32 ++++++++++++++++++++++++++++++++ skills/plan/design/templates/scripts-setup-test-db-template.sh | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ skills/plan/design/templates/scripts-test-template.sh | 40 ++++++++++++++++++++++++++++++++++++++++ skills/plan/init/SKILL.md | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ skills/plan/init/scripts/render.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ skills/plan/init/templates/CLAUDE-template.md | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ skills/plan/init/templates/_module-template.md | 5 +++++ skills/plan/init/templates/docs-01-index-template.md | 16 ++++++++++++++++ skills/plan/init/templates/docs-04-stack-template.md | 32 ++++++++++++++++++++++++++++++++ skills/plan/init/templates/docs-08-initial-template.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ skills/plan/init/templates/req-card-template.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ skills/plan/lite-build-db/SKILL.md | 255 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- skills/plan/lite-build-db/scripts/validate.sh | 96 ------------------------------------------------------------------------------------------------ skills/plan/lite-build-db/templates/docs-05-endpoint-template.md | 12 ------------ skills/plan/lite-build-db/templates/docs-05-header-template.md | 30 ------------------------------ skills/plan/lite-build-db/templates/docs-08-module-row-template.md | 6 ------ skills/plan/lite-design/SKILL.md | 174 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ skills/plan/lite-design/scripts/merge-gitignore.sh | 39 --------------------------------------- skills/plan/lite-design/templates/docs-03-header-template.md | 28 ---------------------------- skills/plan/lite-design/templates/docs-03-table-template.md | 27 --------------------------- skills/plan/lite-design/templates/docs-04-skeleton-template.md | 122 -------------------------------------------------------------------------------------------------------------------------- skills/plan/lite-design/templates/env-local-template | 25 ------------------------- skills/plan/lite-design/templates/gitignore-append-template | 32 -------------------------------- skills/plan/lite-design/templates/scripts-setup-test-db-template.sh | 65 ----------------------------------------------------------------- skills/plan/lite-design/templates/scripts-test-template.sh | 40 ---------------------------------------- skills/plan/lite-init/SKILL.md | 233 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- skills/plan/lite-init/scripts/render.sh | 42 ------------------------------------------ skills/plan/lite-init/templates/CLAUDE-template.md | 280 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- skills/plan/lite-init/templates/_module-template.md | 5 ----- skills/plan/lite-init/templates/docs-01-index-template.md | 16 ---------------- skills/plan/lite-init/templates/docs-04-stack-template.md | 32 -------------------------------- skills/plan/lite-init/templates/docs-08-initial-template.md | 52 ---------------------------------------------------- skills/plan/lite-init/templates/req-card-template.md | 63 --------------------------------------------------------------- 53 files changed, 1764 insertions(+), 1764 deletions(-) delete mode 100644 skills/crosscut/coding-start/banners/flow-lite.txt create mode 100644 skills/crosscut/coding-start/banners/flow.txt delete mode 100644 skills/crosscut/plan-start/banners/flow-lite.txt create mode 100644 skills/crosscut/plan-start/banners/flow.txt create mode 100644 skills/plan/build-db/SKILL.md create mode 100644 skills/plan/build-db/scripts/validate.sh create mode 100644 skills/plan/build-db/templates/docs-05-endpoint-template.md create mode 100644 skills/plan/build-db/templates/docs-05-header-template.md create mode 100644 skills/plan/build-db/templates/docs-08-module-row-template.md create mode 100644 skills/plan/design/SKILL.md create mode 100755 skills/plan/design/scripts/merge-gitignore.sh create mode 100644 skills/plan/design/templates/docs-03-header-template.md create mode 100644 skills/plan/design/templates/docs-03-table-template.md create mode 100644 skills/plan/design/templates/docs-04-skeleton-template.md create mode 100644 skills/plan/design/templates/env-local-template create mode 100644 skills/plan/design/templates/gitignore-append-template create mode 100644 skills/plan/design/templates/scripts-setup-test-db-template.sh create mode 100644 skills/plan/design/templates/scripts-test-template.sh create mode 100644 skills/plan/init/SKILL.md create mode 100644 skills/plan/init/scripts/render.sh create mode 100644 skills/plan/init/templates/CLAUDE-template.md create mode 100644 skills/plan/init/templates/_module-template.md create mode 100644 skills/plan/init/templates/docs-01-index-template.md create mode 100644 skills/plan/init/templates/docs-04-stack-template.md create mode 100644 skills/plan/init/templates/docs-08-initial-template.md create mode 100644 skills/plan/init/templates/req-card-template.md delete mode 100644 skills/plan/lite-build-db/SKILL.md delete mode 100644 skills/plan/lite-build-db/scripts/validate.sh delete mode 100644 skills/plan/lite-build-db/templates/docs-05-endpoint-template.md delete mode 100644 skills/plan/lite-build-db/templates/docs-05-header-template.md delete mode 100644 skills/plan/lite-build-db/templates/docs-08-module-row-template.md delete mode 100644 skills/plan/lite-design/SKILL.md delete mode 100755 skills/plan/lite-design/scripts/merge-gitignore.sh delete mode 100644 skills/plan/lite-design/templates/docs-03-header-template.md delete mode 100644 skills/plan/lite-design/templates/docs-03-table-template.md delete mode 100644 skills/plan/lite-design/templates/docs-04-skeleton-template.md delete mode 100644 skills/plan/lite-design/templates/env-local-template delete mode 100644 skills/plan/lite-design/templates/gitignore-append-template delete mode 100644 skills/plan/lite-design/templates/scripts-setup-test-db-template.sh delete mode 100644 skills/plan/lite-design/templates/scripts-test-template.sh delete mode 100644 skills/plan/lite-init/SKILL.md delete mode 100644 skills/plan/lite-init/scripts/render.sh delete mode 100644 skills/plan/lite-init/templates/CLAUDE-template.md delete mode 100644 skills/plan/lite-init/templates/_module-template.md delete mode 100644 skills/plan/lite-init/templates/docs-01-index-template.md delete mode 100644 skills/plan/lite-init/templates/docs-04-stack-template.md delete mode 100644 skills/plan/lite-init/templates/docs-08-initial-template.md delete mode 100644 skills/plan/lite-init/templates/req-card-template.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 95600f1..0f8d1ad 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "erp-workflow", - "description": "ERP/全栈项目精简流程框架(lite):计划三段(一次性)+ 编码统一功能循环(后端模块 / 前端阶段共用),保留 TDD、需求可追溯、DB-as-SSoT + Flyway、本地里程碑 tag。", - "version": "0.1.0-lite", + "description": "ERP/全栈项目全流程开发框架:计划三段(一次性)+ 编码统一功能循环(后端模块 / 前端阶段共用),保留 TDD、需求可追溯、DB-as-SSoT + Flyway、本地里程碑 tag。", + "version": "0.1.0", "skills": ["./skills/plan", "./skills/coding", "./skills/crosscut"] } diff --git a/README.md b/README.md index d52d64a..db26c9f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# erp-workflow(lite) +# erp-workflow -Claude Code 插件:ERP / 后端管理系统全流程开发框架(精简版)。 +Claude Code 插件:ERP / 后端管理系统全流程开发框架。 把"从零到 N 个后端模块上线 + 前端整体阶段"的整个流程固化成 **11 个 skill + 2 个 agent + 22 份模板 + 3 个脚本**,让 CC 在 schema 演化用 Flyway migration、需求可追溯、纯本地 git 的前提下推进编码。后端按模块循环依次打里程碑 tag,所有后端模块打里程碑后进入前端整体阶段(以项目根 `prototype/` 静态 HTML mockup 为页面权威)。两阶段共用同一套功能循环 skill,由 `phase` 参数区分。 @@ -8,12 +8,12 @@ Claude Code 插件:ERP / 后端管理系统全流程开发框架(精简版 ``` ┌────────────────────────────────────────────────────────┐ -│ erp-workflow-lite │ +│ erp-workflow │ │ │ │ 计划(/plan-start,一次性,2 个审阅断点) │ -│ ① lite-init 初始化 + REQ 卡片 ⏸ 审阅 REQ │ -│ ② lite-design 脚手架 + docs/03 ⏸ 审阅 schema │ -│ ③ lite-build-db V1+apply + docs/05/08 │ +│ ① init 初始化 + REQ 卡片 ⏸ 审阅 REQ │ +│ ② design 脚手架 + docs/03 ⏸ 审阅 schema │ +│ ③ build-db V1+apply + docs/05/08 │ │ │ │ 编码(/coding-start,统一功能循环) │ │ 后端模块循环 ┐ │ @@ -37,9 +37,9 @@ Claude Code 插件:ERP / 后端管理系统全流程开发框架(精简版 ``` Plan 阶段**三段式**执行,中间有两个人工审阅断点: - - **第一段(首次运行)**:执行 `lite-init`(依赖检查 / git init / 初始化 docs + CLAUDE.md / 引导填技术栈 + 需求索引 / 生成 REQ 卡片骨架)后**停下**,等你审阅并补全 `docs/01-需求清单//REQ-*.md`(第一个人工关口:业务范围) - - **第二段(REQ 审阅完重新运行)**:执行 `lite-design`(生成 docs/04 架构规范 / scripts / .env.local / 从 REQ 正向设计 `docs/03-数据库设计文档.md`)后再次**停下**,等你审阅 docs/03 的表 / 字段 / 索引 / 外键(第二个人工关口:database schema) - - **第三段(docs/03 审阅完重新运行)**:执行 `lite-build-db`(解析 docs/03 → 生成 V1 migration → DROP+CREATE 本地 schema 并 apply → 生成 docs/05 API 契约 + 追加 docs/08 § 二 模块清单),Plan 完成后**停下** + - **第一段(首次运行)**:执行 `init`(依赖检查 / git init / 初始化 docs + CLAUDE.md / 引导填技术栈 + 需求索引 / 生成 REQ 卡片骨架)后**停下**,等你审阅并补全 `docs/01-需求清单//REQ-*.md`(第一个人工关口:业务范围) + - **第二段(REQ 审阅完重新运行)**:执行 `design`(生成 docs/04 架构规范 / scripts / .env.local / 从 REQ 正向设计 `docs/03-数据库设计文档.md`)后再次**停下**,等你审阅 docs/03 的表 / 字段 / 索引 / 外键(第二个人工关口:database schema) + - **第三段(docs/03 审阅完重新运行)**:执行 `build-db`(解析 docs/03 → 生成 V1 migration → DROP+CREATE 本地 schema 并 apply → 生成 docs/05 API 契约 + 追加 docs/08 § 二 模块清单),Plan 完成后**停下** 每次运行都会自动接上次停下的地方继续。Plan 完成后**不会自动进入编码**,需要你手动运行 `/erp-workflow:coding-start`。 @@ -83,9 +83,9 @@ erp-workflow-plugin/ │ └── fe-code-reviewer.md # 前端专用 reviewer(feature-review 前端阶段调用,7 维 review) └── skills/ ├── plan/ # 计划阶段:3 个一次性规划 skill - │ ├── lite-init/ - │ ├── lite-design/ - │ └── lite-build-db/ + │ ├── init/ + │ ├── design/ + │ └── build-db/ ├── coding/ # 编码阶段:5 个 skill(两阶段共用统一功能循环) │ ├── phase-driver/ │ ├── feature-spec/ @@ -100,7 +100,7 @@ erp-workflow-plugin/ ## Hook 清单 -lite 版本**无 Hook**——跨模块改动留痕已移除。跨模块改动须在 `milestone` 完成报告的「偏离与取舍」节人工记录。 +本插件**无 Hook**——跨模块改动留痕已移除。跨模块改动须在 `milestone` 完成报告的「偏离与取舍」节人工记录。 ## Skill 清单(11 个) @@ -116,9 +116,9 @@ lite 版本**无 Hook**——跨模块改动留痕已移除。跨模块改动须 | Skill | 作用 | 流程中谁调用 | |---|---|---| -| `lite-init` | 计划 ①:依赖检查 / git init / 创建 CLAUDE.md + docs/01/index.md + docs/04 § 零 + docs/08;引导填项目概述 / 技术栈 / 需求索引;按模块生成 REQ 卡片骨架;**停下**等人工审阅 REQ | `plan-start` | -| `lite-design` | 计划 ②:生成 docs/04 架构规范大纲 + scripts(test.sh / setup-test-db.sh)+ .env.local + .gitignore 合并;从 docs/01 REQ 正向设计 `docs/03-数据库设计文档.md`(schema SSoT);**停下**等人工审阅 docs/03 | `plan-start` | -| `lite-build-db` | 计划 ③:解析 docs/03 → `sql/migrations/V1__initial_schema.sql`(5 维度校验 DDL ↔ docs/03)→ DROP+CREATE 本地 schema 并 apply V1;生成 docs/05 API 契约 + 回填 REQ 依赖接口;追加模块清单到 docs/08 § 二;打印 Plan 完成横幅并**停下** | `plan-start` | +| `init` | 计划 ①:依赖检查 / git init / 创建 CLAUDE.md + docs/01/index.md + docs/04 § 零 + docs/08;引导填项目概述 / 技术栈 / 需求索引;按模块生成 REQ 卡片骨架;**停下**等人工审阅 REQ | `plan-start` | +| `design` | 计划 ②:生成 docs/04 架构规范大纲 + scripts(test.sh / setup-test-db.sh)+ .env.local + .gitignore 合并;从 docs/01 REQ 正向设计 `docs/03-数据库设计文档.md`(schema SSoT);**停下**等人工审阅 docs/03 | `plan-start` | +| `build-db` | 计划 ③:解析 docs/03 → `sql/migrations/V1__initial_schema.sql`(5 维度校验 DDL ↔ docs/03)→ DROP+CREATE 本地 schema 并 apply V1;生成 docs/05 API 契约 + 回填 REQ 依赖接口;追加模块清单到 docs/08 § 二;打印 Plan 完成横幅并**停下** | `plan-start` | ### 编码阶段(`skills/coding/`) @@ -143,29 +143,29 @@ lite 版本**无 Hook**——跨模块改动留痕已移除。跨模块改动须 | 所属 Skill | Banner 文件 | 用途 | |---|---|---| -| `plan-start` | `banners/flow-lite.txt` | 整体流程图(▶ 标在 plan-start 分发横幅前) | -| `coding-start` | `banners/flow-lite.txt` | 整体流程图(▶ 标在 coding-start 分发横幅前) | +| `plan-start` | `banners/flow.txt` | 整体流程图(▶ 标在 plan-start 分发横幅前) | +| `coding-start` | `banners/flow.txt` | 整体流程图(▶ 标在 coding-start 分发横幅前) | ## Templates 清单(22 份模板文件,21 个不同名——`commit-message-template.md` 由 feature-tdd / feature-review 各持一份) | 所属 Skill | 模板文件 | 用途 | |---|---|---| -| `lite-init` | `CLAUDE-template.md` | 项目根的 CLAUDE.md(4 条通用准则 + ERP 专属约定 + skill 索引) | -| `lite-init` | `docs-01-index-template.md` | 需求清单索引骨架 | -| `lite-init` | `docs-08-initial-template.md` | 工作流进度文件骨架(Plan ①②③ checkbox) | -| `lite-init` | `docs-04-stack-template.md` | docs/04 § 零 默认技术栈总览(零槽位,cp 即可) | -| `lite-init` | `req-card-template.md` | 单张 REQ-XXX-NNN 卡片骨架(6 个 `{{...}}` 占位符由 CC 替换) | -| `lite-init` | `_module-template.md` | 模块子目录的 `_module.md` 模块头 | -| `lite-design` | `docs-04-skeleton-template.md` | docs/04 § 一+ 编码规范大纲 | -| `lite-design` | `docs-03-header-template.md` | docs/03 数据库设计头部 | -| `lite-design` | `docs-03-table-template.md` | docs/03 单表小节模板 | -| `lite-design` | `scripts-setup-test-db-template.sh` | drop + create 空库脚本(0 槽位) | -| `lite-design` | `scripts-test-template.sh` | test.sh 骨架(多个命令槽位,由 lite-design 按技术栈推断填充) | -| `lite-design` | `env-local-template` | 6 字段凭据模板(DB_* + JWT_SECRET) | -| `lite-design` | `gitignore-append-template` | 插件推荐忽略项(`.env.local`、`.tmp/`、构建产物等) | -| `lite-build-db` | `docs-05-header-template.md` | docs/05 API 契约头部 | -| `lite-build-db` | `docs-05-endpoint-template.md` | docs/05 单接口小节 | -| `lite-build-db` | `docs-08-module-row-template.md` | docs/08 § 二 单模块 bullet 行 | +| `init` | `CLAUDE-template.md` | 项目根的 CLAUDE.md(4 条通用准则 + ERP 专属约定 + skill 索引) | +| `init` | `docs-01-index-template.md` | 需求清单索引骨架 | +| `init` | `docs-08-initial-template.md` | 工作流进度文件骨架(Plan ①②③ checkbox) | +| `init` | `docs-04-stack-template.md` | docs/04 § 零 默认技术栈总览(零槽位,cp 即可) | +| `init` | `req-card-template.md` | 单张 REQ-XXX-NNN 卡片骨架(6 个 `{{...}}` 占位符由 CC 替换) | +| `init` | `_module-template.md` | 模块子目录的 `_module.md` 模块头 | +| `design` | `docs-04-skeleton-template.md` | docs/04 § 一+ 编码规范大纲 | +| `design` | `docs-03-header-template.md` | docs/03 数据库设计头部 | +| `design` | `docs-03-table-template.md` | docs/03 单表小节模板 | +| `design` | `scripts-setup-test-db-template.sh` | drop + create 空库脚本(0 槽位) | +| `design` | `scripts-test-template.sh` | test.sh 骨架(多个命令槽位,由 design 按技术栈推断填充) | +| `design` | `env-local-template` | 6 字段凭据模板(DB_* + JWT_SECRET) | +| `design` | `gitignore-append-template` | 插件推荐忽略项(`.env.local`、`.tmp/`、构建产物等) | +| `build-db` | `docs-05-header-template.md` | docs/05 API 契约头部 | +| `build-db` | `docs-05-endpoint-template.md` | docs/05 单接口小节 | +| `build-db` | `docs-08-module-row-template.md` | docs/08 § 二 单模块 bullet 行 | | `feature-spec` | `feature-spec-plan-template.md` | 功能规格 + 任务级计划合并文档 | | `feature-review` | `feature-review-template.md` | 自审报告结构 | | `feature-review` | `commit-message-template.md` | review fix commit 信息 | @@ -177,21 +177,21 @@ lite 版本**无 Hook**——跨模块改动留痕已移除。跨模块改动须 | 所属 Skill | 脚本文件 | 用途 | |---|---|---| -| `lite-init` | `scripts/render.sh` | 渲染单个 `_module.md` 或 `REQ-*.md`(替换 6 个占位符) | -| `lite-design` | `scripts/merge-gitignore.sh` | 合并 .gitignore(逐行判重) | +| `init` | `scripts/render.sh` | 渲染单个 `_module.md` 或 `REQ-*.md`(替换 6 个占位符) | +| `design` | `scripts/merge-gitignore.sh` | 合并 .gitignore(逐行判重) | **流程使用情况**:所有模板都被对应 skill 的 `SKILL.md` 引用,没有孤儿模板。 ## 前置依赖 -- **MySQL 8.x** 实例已就绪(推荐本地 / `*.local` host;`lite-build-db` 的安全守护要求 host 在白名单且 schema 名含 `test`/`dev`/`local`,避免误删生产库) -- **`mysql` 命令行**:`lite-build-db` 验证连接 + 自动 `DROP+CREATE` schema 后 apply V1;`scripts/setup-test-db.sh` 在测试闸门前后 drop+create 空库 +- **MySQL 8.x** 实例已就绪(推荐本地 / `*.local` host;`build-db` 的安全守护要求 host 在白名单且 schema 名含 `test`/`dev`/`local`,避免误删生产库) +- **`mysql` 命令行**:`build-db` 验证连接 + 自动 `DROP+CREATE` schema 后 apply V1;`scripts/setup-test-db.sh` 在测试闸门前后 drop+create 空库 - **Spring Boot + Flyway**(**必需**):pom.xml 声明 `flyway-core` + `flyway-mysql`;Spring 启动时自动 apply `sql/migrations/V*.sql`。本插件生成的 `setup-test-db.sh` 只清库,schema 必须由 Flyway 应用 -- **本地 git 仓库**(纯本地,**无需远程 / push / GitLab**):`lite-init` 执行 `git init`;编码阶段每模块由 `milestone` 本地 `git merge --no-ff` 进默认分支并 `git tag -a milestone/`,完成信号由 `git tag -l` 判定 -- **本地可运行 `mvn test` / `pnpm test`**:测试闸门 `scripts/test.sh` 由 `lite-design` 生成 +- **本地 git 仓库**(纯本地,**无需远程 / push / GitLab**):`init` 执行 `git init`;编码阶段每模块由 `milestone` 本地 `git merge --no-ff` 进默认分支并 `git tag -a milestone/`,完成信号由 `git tag -l` 判定 +- **本地可运行 `mvn test` / `pnpm test`**:测试闸门 `scripts/test.sh` 由 `design` 生成 ## 设计原则 -参见 `lite-init/templates/CLAUDE-template.md` 末尾的「通用工作准则」4 条:① Think Before Coding ② Simplicity First ③ Surgical Changes ④ Goal-Driven Execution。 +参见 `init/templates/CLAUDE-template.md` 末尾的「通用工作准则」4 条:① Think Before Coding ② Simplicity First ③ Surgical Changes ④ Goal-Driven Execution。 最关键的 1 条:"**所有测试与验证派发到全新子会话执行,主会话只接收结构化结论**"——避免主会话被测试输出污染,并让测试结果作为独立证据存档。 diff --git a/skills/coding/milestone/SKILL.md b/skills/coding/milestone/SKILL.md index 434fe35..ff51d73 100644 --- a/skills/coding/milestone/SKILL.md +++ b/skills/coding/milestone/SKILL.md @@ -1,6 +1,6 @@ --- name: milestone -description: 单元(后端模块 / 前端阶段)全部 approve 后的收尾闸门:子会话跑测试 → 写精简完成报告 → 本地 merge 进默认分支 + 打 milestone/ tag + 回写 docs/08 → 自动回调 coding-start。phase 由当前分支推断。 +description: 单元(后端模块 / 前端阶段)全部 approve 后的收尾闸门:子会话跑测试 → 写完成报告 → 本地 merge 进默认分支 + 打 milestone/ tag + 回写 docs/08 → 自动回调 coding-start。phase 由当前分支推断。 user-invocable: false allowed-tools: Read Write Edit Skill Agent Bash(git *) --- @@ -13,7 +13,7 @@ allowed-tools: Read Write Edit Skill Agent Bash(git *) 1. **推断 phase**(分支名 → backend / frontend) 2. **测试闸门**(子会话跑测试,绿才能继续) -3. **精简完成报告**(6 节,commit 到当前分支) +3. **完成报告**(6 节,commit 到当前分支) 4. **本地集成 + tag + 回写 docs/08 + 自动回调** ## 阶段 0:推断 phase 与关键变量 @@ -76,7 +76,7 @@ allowed-tools: Read Write Edit Skill Agent Bash(git *) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` -## 阶段 2:精简完成报告 +## 阶段 2:完成报告 > **核心约束:只收集 git 摘要,绝不把 diff 正文读入主会话上下文。** @@ -200,6 +200,6 @@ coding-start 重新检查后端 / 前端完成性(按 `里程碑:` 字段 + `g ## 参考 -- `${CLAUDE_SKILL_DIR}/templates/milestone-report-template.md`(6 节精简报告) +- `${CLAUDE_SKILL_DIR}/templates/milestone-report-template.md`(6 节完成报告) - 上游:`phase-driver`(后端所有 REQ / 前端所有 FE 全部 approve 后派发到此) - 下游:`coding-start`(自治回调,由其路由下一阶段) diff --git a/skills/crosscut/coding-start/SKILL.md b/skills/crosscut/coding-start/SKILL.md index 3a92bf6..2bdb415 100644 --- a/skills/crosscut/coding-start/SKILL.md +++ b/skills/crosscut/coding-start/SKILL.md @@ -13,10 +13,10 @@ allowed-tools: Skill Read Glob Grep Bash(cat *) Bash(git tag *) ### 步骤 0:打印流程图 -**第一件事**:打印 lite 整体流程图。 +**第一件事**:打印 整体流程图。 ```bash -cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/coding-start/banners/flow-lite.txt" +cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/coding-start/banners/flow.txt" ``` ### 步骤 1:确认 docs/08 存在 @@ -26,7 +26,7 @@ cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/coding-start/banners/flow-lite.txt" ### 步骤 2:计划完成性检查 -读取 `docs/08-模块任务管理.md § 一`,判断 ①②③ 三个 lite 计划阶段是否**全部勾选**(含各阶段子项)。 +读取 `docs/08-模块任务管理.md § 一`,判断 ①②③ 三个 计划阶段是否**全部勾选**(含各阶段子项)。 - 任一未勾选 → 提示用户先运行 `/erp-workflow:plan-start` 完成计划阶段,并停下。 - 全部勾选 → 进入步骤 3。 diff --git a/skills/crosscut/coding-start/banners/flow-lite.txt b/skills/crosscut/coding-start/banners/flow-lite.txt deleted file mode 100644 index d82cdf3..0000000 --- a/skills/crosscut/coding-start/banners/flow-lite.txt +++ /dev/null @@ -1,14 +0,0 @@ -┌────────────────────────────────────────────────────────┐ -│ erp-workflow-lite │ -│ │ -│ 计划(/plan-start,一次性,2 个审阅断点) │ -│ ① lite-init 初始化 + REQ 卡片 ⏸ 审阅 REQ │ -│ ② lite-design 脚手架 + docs/03 ⏸ 审阅 schema │ -│ ③ lite-build-db V1+apply + docs/05/08 │ -│ │ -│ 编码(/coding-start,统一功能循环) │ -│ 后端模块循环 ┐ │ -│ 前端整体阶段 ┘→ phase-driver │ -│ feature-spec → feature-tdd → feature-review │ -│ 全 approve → milestone(test→报告→merge+tag) │ -└────────────────────────────────────────────────────────┘ diff --git a/skills/crosscut/coding-start/banners/flow.txt b/skills/crosscut/coding-start/banners/flow.txt new file mode 100644 index 0000000..06609c4 --- /dev/null +++ b/skills/crosscut/coding-start/banners/flow.txt @@ -0,0 +1,14 @@ +┌────────────────────────────────────────────────────────┐ +│ erp-workflow │ +│ │ +│ 计划(/plan-start,一次性,2 个审阅断点) │ +│ ① init 初始化 + REQ 卡片 ⏸ 审阅 REQ │ +│ ② design 脚手架 + docs/03 ⏸ 审阅 schema │ +│ ③ build-db V1+apply + docs/05/08 │ +│ │ +│ 编码(/coding-start,统一功能循环) │ +│ 后端模块循环 ┐ │ +│ 前端整体阶段 ┘→ phase-driver │ +│ feature-spec → feature-tdd → feature-review │ +│ 全 approve → milestone(test→报告→merge+tag) │ +└────────────────────────────────────────────────────────┘ diff --git a/skills/crosscut/plan-start/SKILL.md b/skills/crosscut/plan-start/SKILL.md index e91cdfd..a2356b6 100644 --- a/skills/crosscut/plan-start/SKILL.md +++ b/skills/crosscut/plan-start/SKILL.md @@ -1,6 +1,6 @@ --- name: plan-start -description: 计划阶段(Plan)入口与分发器。根据 docs/08 § 一 的 checkbox 状态派发到 ①②③ 对应的 lite 计划 skill。三阶段全部完成后打印提示让用户运行 /erp-workflow:coding-start 进入编码阶段。 +description: 计划阶段(Plan)入口与分发器。根据 docs/08 § 一 的 checkbox 状态派发到 ①②③ 对应的 计划 skill。三阶段全部完成后打印提示让用户运行 /erp-workflow:coding-start 进入编码阶段。 user-invocable: true allowed-tools: Skill Read Glob Grep Bash(cat *) --- @@ -11,10 +11,10 @@ allowed-tools: Skill Read Glob Grep Bash(cat *) ## 步骤 0:打印流程图 -**第一件事**:打印 lite 整体流程图。 +**第一件事**:打印 整体流程图。 ```bash -cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/plan-start/banners/flow-lite.txt" +cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/plan-start/banners/flow.txt" ``` ## 步骤 1:读取 docs/08 + 决定分发目标 @@ -22,15 +22,15 @@ cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/plan-start/banners/flow-lite.txt" docs/08 § 一 是**计划阶段进度追踪**(①②③ 的 checkbox)。 用 `Glob` 检查 `docs/08-模块任务管理.md` 是否存在: -- 不存在 → 后续 = `lite-init`(对应阶段 ①) +- 不存在 → 后续 = `init`(对应阶段 ①) -若存在,读取 `docs/08-模块任务管理.md § 一`,找到**第一个未勾选(`- [ ]`)的 lite 计划阶段**: +若存在,读取 `docs/08-模块任务管理.md § 一`,找到**第一个未勾选(`- [ ]`)的 计划阶段**: | 进度 | 后续 | |---|---| -| 无 docs/08,或 ① 未勾选 | `lite-init` | -| ① 已勾、② 未勾选 | `lite-design` | -| ①② 已勾、③ 未勾选 | `lite-build-db` | +| 无 docs/08,或 ① 未勾选 | `init` | +| ① 已勾、② 未勾选 | `design` | +| ①② 已勾、③ 未勾选 | `build-db` | | ①②③ 全部勾选 | **无分发**(计划阶段结束) | ## 步骤 2:分发通知 + 调用目标 skill @@ -68,12 +68,12 @@ docs/08 § 一 是**计划阶段进度追踪**(①②③ 的 checkbox)。 ``` 立即用 `Skill` 工具调用 `后续`: -- ① → `Skill(lite-init)` -- ② → `Skill(lite-design)` -- ③ → `Skill(lite-build-db)` +- ① → `Skill(init)` +- ② → `Skill(design)` +- ③ → `Skill(build-db)` ## 参考 - `docs/08-模块任务管理.md § 一`(计划阶段进度追踪,①②③ checkbox) - `CLAUDE.md`(项目指令) -- 后续 skills(通过 `Skill` 工具按名称调用):`lite-init`、`lite-design`、`lite-build-db` +- 后续 skills(通过 `Skill` 工具按名称调用):`init`、`design`、`build-db` diff --git a/skills/crosscut/plan-start/banners/flow-lite.txt b/skills/crosscut/plan-start/banners/flow-lite.txt deleted file mode 100644 index d82cdf3..0000000 --- a/skills/crosscut/plan-start/banners/flow-lite.txt +++ /dev/null @@ -1,14 +0,0 @@ -┌────────────────────────────────────────────────────────┐ -│ erp-workflow-lite │ -│ │ -│ 计划(/plan-start,一次性,2 个审阅断点) │ -│ ① lite-init 初始化 + REQ 卡片 ⏸ 审阅 REQ │ -│ ② lite-design 脚手架 + docs/03 ⏸ 审阅 schema │ -│ ③ lite-build-db V1+apply + docs/05/08 │ -│ │ -│ 编码(/coding-start,统一功能循环) │ -│ 后端模块循环 ┐ │ -│ 前端整体阶段 ┘→ phase-driver │ -│ feature-spec → feature-tdd → feature-review │ -│ 全 approve → milestone(test→报告→merge+tag) │ -└────────────────────────────────────────────────────────┘ diff --git a/skills/crosscut/plan-start/banners/flow.txt b/skills/crosscut/plan-start/banners/flow.txt new file mode 100644 index 0000000..06609c4 --- /dev/null +++ b/skills/crosscut/plan-start/banners/flow.txt @@ -0,0 +1,14 @@ +┌────────────────────────────────────────────────────────┐ +│ erp-workflow │ +│ │ +│ 计划(/plan-start,一次性,2 个审阅断点) │ +│ ① init 初始化 + REQ 卡片 ⏸ 审阅 REQ │ +│ ② design 脚手架 + docs/03 ⏸ 审阅 schema │ +│ ③ build-db V1+apply + docs/05/08 │ +│ │ +│ 编码(/coding-start,统一功能循环) │ +│ 后端模块循环 ┐ │ +│ 前端整体阶段 ┘→ phase-driver │ +│ feature-spec → feature-tdd → feature-review │ +│ 全 approve → milestone(test→报告→merge+tag) │ +└────────────────────────────────────────────────────────┘ diff --git a/skills/plan/build-db/SKILL.md b/skills/plan/build-db/SKILL.md new file mode 100644 index 0000000..66c9211 --- /dev/null +++ b/skills/plan/build-db/SKILL.md @@ -0,0 +1,255 @@ +--- +name: build-db +description: 计划第 3 段——解析 docs/03 → V1 migration + validate.sh 校验 + apply 到本地 MySQL;生成 docs/05 API 契约 + 回填 REQ 依赖接口;计算模块/REQ 依赖顺序写入 docs/08 § 二(排序权威);最终占位符扫描后停下(计划完成)。 +user-invocable: false +allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(mkdir *) Bash(mysql *) Bash(set *) Bash(. .env.local) Bash(grep *) Bash(bash *) Bash(./scripts/setup-test-db.sh) Bash(cat *) Bash(cp *) +--- + +**所有输出必须使用中文。** + +# build-db + +## 执行步骤 + +### 步骤 0:打印当前位置流程图 + +用 `Bash` 执行以下命令(文件不存在时静默忽略,不报错): + +```bash +cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/plan-start/banners/flow.txt" 2>/dev/null || true +``` + +打印横幅:`▶ 计划阶段 ③ — build-db`。 + +### A. DDL 生成(不依赖数据库连接) + +#### A.1 读 docs/03 并翻译为 DDL + +读取 `docs/03-数据库设计文档.md`,按字段 / 索引 / 外键 / 业务注记**严格翻译**为: + +- 每张表一段 `CREATE TABLE` +- 字段顺序与 docs/03 表格行序一致;`Nullable` 列直接映射 `NOT NULL` / `NULL`;`默认` 列映射 `DEFAULT `;列尾用 `COMMENT '<业务含义>'` 写注释 +- 索引 +- 外键:在所有表创建完成后**统一追加** + +要求: +- **严禁臆造** docs/03 中没有的表 / 字段 / 索引 / 外键 +- **严禁省略** docs/03 中已有的列、注释或约束 +- 字符集统一 `utf8mb4` + `utf8mb4_unicode_ci`,引擎统一 `InnoDB`,除非 docs/03 业务注记明确要求其他设置 + +#### A.2 落盘 V1 文件 + +`Bash`: `mkdir -p sql/migrations`。 + +用 `Write` 写 `sql/migrations/V1__initial_schema.sql`,内容 = 头部注释 + DDL 主体: + +1. **头部注释**(6 行 SQL 注释): + - `-- Flyway migration V1 — initial schema for `(从 `CLAUDE.md § 🎯 项目概述` 读) + - `-- Generated: `(UTC ISO 8601 时间戳) + - `-- Source: 由计划 ③ build-db 从 docs/03-数据库设计文档.md 翻译生成(schema SSoT 是 docs/03)` + - `-- This is the FIRST migration; subsequent schema changes must be written as new files sql/migrations/V2__.sql, V3__... etc.` + - `-- Apply: Flyway runs this automatically at Spring Boot startup.` + - `-- Do not hand-edit this file after it is committed; write a new migration instead.` + +2. **DDL 主体**:A.1 推导出的所有 `CREATE TABLE` → `CREATE INDEX` → `ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY`,按此顺序拼接。 + +#### A.3 校验 V1 ↔ docs/03 集合一致性 + 自主修正 + +调 `${CLAUDE_SKILL_DIR}/scripts/validate.sh` 做脚本化的校验: + +```bash +bash "${CLAUDE_SKILL_DIR}/scripts/validate.sh" \ + sql/migrations/V1__initial_schema.sql \ + docs/03-数据库设计文档.md +``` + +退出码与处理: +- `0` → 通过,进入步骤 B +- `1` → **自主修正循环**(最多 3 轮,docs/03 是 SSoT 不动): + 1. 解析 stderr 差异清单,修正 V1.sql + 2. 重跑 validate.sh + 3. 退出 0 → 进入 B;退出 1 且本轮 < 3 → 回步骤 1;本轮 ≥ 3 仍失败 → 停下,打印最终残留差异 + 已尝试的 3 轮修正摘要,让用户介入 +- `2` → 用法错(V1 / docs 路径找不到),打印路径并停下 + +完成后(V1 写入并通过 validate.sh 校验),用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] V1 migration 已生成并校验 + apply 到本地 MySQL`(步骤 C 完成后一并勾选) + +### B. 数据库环境检查 + +#### B.1 检查 .env.local 凭据 + +用 `Glob` 检查 `.env.local` 是否存在;不存在 → 提示用户重新运行计划 ② `design` 重建并停下。 + +用 `Bash` 加载并校验 5 个必填字段非空: + +```bash +set -a; . .env.local; set +a +for v in DB_HOST DB_PORT DB_USER DB_PASSWORD DB_SCHEMA; do + eval val=\${$v:-} + [ -z "$val" ] && echo "MISSING: $v" +done +``` + +任一缺失 → 打印缺失字段名并停下,提示用户编辑 `.env.local` 后重跑。 + +#### B.2 验证 MySQL 连接 + +```bash +set -a; . .env.local; set +a +mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" -e "SELECT 1;" +``` + +- **成功** → 进入步骤 C +- **失败** → 打印具体错误(认证 / 主机不可达 / 端口拒接等),提示检查 `.env.local`,**停下**。 + +### C. 自动导入 MySQL + +#### C.1 DROP+CREATE 空库 + +```bash +./scripts/setup-test-db.sh +``` + +#### C.2 把 V1 灌入已清空的 schema + +```bash +set -a; . .env.local; set +a +mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" "$DB_SCHEMA" \ + < sql/migrations/V1__initial_schema.sql +``` + +非零退出 → 报错停下,打印 mysql stderr。 + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] V1 migration 已生成并校验 + apply 到本地 MySQL` + +#### C.3 自检 SHOW TABLES + +```bash +set -a; . .env.local; set +a +ACTUAL=$(mysql -N -B -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" \ + -e "SHOW TABLES;" "$DB_SCHEMA" | wc -l | tr -d ' ') +EXPECTED=$(grep -c '^## `' docs/03-数据库设计文档.md) +[ "$ACTUAL" = "$EXPECTED" ] || { echo "MISMATCH: actual=$ACTUAL expected=$EXPECTED"; exit 1; } +``` + +行数不一致 → 报错停下;一致 → 进入步骤 D。 + +### D. 生成 docs/05 API 契约 + 回填 REQ 依赖接口 + +#### D.1 渲染 docs/05 + +1. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-05-header-template.md`,填充 `base_path`(从 `docs/04 § 一` 推导 API 前缀,如 `/api/v1`)、`auth_note`(认证方式说明)、`pagination_note`(分页参数约定),写入 `docs/05-API接口契约.md` 头部。 +2. 对所有模块的每个 REQ:读取并推断 `${CLAUDE_SKILL_DIR}/templates/docs-05-endpoint-template.md`,追加到 docs/05。 + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] docs/05 API 契约已生成 + 回填 REQ 依赖接口`(步骤 D.2 完成后一并勾选) + +#### D.2 回填模块头 + REQ 卡片的 TBD 字段 + +1. 在 `docs/01-需求清单/*/_module.md`(模块头)和 `docs/01-需求清单/*/REQ-*.md`(REQ 卡片)中搜索 `TBD(build-db 自动补)` 并回填。**不动** `TBD(design 自动补)`(应已由 design 回填完毕)。 + - `_module.md` 的 `依赖模块` 字段:填入该模块所依赖的其他模块 ID(逗号分隔,无则填 `—`) + - `REQ-*.md` 的 `依赖接口` 字段:填入该 REQ 依赖的接口路径(逗号分隔,无则填 `—`) +2. 打印回填统计:`build-db 回填 处模块"依赖模块" + 处 REQ"依赖接口"`。 + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] docs/05 API 契约已生成 + 回填 REQ 依赖接口` + +### E. 模块/REQ 依赖顺序 → docs/08 § 二 + +本步骤计算模块/REQ 依赖拓扑顺序,将结果写入 docs/08 § 二(该 § 二 行序是 coding-start 的排序权威,无单独开发计划文件)。 + +#### E.1 构建模块依赖 DAG + 拓扑排序 + +1. 读取所有 `docs/01-需求清单/*/_module.md`,提取每个模块的 `依赖模块` 字段(经步骤 D.2 已回填)。 +2. 构建**模块依赖 DAG**(有向无环图),节点 = 模块 ID,边 = 「A 依赖 B → B 先于 A」。 +3. 拓扑排序得到 `module_topo_order[]`。 +4. **环依赖打破**:若模块 DAG 存在环(module_A ↔ module_B),按启发式(字母序 / 被依赖次数多者先)破环排出 `module_topo_order`,并在**参与环的模块里第一个 REQ** 的 `note` 字段填入原因(如 "A↔B 互依赖:先做 A 的骨架")。 + +#### E.2 模块内 REQ 排序 + +对每个模块内部: +1. 读取该模块所有 `REQ-*.md`,提取每个 REQ 的 `依赖接口` + `依赖表` 字段,推导 REQ 间依赖关系。 +2. 拓扑排序得到模块内 `req_order[]`。 +3. **REQ 级环依赖打破**:若模块内 REQ 互依赖,按字母序 / 被依赖次数多者先破环,`note` 填原因;非环 REQ `note` 留 `—`。 + +#### E.3 渲染 docs/08 § 二 + +按 `module_topo_order[]` 依次为每个模块渲染 bullet,追加到 `docs/08-模块任务管理.md` § 二(追加在 § 二 的注释块之后,保留原有注释格式示例): + +读取 `${CLAUDE_SKILL_DIR}/templates/docs-08-module-row-template.md`,填充: +- `{{module_id}}`:模块 ID +- `{{module_name}}`:模块中文名 +- `{{depends_on}}`:依赖模块 ID 列表(逗号分隔,无则填 `—`) +- `{{path_scopes}}`:`backend/module//` +- `{{req_checklist}}`:按模块内 `req_order[]` 生成,每行 ` - [ ] REQ-XXX-NNN 功能名` + +每个模块 bullet 间空一行,一次性追加全部模块。 + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] docs/08 § 二 模块清单(含 REQ 顺序)已生成` + +### F. 一致性检查 + 占位符扫描 + 计划完成 + +#### F.1 一致性检查(最多 3 轮自修复) + +**检查项**: +- 每个 docs/01 REQ 都出现在 docs/05(作为接口,如适用) +- docs/08 § 二 的 `module_id` 集合 = docs/01-需求清单/ 的模块目录集合 + +**不一致 → 按差异类型自主修复**: +- **REQ 缺 docs/05 endpoint** → 按步骤 D.1 规则为该 REQ 推测,并追加到 docs/05 +- **module_id 缺 docs/08 § 二** → 按步骤 E 规则渲染该模块 bullet,按拓扑序插入正确位置 + +修复后重跑检查;通过 → 进入 F.2;3 轮仍失败 → 停下,打印最终残留差异 + 已尝试的 3 轮修复摘要让用户介入。 + +#### F.2 最终占位符扫描 + +a. **`TBD` → 自动补齐**:Grep 搜索 `TBD(design 自动补)` 和 `TBD(build-db 自动补)`。有命中则就地补填(design 残留 → 查 docs/03 填 `依赖表`;build-db 残留 → 查 docs/05 按 REQ-ID 填 `依赖接口`),再 Grep 确认 0 命中;仍残留报错停下。 + +b. **`【人工填写:...】` → QA 循环等用户补**: + + 循环执行直到搜索不到 `【人工填写:` 且用户选「继续」: + - 0 命中 → 直接放行进入步骤 F.3 + - 有命中 → 打印残留清单(`<文件:行号> — <内容摘要>`),用 `AskUserQuestion` 弹「继续」/「有疑问想先沟通」二选一;用户回答后重扫验证再决定放行 / 继续循环 + + **每次弹 QA 前都重扫一次**——保证用户看到的 N 是最新的,避免「用户以为填完但实际还有残留」直接放行。 + +#### F.3 勾选 § 一 ③ 顶层 + 打印计划完成横幅 + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选 ③ 顶层: +- `- [ ] 计划 ③ DB 初始化 + 下游文档 — build-db` + +打印计划阶段终止横幅并**停下**(不自动进入 coding 阶段): + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + [build-db] ✅ 计划阶段(①②③)全部完成 + + 所有规划文档已就绪,docs/08 § 一 全部勾选。 + + ⚠️ 进入 Coding 阶段前必须完成: + 1. 审核全部 Plan 产出(docs/01 / 03 / 04 / 05 / 08 + CLAUDE.md + sql/migrations/V1 + scripts/*) + + 2. 把全部 Plan 产物 commit 到本地默认分支(main / master): + git add -A && git commit -m "chore: plan phase done" + + 3. 运行 /erp-workflow:coding-start 进入编码阶段 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` + +**停止**,不调用任何下游 skill。 + +## 参考 + +- `docs/03-数据库设计文档.md`(DDL 翻译输入,SSoT) +- `docs/01-需求清单/index.md`(模块索引) +- `docs/01-需求清单//_module.md`(模块依赖:回填 `依赖模块`;拓扑排序输入) +- `docs/01-需求清单//REQ-*.md`(REQ 依赖:回填 `依赖接口`;模块内 REQ 排序输入) +- `docs/08-模块任务管理.md` § 二(模块拓扑顺序追加目标;是 coding-start 的排序权威) +- `${CLAUDE_SKILL_DIR}/scripts/validate.sh`(A.3 表名 + 每表列名集合校验脚本) +- `${CLAUDE_SKILL_DIR}/templates/docs-05-header-template.md` +- `${CLAUDE_SKILL_DIR}/templates/docs-05-endpoint-template.md` +- `${CLAUDE_SKILL_DIR}/templates/docs-08-module-row-template.md`(模块 bullet 行模板) +- `.env.local`(DB 凭据) +- 产物:`sql/migrations/V1__initial_schema.sql`(由 Flyway 在 Spring Boot 启动时 apply) diff --git a/skills/plan/build-db/scripts/validate.sh b/skills/plan/build-db/scripts/validate.sh new file mode 100644 index 0000000..bed28ad --- /dev/null +++ b/skills/plan/build-db/scripts/validate.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# validate.sh — 校验 V1.sql 与 docs/03 的两个集合一致性: +# 维度 1: 表名集合 +# 维度 2: 每张共有表的列名集合 +# +# 用法: bash validate.sh +# 退出码: +# 0 = 一致 +# 1 = 不一致(差异明细打印到 stderr) +# 2 = 用法错误(路径找不到等) + +set -uo pipefail +export LC_ALL=C # sort / comm 行为确定 + +V1=${1:?missing V1 sql path} +DOC=${2:?missing docs/03 path} + +[ -f "$V1" ] || { echo "validate.sh: V1 not found: $V1" >&2; exit 2; } +[ -f "$DOC" ] || { echo "validate.sh: docs not found: $DOC" >&2; exit 2; } + +ERR=0 + +# ─── 维度 1: 表名集合 ─────────────────────────────────────────── +TABLES_DOC=$(grep -E '^## `[^`]+`' "$DOC" \ + | sed -E 's/^## `([^`]+)`.*/\1/' | sort -u) +TABLES_SQL=$(grep -E '^CREATE TABLE `[^`]+`' "$V1" \ + | sed -E 's/^CREATE TABLE `([^`]+)`.*/\1/' | sort -u) + +ONLY_DOC=$(comm -23 <(echo "$TABLES_DOC") <(echo "$TABLES_SQL")) +ONLY_SQL=$(comm -13 <(echo "$TABLES_DOC") <(echo "$TABLES_SQL")) + +if [ -n "$ONLY_DOC" ] || [ -n "$ONLY_SQL" ]; then + { + echo "=== 维度 1: 表名集合不一致 ===" + [ -n "$ONLY_DOC" ] && { echo " docs/03 有但 V1 无:"; echo "$ONLY_DOC" | sed 's/^/ - /'; } + [ -n "$ONLY_SQL" ] && { echo " V1 有但 docs/03 无:"; echo "$ONLY_SQL" | sed 's/^/ - /'; } + } >&2 + ERR=1 + # 表数差异 → 不再做列校验 + exit 1 +fi + +# ─── 维度 2: 每张共有表的列名集合 ────────────────────────────── +COMMON=$(comm -12 <(echo "$TABLES_DOC") <(echo "$TABLES_SQL")) + +extract_doc_cols() { + local table=$1 + awk -v t="$table" ' + $0 ~ "^## `" t "`" { in_table=1; in_fields=0; next } + in_table && /^## `/ { exit } + in_table && /^### 字段/ { in_fields=1; next } + in_table && in_fields && /^###/ { in_fields=0 } + in_table && in_fields && /^\|/ { + n = split($0, a, "|") + gsub(/^[ ]+|[ ]+$/, "", a[2]) + gsub(/`/, "", a[2]) + if (a[2] != "" && a[2] != "字段" && a[2] !~ /^-+$/) print a[2] + } + ' "$DOC" | sort -u +} + +extract_sql_cols() { + local table=$1 + awk -v t="$table" ' + $0 ~ "^CREATE TABLE `" t "`" { in_table=1; next } + in_table && /^\)/ { in_table=0; next } + in_table && /^[[:space:]]*`[^`]+`/ \ + && $0 !~ /^[[:space:]]*(PRIMARY|UNIQUE|KEY|FOREIGN|CONSTRAINT|INDEX)/ { + match($0, /`[^`]+`/) + print substr($0, RSTART+1, RLENGTH-2) + } + ' "$V1" | sort -u +} + +while IFS= read -r t; do + [ -z "$t" ] && continue + D_COLS=$(extract_doc_cols "$t") + S_COLS=$(extract_sql_cols "$t") + ONLY_D=$(comm -23 <(echo "$D_COLS") <(echo "$S_COLS")) + ONLY_S=$(comm -13 <(echo "$D_COLS") <(echo "$S_COLS")) + if [ -n "$ONLY_D" ] || [ -n "$ONLY_S" ]; then + { + echo "=== 维度 2: 表 \`$t\` 列名不一致 ===" + [ -n "$ONLY_D" ] && { echo " docs/03 有但 V1 无:"; echo "$ONLY_D" | sed 's/^/ - /'; } + [ -n "$ONLY_S" ] && { echo " V1 有但 docs/03 无:"; echo "$ONLY_S" | sed 's/^/ - /'; } + } >&2 + ERR=1 + fi +done <<< "$COMMON" + +if [ $ERR -ne 0 ]; then + exit 1 +fi + +echo "validate.sh: ✓ 表名集合 + 每表列名集合 与 docs/03 一致" +exit 0 diff --git a/skills/plan/build-db/templates/docs-05-endpoint-template.md b/skills/plan/build-db/templates/docs-05-endpoint-template.md new file mode 100644 index 0000000..91a1fda --- /dev/null +++ b/skills/plan/build-db/templates/docs-05-endpoint-template.md @@ -0,0 +1,12 @@ +### {{req_id}} {{title}} + +- **Method**: {{method}} +- **Path**: `{{path}}` +- **Auth**: {{auth}} +- **请求**: {{request_summary}} +- **响应**: {{response_summary}} + +#### 错误码 +{{#each errors}} +- `{{code}}` — {{message}} +{{/each}} diff --git a/skills/plan/build-db/templates/docs-05-header-template.md b/skills/plan/build-db/templates/docs-05-header-template.md new file mode 100644 index 0000000..ca0b68e --- /dev/null +++ b/skills/plan/build-db/templates/docs-05-header-template.md @@ -0,0 +1,30 @@ +# 05-API接口契约 + +BasePath: `{{base_path}}` +端口: `【人工填写:后端端口,默认 8080】` + +## 全局约定 + +### 响应格式 +```json +{"code": 200, "message": "操作成功", "data": {}, "timestamp": 1700000000000} +``` + +### 错误码 +| 范围 | 含义 | +|---|---| +| 200 | 成功 | +| 400xx | 客户端参数错误 | +| 401xx | 认证/授权错误 | +| 403xx | 权限不足 | +| 404xx | 资源不存在 | +| 500xx | 服务端内部错误 | + +### 鉴权 +{{auth_note}} + +### 分页参数 +{{pagination_note}} + +## 接口清单 +(各模块接口段落见下方,由 `build-db` 按 REQ 填入) diff --git a/skills/plan/build-db/templates/docs-08-module-row-template.md b/skills/plan/build-db/templates/docs-08-module-row-template.md new file mode 100644 index 0000000..edd15f1 --- /dev/null +++ b/skills/plan/build-db/templates/docs-08-module-row-template.md @@ -0,0 +1,6 @@ +- {{module_id}} {{module_name}} + - 依赖: {{depends_on}} + - 路径: {{path_scopes}} + - 里程碑: — + - 功能: +{{req_checklist}} diff --git a/skills/plan/design/SKILL.md b/skills/plan/design/SKILL.md new file mode 100644 index 0000000..52cb725 --- /dev/null +++ b/skills/plan/design/SKILL.md @@ -0,0 +1,174 @@ +--- +name: design +description: 计划第 2 段——生成架构文档(docs/04 § 一+,含前端 Design Tokens + 环境配置)+ 工具脚本 + .env.local + sql/migrations/,然后从 REQ 正向设计 docs/03 并回填 REQ 依赖表,停下等人工审阅 docs/03。 +user-invocable: false +allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(mkdir *) Bash(cp *) Bash(cat *) Bash(bash *) +--- + +**所有输出必须使用中文。** + +# design + +## 执行步骤 + +### 步骤 0:打印当前位置流程图 + +用 `Bash` 执行以下命令(文件不存在时静默忽略,不报错): + +```bash +cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/plan-start/banners/flow.txt" 2>/dev/null || true +``` + +打印横幅:`▶ 计划阶段 ② — design`。 + +### A. 读取锁定的输入 + +用 `Read` 读取: +- `docs/04-技术规范.md` § 零 技术栈表 +- `docs/01-需求清单/index.md` 需求索引 +- `docs/01-需求清单/` 下所有 REQ 卡片(`docs/01-需求清单/*/REQ-*.md`) + +后续所有内容都基于它们推导。 + +### B. 生成 docs/04 § 一+(保留 § 零 不覆盖) + +docs/04 已由 init 写入 § 零。本步骤追加 § 一 ~ 五。 + +docs/04 承担三类内容(不再生成独立的前端规范文件或环境配置文件): +- § 一~三:后端/前端/共同编码规范 +- § 四:前端 Design Tokens + 交互约定 +- § 五:环境配置 + +操作: +1. 读取 `docs/04-技术规范.md`(现有 § 零 完整内容)。 +2. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`。 +3. 基于技术栈,按大纲生成 § 一 ~ 五 的项目专属内容,剥掉 HTML 注释(注释是给 LLM 的提示,不应出现在最终文档里)。 +4. 拼接原有内容和新生成内容,写回 `docs/04-技术规范.md`。 + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] 架构文档已生成(docs/04 § 一+ | scripts/*.sh | .env.local | sql/migrations/)`(步骤 C 完成后一并勾选) + +### C. 生成工具脚本 + 目录结构 + +#### C.1 复制固定文件 + +```bash +mkdir -p scripts sql/migrations src/styles +cp "${CLAUDE_SKILL_DIR}/templates/env-local-template" .env.local +cp "${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh" scripts/setup-test-db.sh +``` + +注意:本阶段不生成 `src/styles/tokens.css`(前端 token 骨架由前端阶段处理)。 + +#### C.2 渲染 scripts/test.sh + +读取 `${CLAUDE_SKILL_DIR}/templates/scripts-test-template.sh`,基于步骤 A 的技术栈(docs/04 § 零)为以下 7 个命令槽推断命令后写到 `scripts/test.sh`(纯后端项目可把前端 / E2E 槽填 `echo` 占位): + +- `{{backend_build}}` / `{{backend_lint}}` / `{{backend_test}}` — 后端各 stage 命令 +- `{{frontend_build}}` / `{{frontend_lint}}` / `{{frontend_test}}` — 前端各 stage 命令 +- `{{e2e_cmd}}` — E2E(无 E2E 工具则填 `echo "[test.sh] e2e 略"`) + +> 推断规则:根据 `docs/04 § 零`。 +> - 「后端*」存在 → 据后端技术栈推 backend 三槽(build / lint / test 命令) +> - 「前端*」存在 → 据前端技术栈推 frontend 三槽 +> - 缺席 stack → 三槽全填 `:`(语法合法即可) +> - `{{e2e_cmd}}` 通常仅前端,按上述前端规则或填 `echo "[test.sh] e2e 略"` +> +> 表结构异常(列名变更 / 无中文前缀)时停下,用 `AskUserQuestion` 让用户显式确认每 stack 命令。 + +#### C.3 赋权 + +```bash +bash -c "chmod +x scripts/*.sh" +``` + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] 架构文档已生成(docs/04 § 一+ | scripts/*.sh | .env.local | sql/migrations/)` + +### D. 追加 .gitignore 忽略项 + +调用脚本完成合并: + +```bash +bash "${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh" "${CLAUDE_SKILL_DIR}/templates/gitignore-append-template" +``` + +### E. 推导 schema + 渲染 docs/03 + +基于步骤 A 读到的 REQ + docs/04 § 一命名规范,**正向推导**业务实体 → 表 + 字段 + 索引 + 外键。要求: + +1. 严格套用 `docs/04 § 一` 的命名规范(匈牙利前缀 `i` int / `s` varchar / `t` datetime 等) +2. **主键**:模板内置 `iIncrement` 为主键。REQ 明确要求复合主键 / UUID / 业务主键时按 REQ;其他主键变更需同步改 docs-03-header / docs-03-table 两份模板 +3. **外键**:依据 REQ 中的引用关系(如「订单引用客户」),明确列出 `ON DELETE` / `ON UPDATE` 策略;不能确定时默认 `RESTRICT` +4. **索引**:根据 REQ 的查询模式推导业务索引;外键列默认建索引;标准列里 `sBrandsId` / `sSubsidiaryId` 这类多租户隔离列,按业务查询模式建组合索引 +5. **业务注记**:对每张表用一两句话说明业务用途、关键约束、与其他表的关系 + +如果某 REQ 表述模糊以致无法推断关键 schema 细节(如:枚举值范围 / 字段长度上限 / 必填性),先按合理默认推导并在该字段「业务含义」列加 `【人工填写:需用户审阅】` 标注,不打断本次推导。 + +渲染 docs/03: +1. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md`,填充 `schema_name`(从 `.env.local` 读 `DB_SCHEMA`,无则填 `【人工填写:DB_SCHEMA】`)、`er_overview`(纯文本 ER 概览)。 +2. 渲染「表清单」:对每张表,读取并填充 `${CLAUDE_SKILL_DIR}/templates/docs-03-table-template.md`。 +3. 写入 `docs/03-数据库设计文档.md`。 + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] docs/03 数据库设计已生成(REQ → 表/字段/索引/外键,回填 REQ 依赖表)` + +### F. 回填模块头 + REQ 卡片的 TBD 字段 + +1. 列出 `docs/01-需求清单/*/_module.md`(模块头)和 `docs/01-需求清单/*/REQ-*.md`(REQ 卡片)。 +2. 在这些文件中搜索 `TBD(design 自动补)` 并回填为实际表名。**不动** `TBD(build-db 自动补)`。 + - `_module.md` 的 `涉及表` 字段:填入该模块涉及的所有表名(逗号分隔) + - `REQ-*.md` 的 `依赖表` 字段:填入该 REQ 操作的表名(逗号分隔) +3. 打印回填统计:`design 回填 处模块"涉及表" + 处 REQ"依赖表"`。 + +### G. 勾选 § 一 ② 顶层 + 停下等人工审阅 + +1. 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选 ② 顶层: + - `- [ ] 计划 ② 脚手架 + 数据库设计 — design` + +2. 打印停下横幅并**停下**: + + ``` + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + [design] ✅ 计划 ② 完成 + + 产出: + ✓ docs/04-技术规范.md(§ 一+ | § 四 Design Tokens | § 五 环境配置) + ✓ scripts/setup-test-db.sh + scripts/test.sh(已赋权) + ✓ .env.local(含占位符,凭据请自填) + ✓ sql/migrations/(目录已建) + ✓ .gitignore(已追加忽略项) + ✓ docs/03-数据库设计文档.md + ✓ docs/01 各 REQ 卡片"依赖表" + 模块头"涉及表" 已回填 + + ⏸ 现在请你审阅 docs/03。 + 重点关注: + - 业务实体覆盖是否完整 + - 字段类型 / 长度 / 是否可空 / 默认值是否合理 + - 索引是否覆盖主要查询模式 + - 外键 ON DELETE / ON UPDATE 策略是否符合业务 + - 字段「业务含义」列含 `【人工填写:需用户审阅】` 标注的位置需逐一确认 + - .env.local 中的凭据占位符请直接编辑文件填写(凭据不进会话) + + 审阅完成后,再运行: + /erp-workflow:plan-start + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + ``` + + **停止**,不调用任何下游 skill。 + +## 参考 + +- `docs/04-技术规范.md` § 零(技术栈输入) +- `docs/01-需求清单/index.md`(模块索引输入) +- `docs/01-需求清单//_module.md`(模块头:回填 `涉及表`) +- `docs/01-需求清单//REQ-*.md`(REQ 输入 + 回填 `依赖表`) +- `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`(大纲:§ 一~三 编码规范 + § 四 Design Tokens + § 五 环境配置) +- `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md` +- `${CLAUDE_SKILL_DIR}/templates/docs-03-table-template.md` +- `${CLAUDE_SKILL_DIR}/templates/scripts-test-template.sh`(推断命令填充槽位;缺席 stack 填 `:`) +- `${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh`(0 槽位) +- `${CLAUDE_SKILL_DIR}/templates/env-local-template`(0 槽位) +- `${CLAUDE_SKILL_DIR}/templates/gitignore-append-template`(0 槽位) +- `${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh`(.gitignore 逐行判重合并脚本) diff --git a/skills/plan/design/scripts/merge-gitignore.sh b/skills/plan/design/scripts/merge-gitignore.sh new file mode 100755 index 0000000..5beb4f6 --- /dev/null +++ b/skills/plan/design/scripts/merge-gitignore.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# merge-gitignore.sh +# 把模板里的忽略规则合并到项目根的 .gitignore: +# - 若 .gitignore 不存在 → 直接 cp 模板(含注释头和结构) +# - 若已存在 → 逐行判重,只追加模板里缺失的规则行(跳过注释/空行) +# +# 用法:merge-gitignore.sh [] +# template_path 模板文件绝对路径(由 design skill 传入) +# target_gitignore_path 目标 .gitignore 路径,默认为当前工作目录下的 .gitignore +# +# 判重:grep -xF 整行精确匹配 + 字面字符串(非正则),避免 .env 误匹配 .env.local, +# 也避免 *.class / *.iml 等通配符被当作 regex。 + +set -euo pipefail + +template="${1:?usage: merge-gitignore.sh []}" +target="${2:-.gitignore}" + +if [ ! -f "$template" ]; then + echo "[merge-gitignore] ERROR: template not found: $template" >&2 + exit 1 +fi + +if [ ! -f "$target" ]; then + cp "$template" "$target" + echo "[merge-gitignore] created $target from template" + exit 0 +fi + +added=0 +while IFS= read -r line; do + case "$line" in ""|"#"*) continue ;; esac + if ! grep -qxF "$line" "$target"; then + echo "$line" >> "$target" + added=$((added + 1)) + fi +done < "$template" + +echo "[merge-gitignore] $target updated (+$added rules)" diff --git a/skills/plan/design/templates/docs-03-header-template.md b/skills/plan/design/templates/docs-03-header-template.md new file mode 100644 index 0000000..0def776 --- /dev/null +++ b/skills/plan/design/templates/docs-03-header-template.md @@ -0,0 +1,28 @@ +# 03-数据库设计文档 + +- **Schema**: `{{schema_name}}` +- **Migration 清单**: `sql/migrations/V*.sql`(由 Flyway 顺序 apply) +- **生成方式**: 由计划 ② `design` 基于 `docs/01-需求清单//REQ-*.md` REQ 卡片正向设计生成(schema SSoT)。 + +## 项目标准列约定 + +下文每张业务表的字段清单都自动包含以下 5 个标准列(匈牙利前缀 `i` int / `s` varchar / `t` datetime)。渲染时由 `docs-03-table-template.md` 模板内置原样输出。 + +| 列名 | 类型 | 可空 | 主键 | 说明 | +|---|---|---|---|---| +| `iIncrement` | int | 否 | 是 | 整数主键 ID(自增方式由实现决定:DB `AUTO_INCREMENT` 或应用 / 触发器分配) | +| `sId` | varchar(100) | 是 | — | 业务 ID(对外暴露的字符串标识,如 UUID / 人类可读编号) | +| `sBrandsId` | varchar(100) | 是 | — | 品牌 ID(多租户隔离) | +| `sSubsidiaryId` | varchar(100) | 是 | — | 子公司 ID(组织层级隔离) | +| `tCreateDate` | datetime | 否 | — | 记录创建时间 | + +字典 / 辅助表如有豁免,在该表业务注记里注明豁免原因。 + +## ER 关系概览 + +{{er_overview}} + +## 表清单 +{{#each tables}} +- `{{table_name}}` — {{purpose}} +{{/each}} diff --git a/skills/plan/design/templates/docs-03-table-template.md b/skills/plan/design/templates/docs-03-table-template.md new file mode 100644 index 0000000..d05c5be --- /dev/null +++ b/skills/plan/design/templates/docs-03-table-template.md @@ -0,0 +1,27 @@ +## `{{table_name}}` — {{purpose}} + +### 字段 + +| 字段 | 类型 | Nullable | 默认 | 业务含义 | +|---|---|---|---|---| +| `iIncrement` | int | 否 | 自增函数 | 整数主键 ID(标准列) | +| `sId` | varchar(100) | 是 | uuid 函数 | 业务 ID(标准列) | +| `sBrandsId` | varchar(100) | 是 | `1111111111` | 品牌 ID(多租户隔离,标准列) | +| `sSubsidiaryId` | varchar(100) | 是 | `1111111111` | 子公司 ID(组织层级隔离,标准列) | +| `tCreateDate` | datetime | 否 | 当前时间 | 创建时间(标准列) | +{{#each columns}} +| {{name}} | {{type}} | {{nullable}} | {{default}} | {{business_meaning}} | +{{/each}} + +### 索引 +{{#each indexes}} +- `{{name}}` ({{type}}): {{columns}} +{{/each}} + +### 外键 +{{#each foreign_keys}} +- `{{name}}`: {{from_col}} → {{to_table}}.{{to_col}} ({{on_delete}}) +{{/each}} + +### 业务注记 +{{notes}} diff --git a/skills/plan/design/templates/docs-04-skeleton-template.md b/skills/plan/design/templates/docs-04-skeleton-template.md new file mode 100644 index 0000000..e2e659c --- /dev/null +++ b/skills/plan/design/templates/docs-04-skeleton-template.md @@ -0,0 +1,122 @@ + + +## 一、后端规范 + +### 1.1 规则 + +- 【人工填写:一条后端通用约定,按需复制本行新增更多;无则填「无」】 + +### 1.2 分层结构 + + +### 1.3 命名约定 + + +### 1.4 统一响应格式 + + +### 1.5 异常处理 + + +### 1.6 事务 + + +### 1.7 认证 + + +## 二、前端规范 + +### 2.1 目录约定 + + +### 2.2 状态管理 + + +### 2.3 请求封装 + + +### 2.4 错误处理 + + +### 2.5 样式与主题 + + +## 三、共同约定 + +### 3.1 Git 提交 +`(): REQ-XXX-NNN` + +### 3.2 分页查询 + + +### 3.3 日期与金额 + + +### 3.4 数据访问规约 + + +### 3.5 配置与安全 + + +## 四、前端 Design Tokens / 交互约定 + +> 所有色值统一以 CSS 变量定义于 src/styles/tokens.css;命名规范见 § 2.5。 +> 本项目所有页面布局以项目根 `prototype/` 目录下的静态 HTML mockup 为权威。 +> 前端阶段实现时直接以 prototype/ HTML 推导组件树与样式。本节仅承载跨页面通用规则与 Design Tokens。 + +### 4.1 通用交互规则 + +#### 4.1.1 操作反馈 + + +#### 4.1.2 数据展示 + + +#### 4.1.3 权限控制(前端) + + +### 4.2 全局调色板 + + +### 4.3 组件级状态色 + + +### 4.4 引用约定 + + +## 五、环境配置 + +### 5.1 依赖清单 + + + +### 5.2 端口约定 + + + +### 5.3 环境变量 + +运行时凭据(数据库连接、JWT 密钥等)全部放在仓库根的 `.env.local`,不入 git。 +字段清单与占位符见该文件,真实值由开发者本地填写。 + +### 5.4 常用命令 + + diff --git a/skills/plan/design/templates/env-local-template b/skills/plan/design/templates/env-local-template new file mode 100644 index 0000000..c16e67f --- /dev/null +++ b/skills/plan/design/templates/env-local-template @@ -0,0 +1,25 @@ +# .env.local — 本地开发凭据(入 .gitignore,不提交) +# +# 规则: +# 1. 值含 `$`、反引号、空格、`!` 等 shell 特殊字符时,必须用单引号包裹: +# DB_PASSWORD='p@ss$w0rd!' +# 否则 `set -a; . .env.local; set +a` 会做变量展开导致密码错乱。 +# 2. DB_HOST 建议保持 localhost / 127.0.0.1;非本地 host 默认会被 scripts/setup-test-db.sh 防护拒绝。 +# 若必须用远程测试库,把 host 列入下方 TEST_DB_ALLOWED_HOSTS。 +# 3. DB_SCHEMA 建议命名含 test / _dev / _local / _ci,避免与生产库同名。 + +DB_HOST=【人工填写:MySQL host,推荐 localhost】 +DB_PORT=【人工填写:MySQL port,默认 3306】 +DB_USER=【人工填写:开发账号名】 +DB_PASSWORD=【人工填写:对应密码,含特殊字符时用单引号包裹】 +DB_SCHEMA=【人工填写:schema 名,推荐含 test/_dev/_local,例如 erp_dev】 +JWT_SECRET=【人工填写:JWT 签名密钥,256+ bit 随机串】 + +# 可选:额外允许 DROP CREATE 的远程 host(空格或逗号分隔)。仅当 DB_HOST 指向公司测试 MySQL 等 +# 非本地服务器时填写;留空表示只允许 localhost / 127.0.0.1 / ::1。 +# 示例:TEST_DB_ALLOWED_HOSTS="118.178.19.35 test-mysql.internal" +# +# ⚠️ 列入后该 host 每次 test.sh 都会被 DROP CREATE(无二次确认)。 +# 仅用于你完全可控的测试库;生产/共享库/多人共享的 staging 库**千万别列**。 +# (防护 2 还会检查 schema 名须含 test/_dev/_local/_ci,独立兜底。) +TEST_DB_ALLOWED_HOSTS= diff --git a/skills/plan/design/templates/gitignore-append-template b/skills/plan/design/templates/gitignore-append-template new file mode 100644 index 0000000..4aba130 --- /dev/null +++ b/skills/plan/design/templates/gitignore-append-template @@ -0,0 +1,32 @@ +# ==== ERP 插件推荐忽略项(design 追加) ==== +# 本地运行时配置(含真实凭据,严禁入库) +.env.local +.env.*.local + +# Java / Maven +target/ +*.class + +# Node / 前端构建产物 +node_modules/ +dist/ +build/ +coverage/ + +# IDE +.idea/ +.vscode/ +*.iml + +# OS +.DS_Store +Thumbs.db + +# 日志 +*.log +logs/ + +# 插件运行时临时文件 +.tmp/ +*.raw +# ==== 结束 ==== diff --git a/skills/plan/design/templates/scripts-setup-test-db-template.sh b/skills/plan/design/templates/scripts-setup-test-db-template.sh new file mode 100644 index 0000000..41a3970 --- /dev/null +++ b/skills/plan/design/templates/scripts-setup-test-db-template.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# scripts/setup-test-db.sh — 数据库重置脚本:drop + create 空库。 +# schema apply 由 Flyway 在 Spring Boot 启动时自动处理(见 docs/04 技术栈 + sql/migrations/V*.sql)。 +# seed 数据由测试框架负责(Spring @Sql / Flyway R__seed.sql / data.sql)。 +# +# 使用场景: +# - scripts/test.sh 开头:清空库,让 Spring 启动时 Flyway 从 V1 开始重放所有 migration +# - scripts/test.sh 结尾:清空库,避免测试遗留污染下次运行 +# - 手动调试时:reset 到零状态 +# +# 防护:本脚本只允许在本地 host + 测试库名上执行;非预期目标会被拒绝, +# 避免 .env.local 误指向 staging/prod 时触发不可逆 DROP。 + +set -euo pipefail + +ENV_FILE="$(dirname "$0")/../.env.local" +[ -f "$ENV_FILE" ] || { echo "[setup-test-db] ⚠️ .env.local 不存在($ENV_FILE)" >&2; exit 1; } + +# 用 set -a 加载,让 KEY=VALUE 导出为环境变量;密码中含特殊字符时 .env.local 请用单引号包裹 +set -a; . "$ENV_FILE"; set +a + +# 防护 1:默认只允许本地 host(localhost / 127.0.0.1 / ::1)。 +# 若要为本项目额外允许某些远程 host(如公司测试 MySQL),在 .env.local 里设: +# TEST_DB_ALLOWED_HOSTS="118.178.19.35 test-mysql.internal" # 空格或逗号分隔 +# 被列入者可直接 DROP CREATE,不再需要 TEST_DB_ALLOW_REMOTE=1。 +ALLOWED_HOSTS="localhost 127.0.0.1 ::1 ${TEST_DB_ALLOWED_HOSTS//,/ }" +host_allowed=0 +for h in $ALLOWED_HOSTS; do + [ "${DB_HOST:-}" = "$h" ] && { host_allowed=1; break; } +done +if [ "$host_allowed" -ne 1 ]; then + echo "[setup-test-db] ⚠️ 拒绝在非白名单 host (${DB_HOST}) 上执行 DROP DATABASE" >&2 + echo " 当前白名单:${ALLOWED_HOSTS}" >&2 + echo " 加入 host:在 .env.local 追加 TEST_DB_ALLOWED_HOSTS=\" \"" >&2 + echo " 一次性绕过:TEST_DB_ALLOW_REMOTE=1 $0" >&2 + [ "${TEST_DB_ALLOW_REMOTE:-0}" = "1" ] || exit 1 +fi + +# 防护 2:schema 名需像测试/开发库(含 test / _dev / _local),否则要求显式确认 +case "${DB_SCHEMA:-}" in + *test*|*_dev|*_local|*_ci) + ;; + *) + echo "[setup-test-db] ⚠️ schema '${DB_SCHEMA}' 不像测试库(期望命名含 test / _dev / _local / _ci)" >&2 + echo " 如确为期望行为,请显式声明:TEST_DB_ALLOW_PROD_NAME=1 $0" >&2 + [ "${TEST_DB_ALLOW_PROD_NAME:-0}" = "1" ] || exit 1 + ;; +esac + +# 防护 3:显式 banner,让人看见自己在 drop 什么;远程 host 额外提示白名单内容 +echo "[setup-test-db] 即将 DROP + CREATE \`${DB_SCHEMA}\` on ${DB_HOST}:${DB_PORT}" +case "${DB_HOST:-}" in + localhost|127.0.0.1|::1) ;; + *) + echo "[setup-test-db] ⚠️ 目标是 **远程** host(已在 TEST_DB_ALLOWED_HOSTS 白名单中,每次 test.sh 都会 DROP)" + echo "[setup-test-db] 当前白名单: ${ALLOWED_HOSTS}" + echo "[setup-test-db] 若不希望每次自动 DROP,从 .env.local 的 TEST_DB_ALLOWED_HOSTS 删掉此 host" + ;; +esac + +MYSQL_CMD="mysql -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD}" + +$MYSQL_CMD -e "DROP DATABASE IF EXISTS \`${DB_SCHEMA}\`; CREATE DATABASE \`${DB_SCHEMA}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" + +echo "[setup-test-db] done — schema will be applied by Flyway when Spring Boot starts" diff --git a/skills/plan/design/templates/scripts-test-template.sh b/skills/plan/design/templates/scripts-test-template.sh new file mode 100644 index 0000000..07d705d --- /dev/null +++ b/skills/plan/design/templates/scripts-test-template.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# scripts/test.sh —— 合并到默认分支(main / master)前的测试闸门。 +# 顺序:detect → setup-db → build → lint → unit+integration → e2e → reset-db +# 由 milestone skill(通过子会话)调用。 + +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$PROJECT_ROOT" + +# Stack detection (runtime, mode-agnostic) +HAS_BACKEND=0; [ -d backend ] && HAS_BACKEND=1 +HAS_FRONTEND=0; [ -d frontend ] && HAS_FRONTEND=1 +if [ $HAS_BACKEND -eq 0 ] && [ $HAS_FRONTEND -eq 0 ]; then + echo "[test.sh] FATAL: neither backend/ nor frontend/ exists" >&2 + exit 1 +fi + +echo "[test.sh] 1/6 setup test db" +./scripts/setup-test-db.sh + +echo "[test.sh] 2/6 build" +if [ $HAS_BACKEND -eq 1 ]; then (cd backend && {{backend_build}}); else echo "[test.sh] skip backend build"; fi +if [ $HAS_FRONTEND -eq 1 ]; then (cd frontend && {{frontend_build}}); else echo "[test.sh] skip frontend build"; fi + +echo "[test.sh] 3/6 lint" +if [ $HAS_BACKEND -eq 1 ]; then (cd backend && {{backend_lint}}); else echo "[test.sh] skip backend lint"; fi +if [ $HAS_FRONTEND -eq 1 ]; then (cd frontend && {{frontend_lint}}); else echo "[test.sh] skip frontend lint"; fi + +echo "[test.sh] 4/6 unit + integration" +if [ $HAS_BACKEND -eq 1 ]; then (cd backend && {{backend_test}}); else echo "[test.sh] skip backend test"; fi +if [ $HAS_FRONTEND -eq 1 ]; then (cd frontend && {{frontend_test}}); else echo "[test.sh] skip frontend test"; fi + +echo "[test.sh] 5/6 E2E" +{{e2e_cmd}} + +echo "[test.sh] 6/6 reset test db" +./scripts/setup-test-db.sh + +echo "[test.sh] GREEN" diff --git a/skills/plan/init/SKILL.md b/skills/plan/init/SKILL.md new file mode 100644 index 0000000..7863637 --- /dev/null +++ b/skills/plan/init/SKILL.md @@ -0,0 +1,233 @@ +--- +name: init +description: 计划第 1 段——项目初始化 + 范围锁定。复制 CLAUDE.md/docs(01/04/08) 模板、依赖检查、git init,引导项目概述+技术栈+需求索引,生成 REQ 卡片骨架,停下等人工审阅 REQ。 +user-invocable: false +allowed-tools: Glob Read Edit Grep Skill AskUserQuestion Bash(mkdir *) Bash(cp *) Bash(sed *) Bash(bash *) Bash(cat *) Bash(git init) Bash(command -v *) Bash(uname *) Bash(brew *) Bash(apt *) Bash(apt-get *) Bash(yum *) Bash(apk *) Bash(export PATH=*) Bash(echo *) +--- + +**所有输出必须使用中文。** + +你负责完成计划第 ① 段:项目初始化 + 范围锁定。 + +## 执行步骤 + +### 步骤 0:打印计划流程图 + +用 `Bash` 向用户展示整体流程图(▶ 位于"计划 ①"): + +```bash +cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/plan-start/banners/flow.txt" 2>/dev/null || true +``` + +> 注:`flow.txt` 由 Task 7 创建,当前若文件不存在,命令静默忽略,不影响后续执行。 + +打印分发横幅: + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + [init] 计划 ① 初始化 + 范围锁定 + ▶ 当前位置:计划 ① / 共 ③ +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` + +### A. 幂等复制模板文件 + +用 `Bash` 一次性完成。`cp -n` 表示"不覆盖已存在的文件": + +```bash +mkdir -p docs/01-需求清单 +cp -n "${CLAUDE_SKILL_DIR}/templates/CLAUDE-template.md" CLAUDE.md +cp -n "${CLAUDE_SKILL_DIR}/templates/docs-01-index-template.md" docs/01-需求清单/index.md +cp -n "${CLAUDE_SKILL_DIR}/templates/docs-04-stack-template.md" docs/04-技术规范.md +cp -n "${CLAUDE_SKILL_DIR}/templates/docs-08-initial-template.md" docs/08-模块任务管理.md +``` + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] 项目文件骨架已创建(CLAUDE.md + docs/01 index + docs/04 + docs/08)` + +### B. 依赖检查 + 自动安装(命令行工具) + +对 **git、mysql** 两个工具依次执行以下流程: + 1. 如果缺失,尝试自动安装。 + 2. 如果检测到不在 PATH,尝试添加进 PATH,并加载。 + +全部通过后打印单行汇总再进入步骤 C: + +``` +[init] 依赖检查: git ✓ mysql ✓ +``` + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] 依赖检查通过(git / mysql)` + +### C. 初始化 Git(如尚未初始化) + +用 `Glob` 检查 `.git/` 目录是否存在。 +- 不存在 → 用 `Bash` 执行 `git init`。 +- 已存在 → 跳过。 + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] Git 已初始化` + +打印完成横幅: + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + [init] 项目初始化完成 + + 已创建: + ✓ CLAUDE.md(从插件模板复制) + ✓ docs/01-需求清单/index.md(待人工填写模块索引) + ✓ docs/04-技术规范.md(默认技术栈,步骤 E 让用户确认) + ✓ docs/08-模块任务管理.md(全流程进度跟踪) + 已勾选:初始化子项 3 项 + + 下一步:引导项目概述 + 技术栈 + 需求索引 + 生成 REQ 卡片 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` + +### D. 提示用户填写项目概述并等待 + +向用户输出: + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + [init] 请填写项目概述 + + 📄 文件位置: ./CLAUDE.md + 📌 编辑位置: § 🎯 项目概述 + + 请将以下占位符替换为实际值: + - 项目名称 + - 项目简述 + - 目标用户 + - 部署方式 + 改完后回来选择「继续」。 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` + +用 `AskUserQuestion` 询问: +- **question**: `项目概述填写完毕了吗?` + - 用户选择「继续」→ 用 `Grep` 在 `CLAUDE.md` 搜索 `【人工填写:`(限定 § 🎯 项目概述 节)。命中 → 打印残留行 + 路径,重新弹出同样的 AskUserQuestion;0 命中 → 勾选并进入步骤 E。 + - 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。 + +0 命中后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述)` + +### E. 提示用户检查默认技术栈并等待 + +`docs/04-技术规范.md` 已由步骤 A 用模板复制(默认技术栈)。本步骤让用户检查 / 调整 § 零。 + +向用户输出: + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + [init] 技术栈已保存 + + 📄 文件位置: ./docs/04-技术规范.md(由模板生成) + 📌 编辑位置: § 零、技术栈总览 + + 请检查技术栈表: + - 不需要的行直接删除(如纯后端项目删前端行) + - 需要替换的技术直接改 + - 需要新增的条目直接加行 + 改完后回来选择「继续」。 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` + +用 `AskUserQuestion` 询问: +- **question**: `技术栈检查完毕了吗?` + - 用户选择「继续」→ 进入步骤 F。 + - 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。 + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] 技术栈已确认(docs/04 § 零)` + +### F. 提示用户填写需求清单并等待 + +`docs/01-需求清单/index.md` 已由步骤 A 写入占位符模板,这里让用户补齐模块清单。 + +向用户输出: + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + [init] 请填写需求清单模块索引 + + 📄 文件位置: ./docs/01-需求清单/index.md + 📌 编辑位置: § 模块索引(表格) + + 请按业务列出所有模块: + - 每行一个模块(如 SYS 系统管理 / PUR 采购 / SAL 销售) + - 「核心功能点」只需关键词,CC 会拆分为 REQ 卡片 + 改完后回来选择「继续」。 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` + +用 `AskUserQuestion` 询问: +- **question**: `需求清单模块索引填写完毕了吗?` + - 用户选择「继续」→ 进入步骤 G。 + - 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。 + +完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: +- ` - [ ] 需求清单索引已填写(docs/01-需求清单/index.md)` + +### G. 生成 REQ 卡片骨架并停下等人工审阅 + +1. 用 `Grep` 校验 `docs/01-需求清单/index.md` 无 `【人工填写:` 残留;有则回步骤 F。 +2. 用 `Read` 读 `index.md` 解析模块索引。 +3. **单次 Bash 写入所有文件**(替代 N×9 次 Edit): + + - **每模块推断**:三元组 `{module_code, module_name, module_brief}` + N 个 REQ 的六元组 `{req_id, title, goal, rules, constraints, acceptance}`。`req_id`/`title` 从核心功能点拆分;`goal` 展开 `title`;`rules`/`constraints`/`acceptance` 起草业务语义。**不推断**输入 / 输出(模板原样保留示例)。 + - **单次 Bash**:调 `${CLAUDE_SKILL_DIR}/scripts/render.sh` 落盘所有文件(脚本内部完成模板读取 + 占位符替换 + HTML 注释剥离)。下面是**调用形态**示例,`` / `<模块名>` / `` 等尖括号位置 CC 按 `index.md` 实际值替换: + + ```bash + R="${CLAUDE_SKILL_DIR}/scripts/render.sh" + # 每个模块:mkdir + 1 个 render module + N 个 render req(每 REQ 一行) + mkdir -p "docs/01-需求清单/-<模块名>" + bash "$R" module "docs/01-需求清单/-<模块名>/_module.md" "" "<模块名>" "" + bash "$R" req "docs/01-需求清单/-<模块名>/.md" "" "" "<goal>" "<rules>" "<constraints>" "<acceptance>" + ``` + + - **兜底**:值含字面 `$xxx` 或 `}}` 的 REQ 单独走 cp + Edit。 + +4. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选(计划 ① 子项 + ① 顶层): + - ` - [ ] REQ 卡片骨架已生成(docs/01-需求清单/<module>/REQ-*.md)` + - `- [ ] 计划 ① 初始化 + 范围锁定 — init` + +5. 打印停下横幅并**停止**,不自动派发 design: + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + [init] ✅ 计划 ① 完成 + + 产出: + ✓ CLAUDE.md § 🎯 项目概述 + ✓ docs/04 § 零 技术栈 + ✓ docs/01-需求清单/index.md 模块索引 + ✓ docs/01-需求清单/<module>/_module.md 模块头 + ✓ docs/01-需求清单/<module>/REQ-*.md REQ 卡片骨架 + + ⏸ 现在请你逐张打开 REQ 卡片: + - **必改**:输入 / 输出 两段 + · `表1` / `表2` 是模板示例,按本 REQ 业务**改字段 / 增删行 / 增删整张表** + - **审阅**:目标 / 跨字段规则 / 边界 / 验收(已起草,对照业务校正) + - **保留**:`TBD` 不要改,由之后流程自动回填 + + 审阅完成后,运行以下命令进入计划 ②: + /erp-workflow:plan-start + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` + +> **STOP**:此处是人工审阅 REQ 的闸门。停止执行,等待用户运行 `/erp-workflow:plan-start` 后由 plan-start 派发 design。 + +## 参考 + +- `${CLAUDE_SKILL_DIR}/templates/CLAUDE-template.md`(项目级 CLAUDE.md 模板) +- `${CLAUDE_SKILL_DIR}/templates/docs-01-index-template.md`(需求索引初稿) +- `${CLAUDE_SKILL_DIR}/templates/docs-04-stack-template.md`(默认技术栈) +- `${CLAUDE_SKILL_DIR}/templates/docs-08-initial-template.md`(计划阶段进度初始化) +- `${CLAUDE_SKILL_DIR}/templates/req-card-template.md`(REQ 卡片模板) +- `${CLAUDE_SKILL_DIR}/templates/_module-template.md`(模块头模板) +- `${CLAUDE_SKILL_DIR}/scripts/render.sh`(步骤 G 渲染助手,dispatch `module` / `req` 两种模式) +- 下游:人工审阅 REQ 后运行 `/erp-workflow:plan-start`,由 plan-start 派发 `design`(计划 ②) diff --git a/skills/plan/init/scripts/render.sh b/skills/plan/init/scripts/render.sh new file mode 100644 index 0000000..b78e455 --- /dev/null +++ b/skills/plan/init/scripts/render.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# render.sh — init 渲染单个 _module.md 或 REQ-*.md +# +# 用法: +# bash render.sh module <out_path> <module_code> <module_name> <module_brief> +# bash render.sh req <out_path> <req_id> <title> <goal> <rules> <constraints> <acceptance> +# +# 模板路径自定位:脚本同级父目录下 templates/{_module-template.md, req-card-template.md} + +set -euo pipefail + +TYPE=${1:?missing type (module|req)} +shift + +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +TPL_DIR="$SCRIPT_DIR/../templates" + +case "$TYPE" in + module) + out=${1:?missing out_path}; code=${2:?}; name=${3:?}; brief=${4:?} + c=$(cat "$TPL_DIR/_module-template.md") + c="${c//\{\{module_code\}\}/$code}" + c="${c//\{\{module_name\}\}/$name}" + c="${c//\{\{module_brief\}\}/$brief}" + ;; + req) + out=${1:?missing out_path}; req_id=${2:?}; title=${3:?}; goal=${4:?}; rules=${5:?}; constraints=${6:?}; acceptance=${7:?} + c=$(sed '/^<!--$/,/^-->$/d' "$TPL_DIR/req-card-template.md") + c="${c//\{\{req_id\}\}/$req_id}" + c="${c//\{\{title\}\}/$title}" + c="${c//\{\{goal\}\}/$goal}" + c="${c//\{\{rules\}\}/$rules}" + c="${c//\{\{constraints\}\}/$constraints}" + c="${c//\{\{acceptance\}\}/$acceptance}" + ;; + *) + echo "render.sh: unknown type '$TYPE' (expect module|req)" >&2 + exit 1 + ;; +esac + +printf '%s\n' "$c" > "$out" diff --git a/skills/plan/init/templates/CLAUDE-template.md b/skills/plan/init/templates/CLAUDE-template.md new file mode 100644 index 0000000..29feebb --- /dev/null +++ b/skills/plan/init/templates/CLAUDE-template.md @@ -0,0 +1,280 @@ +# CLAUDE.md — ERP项目 Claude Code 主指令文件 + +> 本文件是 Claude Code 的"操作手册"。Claude Code 启动时会自动读取此文件。 + +--- + +## 🎯 项目概述 + +- **项目名称**: 【人工填写:公司 + 项目名,例如"XX 公司 ERP 管理系统"】 +- **项目简述**: 【人工填写:一句话描述项目目标,例如"面向中小制造企业的全流程 ERP,涵盖采购/库存/生产/销售/财务"】 +- **目标用户**: 【人工填写:谁会用,例如"企业内部管理人员(采购员、仓管员、生产主管、销售员、财务人员、管理层)"】 +- **部署方式**: 【人工填写:私有化部署 / 云部署 / Docker 容器化 等】 + +--- + +## 🔄 编码开发流程(两阶段 + 统一功能循环) + +编码阶段入口:`/erp-workflow:coding-start`。本插件保留**后端模块阶段**与**前端整体阶段**两段,但两段共用**同一套功能循环 skill**(`feature-spec → feature-tdd → feature-review`),由 `phase` 参数区分。 + +### 阶段路由(coding-start 内,只做分发) + +`coding-start` 每次入口按"先后端、再前端"检查并派发到 `phase-driver`: + +1. 扫 `docs/08 § 二` 各后端模块 `里程碑:` 字段 + `git tag -l 'milestone/<id>'`:有未打里程碑模块 → 派发 `phase-driver`(phase=backend),结束。 +2. 后端全部打里程碑 → 读 `docs/08 § 三` `整体里程碑:` + `git tag -l 'milestone/frontend-phase'`:未完成 → 派发 `phase-driver`(phase=frontend),结束。 +3. 后端 + 前端都完成 → 输出"所有阶段已完成"。 + +### 统一功能循环(两阶段共用) + +**阶段驱动(外)**:`phase-driver`(phase=backend 走后端模块;phase=frontend 走前端整体阶段——自带 prototype/ 门禁 + 从 prototype/docs01/docs05 推导 FE 清单写入 docs/08 § 三)→ feature 循环 → `milestone`(本地 merge 进默认分支 + 打 `milestone/<id>` 或 `milestone/frontend-phase` tag)→ 自动回调 `coding-start` 路由下一阶段(无人工介入)。 + +**功能循环(内,每个 REQ-XXX-NNN 或 FE-NN 一遍)**:`feature-spec` → `feature-tdd` → `feature-review`。 +- phase=backend:单元是 REQ,分支 `module-<id>`,产出 controller/service/repository/DTO/migration; +- phase=frontend:单元是 FE,分支 `frontend-phase`,产出 `frontend/` 下组件/路由/API client(以 prototype 为页面权威); +- `feature-review` verdict=approve → 勾选 docs/08 § 二(后端 REQ)/ § 三(前端 FE)对应子项,继续下一单元; +- 本阶段单元全部完成 → 调用 `milestone` 打里程碑 tag + 回调 `coding-start`。 + +### 里程碑前守门 + +- `milestone` 在打 tag 前内置测试闸门(phase 由分支推断:后端 `scripts/test.sh`;前端 vitest + Playwright,命令取自 docs/04 § 零);红色不得跳过。 +- 测试 / 验证统一派发到 Agent 子会话执行,主会话只接收结构化结论。 + +--- + +## ✅ 阶段完成判定规则 + +`docs/08-模块任务管理.md` 分三段: +- `§ 一`:计划阶段三段(①②③)进度勾选 +- `§ 二`:后端编码模块元数据表(每个模块一行 bullet,记录依赖 / 路径 / 里程碑 tag / REQ 功能子项;行序即 REQ 开发顺序,是 phase-driver 的排序权威) +- `§ 三`:前端整体阶段(`整体里程碑:` 字段 + FE 功能清单,由 phase-driver(phase=frontend) 推导填入) + +**阶段完成判定**统一以 `里程碑:` 字段(§二 模块 / §三 整体)+ 本地 `git tag -l 'milestone/<id>'` 判定;子项勾选只作可视化进度,不参与完成判定。 + +### 后端模块格式 + +每个后端模块在 docs/08 § 二 中长这样: + +```markdown +- module_0 系统管理 + - 依赖: — + - 路径: backend/module/sys/ + - 里程碑: — + - 功能: + - [ ] REQ-SYS-001 用户登录 + - [ ] REQ-SYS-002 用户注册 +``` + +- `里程碑:` 字段由 `milestone` 在打里程碑 tag 时从 `—` 改为 `milestone/<module_id>`。 +- 每个 `REQ-*` 子项由 `feature-review` 在 verdict=approve 时自动勾选为 `[x]`。 + +### 状态语义 + +| `里程碑:` 字段 | `git tag -l` | 含义 | 你(Claude Code)的行为 | +|---|---|---|---| +| `—` | tag 不存在 | 该阶段未开始 / 进行中(未打里程碑) | ✅ 开始 / 继续该阶段开发 | +| `milestone/<id>` | tag 存在 | 阶段**已完成** | 🟢 进入下一未完成模块;全部完成 → 输出完成信息 | + +### 模块完成报告 + +由 `milestone` skill 产出,模板由 milestone skill 持有。CC 不手写模块报告,仅填模板。 + +--- + +## 🏷️ 占位符统一约定 + +项目文档里有 **2 种填写占位** + **1 种提示占位**: + +| 格式 | 谁填 | 使用阶段 | 说明 | +|------|-----|---------|------| +| `【人工填写:<简短说明>】` | 人 | 仅计划阶段文档 | 密钥 / 账密 / 包名 / 命名约定 / 小版本号等人工才能决定的值;编码阶段 plan/spec 禁止出现,查不到真值时用 `AskUserQuestion` 问用户 | +| `TBD(<责任人>)` | CC 自动 | 计划或编码 | 后缀附带责任方(如 `TBD(design 自动补)` / `TBD(build-db 自动补)`);由对应 skill 就地补填 | + +**HTML 注释 `<!-- ... -->`**:提示占位,是**插件内部大纲模板**里给 LLM 的**填空提示 / 章节引导**,指引 LLM 按结构填实际内容。skill 生成时会**剥除**这些注释,最终产物里注释不会保留。 + +--- + +## 📐 编码行为约束 + +### 你必须做的 ✅ + +1. **严格遵循** `docs/04-技术规范.md`——命名 / 编码 / 统一响应 / 异常处理 / 数据访问 / 配置与安全 / 环境配置(含 .env.local 字段说明)等项目专属技术规约全部在此 +2. **每个后端接口** 必须先在 `docs/05-API接口契约.md` 定义,再编码实现 +3. **每个功能可追溯到 `REQ-XXX-NNN`**——commit tag + 代码注释(如 `// REQ-SYS-001: 用户登录`)+ plan/spec 文件名均用此 tag +4. **遇到跨模块改动**(动到非当前模块的代码)——按 § 🟡 软规则 **S2** 执行(允许改,但必须留痕) +5. **遇到技术栈外组件引入**(`docs/04 § 零` 技术栈表外的框架 / 中间件 / 关键库),按 § 🟡 软规则 **S1** 执行(允许引入,但必须先 AskUserQuestion) + +### 你禁止做的 🚫 + +1. **主会话直接 `mysql -e` 跑业务 DDL**(只读查询 / 临时本地调试除外)——业务 schema 必须走 `sql/migrations/V_n__*.sql`,详见下方 Schema 演化规约 +2. **手动 Edit `docs/08 § 二` 的 `里程碑:` 字段**,必须由 `milestone` 自动回写 + +### Schema 演化规约(Flyway migration) + +1. **文件命名**:`sql/migrations/V<n>__<snake_case_desc>.sql`,例:`V5__add_user_email_unique_index.sql` +2. **版本号分配**:建文件前 `ls sql/migrations/V*.sql` 查当前最大 n,新文件 `n_max + 1` +3. **Apply 方式**:Spring Boot 启动 / 测试启动时 Flyway 自动 apply(项目必须在 `pom.xml` 声明 `flyway-core` + `flyway-mysql` 依赖)。`scripts/setup-test-db.sh` 只负责清空库,不做 apply +4. **已合并的 migration 永不修改**:发现错了写一个补救 migration(如 `V7__fix_V5_index_name.sql`),旧 `V_n.sql` 不动 +5. **临时调试 DDL**:临时在本地试字段/索引可手动 `mysql -e`,但不写 migration;下次 `setup-test-db.sh` 会 drop+create 清掉 +6. **计划 ③ 生成的 V1**:`V1__initial_schema.sql` 是计划阶段由 `build-db` 从 `docs/03-数据库设计文档.md`(design 正向设计的 schema SSoT)翻译生成的初始版本;后续 V2/V3/... 由编码阶段每个 REQ 按需写入,**同时**反向同步更新 docs/03 对应表小节以保持 SSoT 一致 + +--- + +## 🗂️ Git 提交规范 + +每次提交必须遵循以下格式: + +``` +<type>(<scope>): <subject> +``` + +- `scope`: 模块名,如 `user` / `inventory` / `order` +- `subject`: 简短描述;业务类(feat / fix / test)必须带 `REQ-XXX-NNN` 后缀 + +`type` 含义: + +| type | 看到它意味着 | +|-----|-------------| +| `feat` | **新能力上线**——用户多了一个功能、接口、页面或业务规则 | +| `fix` | **修 bug**——原来行为错了,这次改对 | +| `refactor` | **重构**——外部行为不变,只改代码结构 / 命名 / 抽象 | +| `docs` | **文档改动**——只动 Markdown / 代码注释,不动实现 | +| `style` | **格式调整**——空白 / 缩进 / import 顺序,逻辑 0 变化 | +| `test` | **只动测试代码**——补用例 / 修 fixture,不碰实现 | +| `chore` | **流程维护**——构建 / 依赖 / 工具 / 证据档案 / 里程碑元数据等非业务动作 | + +--- + +## 🚩 中断机制 + +功能循环(每个功能 REQ-XXX 的 feature-spec → feature-tdd → feature-review)默认 **静默编程**,但触发以下任何一条必须**立刻停下、记录原因、等人决策**,不得自行绕过: + +| # | 中断 | 例子 | +| - | --- | --- | +| 1 | **测试反复失败** | 同一测试同一功能内连续 **10 次**修复失败 | +| 2 | **要改密钥 / 账密 / 包名** | 涉及 .env.local / docs/04 §零环境 中的密钥/账密字段 | +| 3 | **外部接口不可达** | 第三方 API 无法连接、证书失效等环境问题,并无法自行解决 | + +> 其余需要人类判断的场景一律走普通 `AskUserQuestion` Q&A,不中断、不写 Blocker 文件。 + +**触发中断时的固定动作:** + +1. 在当前功能的 spec 文件里追加一节 `## 🚩 Blocker`(报告格式由 `interrupt-check` 的 `interrupt-block-template.md` 持有) +2. 停止后续所有功能的静默执行 +3. 在主会话输出一句话摘要 + 指向 blocker 文件的路径,等人回复 + +--- + +## 🟡 软规则(允许继续,但有强制后续动作) + +以下情况 **不触发中断**,CC 可自行继续推进,但必须在约定位置留痕,模块完成时统一审计。 + +| # | 软规则 | 允许动作 | 强制后续 | +| - | ----- | ------- | ------- | +| S1 | **技术栈外组件引入** | 用 `AskUserQuestion` 给用户三选一:接受引入 / 换方案 / 拒绝 | ① **接受** → 同会话直接在 `docs/04 § 零` 追加一行 → 继续流程 ② **换方案 / 拒绝** → 视为常规歧义澄清,继续 Q&A 收敛 ③ 不写 Blocker、不中断流程 | +| S2 | **跨模块改动** | **默认不改**,仅为当前模块实现所必需时允许修改 | 在该模块 `milestone` 完成报告的「⑤ 偏离与取舍」节如实记录改了哪个非当前模块的文件 + 原因(本插件无自动留痕 hook,靠报告人工记录) | + +--- + +## 🧭 通用工作准则(General Principles) + +### 1. Think Before Coding + +**Don't assume. Don't hide confusion. Surface tradeoffs.** + +Before implementing: +- State your assumptions explicitly. If uncertain, ask. +- If multiple interpretations exist, present them - don't pick silently. +- If a simpler approach exists, say so. Push back when warranted. +- If something is unclear, stop. Name what's confusing. Ask. + +### 2. Simplicity First + +**Minimum code that solves the problem. Nothing speculative.** + +- No features beyond what was asked. +- No abstractions for single-use code. +- No "flexibility" or "configurability" that wasn't requested. +- No error handling for impossible scenarios. +- If you write 200 lines and it could be 50, rewrite it. + +Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify. + +### 3. Surgical Changes + +**Touch only what you must. Clean up only your own mess.** + +When editing existing code: +- Don't "improve" adjacent code, comments, or formatting. +- Don't refactor things that aren't broken. +- Match existing style, even if you'd do it differently. +- If you notice unrelated dead code, mention it - don't delete it. + +When your changes create orphans: +- Remove imports/variables/functions that YOUR changes made unused. +- Don't remove pre-existing dead code unless asked. + +The test: Every changed line should trace directly to the user's request. + +### 4. Goal-Driven Execution + +**Define success criteria. Loop until verified.** + +Transform tasks into verifiable goals: +- "Add validation" → "Write tests for invalid inputs, then make them pass" +- "Fix the bug" → "Write a test that reproduces it, then make it pass" +- "Refactor X" → "Ensure tests pass before and after" + +For multi-step tasks, state a brief plan: +``` +1. [Step] → verify: [check] +2. [Step] → verify: [check] +3. [Step] → verify: [check] +``` + +Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification. + +--- + +## 🗺️ Skill 索引(erp-workflow,共 11 个) + +### 入口 + +| Skill | 描述 | +|-------|------| +| `plan-start` | 计划阶段入口——扫 docs/08 § 一找第一个未完成计划段(①②③)并派发 | +| `coding-start` | 编码阶段入口 + 阶段分发器——先后端(docs/08 § 二)后前端(§ 三),派发 phase-driver(phase=backend/frontend);都完成则输出全部完成 | + +### 计划阶段 + +| Skill | 描述 | +|-------|------| +| `init` | 计划 ①——项目初始化 + 范围锁定(模板复制、依赖检查、git init、项目概述+技术栈+需求索引、REQ 卡片生成,停下等人工审阅) | +| `design` | 计划 ②——脚手架 + 数据库设计(docs/04 § 一+、scripts、.env.local、docs/03 DB 设计,停下等人工审阅) | +| `build-db` | 计划 ③——DB 初始化 + 下游文档(V1 migration apply、docs/05 API 契约、docs/08 § 二模块清单,计划阶段结束) | + +### 编码阶段 + +| Skill | 描述 | +|-------|------| +| `phase-driver` | 阶段驱动(phase 参数区分)——backend:加载当前模块 REQ 清单逐个派发;frontend:prototype/ 门禁 + 推导 FE 清单写 docs/08 § 三后逐个派发 | +| `feature-spec` | 功能规格(两阶段共用)——为 REQ(后端)/ FE(前端)生成"规格 + 任务级计划"合并文档 | +| `feature-tdd` | TDD 实现(两阶段共用)——按 plan 测试先行再实现,Agent 子会话跑测试;路径护栏按 phase 区分 | +| `feature-review` | 验证 + AI 自审(两阶段共用)——子会话跑测试 + reviewer agent(后端 superpower / 前端 fe-code-reviewer),approve 勾选进度回 phase-driver | +| `milestone` | 里程碑(phase 由分支推断)——内置测试闸门(Agent 子会话),green 则本地 merge + 打 tag,生成完成报告 | + +### 守门 + +| Skill | 描述 | +|-------|------| +| `interrupt-check` | 中断检查——触发中断条件时由功能循环 skill 调用,追加 Blocker 节并停止执行 | + +### 文档套件(5 文档) + +| 文档 | 职责 | +|------|------| +| `docs/01-需求清单/` | REQ 卡片目录(模块子目录 + index.md) | +| `docs/03-数据库设计文档.md` | 表/字段/索引/外键 SSoT(design 生成,编码阶段同步更新) | +| `docs/04-技术规范.md` | 技术栈总览(§ 零)+ 架构规范 + 前端 Design Tokens / 交互约定 + 环境变量说明(含 .env.local 密钥字段)——已把原 UI 规范与环境配置并入此文件 | +| `docs/05-API接口契约.md` | 所有后端接口契约(build-db 生成,feature-spec 按需追加) | +| `docs/08-模块任务管理.md` | 全流程进度跟踪(§ 一计划 / § 二后端模块 / § 三前端整体) | diff --git a/skills/plan/init/templates/_module-template.md b/skills/plan/init/templates/_module-template.md new file mode 100644 index 0000000..d9927fe --- /dev/null +++ b/skills/plan/init/templates/_module-template.md @@ -0,0 +1,5 @@ +# {{module_code}}-{{module_name}} + +- **模块简述**: {{module_brief}} +- **依赖模块**: TBD(build-db 自动补) +- **涉及表**: TBD(design 自动补) diff --git a/skills/plan/init/templates/docs-01-index-template.md b/skills/plan/init/templates/docs-01-index-template.md new file mode 100644 index 0000000..08e326a --- /dev/null +++ b/skills/plan/init/templates/docs-01-index-template.md @@ -0,0 +1,16 @@ +# 需求清单 + +> 本目录按模块组织所有功能需求。每个模块一个子目录,含 `_module.md`(模块头)和 `REQ-XXX-NNN.md`(每张 REQ 卡片一个文件)。下方核心功能点供 CC 拆分出 REQ 编号 + 标题 + 草拟规则;卡片内输入 / 输出的简述句和 N 张字段表由人工编辑。 + +## 模块索引 + +| 模块代码 | 模块名称 | 核心功能点(简要) | +|----------|----------|--------------------| +| 【人工填写:模块代码】 | 【人工填写:模块名称】 | 【人工填写:核心功能点】 | +| SYS | 系统管理 | 用户/角色/权限/部门/字典 等 | + +## 填写说明 + +1. 每个模块占一行,`模块代码` 用大写英文缩写(如 SYS / PUR / INV / SAL / FIN / HR) +2. `核心功能点` 只需列关键词,CC 会基于此拆分出 N 张 REQ 卡片骨架(卡片内输入 / 输出的简述句和字段表仍由人工编辑) +3. 填完后运行 `/erp-workflow:plan-start`,CC 会自动检测并进入需求生成阶段 diff --git a/skills/plan/init/templates/docs-04-stack-template.md b/skills/plan/init/templates/docs-04-stack-template.md new file mode 100644 index 0000000..463d61b --- /dev/null +++ b/skills/plan/init/templates/docs-04-stack-template.md @@ -0,0 +1,32 @@ +# 04-技术规范 + +## 零、技术栈总览 + +| 分层模块 | 技术 | 版本要求 | 说明 | +|---|---|---|---| +| 前端基础框架 | React | 18.x | 构建前端应用 | +| 前端 UI 组件 | Ant Design | 5.x | 页面组件与交互控件 | +| 前端状态管理 | Redux Toolkit | 最新稳定版 | 管理全局状态 | +| 前端路由管理 | React Router | v6 | 页面路由与导航 | +| 前端工程化构建 | Vite | 最新稳定版 | 前端开发与打包构建 | +| 前端接口通信 | Axios | 最新稳定版 | 调用后端 API | +| 后端基础框架 | Spring Boot | 3.x | 构建后端服务 | +| 后端数据访问 | MyBatis-Plus | 最新稳定版 | 数据库访问与 ORM 增强 | +| 工作流引擎 | Activiti | 6.x | 审批流、流程流转 | +| 缓存服务 | Redis | 最新稳定版 | 缓存、会话、分布式能力 | +| 报表打印 | JXLS | 2.8.1 | 基于 Excel 模板生成报表 | +| Excel 导入导出 | EasyExcel | 4.0.3 | Excel 数据导入导出 | +| 关系型数据库 | MySQL | 8.x | 核心业务数据存储 | +| 数据库 schema 迁移 | Flyway (`flyway-core` + `flyway-mysql`) | 10.x / 最新稳定版 | `sql/migrations/V_n__*.sql` 顺序 apply;Spring Boot 启动时自动应用 | +| 接口风格 | RESTful API | 统一规范 | 前后端接口设计规范 | +| 权限认证 | Spring Security / JWT | 最新稳定版 | 登录认证、权限控制 | +| API 文档 | OpenAPI / Swagger | 最新稳定版 | 接口文档与调试 | +| 项目构建管理 | Maven | 3.9.x | Java 项目依赖与构建 | +| JDK 运行环境 | Java | 17 / 21 | Spring Boot 3 推荐版本 | +| 部署容器 | Docker | 最新稳定版 | 容器化部署 | +| Web 服务器 / 反向代理 | Nginx | 最新稳定版 | 前端托管、反向代理、负载分发 | +| 日志管理 | Logback | 默认集成 / 最新稳定版 | 应用日志输出 | +| 对象映射工具 | MapStruct | 最新稳定版 | DTO / VO / Entity 转换 | +| 工具类库 | Hutool / Apache Commons | 最新稳定版 | 常用工具方法支持 | + +> 本表由 init 锁定。后续所有规范基于此表推导。 diff --git a/skills/plan/init/templates/docs-08-initial-template.md b/skills/plan/init/templates/docs-08-initial-template.md new file mode 100644 index 0000000..3bd6a04 --- /dev/null +++ b/skills/plan/init/templates/docs-08-initial-template.md @@ -0,0 +1,52 @@ +# 08-工作流进度 + +> 全流程进度跟踪。CC 每完成一项产出就勾选一项。 +> - **§ 一 计划阶段**:`plan-start` 找第一个未勾的计划段(①②③)分发到对应 skill +> - **§ 二 Coding(后端模块)**:`coding-start` 扫描 docs/08 § 二 的 `里程碑:` 字段 + 本地 `git tag -l 'milestone/<id>'`,找第一个未打里程碑模块,派发 `phase-driver`(phase=backend)。本 § 二 行序即 REQ 开发顺序(build-db 按依赖拓扑写入),是 phase-driver 的排序权威 +> - **§ 三 Coding(前端整体)**:后端全部打里程碑后,`coding-start` 读 § 三 `整体里程碑:` + `git tag -l 'milestone/frontend-phase'`,未完成则派发 `phase-driver`(phase=frontend) + +## 一、计划阶段进度 + +- [ ] 计划 ① 初始化 + 范围锁定 — init + - [ ] 项目文件骨架已创建(CLAUDE.md + docs/01 index + docs/04 + docs/08) + - [ ] 依赖检查通过(git / mysql) + - [ ] Git 已初始化 + - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述) + - [ ] 技术栈已确认(docs/04 § 零) + - [ ] 需求清单索引已填写(docs/01-需求清单/index.md) + - [ ] REQ 卡片骨架已生成(docs/01-需求清单/<module>/REQ-*.md) +- [ ] 计划 ② 脚手架 + 数据库设计 — design + - [ ] 架构文档已生成(docs/04 § 一+ | scripts/*.sh | .env.local | sql/migrations/) + - [ ] docs/03 数据库设计已生成(REQ → 表/字段/索引/外键,回填 REQ 依赖表) +- [ ] 计划 ③ DB 初始化 + 下游文档 — build-db + - [ ] V1 migration 已生成并校验 + apply 到本地 MySQL + - [ ] docs/05 API 契约已生成 + 回填 REQ 依赖接口 + - [ ] docs/08 § 二 模块清单(含 REQ 顺序)已生成 + +## 二、Coding 阶段(模块循环) + +(build-db 填入后,每行一个后端模块。每个模块的 `里程碑:` 字段在 `—` 和 `milestone/<id>` 之间变化,完成由本地 `git tag -l` 判定。`coding-start` 每次扫每模块的里程碑 tag 决定派发。所有模块打里程碑后整体完成。) + +<!-- 模块格式示例(由 build-db 追加;功能子项由 feature-review 在 approve 时勾选): +- module_0 系统管理 + - 依赖: — + - 路径: backend/module/sys/ + - 里程碑: — + - 功能: + - [ ] REQ-SYS-001 用户登录 + - [ ] REQ-SYS-002 用户注册 +--> + +## 三、Coding 阶段(前端整体) + +(`phase-driver`(phase=frontend)进入时扫 prototype/ + docs/01 + docs/05 → AI 自主推导 FE 业务功能清单写到下方"功能:"项(无人工审阅断点;合理性由整体里程碑标记时统一校核)。已有清单则直接加载。整个前端阶段 1 个里程碑 tag,分支 `frontend-phase`。) + +- 整体里程碑: — +- 功能: + <!-- AI 进入时按以下行格式写入(每行 1 个 FE,可关联多个 REQ / 多份原型): + - [ ] FE-NN 功能名 | 关联 REQ:REQ-A, REQ-B | 关联原型:prototype/<file>.html, prototype/<other>.html + + 示例: + - [ ] FE-01 用户登录与注册 | 关联 REQ:REQ-SYS-001, REQ-SYS-002 | 关联原型:prototype/auth.html + - [ ] FE-02 仪表盘总览 | 关联 REQ:REQ-DASH-001 | 关联原型:prototype/dashboard.html + --> diff --git a/skills/plan/init/templates/req-card-template.md b/skills/plan/init/templates/req-card-template.md new file mode 100644 index 0000000..00ba6d2 --- /dev/null +++ b/skills/plan/init/templates/req-card-template.md @@ -0,0 +1,63 @@ +<!-- +req-card-template:单张 REQ 卡片骨架。每张卡片是 docs/01-需求清单/<module>/REQ-XXX-NNN.md 一个独立文件。 +渲染约定: +1) init 渲染时**只替换 6 个占位符**:{{req_id}} / {{title}} / {{goal}} / {{rules}} / {{constraints}} / {{acceptance}} + 这 6 项由 CC 根据 docs/01-需求清单/index.md 的「核心功能点」推断起草: + - req_id / title:从核心功能点拆分命名得来 + - goal:用一句话展开 title + - rules / constraints / acceptance:业务语义层面的合理起草,待人工审阅修订 +2) `**输入**` / `**输出**` 二级结构:每段先一句话总结(如「用户提交...」/「返回用户 id」),再跟「表1 / 表2 / ...」N 张平铺的字段表。CC 渲染时对**两段简述 + 所有表(含示例数据)全部原样复制**,不要根据 REQ 业务篡改示例字段、也不要换列结构: + - `输入` 的表:8 列(字段 / 类型 / 必填 / 输入方式 / 显示来源 / 预加载 / 默认值 / 业务规则),其中 `预加载` 取值为 `页面加载时` / `用户操作时` / `—`;模板内含示例数据(表1 6 行、表2 3 行) + - `输出` 的表:3 列(字段 / 类型 / 显示来源),模板内含示例数据(表1 / 表2 各 3 行) + - 表的数量是可变的:人工拿到卡片后按 REQ 实际情况增删表(删多余的 `表N` 整段 / 复制为 `表3 / 表4 / ...`)和编辑字段 +3) `**依赖表**: TBD(design 自动补)` 和 `**依赖接口**: TBD(build-db 自动补)` 是后续 skill 自动回填的占位,渲染时**保持原样**,不要替换为 `-` 也不要替换为 `{{...}}` +4) 渲染后这段 HTML 注释要**剥掉**,不进入最终卡片 +--> +### {{req_id}} {{title}} + +**目标**: {{goal}} + +- **输入**: 用户提交用户名(3-20 位字母数字下划线,系统内唯一)、姓名(2-50字符)、手机号(11 位数字,系统内唯一)、邮箱(标准邮箱格式,可选)、初始密码(8-20位含大小写字母和数字) + + - **表1**: + + | 字段 | 类型 | 必填 | 输入方式 | 显示来源 | 预加载 | 默认值 | 业务规则 | + | ---- | ---- | --- | ---- | ----- | --- | --- | ------------------- | + | 用户名 | 文本 | 是 | 手工输入 | `职员表` | 否 | — | 3-20 位字母数字下划线;系统内唯一 | + | 姓名 | 文本 | 是 | 下拉单选 | `职员表` | 用户操作时 | — | 2-50 个字符 | + | 手机号 | 文本 | 是 | 手工输入 | `职员表` | 否 | — | 11 位数字;系统内唯一 | + | 邮箱 | 文本 | 否 | 手工输入 | `职员表` | 否 | — | 标准邮箱格式 | + | 角色 | 文本 | 是 | 下拉单选 | 普通用户/超级管理员 | 页面加载时 | 普通用户 | 至少选择 1 个 | + | 初始密码 | 文本 | 是 | 手工输入 | — | — | — | 8-20 位;含大小写字母和数字;显示星号 | + + - **表2**: + + | 字段 | 类型 | 必填 | 输入方式 | 显示来源 | 预加载 | 默认值 | 业务规则 | + | --- | --- | --- | --- | --- | --- | --- | --- | + | 用户名 | 文本 | 是 | 手工输入 | `职员表` | 否 | — | 3-20 位字母数字下划线;系统内唯一 | + | 姓名 | 文本 | 是 | 下拉单选 | `职员表` | 用户操作时 | — | 2-50 个字符 | + | 手机号 | 文本 | 是 | 手工输入 | `职员表` | 否 | — | 11 位数字;系统内唯一 | + +- **输出**: 返回用户 id + + - **表1**: + + | 字段 | 类型 | 显示来源 | + | --- | --- | --- | + | 用户名 | 文本 | `职员表` | + | 姓名 | 文本 | `职员表` | + | 角色 | 文本 | `职员表` | + + - **表2**: + + | 字段 | 类型 | 显示来源 | + | --- | --- | --- | + | 用户名 | 文本 | `职员表` | + | 姓名 | 文本 | `职员表` | + | 角色 | 文本 | `职员表` | + +- **跨字段规则**: {{rules}} +- **边界**: {{constraints}} +- **验收**: {{acceptance}} +- **依赖表**: TBD(design 自动补) +- **依赖接口**: TBD(build-db 自动补) diff --git a/skills/plan/lite-build-db/SKILL.md b/skills/plan/lite-build-db/SKILL.md deleted file mode 100644 index 7a51dc1..0000000 --- a/skills/plan/lite-build-db/SKILL.md +++ /dev/null @@ -1,255 +0,0 @@ ---- -name: lite-build-db -description: 计划第 3 段——解析 docs/03 → V1 migration + validate.sh 校验 + apply 到本地 MySQL;生成 docs/05 API 契约 + 回填 REQ 依赖接口;计算模块/REQ 依赖顺序写入 docs/08 § 二(排序权威);最终占位符扫描后停下(计划完成)。 -user-invocable: false -allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(mkdir *) Bash(mysql *) Bash(set *) Bash(. .env.local) Bash(grep *) Bash(bash *) Bash(./scripts/setup-test-db.sh) Bash(cat *) Bash(cp *) ---- - -**所有输出必须使用中文。** - -# lite-build-db - -## 执行步骤 - -### 步骤 0:打印当前位置流程图 - -用 `Bash` 执行以下命令(文件不存在时静默忽略,不报错): - -```bash -cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/plan-start/banners/flow-lite.txt" 2>/dev/null || true -``` - -打印横幅:`▶ 计划阶段 ③ — lite-build-db`。 - -### A. DDL 生成(不依赖数据库连接) - -#### A.1 读 docs/03 并翻译为 DDL - -读取 `docs/03-数据库设计文档.md`,按字段 / 索引 / 外键 / 业务注记**严格翻译**为: - -- 每张表一段 `CREATE TABLE` -- 字段顺序与 docs/03 表格行序一致;`Nullable` 列直接映射 `NOT NULL` / `NULL`;`默认` 列映射 `DEFAULT <value>`;列尾用 `COMMENT '<业务含义>'` 写注释 -- 索引 -- 外键:在所有表创建完成后**统一追加** - -要求: -- **严禁臆造** docs/03 中没有的表 / 字段 / 索引 / 外键 -- **严禁省略** docs/03 中已有的列、注释或约束 -- 字符集统一 `utf8mb4` + `utf8mb4_unicode_ci`,引擎统一 `InnoDB`,除非 docs/03 业务注记明确要求其他设置 - -#### A.2 落盘 V1 文件 - -`Bash`: `mkdir -p sql/migrations`。 - -用 `Write` 写 `sql/migrations/V1__initial_schema.sql`,内容 = 头部注释 + DDL 主体: - -1. **头部注释**(6 行 SQL 注释): - - `-- Flyway migration V1 — initial schema for <project_name>`(从 `CLAUDE.md § 🎯 项目概述` 读) - - `-- Generated: <YYYY-MM-DDTHH:MM:SSZ>`(UTC ISO 8601 时间戳) - - `-- Source: 由计划 ③ lite-build-db 从 docs/03-数据库设计文档.md 翻译生成(schema SSoT 是 docs/03)` - - `-- This is the FIRST migration; subsequent schema changes must be written as new files sql/migrations/V2__<desc>.sql, V3__... etc.` - - `-- Apply: Flyway runs this automatically at Spring Boot startup.` - - `-- Do not hand-edit this file after it is committed; write a new migration instead.` - -2. **DDL 主体**:A.1 推导出的所有 `CREATE TABLE` → `CREATE INDEX` → `ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY`,按此顺序拼接。 - -#### A.3 校验 V1 ↔ docs/03 集合一致性 + 自主修正 - -调 `${CLAUDE_SKILL_DIR}/scripts/validate.sh` 做脚本化的校验: - -```bash -bash "${CLAUDE_SKILL_DIR}/scripts/validate.sh" \ - sql/migrations/V1__initial_schema.sql \ - docs/03-数据库设计文档.md -``` - -退出码与处理: -- `0` → 通过,进入步骤 B -- `1` → **自主修正循环**(最多 3 轮,docs/03 是 SSoT 不动): - 1. 解析 stderr 差异清单,修正 V1.sql - 2. 重跑 validate.sh - 3. 退出 0 → 进入 B;退出 1 且本轮 < 3 → 回步骤 1;本轮 ≥ 3 仍失败 → 停下,打印最终残留差异 + 已尝试的 3 轮修正摘要,让用户介入 -- `2` → 用法错(V1 / docs 路径找不到),打印路径并停下 - -完成后(V1 写入并通过 validate.sh 校验),用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] V1 migration 已生成并校验 + apply 到本地 MySQL`(步骤 C 完成后一并勾选) - -### B. 数据库环境检查 - -#### B.1 检查 .env.local 凭据 - -用 `Glob` 检查 `.env.local` 是否存在;不存在 → 提示用户重新运行计划 ② `lite-design` 重建并停下。 - -用 `Bash` 加载并校验 5 个必填字段非空: - -```bash -set -a; . .env.local; set +a -for v in DB_HOST DB_PORT DB_USER DB_PASSWORD DB_SCHEMA; do - eval val=\${$v:-} - [ -z "$val" ] && echo "MISSING: $v" -done -``` - -任一缺失 → 打印缺失字段名并停下,提示用户编辑 `.env.local` 后重跑。 - -#### B.2 验证 MySQL 连接 - -```bash -set -a; . .env.local; set +a -mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" -e "SELECT 1;" -``` - -- **成功** → 进入步骤 C -- **失败** → 打印具体错误(认证 / 主机不可达 / 端口拒接等),提示检查 `.env.local`,**停下**。 - -### C. 自动导入 MySQL - -#### C.1 DROP+CREATE 空库 - -```bash -./scripts/setup-test-db.sh -``` - -#### C.2 把 V1 灌入已清空的 schema - -```bash -set -a; . .env.local; set +a -mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" "$DB_SCHEMA" \ - < sql/migrations/V1__initial_schema.sql -``` - -非零退出 → 报错停下,打印 mysql stderr。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] V1 migration 已生成并校验 + apply 到本地 MySQL` - -#### C.3 自检 SHOW TABLES - -```bash -set -a; . .env.local; set +a -ACTUAL=$(mysql -N -B -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" \ - -e "SHOW TABLES;" "$DB_SCHEMA" | wc -l | tr -d ' ') -EXPECTED=$(grep -c '^## `' docs/03-数据库设计文档.md) -[ "$ACTUAL" = "$EXPECTED" ] || { echo "MISMATCH: actual=$ACTUAL expected=$EXPECTED"; exit 1; } -``` - -行数不一致 → 报错停下;一致 → 进入步骤 D。 - -### D. 生成 docs/05 API 契约 + 回填 REQ 依赖接口 - -#### D.1 渲染 docs/05 - -1. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-05-header-template.md`,填充 `base_path`(从 `docs/04 § 一` 推导 API 前缀,如 `/api/v1`)、`auth_note`(认证方式说明)、`pagination_note`(分页参数约定),写入 `docs/05-API接口契约.md` 头部。 -2. 对所有模块的每个 REQ:读取并推断 `${CLAUDE_SKILL_DIR}/templates/docs-05-endpoint-template.md`,追加到 docs/05。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] docs/05 API 契约已生成 + 回填 REQ 依赖接口`(步骤 D.2 完成后一并勾选) - -#### D.2 回填模块头 + REQ 卡片的 TBD 字段 - -1. 在 `docs/01-需求清单/*/_module.md`(模块头)和 `docs/01-需求清单/*/REQ-*.md`(REQ 卡片)中搜索 `TBD(lite-build-db 自动补)` 并回填。**不动** `TBD(lite-design 自动补)`(应已由 lite-design 回填完毕)。 - - `_module.md` 的 `依赖模块` 字段:填入该模块所依赖的其他模块 ID(逗号分隔,无则填 `—`) - - `REQ-*.md` 的 `依赖接口` 字段:填入该 REQ 依赖的接口路径(逗号分隔,无则填 `—`) -2. 打印回填统计:`lite-build-db 回填 <M> 处模块"依赖模块" + <N> 处 REQ"依赖接口"`。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] docs/05 API 契约已生成 + 回填 REQ 依赖接口` - -### E. 模块/REQ 依赖顺序 → docs/08 § 二 - -本步骤计算模块/REQ 依赖拓扑顺序,将结果写入 docs/08 § 二(该 § 二 行序是 coding-start 的排序权威,无单独开发计划文件)。 - -#### E.1 构建模块依赖 DAG + 拓扑排序 - -1. 读取所有 `docs/01-需求清单/*/_module.md`,提取每个模块的 `依赖模块` 字段(经步骤 D.2 已回填)。 -2. 构建**模块依赖 DAG**(有向无环图),节点 = 模块 ID,边 = 「A 依赖 B → B 先于 A」。 -3. 拓扑排序得到 `module_topo_order[]`。 -4. **环依赖打破**:若模块 DAG 存在环(module_A ↔ module_B),按启发式(字母序 / 被依赖次数多者先)破环排出 `module_topo_order`,并在**参与环的模块里第一个 REQ** 的 `note` 字段填入原因(如 "A↔B 互依赖:先做 A 的骨架")。 - -#### E.2 模块内 REQ 排序 - -对每个模块内部: -1. 读取该模块所有 `REQ-*.md`,提取每个 REQ 的 `依赖接口` + `依赖表` 字段,推导 REQ 间依赖关系。 -2. 拓扑排序得到模块内 `req_order[]`。 -3. **REQ 级环依赖打破**:若模块内 REQ 互依赖,按字母序 / 被依赖次数多者先破环,`note` 填原因;非环 REQ `note` 留 `—`。 - -#### E.3 渲染 docs/08 § 二 - -按 `module_topo_order[]` 依次为每个模块渲染 bullet,追加到 `docs/08-模块任务管理.md` § 二(追加在 § 二 的注释块之后,保留原有注释格式示例): - -读取 `${CLAUDE_SKILL_DIR}/templates/docs-08-module-row-template.md`,填充: -- `{{module_id}}`:模块 ID -- `{{module_name}}`:模块中文名 -- `{{depends_on}}`:依赖模块 ID 列表(逗号分隔,无则填 `—`) -- `{{path_scopes}}`:`backend/module/<id>/` -- `{{req_checklist}}`:按模块内 `req_order[]` 生成,每行 ` - [ ] REQ-XXX-NNN 功能名` - -每个模块 bullet 间空一行,一次性追加全部模块。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] docs/08 § 二 模块清单(含 REQ 顺序)已生成` - -### F. 一致性检查 + 占位符扫描 + 计划完成 - -#### F.1 一致性检查(最多 3 轮自修复) - -**检查项**: -- 每个 docs/01 REQ 都出现在 docs/05(作为接口,如适用) -- docs/08 § 二 的 `module_id` 集合 = docs/01-需求清单/ 的模块目录集合 - -**不一致 → 按差异类型自主修复**: -- **REQ 缺 docs/05 endpoint** → 按步骤 D.1 规则为该 REQ 推测,并追加到 docs/05 -- **module_id 缺 docs/08 § 二** → 按步骤 E 规则渲染该模块 bullet,按拓扑序插入正确位置 - -修复后重跑检查;通过 → 进入 F.2;3 轮仍失败 → 停下,打印最终残留差异 + 已尝试的 3 轮修复摘要让用户介入。 - -#### F.2 最终占位符扫描 - -a. **`TBD` → 自动补齐**:Grep 搜索 `TBD(lite-design 自动补)` 和 `TBD(lite-build-db 自动补)`。有命中则就地补填(lite-design 残留 → 查 docs/03 填 `依赖表`;lite-build-db 残留 → 查 docs/05 按 REQ-ID 填 `依赖接口`),再 Grep 确认 0 命中;仍残留报错停下。 - -b. **`【人工填写:...】` → QA 循环等用户补**: - - 循环执行直到搜索不到 `【人工填写:` 且用户选「继续」: - - 0 命中 → 直接放行进入步骤 F.3 - - 有命中 → 打印残留清单(`<文件:行号> — <内容摘要>`),用 `AskUserQuestion` 弹「继续」/「有疑问想先沟通」二选一;用户回答后重扫验证再决定放行 / 继续循环 - - **每次弹 QA 前都重扫一次**——保证用户看到的 N 是最新的,避免「用户以为填完但实际还有残留」直接放行。 - -#### F.3 勾选 § 一 ③ 顶层 + 打印计划完成横幅 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选 ③ 顶层: -- `- [ ] 计划 ③ DB 初始化 + 下游文档 — lite-build-db` - -打印计划阶段终止横幅并**停下**(不自动进入 coding 阶段): - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - [lite-build-db] ✅ 计划阶段(①②③)全部完成 - - 所有规划文档已就绪,docs/08 § 一 全部勾选。 - - ⚠️ 进入 Coding 阶段前必须完成: - 1. 审核全部 Plan 产出(docs/01 / 03 / 04 / 05 / 08 + CLAUDE.md + sql/migrations/V1 + scripts/*) - - 2. 把全部 Plan 产物 commit 到本地默认分支(main / master): - git add -A && git commit -m "chore: plan phase done" - - 3. 运行 /erp-workflow:coding-start 进入编码阶段 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -**停止**,不调用任何下游 skill。 - -## 参考 - -- `docs/03-数据库设计文档.md`(DDL 翻译输入,SSoT) -- `docs/01-需求清单/index.md`(模块索引) -- `docs/01-需求清单/<module>/_module.md`(模块依赖:回填 `依赖模块`;拓扑排序输入) -- `docs/01-需求清单/<module>/REQ-*.md`(REQ 依赖:回填 `依赖接口`;模块内 REQ 排序输入) -- `docs/08-模块任务管理.md` § 二(模块拓扑顺序追加目标;是 coding-start 的排序权威) -- `${CLAUDE_SKILL_DIR}/scripts/validate.sh`(A.3 表名 + 每表列名集合校验脚本) -- `${CLAUDE_SKILL_DIR}/templates/docs-05-header-template.md` -- `${CLAUDE_SKILL_DIR}/templates/docs-05-endpoint-template.md` -- `${CLAUDE_SKILL_DIR}/templates/docs-08-module-row-template.md`(模块 bullet 行模板) -- `.env.local`(DB 凭据) -- 产物:`sql/migrations/V1__initial_schema.sql`(由 Flyway 在 Spring Boot 启动时 apply) diff --git a/skills/plan/lite-build-db/scripts/validate.sh b/skills/plan/lite-build-db/scripts/validate.sh deleted file mode 100644 index bed28ad..0000000 --- a/skills/plan/lite-build-db/scripts/validate.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env bash -# validate.sh — 校验 V1.sql 与 docs/03 的两个集合一致性: -# 维度 1: 表名集合 -# 维度 2: 每张共有表的列名集合 -# -# 用法: bash validate.sh <V1.sql> <docs/03 path> -# 退出码: -# 0 = 一致 -# 1 = 不一致(差异明细打印到 stderr) -# 2 = 用法错误(路径找不到等) - -set -uo pipefail -export LC_ALL=C # sort / comm 行为确定 - -V1=${1:?missing V1 sql path} -DOC=${2:?missing docs/03 path} - -[ -f "$V1" ] || { echo "validate.sh: V1 not found: $V1" >&2; exit 2; } -[ -f "$DOC" ] || { echo "validate.sh: docs not found: $DOC" >&2; exit 2; } - -ERR=0 - -# ─── 维度 1: 表名集合 ─────────────────────────────────────────── -TABLES_DOC=$(grep -E '^## `[^`]+`' "$DOC" \ - | sed -E 's/^## `([^`]+)`.*/\1/' | sort -u) -TABLES_SQL=$(grep -E '^CREATE TABLE `[^`]+`' "$V1" \ - | sed -E 's/^CREATE TABLE `([^`]+)`.*/\1/' | sort -u) - -ONLY_DOC=$(comm -23 <(echo "$TABLES_DOC") <(echo "$TABLES_SQL")) -ONLY_SQL=$(comm -13 <(echo "$TABLES_DOC") <(echo "$TABLES_SQL")) - -if [ -n "$ONLY_DOC" ] || [ -n "$ONLY_SQL" ]; then - { - echo "=== 维度 1: 表名集合不一致 ===" - [ -n "$ONLY_DOC" ] && { echo " docs/03 有但 V1 无:"; echo "$ONLY_DOC" | sed 's/^/ - /'; } - [ -n "$ONLY_SQL" ] && { echo " V1 有但 docs/03 无:"; echo "$ONLY_SQL" | sed 's/^/ - /'; } - } >&2 - ERR=1 - # 表数差异 → 不再做列校验 - exit 1 -fi - -# ─── 维度 2: 每张共有表的列名集合 ────────────────────────────── -COMMON=$(comm -12 <(echo "$TABLES_DOC") <(echo "$TABLES_SQL")) - -extract_doc_cols() { - local table=$1 - awk -v t="$table" ' - $0 ~ "^## `" t "`" { in_table=1; in_fields=0; next } - in_table && /^## `/ { exit } - in_table && /^### 字段/ { in_fields=1; next } - in_table && in_fields && /^###/ { in_fields=0 } - in_table && in_fields && /^\|/ { - n = split($0, a, "|") - gsub(/^[ ]+|[ ]+$/, "", a[2]) - gsub(/`/, "", a[2]) - if (a[2] != "" && a[2] != "字段" && a[2] !~ /^-+$/) print a[2] - } - ' "$DOC" | sort -u -} - -extract_sql_cols() { - local table=$1 - awk -v t="$table" ' - $0 ~ "^CREATE TABLE `" t "`" { in_table=1; next } - in_table && /^\)/ { in_table=0; next } - in_table && /^[[:space:]]*`[^`]+`/ \ - && $0 !~ /^[[:space:]]*(PRIMARY|UNIQUE|KEY|FOREIGN|CONSTRAINT|INDEX)/ { - match($0, /`[^`]+`/) - print substr($0, RSTART+1, RLENGTH-2) - } - ' "$V1" | sort -u -} - -while IFS= read -r t; do - [ -z "$t" ] && continue - D_COLS=$(extract_doc_cols "$t") - S_COLS=$(extract_sql_cols "$t") - ONLY_D=$(comm -23 <(echo "$D_COLS") <(echo "$S_COLS")) - ONLY_S=$(comm -13 <(echo "$D_COLS") <(echo "$S_COLS")) - if [ -n "$ONLY_D" ] || [ -n "$ONLY_S" ]; then - { - echo "=== 维度 2: 表 \`$t\` 列名不一致 ===" - [ -n "$ONLY_D" ] && { echo " docs/03 有但 V1 无:"; echo "$ONLY_D" | sed 's/^/ - /'; } - [ -n "$ONLY_S" ] && { echo " V1 有但 docs/03 无:"; echo "$ONLY_S" | sed 's/^/ - /'; } - } >&2 - ERR=1 - fi -done <<< "$COMMON" - -if [ $ERR -ne 0 ]; then - exit 1 -fi - -echo "validate.sh: ✓ 表名集合 + 每表列名集合 与 docs/03 一致" -exit 0 diff --git a/skills/plan/lite-build-db/templates/docs-05-endpoint-template.md b/skills/plan/lite-build-db/templates/docs-05-endpoint-template.md deleted file mode 100644 index 91a1fda..0000000 --- a/skills/plan/lite-build-db/templates/docs-05-endpoint-template.md +++ /dev/null @@ -1,12 +0,0 @@ -### {{req_id}} {{title}} - -- **Method**: {{method}} -- **Path**: `{{path}}` -- **Auth**: {{auth}} -- **请求**: {{request_summary}} -- **响应**: {{response_summary}} - -#### 错误码 -{{#each errors}} -- `{{code}}` — {{message}} -{{/each}} diff --git a/skills/plan/lite-build-db/templates/docs-05-header-template.md b/skills/plan/lite-build-db/templates/docs-05-header-template.md deleted file mode 100644 index ff6df19..0000000 --- a/skills/plan/lite-build-db/templates/docs-05-header-template.md +++ /dev/null @@ -1,30 +0,0 @@ -# 05-API接口契约 - -BasePath: `{{base_path}}` -端口: `【人工填写:后端端口,默认 8080】` - -## 全局约定 - -### 响应格式 -```json -{"code": 200, "message": "操作成功", "data": {}, "timestamp": 1700000000000} -``` - -### 错误码 -| 范围 | 含义 | -|---|---| -| 200 | 成功 | -| 400xx | 客户端参数错误 | -| 401xx | 认证/授权错误 | -| 403xx | 权限不足 | -| 404xx | 资源不存在 | -| 500xx | 服务端内部错误 | - -### 鉴权 -{{auth_note}} - -### 分页参数 -{{pagination_note}} - -## 接口清单 -(各模块接口段落见下方,由 `lite-build-db` 按 REQ 填入) diff --git a/skills/plan/lite-build-db/templates/docs-08-module-row-template.md b/skills/plan/lite-build-db/templates/docs-08-module-row-template.md deleted file mode 100644 index edd15f1..0000000 --- a/skills/plan/lite-build-db/templates/docs-08-module-row-template.md +++ /dev/null @@ -1,6 +0,0 @@ -- {{module_id}} {{module_name}} - - 依赖: {{depends_on}} - - 路径: {{path_scopes}} - - 里程碑: — - - 功能: -{{req_checklist}} diff --git a/skills/plan/lite-design/SKILL.md b/skills/plan/lite-design/SKILL.md deleted file mode 100644 index 8729a64..0000000 --- a/skills/plan/lite-design/SKILL.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -name: lite-design -description: 计划第 2 段——生成架构文档(docs/04 § 一+,含前端 Design Tokens + 环境配置)+ 工具脚本 + .env.local + sql/migrations/,然后从 REQ 正向设计 docs/03 并回填 REQ 依赖表,停下等人工审阅 docs/03。 -user-invocable: false -allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(mkdir *) Bash(cp *) Bash(cat *) Bash(bash *) ---- - -**所有输出必须使用中文。** - -# lite-design - -## 执行步骤 - -### 步骤 0:打印当前位置流程图 - -用 `Bash` 执行以下命令(文件不存在时静默忽略,不报错): - -```bash -cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/plan-start/banners/flow-lite.txt" 2>/dev/null || true -``` - -打印横幅:`▶ 计划阶段 ② — lite-design`。 - -### A. 读取锁定的输入 - -用 `Read` 读取: -- `docs/04-技术规范.md` § 零 技术栈表 -- `docs/01-需求清单/index.md` 需求索引 -- `docs/01-需求清单/` 下所有 REQ 卡片(`docs/01-需求清单/*/REQ-*.md`) - -后续所有内容都基于它们推导。 - -### B. 生成 docs/04 § 一+(保留 § 零 不覆盖) - -docs/04 已由 lite-init 写入 § 零。本步骤追加 § 一 ~ 五。 - -lite 版的 docs/04 承担三类内容(不再生成独立的前端规范文件或环境配置文件): -- § 一~三:后端/前端/共同编码规范 -- § 四:前端 Design Tokens + 交互约定 -- § 五:环境配置 - -操作: -1. 读取 `docs/04-技术规范.md`(现有 § 零 完整内容)。 -2. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`。 -3. 基于技术栈,按大纲生成 § 一 ~ 五 的项目专属内容,剥掉 HTML 注释(注释是给 LLM 的提示,不应出现在最终文档里)。 -4. 拼接原有内容和新生成内容,写回 `docs/04-技术规范.md`。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] 架构文档已生成(docs/04 § 一+ | scripts/*.sh | .env.local | sql/migrations/)`(步骤 C 完成后一并勾选) - -### C. 生成工具脚本 + 目录结构 - -#### C.1 复制固定文件 - -```bash -mkdir -p scripts sql/migrations src/styles -cp "${CLAUDE_SKILL_DIR}/templates/env-local-template" .env.local -cp "${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh" scripts/setup-test-db.sh -``` - -注意:lite 版不生成 `src/styles/tokens.css`(前端 token 骨架由前端阶段处理)。 - -#### C.2 渲染 scripts/test.sh - -读取 `${CLAUDE_SKILL_DIR}/templates/scripts-test-template.sh`,基于步骤 A 的技术栈(docs/04 § 零)为以下 7 个命令槽推断命令后写到 `scripts/test.sh`(纯后端项目可把前端 / E2E 槽填 `echo` 占位): - -- `{{backend_build}}` / `{{backend_lint}}` / `{{backend_test}}` — 后端各 stage 命令 -- `{{frontend_build}}` / `{{frontend_lint}}` / `{{frontend_test}}` — 前端各 stage 命令 -- `{{e2e_cmd}}` — E2E(无 E2E 工具则填 `echo "[test.sh] e2e 略"`) - -> 推断规则:根据 `docs/04 § 零`。 -> - 「后端*」存在 → 据后端技术栈推 backend 三槽(build / lint / test 命令) -> - 「前端*」存在 → 据前端技术栈推 frontend 三槽 -> - 缺席 stack → 三槽全填 `:`(语法合法即可) -> - `{{e2e_cmd}}` 通常仅前端,按上述前端规则或填 `echo "[test.sh] e2e 略"` -> -> 表结构异常(列名变更 / 无中文前缀)时停下,用 `AskUserQuestion` 让用户显式确认每 stack 命令。 - -#### C.3 赋权 - -```bash -bash -c "chmod +x scripts/*.sh" -``` - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] 架构文档已生成(docs/04 § 一+ | scripts/*.sh | .env.local | sql/migrations/)` - -### D. 追加 .gitignore 忽略项 - -调用脚本完成合并: - -```bash -bash "${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh" "${CLAUDE_SKILL_DIR}/templates/gitignore-append-template" -``` - -### E. 推导 schema + 渲染 docs/03 - -基于步骤 A 读到的 REQ + docs/04 § 一命名规范,**正向推导**业务实体 → 表 + 字段 + 索引 + 外键。要求: - -1. 严格套用 `docs/04 § 一` 的命名规范(匈牙利前缀 `i` int / `s` varchar / `t` datetime 等) -2. **主键**:模板内置 `iIncrement` 为主键。REQ 明确要求复合主键 / UUID / 业务主键时按 REQ;其他主键变更需同步改 docs-03-header / docs-03-table 两份模板 -3. **外键**:依据 REQ 中的引用关系(如「订单引用客户」),明确列出 `ON DELETE` / `ON UPDATE` 策略;不能确定时默认 `RESTRICT` -4. **索引**:根据 REQ 的查询模式推导业务索引;外键列默认建索引;标准列里 `sBrandsId` / `sSubsidiaryId` 这类多租户隔离列,按业务查询模式建组合索引 -5. **业务注记**:对每张表用一两句话说明业务用途、关键约束、与其他表的关系 - -如果某 REQ 表述模糊以致无法推断关键 schema 细节(如:枚举值范围 / 字段长度上限 / 必填性),先按合理默认推导并在该字段「业务含义」列加 `【人工填写:需用户审阅】` 标注,不打断本次推导。 - -渲染 docs/03: -1. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md`,填充 `schema_name`(从 `.env.local` 读 `DB_SCHEMA`,无则填 `【人工填写:DB_SCHEMA】`)、`er_overview`(纯文本 ER 概览)。 -2. 渲染「表清单」:对每张表,读取并填充 `${CLAUDE_SKILL_DIR}/templates/docs-03-table-template.md`。 -3. 写入 `docs/03-数据库设计文档.md`。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] docs/03 数据库设计已生成(REQ → 表/字段/索引/外键,回填 REQ 依赖表)` - -### F. 回填模块头 + REQ 卡片的 TBD 字段 - -1. 列出 `docs/01-需求清单/*/_module.md`(模块头)和 `docs/01-需求清单/*/REQ-*.md`(REQ 卡片)。 -2. 在这些文件中搜索 `TBD(lite-design 自动补)` 并回填为实际表名。**不动** `TBD(lite-build-db 自动补)`。 - - `_module.md` 的 `涉及表` 字段:填入该模块涉及的所有表名(逗号分隔) - - `REQ-*.md` 的 `依赖表` 字段:填入该 REQ 操作的表名(逗号分隔) -3. 打印回填统计:`lite-design 回填 <M> 处模块"涉及表" + <N> 处 REQ"依赖表"`。 - -### G. 勾选 § 一 ② 顶层 + 停下等人工审阅 - -1. 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选 ② 顶层: - - `- [ ] 计划 ② 脚手架 + 数据库设计 — lite-design` - -2. 打印停下横幅并**停下**: - - ``` - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - [lite-design] ✅ 计划 ② 完成 - - 产出: - ✓ docs/04-技术规范.md(§ 一+ | § 四 Design Tokens | § 五 环境配置) - ✓ scripts/setup-test-db.sh + scripts/test.sh(已赋权) - ✓ .env.local(含占位符,凭据请自填) - ✓ sql/migrations/(目录已建) - ✓ .gitignore(已追加忽略项) - ✓ docs/03-数据库设计文档.md - ✓ docs/01 各 REQ 卡片"依赖表" + 模块头"涉及表" 已回填 - - ⏸ 现在请你审阅 docs/03。 - 重点关注: - - 业务实体覆盖是否完整 - - 字段类型 / 长度 / 是否可空 / 默认值是否合理 - - 索引是否覆盖主要查询模式 - - 外键 ON DELETE / ON UPDATE 策略是否符合业务 - - 字段「业务含义」列含 `【人工填写:需用户审阅】` 标注的位置需逐一确认 - - .env.local 中的凭据占位符请直接编辑文件填写(凭据不进会话) - - 审阅完成后,再运行: - /erp-workflow:plan-start - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ``` - - **停止**,不调用任何下游 skill。 - -## 参考 - -- `docs/04-技术规范.md` § 零(技术栈输入) -- `docs/01-需求清单/index.md`(模块索引输入) -- `docs/01-需求清单/<module>/_module.md`(模块头:回填 `涉及表`) -- `docs/01-需求清单/<module>/REQ-*.md`(REQ 输入 + 回填 `依赖表`) -- `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`(大纲:§ 一~三 编码规范 + § 四 Design Tokens + § 五 环境配置) -- `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md` -- `${CLAUDE_SKILL_DIR}/templates/docs-03-table-template.md` -- `${CLAUDE_SKILL_DIR}/templates/scripts-test-template.sh`(推断命令填充槽位;缺席 stack 填 `:`) -- `${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh`(0 槽位) -- `${CLAUDE_SKILL_DIR}/templates/env-local-template`(0 槽位) -- `${CLAUDE_SKILL_DIR}/templates/gitignore-append-template`(0 槽位) -- `${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh`(.gitignore 逐行判重合并脚本) diff --git a/skills/plan/lite-design/scripts/merge-gitignore.sh b/skills/plan/lite-design/scripts/merge-gitignore.sh deleted file mode 100755 index 478182e..0000000 --- a/skills/plan/lite-design/scripts/merge-gitignore.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash -# merge-gitignore.sh -# 把模板里的忽略规则合并到项目根的 .gitignore: -# - 若 .gitignore 不存在 → 直接 cp 模板(含注释头和结构) -# - 若已存在 → 逐行判重,只追加模板里缺失的规则行(跳过注释/空行) -# -# 用法:merge-gitignore.sh <template_path> [<target_gitignore_path>] -# template_path 模板文件绝对路径(由 lite-design skill 传入) -# target_gitignore_path 目标 .gitignore 路径,默认为当前工作目录下的 .gitignore -# -# 判重:grep -xF 整行精确匹配 + 字面字符串(非正则),避免 .env 误匹配 .env.local, -# 也避免 *.class / *.iml 等通配符被当作 regex。 - -set -euo pipefail - -template="${1:?usage: merge-gitignore.sh <template_path> [<target_gitignore_path>]}" -target="${2:-.gitignore}" - -if [ ! -f "$template" ]; then - echo "[merge-gitignore] ERROR: template not found: $template" >&2 - exit 1 -fi - -if [ ! -f "$target" ]; then - cp "$template" "$target" - echo "[merge-gitignore] created $target from template" - exit 0 -fi - -added=0 -while IFS= read -r line; do - case "$line" in ""|"#"*) continue ;; esac - if ! grep -qxF "$line" "$target"; then - echo "$line" >> "$target" - added=$((added + 1)) - fi -done < "$template" - -echo "[merge-gitignore] $target updated (+$added rules)" diff --git a/skills/plan/lite-design/templates/docs-03-header-template.md b/skills/plan/lite-design/templates/docs-03-header-template.md deleted file mode 100644 index 1fc6a44..0000000 --- a/skills/plan/lite-design/templates/docs-03-header-template.md +++ /dev/null @@ -1,28 +0,0 @@ -# 03-数据库设计文档 - -- **Schema**: `{{schema_name}}` -- **Migration 清单**: `sql/migrations/V*.sql`(由 Flyway 顺序 apply) -- **生成方式**: 由计划 ② `lite-design` 基于 `docs/01-需求清单/<module>/REQ-*.md` REQ 卡片正向设计生成(schema SSoT)。 - -## 项目标准列约定 - -下文每张业务表的字段清单都自动包含以下 5 个标准列(匈牙利前缀 `i` int / `s` varchar / `t` datetime)。渲染时由 `docs-03-table-template.md` 模板内置原样输出。 - -| 列名 | 类型 | 可空 | 主键 | 说明 | -|---|---|---|---|---| -| `iIncrement` | int | 否 | 是 | 整数主键 ID(自增方式由实现决定:DB `AUTO_INCREMENT` 或应用 / 触发器分配) | -| `sId` | varchar(100) | 是 | — | 业务 ID(对外暴露的字符串标识,如 UUID / 人类可读编号) | -| `sBrandsId` | varchar(100) | 是 | — | 品牌 ID(多租户隔离) | -| `sSubsidiaryId` | varchar(100) | 是 | — | 子公司 ID(组织层级隔离) | -| `tCreateDate` | datetime | 否 | — | 记录创建时间 | - -字典 / 辅助表如有豁免,在该表业务注记里注明豁免原因。 - -## ER 关系概览 - -{{er_overview}} - -## 表清单 -{{#each tables}} -- `{{table_name}}` — {{purpose}} -{{/each}} diff --git a/skills/plan/lite-design/templates/docs-03-table-template.md b/skills/plan/lite-design/templates/docs-03-table-template.md deleted file mode 100644 index d05c5be..0000000 --- a/skills/plan/lite-design/templates/docs-03-table-template.md +++ /dev/null @@ -1,27 +0,0 @@ -## `{{table_name}}` — {{purpose}} - -### 字段 - -| 字段 | 类型 | Nullable | 默认 | 业务含义 | -|---|---|---|---|---| -| `iIncrement` | int | 否 | 自增函数 | 整数主键 ID(标准列) | -| `sId` | varchar(100) | 是 | uuid 函数 | 业务 ID(标准列) | -| `sBrandsId` | varchar(100) | 是 | `1111111111` | 品牌 ID(多租户隔离,标准列) | -| `sSubsidiaryId` | varchar(100) | 是 | `1111111111` | 子公司 ID(组织层级隔离,标准列) | -| `tCreateDate` | datetime | 否 | 当前时间 | 创建时间(标准列) | -{{#each columns}} -| {{name}} | {{type}} | {{nullable}} | {{default}} | {{business_meaning}} | -{{/each}} - -### 索引 -{{#each indexes}} -- `{{name}}` ({{type}}): {{columns}} -{{/each}} - -### 外键 -{{#each foreign_keys}} -- `{{name}}`: {{from_col}} → {{to_table}}.{{to_col}} ({{on_delete}}) -{{/each}} - -### 业务注记 -{{notes}} diff --git a/skills/plan/lite-design/templates/docs-04-skeleton-template.md b/skills/plan/lite-design/templates/docs-04-skeleton-template.md deleted file mode 100644 index 96d300f..0000000 --- a/skills/plan/lite-design/templates/docs-04-skeleton-template.md +++ /dev/null @@ -1,122 +0,0 @@ -<!-- -本文件是 docs/04-技术规范.md 的 § 一+ 大纲(lite 版)。 -lite-design 读取 docs/04 § 零(技术栈表)和 docs/01-需求清单/index.md(模块索引), -按下述大纲生成本项目专属的规范内容。LLM 不要原样拷贝提示文字,只保留 section 标题。 -lite 版将前端 Design Tokens + 环境配置内容折叠到本文件 § 四 + § 五, -不再生成独立的前端规范文件或环境配置文件。 ---> - -## 一、后端规范 - -### 1.1 规则 -<!-- 后端通用约定:保留下方占位符不要代填,由人工在 lite-design § E 填写;每条一个 bullet,按需复制本行新增更多。 --> -- 【人工填写:一条后端通用约定,按需复制本行新增更多;无则填「无」】 - -### 1.2 分层结构 -<!-- 按 § 零 的后端框架定层次:controller/service/mapper 等;每层职责一句话。 --> - -### 1.3 命名约定 -<!-- 包名(根包用【人工填写:根包名】占位)/ 类名 / 方法名 / 常量的大小写规则,含 2 个示例。 --> - -### 1.4 统一响应格式 -<!-- 成功/失败的 JSON 结构,错误码段位划分。 --> - -### 1.5 异常处理 -<!-- 全局异常处理器的使用方式;哪些异常要 catch,哪些禁止;**接口响应禁止回显后端异常堆栈**(返用户友好错误码 + 文案)。 --> - -### 1.6 事务 -<!-- 事务边界(通常 service 层);跨服务调用的禁止/替代方案。 --> - -### 1.7 认证 -<!-- 基于 § 零 认证方案推导:token 生命周期、刷新机制、密钥管理。 --> - -## 二、前端规范 - -### 2.1 目录约定 -<!-- 基于 § 零 前端框架推导:api/components/pages/store/hooks/utils 的职责;**前端禁止直接写 SQL / 操作 DB**,所有数据访问走 api/ 层统一封装。 --> - -### 2.2 状态管理 -<!-- 基于 § 零 状态管理技术推导:全局 vs 局部、服务端数据的存放。 --> - -### 2.3 请求封装 -<!-- HTTP 客户端的拦截器、超时、错误重试、鉴权注入。 --> - -### 2.4 错误处理 -<!-- 网络错误 / 业务错误 / 页面级错误的分层处理。 --> - -### 2.5 样式与主题 -<!-- 基于 § 零 UI 库给出 CSS 变量约定: - - 命名格式 `--color-<scope>-<role>-<state>`(scope=form/table-row/...,role=bg/fg/border,state=edit/readonly/hover/selected) - - 文件位置 `src/styles/tokens.css`(前端阶段处理,lite-design 不生成);色值由 § 四锁定后在前端阶段填入 - - 组件样式中只用 var(--color-xxx),禁止硬编码 hex/rgba - - 与 UI 库主题对接(如 Ant Design ConfigProvider.theme.token)的映射方式 - 具体 token 表见 § 四。 --> - -## 三、共同约定 - -### 3.1 Git 提交 -`<type>(<scope>): <subject> REQ-XXX-NNN` - -### 3.2 分页查询 -<!-- 后端分页对象 + 前端分页组件,入参出参约定。 --> - -### 3.3 日期与金额 -<!-- 后端类型(如 LocalDateTime / BigDecimal)+ 前端展示工具;金额精度约定。 --> - -### 3.4 数据访问规约 -<!-- 基于 § 零 数据访问技术(MyBatis-Plus / JPA 等):SELECT 字段显式列举,**禁止 `SELECT *`**;循环中不得执行 DB 查询(**N+1 反模式**),改用批量查 / IN 子句 / JOIN;Mapper XML 里字段与表名用常量或引用,避免拼字符串。 --> - -### 3.5 配置与安全 -<!-- 配置:DB 连接 / 端口 / 密钥 / 第三方 URL 等一律放 `application.yml` + `.env.local`,代码里**禁止硬编码**。 - 前端安全:`localStorage` 不存敏感信息(token / 身份 / 个人数据),推荐 HttpOnly Cookie 或 内存 + 刷新 token 模式;接口响应禁止回显后端异常堆栈(与 § 1.5 一致)。 --> - -## 四、前端 Design Tokens / 交互约定 - -> 所有色值统一以 CSS 变量定义于 src/styles/tokens.css;命名规范见 § 2.5。 -> 本项目所有页面布局以项目根 `prototype/` 目录下的静态 HTML mockup 为权威。 -> 前端阶段实现时直接以 prototype/ HTML 推导组件树与样式。本节仅承载跨页面通用规则与 Design Tokens。 - -### 4.1 通用交互规则 - -#### 4.1.1 操作反馈 -<!-- 成功/失败消息;危险操作二次确认;长耗时按钮 loading 态。 --> - -#### 4.1.2 数据展示 -<!-- 空状态 / 加载 / 异常 的统一组件与文案。 --> - -#### 4.1.3 权限控制(前端) -<!-- 菜单级 / 按钮级 / 路由级的控制方式,关联后端 RBAC。 --> - -### 4.2 全局调色板 -<!-- 与 § 零 UI 库主题对齐:列名 = 语义 / 变量名 / 默认值 / 用途。 - 至少含:主色/成功/警告/错误/主文字/次文字/边框/背景。 --> - -### 4.3 组件级状态色 -<!-- 场景 × 状态映射表:列名 = 序号 / 组件 / 编辑bg / 只读bg / 悬浮bg / 编辑fg / 只读fg / 悬浮fg / 备注。 - 单元格写 token 名(var(--color-xxx) 形式),不写 hex;"—" 表示该状态不适用。 - 表后追加「Token 默认值」表,列出每个 --color-xxx 在 tokens.css 的默认值。 --> - -### 4.4 引用约定 -<!-- 一句话三条: - - 组件样式只用 var(--color-xxx),禁止硬编码 - - 新增 token 须先登记到 § 4.2/4.3 再补 tokens.css - - 修改色值只改 tokens.css 一处,不允许组件覆盖 --> - -## 五、环境配置 - -### 5.1 依赖清单 - -<!-- 表格:| 层 | 依赖 | 版本 | 说明 |;覆盖 运行时 / 构建 / 容器 / CLI 工具。 --> - -### 5.2 端口约定 - -<!-- 表格:| 服务 | 端口 | 说明 |;至少列 后端 HTTP / 前端 dev / 数据库 / 缓存 / 反代。 --> - -### 5.3 环境变量 - -运行时凭据(数据库连接、JWT 密钥等)全部放在仓库根的 `.env.local`,不入 git。 -字段清单与占位符见该文件,真实值由开发者本地填写。 - -### 5.4 常用命令 - -<!-- 表格:| 命令 | 说明 |;包含 启动后端 / 启动前端 / 打包 / 运行测试 / 重置测试数据。 --> diff --git a/skills/plan/lite-design/templates/env-local-template b/skills/plan/lite-design/templates/env-local-template deleted file mode 100644 index c16e67f..0000000 --- a/skills/plan/lite-design/templates/env-local-template +++ /dev/null @@ -1,25 +0,0 @@ -# .env.local — 本地开发凭据(入 .gitignore,不提交) -# -# 规则: -# 1. 值含 `$`、反引号、空格、`!` 等 shell 特殊字符时,必须用单引号包裹: -# DB_PASSWORD='p@ss$w0rd!' -# 否则 `set -a; . .env.local; set +a` 会做变量展开导致密码错乱。 -# 2. DB_HOST 建议保持 localhost / 127.0.0.1;非本地 host 默认会被 scripts/setup-test-db.sh 防护拒绝。 -# 若必须用远程测试库,把 host 列入下方 TEST_DB_ALLOWED_HOSTS。 -# 3. DB_SCHEMA 建议命名含 test / _dev / _local / _ci,避免与生产库同名。 - -DB_HOST=【人工填写:MySQL host,推荐 localhost】 -DB_PORT=【人工填写:MySQL port,默认 3306】 -DB_USER=【人工填写:开发账号名】 -DB_PASSWORD=【人工填写:对应密码,含特殊字符时用单引号包裹】 -DB_SCHEMA=【人工填写:schema 名,推荐含 test/_dev/_local,例如 erp_dev】 -JWT_SECRET=【人工填写:JWT 签名密钥,256+ bit 随机串】 - -# 可选:额外允许 DROP CREATE 的远程 host(空格或逗号分隔)。仅当 DB_HOST 指向公司测试 MySQL 等 -# 非本地服务器时填写;留空表示只允许 localhost / 127.0.0.1 / ::1。 -# 示例:TEST_DB_ALLOWED_HOSTS="118.178.19.35 test-mysql.internal" -# -# ⚠️ 列入后该 host 每次 test.sh 都会被 DROP CREATE(无二次确认)。 -# 仅用于你完全可控的测试库;生产/共享库/多人共享的 staging 库**千万别列**。 -# (防护 2 还会检查 schema 名须含 test/_dev/_local/_ci,独立兜底。) -TEST_DB_ALLOWED_HOSTS= diff --git a/skills/plan/lite-design/templates/gitignore-append-template b/skills/plan/lite-design/templates/gitignore-append-template deleted file mode 100644 index c8635ec..0000000 --- a/skills/plan/lite-design/templates/gitignore-append-template +++ /dev/null @@ -1,32 +0,0 @@ -# ==== ERP 插件推荐忽略项(lite-design 追加) ==== -# 本地运行时配置(含真实凭据,严禁入库) -.env.local -.env.*.local - -# Java / Maven -target/ -*.class - -# Node / 前端构建产物 -node_modules/ -dist/ -build/ -coverage/ - -# IDE -.idea/ -.vscode/ -*.iml - -# OS -.DS_Store -Thumbs.db - -# 日志 -*.log -logs/ - -# 插件运行时临时文件 -.tmp/ -*.raw -# ==== 结束 ==== diff --git a/skills/plan/lite-design/templates/scripts-setup-test-db-template.sh b/skills/plan/lite-design/templates/scripts-setup-test-db-template.sh deleted file mode 100644 index 41a3970..0000000 --- a/skills/plan/lite-design/templates/scripts-setup-test-db-template.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash -# scripts/setup-test-db.sh — 数据库重置脚本:drop + create 空库。 -# schema apply 由 Flyway 在 Spring Boot 启动时自动处理(见 docs/04 技术栈 + sql/migrations/V*.sql)。 -# seed 数据由测试框架负责(Spring @Sql / Flyway R__seed.sql / data.sql)。 -# -# 使用场景: -# - scripts/test.sh 开头:清空库,让 Spring 启动时 Flyway 从 V1 开始重放所有 migration -# - scripts/test.sh 结尾:清空库,避免测试遗留污染下次运行 -# - 手动调试时:reset 到零状态 -# -# 防护:本脚本只允许在本地 host + 测试库名上执行;非预期目标会被拒绝, -# 避免 .env.local 误指向 staging/prod 时触发不可逆 DROP。 - -set -euo pipefail - -ENV_FILE="$(dirname "$0")/../.env.local" -[ -f "$ENV_FILE" ] || { echo "[setup-test-db] ⚠️ .env.local 不存在($ENV_FILE)" >&2; exit 1; } - -# 用 set -a 加载,让 KEY=VALUE 导出为环境变量;密码中含特殊字符时 .env.local 请用单引号包裹 -set -a; . "$ENV_FILE"; set +a - -# 防护 1:默认只允许本地 host(localhost / 127.0.0.1 / ::1)。 -# 若要为本项目额外允许某些远程 host(如公司测试 MySQL),在 .env.local 里设: -# TEST_DB_ALLOWED_HOSTS="118.178.19.35 test-mysql.internal" # 空格或逗号分隔 -# 被列入者可直接 DROP CREATE,不再需要 TEST_DB_ALLOW_REMOTE=1。 -ALLOWED_HOSTS="localhost 127.0.0.1 ::1 ${TEST_DB_ALLOWED_HOSTS//,/ }" -host_allowed=0 -for h in $ALLOWED_HOSTS; do - [ "${DB_HOST:-}" = "$h" ] && { host_allowed=1; break; } -done -if [ "$host_allowed" -ne 1 ]; then - echo "[setup-test-db] ⚠️ 拒绝在非白名单 host (${DB_HOST}) 上执行 DROP DATABASE" >&2 - echo " 当前白名单:${ALLOWED_HOSTS}" >&2 - echo " 加入 host:在 .env.local 追加 TEST_DB_ALLOWED_HOSTS=\"<host1> <host2>\"" >&2 - echo " 一次性绕过:TEST_DB_ALLOW_REMOTE=1 $0" >&2 - [ "${TEST_DB_ALLOW_REMOTE:-0}" = "1" ] || exit 1 -fi - -# 防护 2:schema 名需像测试/开发库(含 test / _dev / _local),否则要求显式确认 -case "${DB_SCHEMA:-}" in - *test*|*_dev|*_local|*_ci) - ;; - *) - echo "[setup-test-db] ⚠️ schema '${DB_SCHEMA}' 不像测试库(期望命名含 test / _dev / _local / _ci)" >&2 - echo " 如确为期望行为,请显式声明:TEST_DB_ALLOW_PROD_NAME=1 $0" >&2 - [ "${TEST_DB_ALLOW_PROD_NAME:-0}" = "1" ] || exit 1 - ;; -esac - -# 防护 3:显式 banner,让人看见自己在 drop 什么;远程 host 额外提示白名单内容 -echo "[setup-test-db] 即将 DROP + CREATE \`${DB_SCHEMA}\` on ${DB_HOST}:${DB_PORT}" -case "${DB_HOST:-}" in - localhost|127.0.0.1|::1) ;; - *) - echo "[setup-test-db] ⚠️ 目标是 **远程** host(已在 TEST_DB_ALLOWED_HOSTS 白名单中,每次 test.sh 都会 DROP)" - echo "[setup-test-db] 当前白名单: ${ALLOWED_HOSTS}" - echo "[setup-test-db] 若不希望每次自动 DROP,从 .env.local 的 TEST_DB_ALLOWED_HOSTS 删掉此 host" - ;; -esac - -MYSQL_CMD="mysql -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD}" - -$MYSQL_CMD -e "DROP DATABASE IF EXISTS \`${DB_SCHEMA}\`; CREATE DATABASE \`${DB_SCHEMA}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" - -echo "[setup-test-db] done — schema will be applied by Flyway when Spring Boot starts" diff --git a/skills/plan/lite-design/templates/scripts-test-template.sh b/skills/plan/lite-design/templates/scripts-test-template.sh deleted file mode 100644 index 07d705d..0000000 --- a/skills/plan/lite-design/templates/scripts-test-template.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash -# scripts/test.sh —— 合并到默认分支(main / master)前的测试闸门。 -# 顺序:detect → setup-db → build → lint → unit+integration → e2e → reset-db -# 由 milestone skill(通过子会话)调用。 - -set -euo pipefail - -PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" -cd "$PROJECT_ROOT" - -# Stack detection (runtime, mode-agnostic) -HAS_BACKEND=0; [ -d backend ] && HAS_BACKEND=1 -HAS_FRONTEND=0; [ -d frontend ] && HAS_FRONTEND=1 -if [ $HAS_BACKEND -eq 0 ] && [ $HAS_FRONTEND -eq 0 ]; then - echo "[test.sh] FATAL: neither backend/ nor frontend/ exists" >&2 - exit 1 -fi - -echo "[test.sh] 1/6 setup test db" -./scripts/setup-test-db.sh - -echo "[test.sh] 2/6 build" -if [ $HAS_BACKEND -eq 1 ]; then (cd backend && {{backend_build}}); else echo "[test.sh] skip backend build"; fi -if [ $HAS_FRONTEND -eq 1 ]; then (cd frontend && {{frontend_build}}); else echo "[test.sh] skip frontend build"; fi - -echo "[test.sh] 3/6 lint" -if [ $HAS_BACKEND -eq 1 ]; then (cd backend && {{backend_lint}}); else echo "[test.sh] skip backend lint"; fi -if [ $HAS_FRONTEND -eq 1 ]; then (cd frontend && {{frontend_lint}}); else echo "[test.sh] skip frontend lint"; fi - -echo "[test.sh] 4/6 unit + integration" -if [ $HAS_BACKEND -eq 1 ]; then (cd backend && {{backend_test}}); else echo "[test.sh] skip backend test"; fi -if [ $HAS_FRONTEND -eq 1 ]; then (cd frontend && {{frontend_test}}); else echo "[test.sh] skip frontend test"; fi - -echo "[test.sh] 5/6 E2E" -{{e2e_cmd}} - -echo "[test.sh] 6/6 reset test db" -./scripts/setup-test-db.sh - -echo "[test.sh] GREEN" diff --git a/skills/plan/lite-init/SKILL.md b/skills/plan/lite-init/SKILL.md deleted file mode 100644 index ab1448c..0000000 --- a/skills/plan/lite-init/SKILL.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -name: lite-init -description: 计划第 1 段——项目初始化 + 范围锁定。复制 CLAUDE.md/docs(01/04/08) 模板、依赖检查、git init,引导项目概述+技术栈+需求索引,生成 REQ 卡片骨架,停下等人工审阅 REQ。 -user-invocable: false -allowed-tools: Glob Read Edit Grep Skill AskUserQuestion Bash(mkdir *) Bash(cp *) Bash(sed *) Bash(bash *) Bash(cat *) Bash(git init) Bash(command -v *) Bash(uname *) Bash(brew *) Bash(apt *) Bash(apt-get *) Bash(yum *) Bash(apk *) Bash(export PATH=*) Bash(echo *) ---- - -**所有输出必须使用中文。** - -你负责完成计划第 ① 段:项目初始化 + 范围锁定。 - -## 执行步骤 - -### 步骤 0:打印计划流程图 - -用 `Bash` 向用户展示 lite 流程图(▶ 位于"计划 ①"): - -```bash -cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/plan-start/banners/flow-lite.txt" 2>/dev/null || true -``` - -> 注:`flow-lite.txt` 由 Task 7 创建,当前若文件不存在,命令静默忽略,不影响后续执行。 - -打印分发横幅: - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - [lite-init] 计划 ① 初始化 + 范围锁定 - ▶ 当前位置:计划 ① / 共 ③ -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -### A. 幂等复制模板文件 - -用 `Bash` 一次性完成。`cp -n` 表示"不覆盖已存在的文件": - -```bash -mkdir -p docs/01-需求清单 -cp -n "${CLAUDE_SKILL_DIR}/templates/CLAUDE-template.md" CLAUDE.md -cp -n "${CLAUDE_SKILL_DIR}/templates/docs-01-index-template.md" docs/01-需求清单/index.md -cp -n "${CLAUDE_SKILL_DIR}/templates/docs-04-stack-template.md" docs/04-技术规范.md -cp -n "${CLAUDE_SKILL_DIR}/templates/docs-08-initial-template.md" docs/08-模块任务管理.md -``` - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] 项目文件骨架已创建(CLAUDE.md + docs/01 index + docs/04 + docs/08)` - -### B. 依赖检查 + 自动安装(命令行工具) - -对 **git、mysql** 两个工具依次执行以下流程: - 1. 如果缺失,尝试自动安装。 - 2. 如果检测到不在 PATH,尝试添加进 PATH,并加载。 - -全部通过后打印单行汇总再进入步骤 C: - -``` -[lite-init] 依赖检查: git ✓ mysql ✓ -``` - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] 依赖检查通过(git / mysql)` - -### C. 初始化 Git(如尚未初始化) - -用 `Glob` 检查 `.git/` 目录是否存在。 -- 不存在 → 用 `Bash` 执行 `git init`。 -- 已存在 → 跳过。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] Git 已初始化` - -打印完成横幅: - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - [lite-init] 项目初始化完成 - - 已创建: - ✓ CLAUDE.md(从插件模板复制) - ✓ docs/01-需求清单/index.md(待人工填写模块索引) - ✓ docs/04-技术规范.md(默认技术栈,步骤 E 让用户确认) - ✓ docs/08-模块任务管理.md(全流程进度跟踪) - 已勾选:初始化子项 3 项 - - 下一步:引导项目概述 + 技术栈 + 需求索引 + 生成 REQ 卡片 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -### D. 提示用户填写项目概述并等待 - -向用户输出: - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - [lite-init] 请填写项目概述 - - 📄 文件位置: ./CLAUDE.md - 📌 编辑位置: § 🎯 项目概述 - - 请将以下占位符替换为实际值: - - 项目名称 - - 项目简述 - - 目标用户 - - 部署方式 - 改完后回来选择「继续」。 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -用 `AskUserQuestion` 询问: -- **question**: `项目概述填写完毕了吗?` - - 用户选择「继续」→ 用 `Grep` 在 `CLAUDE.md` 搜索 `【人工填写:`(限定 § 🎯 项目概述 节)。命中 → 打印残留行 + 路径,重新弹出同样的 AskUserQuestion;0 命中 → 勾选并进入步骤 E。 - - 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。 - -0 命中后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述)` - -### E. 提示用户检查默认技术栈并等待 - -`docs/04-技术规范.md` 已由步骤 A 用模板复制(默认技术栈)。本步骤让用户检查 / 调整 § 零。 - -向用户输出: - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - [lite-init] 技术栈已保存 - - 📄 文件位置: ./docs/04-技术规范.md(由模板生成) - 📌 编辑位置: § 零、技术栈总览 - - 请检查技术栈表: - - 不需要的行直接删除(如纯后端项目删前端行) - - 需要替换的技术直接改 - - 需要新增的条目直接加行 - 改完后回来选择「继续」。 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -用 `AskUserQuestion` 询问: -- **question**: `技术栈检查完毕了吗?` - - 用户选择「继续」→ 进入步骤 F。 - - 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] 技术栈已确认(docs/04 § 零)` - -### F. 提示用户填写需求清单并等待 - -`docs/01-需求清单/index.md` 已由步骤 A 写入占位符模板,这里让用户补齐模块清单。 - -向用户输出: - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - [lite-init] 请填写需求清单模块索引 - - 📄 文件位置: ./docs/01-需求清单/index.md - 📌 编辑位置: § 模块索引(表格) - - 请按业务列出所有模块: - - 每行一个模块(如 SYS 系统管理 / PUR 采购 / SAL 销售) - - 「核心功能点」只需关键词,CC 会拆分为 REQ 卡片 - 改完后回来选择「继续」。 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -用 `AskUserQuestion` 询问: -- **question**: `需求清单模块索引填写完毕了吗?` - - 用户选择「继续」→ 进入步骤 G。 - - 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] 需求清单索引已填写(docs/01-需求清单/index.md)` - -### G. 生成 REQ 卡片骨架并停下等人工审阅 - -1. 用 `Grep` 校验 `docs/01-需求清单/index.md` 无 `【人工填写:` 残留;有则回步骤 F。 -2. 用 `Read` 读 `index.md` 解析模块索引。 -3. **单次 Bash 写入所有文件**(替代 N×9 次 Edit): - - - **每模块推断**:三元组 `{module_code, module_name, module_brief}` + N 个 REQ 的六元组 `{req_id, title, goal, rules, constraints, acceptance}`。`req_id`/`title` 从核心功能点拆分;`goal` 展开 `title`;`rules`/`constraints`/`acceptance` 起草业务语义。**不推断**输入 / 输出(模板原样保留示例)。 - - **单次 Bash**:调 `${CLAUDE_SKILL_DIR}/scripts/render.sh` 落盘所有文件(脚本内部完成模板读取 + 占位符替换 + HTML 注释剥离)。下面是**调用形态**示例,`<MOD>` / `<模块名>` / `<REQ-MOD-NNN>` 等尖括号位置 CC 按 `index.md` 实际值替换: - - ```bash - R="${CLAUDE_SKILL_DIR}/scripts/render.sh" - # 每个模块:mkdir + 1 个 render module + N 个 render req(每 REQ 一行) - mkdir -p "docs/01-需求清单/<MOD>-<模块名>" - bash "$R" module "docs/01-需求清单/<MOD>-<模块名>/_module.md" "<MOD>" "<模块名>" "<module_brief>" - bash "$R" req "docs/01-需求清单/<MOD>-<模块名>/<REQ-MOD-NNN>.md" "<REQ-MOD-NNN>" "<title>" "<goal>" "<rules>" "<constraints>" "<acceptance>" - ``` - - - **兜底**:值含字面 `$xxx` 或 `}}` 的 REQ 单独走 cp + Edit。 - -4. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选(计划 ① 子项 + ① 顶层): - - ` - [ ] REQ 卡片骨架已生成(docs/01-需求清单/<module>/REQ-*.md)` - - `- [ ] 计划 ① 初始化 + 范围锁定 — lite-init` - -5. 打印停下横幅并**停止**,不自动派发 lite-design: - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - [lite-init] ✅ 计划 ① 完成 - - 产出: - ✓ CLAUDE.md § 🎯 项目概述 - ✓ docs/04 § 零 技术栈 - ✓ docs/01-需求清单/index.md 模块索引 - ✓ docs/01-需求清单/<module>/_module.md 模块头 - ✓ docs/01-需求清单/<module>/REQ-*.md REQ 卡片骨架 - - ⏸ 现在请你逐张打开 REQ 卡片: - - **必改**:输入 / 输出 两段 - · `表1` / `表2` 是模板示例,按本 REQ 业务**改字段 / 增删行 / 增删整张表** - - **审阅**:目标 / 跨字段规则 / 边界 / 验收(已起草,对照业务校正) - - **保留**:`TBD` 不要改,由之后流程自动回填 - - 审阅完成后,运行以下命令进入计划 ②: - /erp-workflow:plan-start - -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -> **STOP**:此处是人工审阅 REQ 的闸门。停止执行,等待用户运行 `/erp-workflow:plan-start` 后由 plan-start 派发 lite-design。 - -## 参考 - -- `${CLAUDE_SKILL_DIR}/templates/CLAUDE-template.md`(项目级 CLAUDE.md 模板) -- `${CLAUDE_SKILL_DIR}/templates/docs-01-index-template.md`(需求索引初稿) -- `${CLAUDE_SKILL_DIR}/templates/docs-04-stack-template.md`(默认技术栈) -- `${CLAUDE_SKILL_DIR}/templates/docs-08-initial-template.md`(计划阶段进度初始化) -- `${CLAUDE_SKILL_DIR}/templates/req-card-template.md`(REQ 卡片模板) -- `${CLAUDE_SKILL_DIR}/templates/_module-template.md`(模块头模板) -- `${CLAUDE_SKILL_DIR}/scripts/render.sh`(步骤 G 渲染助手,dispatch `module` / `req` 两种模式) -- 下游:人工审阅 REQ 后运行 `/erp-workflow:plan-start`,由 plan-start 派发 `lite-design`(计划 ②) diff --git a/skills/plan/lite-init/scripts/render.sh b/skills/plan/lite-init/scripts/render.sh deleted file mode 100644 index 2bf2182..0000000 --- a/skills/plan/lite-init/scripts/render.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash -# render.sh — lite-init 渲染单个 _module.md 或 REQ-*.md -# -# 用法: -# bash render.sh module <out_path> <module_code> <module_name> <module_brief> -# bash render.sh req <out_path> <req_id> <title> <goal> <rules> <constraints> <acceptance> -# -# 模板路径自定位:脚本同级父目录下 templates/{_module-template.md, req-card-template.md} - -set -euo pipefail - -TYPE=${1:?missing type (module|req)} -shift - -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -TPL_DIR="$SCRIPT_DIR/../templates" - -case "$TYPE" in - module) - out=${1:?missing out_path}; code=${2:?}; name=${3:?}; brief=${4:?} - c=$(cat "$TPL_DIR/_module-template.md") - c="${c//\{\{module_code\}\}/$code}" - c="${c//\{\{module_name\}\}/$name}" - c="${c//\{\{module_brief\}\}/$brief}" - ;; - req) - out=${1:?missing out_path}; req_id=${2:?}; title=${3:?}; goal=${4:?}; rules=${5:?}; constraints=${6:?}; acceptance=${7:?} - c=$(sed '/^<!--$/,/^-->$/d' "$TPL_DIR/req-card-template.md") - c="${c//\{\{req_id\}\}/$req_id}" - c="${c//\{\{title\}\}/$title}" - c="${c//\{\{goal\}\}/$goal}" - c="${c//\{\{rules\}\}/$rules}" - c="${c//\{\{constraints\}\}/$constraints}" - c="${c//\{\{acceptance\}\}/$acceptance}" - ;; - *) - echo "render.sh: unknown type '$TYPE' (expect module|req)" >&2 - exit 1 - ;; -esac - -printf '%s\n' "$c" > "$out" diff --git a/skills/plan/lite-init/templates/CLAUDE-template.md b/skills/plan/lite-init/templates/CLAUDE-template.md deleted file mode 100644 index 8da923c..0000000 --- a/skills/plan/lite-init/templates/CLAUDE-template.md +++ /dev/null @@ -1,280 +0,0 @@ -# CLAUDE.md — ERP项目 Claude Code 主指令文件 - -> 本文件是 Claude Code 的"操作手册"。Claude Code 启动时会自动读取此文件。 - ---- - -## 🎯 项目概述 - -- **项目名称**: 【人工填写:公司 + 项目名,例如"XX 公司 ERP 管理系统"】 -- **项目简述**: 【人工填写:一句话描述项目目标,例如"面向中小制造企业的全流程 ERP,涵盖采购/库存/生产/销售/财务"】 -- **目标用户**: 【人工填写:谁会用,例如"企业内部管理人员(采购员、仓管员、生产主管、销售员、财务人员、管理层)"】 -- **部署方式**: 【人工填写:私有化部署 / 云部署 / Docker 容器化 等】 - ---- - -## 🔄 编码开发流程(两阶段 + 统一功能循环) - -编码阶段入口:`/erp-workflow:coding-start`。lite 保留**后端模块阶段**与**前端整体阶段**两段,但两段共用**同一套功能循环 skill**(`feature-spec → feature-tdd → feature-review`),由 `phase` 参数区分。 - -### 阶段路由(coding-start 内,只做分发) - -`coding-start` 每次入口按"先后端、再前端"检查并派发到 `phase-driver`: - -1. 扫 `docs/08 § 二` 各后端模块 `里程碑:` 字段 + `git tag -l 'milestone/<id>'`:有未打里程碑模块 → 派发 `phase-driver`(phase=backend),结束。 -2. 后端全部打里程碑 → 读 `docs/08 § 三` `整体里程碑:` + `git tag -l 'milestone/frontend-phase'`:未完成 → 派发 `phase-driver`(phase=frontend),结束。 -3. 后端 + 前端都完成 → 输出"所有阶段已完成"。 - -### 统一功能循环(两阶段共用) - -**阶段驱动(外)**:`phase-driver`(phase=backend 走后端模块;phase=frontend 走前端整体阶段——自带 prototype/ 门禁 + 从 prototype/docs01/docs05 推导 FE 清单写入 docs/08 § 三)→ feature 循环 → `milestone`(本地 merge 进默认分支 + 打 `milestone/<id>` 或 `milestone/frontend-phase` tag)→ 自动回调 `coding-start` 路由下一阶段(无人工介入)。 - -**功能循环(内,每个 REQ-XXX-NNN 或 FE-NN 一遍)**:`feature-spec` → `feature-tdd` → `feature-review`。 -- phase=backend:单元是 REQ,分支 `module-<id>`,产出 controller/service/repository/DTO/migration; -- phase=frontend:单元是 FE,分支 `frontend-phase`,产出 `frontend/` 下组件/路由/API client(以 prototype 为页面权威); -- `feature-review` verdict=approve → 勾选 docs/08 § 二(后端 REQ)/ § 三(前端 FE)对应子项,继续下一单元; -- 本阶段单元全部完成 → 调用 `milestone` 打里程碑 tag + 回调 `coding-start`。 - -### 里程碑前守门 - -- `milestone` 在打 tag 前内置测试闸门(phase 由分支推断:后端 `scripts/test.sh`;前端 vitest + Playwright,命令取自 docs/04 § 零);红色不得跳过。 -- 测试 / 验证统一派发到 Agent 子会话执行,主会话只接收结构化结论。 - ---- - -## ✅ 阶段完成判定规则 - -`docs/08-模块任务管理.md` 分三段: -- `§ 一`:计划阶段三段(①②③)进度勾选 -- `§ 二`:后端编码模块元数据表(每个模块一行 bullet,记录依赖 / 路径 / 里程碑 tag / REQ 功能子项;行序即 REQ 开发顺序,是 phase-driver 的排序权威) -- `§ 三`:前端整体阶段(`整体里程碑:` 字段 + FE 功能清单,由 phase-driver(phase=frontend) 推导填入) - -**阶段完成判定**统一以 `里程碑:` 字段(§二 模块 / §三 整体)+ 本地 `git tag -l 'milestone/<id>'` 判定;子项勾选只作可视化进度,不参与完成判定。 - -### 后端模块格式 - -每个后端模块在 docs/08 § 二 中长这样: - -```markdown -- module_0 系统管理 - - 依赖: — - - 路径: backend/module/sys/ - - 里程碑: — - - 功能: - - [ ] REQ-SYS-001 用户登录 - - [ ] REQ-SYS-002 用户注册 -``` - -- `里程碑:` 字段由 `milestone` 在打里程碑 tag 时从 `—` 改为 `milestone/<module_id>`。 -- 每个 `REQ-*` 子项由 `feature-review` 在 verdict=approve 时自动勾选为 `[x]`。 - -### 状态语义 - -| `里程碑:` 字段 | `git tag -l` | 含义 | 你(Claude Code)的行为 | -|---|---|---|---| -| `—` | tag 不存在 | 该阶段未开始 / 进行中(未打里程碑) | ✅ 开始 / 继续该阶段开发 | -| `milestone/<id>` | tag 存在 | 阶段**已完成** | 🟢 进入下一未完成模块;全部完成 → 输出完成信息 | - -### 模块完成报告 - -由 `milestone` skill 产出,模板由 milestone skill 持有。CC 不手写模块报告,仅填模板。 - ---- - -## 🏷️ 占位符统一约定 - -项目文档里有 **2 种填写占位** + **1 种提示占位**: - -| 格式 | 谁填 | 使用阶段 | 说明 | -|------|-----|---------|------| -| `【人工填写:<简短说明>】` | 人 | 仅计划阶段文档 | 密钥 / 账密 / 包名 / 命名约定 / 小版本号等人工才能决定的值;编码阶段 plan/spec 禁止出现,查不到真值时用 `AskUserQuestion` 问用户 | -| `TBD(<责任人>)` | CC 自动 | 计划或编码 | 后缀附带责任方(如 `TBD(lite-design 自动补)` / `TBD(lite-build-db 自动补)`);由对应 skill 就地补填 | - -**HTML 注释 `<!-- ... -->`**:提示占位,是**插件内部大纲模板**里给 LLM 的**填空提示 / 章节引导**,指引 LLM 按结构填实际内容。skill 生成时会**剥除**这些注释,最终产物里注释不会保留。 - ---- - -## 📐 编码行为约束 - -### 你必须做的 ✅ - -1. **严格遵循** `docs/04-技术规范.md`——命名 / 编码 / 统一响应 / 异常处理 / 数据访问 / 配置与安全 / 环境配置(含 .env.local 字段说明)等项目专属技术规约全部在此 -2. **每个后端接口** 必须先在 `docs/05-API接口契约.md` 定义,再编码实现 -3. **每个功能可追溯到 `REQ-XXX-NNN`**——commit tag + 代码注释(如 `// REQ-SYS-001: 用户登录`)+ plan/spec 文件名均用此 tag -4. **遇到跨模块改动**(动到非当前模块的代码)——按 § 🟡 软规则 **S2** 执行(允许改,但必须留痕) -5. **遇到技术栈外组件引入**(`docs/04 § 零` 技术栈表外的框架 / 中间件 / 关键库),按 § 🟡 软规则 **S1** 执行(允许引入,但必须先 AskUserQuestion) - -### 你禁止做的 🚫 - -1. **主会话直接 `mysql -e` 跑业务 DDL**(只读查询 / 临时本地调试除外)——业务 schema 必须走 `sql/migrations/V_n__*.sql`,详见下方 Schema 演化规约 -2. **手动 Edit `docs/08 § 二` 的 `里程碑:` 字段**,必须由 `milestone` 自动回写 - -### Schema 演化规约(Flyway migration) - -1. **文件命名**:`sql/migrations/V<n>__<snake_case_desc>.sql`,例:`V5__add_user_email_unique_index.sql` -2. **版本号分配**:建文件前 `ls sql/migrations/V*.sql` 查当前最大 n,新文件 `n_max + 1` -3. **Apply 方式**:Spring Boot 启动 / 测试启动时 Flyway 自动 apply(项目必须在 `pom.xml` 声明 `flyway-core` + `flyway-mysql` 依赖)。`scripts/setup-test-db.sh` 只负责清空库,不做 apply -4. **已合并的 migration 永不修改**:发现错了写一个补救 migration(如 `V7__fix_V5_index_name.sql`),旧 `V_n.sql` 不动 -5. **临时调试 DDL**:临时在本地试字段/索引可手动 `mysql -e`,但不写 migration;下次 `setup-test-db.sh` 会 drop+create 清掉 -6. **计划 ③ 生成的 V1**:`V1__initial_schema.sql` 是计划阶段由 `lite-build-db` 从 `docs/03-数据库设计文档.md`(lite-design 正向设计的 schema SSoT)翻译生成的初始版本;后续 V2/V3/... 由编码阶段每个 REQ 按需写入,**同时**反向同步更新 docs/03 对应表小节以保持 SSoT 一致 - ---- - -## 🗂️ Git 提交规范 - -每次提交必须遵循以下格式: - -``` -<type>(<scope>): <subject> -``` - -- `scope`: 模块名,如 `user` / `inventory` / `order` -- `subject`: 简短描述;业务类(feat / fix / test)必须带 `REQ-XXX-NNN` 后缀 - -`type` 含义: - -| type | 看到它意味着 | -|-----|-------------| -| `feat` | **新能力上线**——用户多了一个功能、接口、页面或业务规则 | -| `fix` | **修 bug**——原来行为错了,这次改对 | -| `refactor` | **重构**——外部行为不变,只改代码结构 / 命名 / 抽象 | -| `docs` | **文档改动**——只动 Markdown / 代码注释,不动实现 | -| `style` | **格式调整**——空白 / 缩进 / import 顺序,逻辑 0 变化 | -| `test` | **只动测试代码**——补用例 / 修 fixture,不碰实现 | -| `chore` | **流程维护**——构建 / 依赖 / 工具 / 证据档案 / 里程碑元数据等非业务动作 | - ---- - -## 🚩 中断机制 - -功能循环(每个功能 REQ-XXX 的 feature-spec → feature-tdd → feature-review)默认 **静默编程**,但触发以下任何一条必须**立刻停下、记录原因、等人决策**,不得自行绕过: - -| # | 中断 | 例子 | -| - | --- | --- | -| 1 | **测试反复失败** | 同一测试同一功能内连续 **10 次**修复失败 | -| 2 | **要改密钥 / 账密 / 包名** | 涉及 .env.local / docs/04 §零环境 中的密钥/账密字段 | -| 3 | **外部接口不可达** | 第三方 API 无法连接、证书失效等环境问题,并无法自行解决 | - -> 其余需要人类判断的场景一律走普通 `AskUserQuestion` Q&A,不中断、不写 Blocker 文件。 - -**触发中断时的固定动作:** - -1. 在当前功能的 spec 文件里追加一节 `## 🚩 Blocker`(报告格式由 `interrupt-check` 的 `interrupt-block-template.md` 持有) -2. 停止后续所有功能的静默执行 -3. 在主会话输出一句话摘要 + 指向 blocker 文件的路径,等人回复 - ---- - -## 🟡 软规则(允许继续,但有强制后续动作) - -以下情况 **不触发中断**,CC 可自行继续推进,但必须在约定位置留痕,模块完成时统一审计。 - -| # | 软规则 | 允许动作 | 强制后续 | -| - | ----- | ------- | ------- | -| S1 | **技术栈外组件引入** | 用 `AskUserQuestion` 给用户三选一:接受引入 / 换方案 / 拒绝 | ① **接受** → 同会话直接在 `docs/04 § 零` 追加一行 → 继续流程 ② **换方案 / 拒绝** → 视为常规歧义澄清,继续 Q&A 收敛 ③ 不写 Blocker、不中断流程 | -| S2 | **跨模块改动** | **默认不改**,仅为当前模块实现所必需时允许修改 | 在该模块 `milestone` 完成报告的「⑤ 偏离与取舍」节如实记录改了哪个非当前模块的文件 + 原因(lite 无自动留痕 hook,靠报告人工记录) | - ---- - -## 🧭 通用工作准则(General Principles) - -### 1. Think Before Coding - -**Don't assume. Don't hide confusion. Surface tradeoffs.** - -Before implementing: -- State your assumptions explicitly. If uncertain, ask. -- If multiple interpretations exist, present them - don't pick silently. -- If a simpler approach exists, say so. Push back when warranted. -- If something is unclear, stop. Name what's confusing. Ask. - -### 2. Simplicity First - -**Minimum code that solves the problem. Nothing speculative.** - -- No features beyond what was asked. -- No abstractions for single-use code. -- No "flexibility" or "configurability" that wasn't requested. -- No error handling for impossible scenarios. -- If you write 200 lines and it could be 50, rewrite it. - -Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify. - -### 3. Surgical Changes - -**Touch only what you must. Clean up only your own mess.** - -When editing existing code: -- Don't "improve" adjacent code, comments, or formatting. -- Don't refactor things that aren't broken. -- Match existing style, even if you'd do it differently. -- If you notice unrelated dead code, mention it - don't delete it. - -When your changes create orphans: -- Remove imports/variables/functions that YOUR changes made unused. -- Don't remove pre-existing dead code unless asked. - -The test: Every changed line should trace directly to the user's request. - -### 4. Goal-Driven Execution - -**Define success criteria. Loop until verified.** - -Transform tasks into verifiable goals: -- "Add validation" → "Write tests for invalid inputs, then make them pass" -- "Fix the bug" → "Write a test that reproduces it, then make it pass" -- "Refactor X" → "Ensure tests pass before and after" - -For multi-step tasks, state a brief plan: -``` -1. [Step] → verify: [check] -2. [Step] → verify: [check] -3. [Step] → verify: [check] -``` - -Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification. - ---- - -## 🗺️ Skill 索引(erp-workflow-lite,共 11 个) - -### 入口 - -| Skill | 描述 | -|-------|------| -| `plan-start` | 计划阶段入口——扫 docs/08 § 一找第一个未完成计划段(①②③)并派发 | -| `coding-start` | 编码阶段入口 + 阶段分发器——先后端(docs/08 § 二)后前端(§ 三),派发 phase-driver(phase=backend/frontend);都完成则输出全部完成 | - -### 计划阶段 - -| Skill | 描述 | -|-------|------| -| `lite-init` | 计划 ①——项目初始化 + 范围锁定(模板复制、依赖检查、git init、项目概述+技术栈+需求索引、REQ 卡片生成,停下等人工审阅) | -| `lite-design` | 计划 ②——脚手架 + 数据库设计(docs/04 § 一+、scripts、.env.local、docs/03 DB 设计,停下等人工审阅) | -| `lite-build-db` | 计划 ③——DB 初始化 + 下游文档(V1 migration apply、docs/05 API 契约、docs/08 § 二模块清单,计划阶段结束) | - -### 编码阶段 - -| Skill | 描述 | -|-------|------| -| `phase-driver` | 阶段驱动(phase 参数区分)——backend:加载当前模块 REQ 清单逐个派发;frontend:prototype/ 门禁 + 推导 FE 清单写 docs/08 § 三后逐个派发 | -| `feature-spec` | 功能规格(两阶段共用)——为 REQ(后端)/ FE(前端)生成"规格 + 任务级计划"合并文档 | -| `feature-tdd` | TDD 实现(两阶段共用)——按 plan 测试先行再实现,Agent 子会话跑测试;路径护栏按 phase 区分 | -| `feature-review` | 验证 + AI 自审(两阶段共用)——子会话跑测试 + reviewer agent(后端 superpower / 前端 fe-code-reviewer),approve 勾选进度回 phase-driver | -| `milestone` | 里程碑(phase 由分支推断)——内置测试闸门(Agent 子会话),green 则本地 merge + 打 tag,生成完成报告 | - -### 守门 - -| Skill | 描述 | -|-------|------| -| `interrupt-check` | 中断检查——触发中断条件时由功能循环 skill 调用,追加 Blocker 节并停止执行 | - -### 文档套件(5 文档) - -| 文档 | 职责 | -|------|------| -| `docs/01-需求清单/` | REQ 卡片目录(模块子目录 + index.md) | -| `docs/03-数据库设计文档.md` | 表/字段/索引/外键 SSoT(lite-design 生成,编码阶段同步更新) | -| `docs/04-技术规范.md` | 技术栈总览(§ 零)+ 架构规范 + 前端 Design Tokens / 交互约定 + 环境变量说明(含 .env.local 密钥字段)——lite 把原 UI 规范与环境配置并入此文件 | -| `docs/05-API接口契约.md` | 所有后端接口契约(lite-build-db 生成,feature-spec 按需追加) | -| `docs/08-模块任务管理.md` | 全流程进度跟踪(§ 一计划 / § 二后端模块 / § 三前端整体) | diff --git a/skills/plan/lite-init/templates/_module-template.md b/skills/plan/lite-init/templates/_module-template.md deleted file mode 100644 index b7b2b75..0000000 --- a/skills/plan/lite-init/templates/_module-template.md +++ /dev/null @@ -1,5 +0,0 @@ -# {{module_code}}-{{module_name}} - -- **模块简述**: {{module_brief}} -- **依赖模块**: TBD(lite-build-db 自动补) -- **涉及表**: TBD(lite-design 自动补) diff --git a/skills/plan/lite-init/templates/docs-01-index-template.md b/skills/plan/lite-init/templates/docs-01-index-template.md deleted file mode 100644 index 08e326a..0000000 --- a/skills/plan/lite-init/templates/docs-01-index-template.md +++ /dev/null @@ -1,16 +0,0 @@ -# 需求清单 - -> 本目录按模块组织所有功能需求。每个模块一个子目录,含 `_module.md`(模块头)和 `REQ-XXX-NNN.md`(每张 REQ 卡片一个文件)。下方核心功能点供 CC 拆分出 REQ 编号 + 标题 + 草拟规则;卡片内输入 / 输出的简述句和 N 张字段表由人工编辑。 - -## 模块索引 - -| 模块代码 | 模块名称 | 核心功能点(简要) | -|----------|----------|--------------------| -| 【人工填写:模块代码】 | 【人工填写:模块名称】 | 【人工填写:核心功能点】 | -| SYS | 系统管理 | 用户/角色/权限/部门/字典 等 | - -## 填写说明 - -1. 每个模块占一行,`模块代码` 用大写英文缩写(如 SYS / PUR / INV / SAL / FIN / HR) -2. `核心功能点` 只需列关键词,CC 会基于此拆分出 N 张 REQ 卡片骨架(卡片内输入 / 输出的简述句和字段表仍由人工编辑) -3. 填完后运行 `/erp-workflow:plan-start`,CC 会自动检测并进入需求生成阶段 diff --git a/skills/plan/lite-init/templates/docs-04-stack-template.md b/skills/plan/lite-init/templates/docs-04-stack-template.md deleted file mode 100644 index f63e037..0000000 --- a/skills/plan/lite-init/templates/docs-04-stack-template.md +++ /dev/null @@ -1,32 +0,0 @@ -# 04-技术规范 - -## 零、技术栈总览 - -| 分层模块 | 技术 | 版本要求 | 说明 | -|---|---|---|---| -| 前端基础框架 | React | 18.x | 构建前端应用 | -| 前端 UI 组件 | Ant Design | 5.x | 页面组件与交互控件 | -| 前端状态管理 | Redux Toolkit | 最新稳定版 | 管理全局状态 | -| 前端路由管理 | React Router | v6 | 页面路由与导航 | -| 前端工程化构建 | Vite | 最新稳定版 | 前端开发与打包构建 | -| 前端接口通信 | Axios | 最新稳定版 | 调用后端 API | -| 后端基础框架 | Spring Boot | 3.x | 构建后端服务 | -| 后端数据访问 | MyBatis-Plus | 最新稳定版 | 数据库访问与 ORM 增强 | -| 工作流引擎 | Activiti | 6.x | 审批流、流程流转 | -| 缓存服务 | Redis | 最新稳定版 | 缓存、会话、分布式能力 | -| 报表打印 | JXLS | 2.8.1 | 基于 Excel 模板生成报表 | -| Excel 导入导出 | EasyExcel | 4.0.3 | Excel 数据导入导出 | -| 关系型数据库 | MySQL | 8.x | 核心业务数据存储 | -| 数据库 schema 迁移 | Flyway (`flyway-core` + `flyway-mysql`) | 10.x / 最新稳定版 | `sql/migrations/V_n__*.sql` 顺序 apply;Spring Boot 启动时自动应用 | -| 接口风格 | RESTful API | 统一规范 | 前后端接口设计规范 | -| 权限认证 | Spring Security / JWT | 最新稳定版 | 登录认证、权限控制 | -| API 文档 | OpenAPI / Swagger | 最新稳定版 | 接口文档与调试 | -| 项目构建管理 | Maven | 3.9.x | Java 项目依赖与构建 | -| JDK 运行环境 | Java | 17 / 21 | Spring Boot 3 推荐版本 | -| 部署容器 | Docker | 最新稳定版 | 容器化部署 | -| Web 服务器 / 反向代理 | Nginx | 最新稳定版 | 前端托管、反向代理、负载分发 | -| 日志管理 | Logback | 默认集成 / 最新稳定版 | 应用日志输出 | -| 对象映射工具 | MapStruct | 最新稳定版 | DTO / VO / Entity 转换 | -| 工具类库 | Hutool / Apache Commons | 最新稳定版 | 常用工具方法支持 | - -> 本表由 lite-init 锁定。后续所有规范基于此表推导。 diff --git a/skills/plan/lite-init/templates/docs-08-initial-template.md b/skills/plan/lite-init/templates/docs-08-initial-template.md deleted file mode 100644 index af432ad..0000000 --- a/skills/plan/lite-init/templates/docs-08-initial-template.md +++ /dev/null @@ -1,52 +0,0 @@ -# 08-工作流进度 - -> 全流程进度跟踪。CC 每完成一项产出就勾选一项。 -> - **§ 一 计划阶段**:`plan-start` 找第一个未勾的计划段(①②③)分发到对应 skill -> - **§ 二 Coding(后端模块)**:`coding-start` 扫描 docs/08 § 二 的 `里程碑:` 字段 + 本地 `git tag -l 'milestone/<id>'`,找第一个未打里程碑模块,派发 `phase-driver`(phase=backend)。本 § 二 行序即 REQ 开发顺序(lite-build-db 按依赖拓扑写入),是 phase-driver 的排序权威 -> - **§ 三 Coding(前端整体)**:后端全部打里程碑后,`coding-start` 读 § 三 `整体里程碑:` + `git tag -l 'milestone/frontend-phase'`,未完成则派发 `phase-driver`(phase=frontend) - -## 一、计划阶段进度 - -- [ ] 计划 ① 初始化 + 范围锁定 — lite-init - - [ ] 项目文件骨架已创建(CLAUDE.md + docs/01 index + docs/04 + docs/08) - - [ ] 依赖检查通过(git / mysql) - - [ ] Git 已初始化 - - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述) - - [ ] 技术栈已确认(docs/04 § 零) - - [ ] 需求清单索引已填写(docs/01-需求清单/index.md) - - [ ] REQ 卡片骨架已生成(docs/01-需求清单/<module>/REQ-*.md) -- [ ] 计划 ② 脚手架 + 数据库设计 — lite-design - - [ ] 架构文档已生成(docs/04 § 一+ | scripts/*.sh | .env.local | sql/migrations/) - - [ ] docs/03 数据库设计已生成(REQ → 表/字段/索引/外键,回填 REQ 依赖表) -- [ ] 计划 ③ DB 初始化 + 下游文档 — lite-build-db - - [ ] V1 migration 已生成并校验 + apply 到本地 MySQL - - [ ] docs/05 API 契约已生成 + 回填 REQ 依赖接口 - - [ ] docs/08 § 二 模块清单(含 REQ 顺序)已生成 - -## 二、Coding 阶段(模块循环) - -(lite-build-db 填入后,每行一个后端模块。每个模块的 `里程碑:` 字段在 `—` 和 `milestone/<id>` 之间变化,完成由本地 `git tag -l` 判定。`coding-start` 每次扫每模块的里程碑 tag 决定派发。所有模块打里程碑后整体完成。) - -<!-- 模块格式示例(由 lite-build-db 追加;功能子项由 feature-review 在 approve 时勾选): -- module_0 系统管理 - - 依赖: — - - 路径: backend/module/sys/ - - 里程碑: — - - 功能: - - [ ] REQ-SYS-001 用户登录 - - [ ] REQ-SYS-002 用户注册 ---> - -## 三、Coding 阶段(前端整体) - -(`phase-driver`(phase=frontend)进入时扫 prototype/ + docs/01 + docs/05 → AI 自主推导 FE 业务功能清单写到下方"功能:"项(无人工审阅断点;合理性由整体里程碑标记时统一校核)。已有清单则直接加载。整个前端阶段 1 个里程碑 tag,分支 `frontend-phase`。) - -- 整体里程碑: — -- 功能: - <!-- AI 进入时按以下行格式写入(每行 1 个 FE,可关联多个 REQ / 多份原型): - - [ ] FE-NN 功能名 | 关联 REQ:REQ-A, REQ-B | 关联原型:prototype/<file>.html, prototype/<other>.html - - 示例: - - [ ] FE-01 用户登录与注册 | 关联 REQ:REQ-SYS-001, REQ-SYS-002 | 关联原型:prototype/auth.html - - [ ] FE-02 仪表盘总览 | 关联 REQ:REQ-DASH-001 | 关联原型:prototype/dashboard.html - --> diff --git a/skills/plan/lite-init/templates/req-card-template.md b/skills/plan/lite-init/templates/req-card-template.md deleted file mode 100644 index 87ee8a5..0000000 --- a/skills/plan/lite-init/templates/req-card-template.md +++ /dev/null @@ -1,63 +0,0 @@ -<!-- -req-card-template:单张 REQ 卡片骨架。每张卡片是 docs/01-需求清单/<module>/REQ-XXX-NNN.md 一个独立文件。 -渲染约定: -1) lite-init 渲染时**只替换 6 个占位符**:{{req_id}} / {{title}} / {{goal}} / {{rules}} / {{constraints}} / {{acceptance}} - 这 6 项由 CC 根据 docs/01-需求清单/index.md 的「核心功能点」推断起草: - - req_id / title:从核心功能点拆分命名得来 - - goal:用一句话展开 title - - rules / constraints / acceptance:业务语义层面的合理起草,待人工审阅修订 -2) `**输入**` / `**输出**` 二级结构:每段先一句话总结(如「用户提交...」/「返回用户 id」),再跟「表1 / 表2 / ...」N 张平铺的字段表。CC 渲染时对**两段简述 + 所有表(含示例数据)全部原样复制**,不要根据 REQ 业务篡改示例字段、也不要换列结构: - - `输入` 的表:8 列(字段 / 类型 / 必填 / 输入方式 / 显示来源 / 预加载 / 默认值 / 业务规则),其中 `预加载` 取值为 `页面加载时` / `用户操作时` / `—`;模板内含示例数据(表1 6 行、表2 3 行) - - `输出` 的表:3 列(字段 / 类型 / 显示来源),模板内含示例数据(表1 / 表2 各 3 行) - - 表的数量是可变的:人工拿到卡片后按 REQ 实际情况增删表(删多余的 `表N` 整段 / 复制为 `表3 / 表4 / ...`)和编辑字段 -3) `**依赖表**: TBD(lite-design 自动补)` 和 `**依赖接口**: TBD(lite-build-db 自动补)` 是后续 skill 自动回填的占位,渲染时**保持原样**,不要替换为 `-` 也不要替换为 `{{...}}` -4) 渲染后这段 HTML 注释要**剥掉**,不进入最终卡片 ---> -### {{req_id}} {{title}} - -**目标**: {{goal}} - -- **输入**: 用户提交用户名(3-20 位字母数字下划线,系统内唯一)、姓名(2-50字符)、手机号(11 位数字,系统内唯一)、邮箱(标准邮箱格式,可选)、初始密码(8-20位含大小写字母和数字) - - - **表1**: - - | 字段 | 类型 | 必填 | 输入方式 | 显示来源 | 预加载 | 默认值 | 业务规则 | - | ---- | ---- | --- | ---- | ----- | --- | --- | ------------------- | - | 用户名 | 文本 | 是 | 手工输入 | `职员表` | 否 | — | 3-20 位字母数字下划线;系统内唯一 | - | 姓名 | 文本 | 是 | 下拉单选 | `职员表` | 用户操作时 | — | 2-50 个字符 | - | 手机号 | 文本 | 是 | 手工输入 | `职员表` | 否 | — | 11 位数字;系统内唯一 | - | 邮箱 | 文本 | 否 | 手工输入 | `职员表` | 否 | — | 标准邮箱格式 | - | 角色 | 文本 | 是 | 下拉单选 | 普通用户/超级管理员 | 页面加载时 | 普通用户 | 至少选择 1 个 | - | 初始密码 | 文本 | 是 | 手工输入 | — | — | — | 8-20 位;含大小写字母和数字;显示星号 | - - - **表2**: - - | 字段 | 类型 | 必填 | 输入方式 | 显示来源 | 预加载 | 默认值 | 业务规则 | - | --- | --- | --- | --- | --- | --- | --- | --- | - | 用户名 | 文本 | 是 | 手工输入 | `职员表` | 否 | — | 3-20 位字母数字下划线;系统内唯一 | - | 姓名 | 文本 | 是 | 下拉单选 | `职员表` | 用户操作时 | — | 2-50 个字符 | - | 手机号 | 文本 | 是 | 手工输入 | `职员表` | 否 | — | 11 位数字;系统内唯一 | - -- **输出**: 返回用户 id - - - **表1**: - - | 字段 | 类型 | 显示来源 | - | --- | --- | --- | - | 用户名 | 文本 | `职员表` | - | 姓名 | 文本 | `职员表` | - | 角色 | 文本 | `职员表` | - - - **表2**: - - | 字段 | 类型 | 显示来源 | - | --- | --- | --- | - | 用户名 | 文本 | `职员表` | - | 姓名 | 文本 | `职员表` | - | 角色 | 文本 | `职员表` | - -- **跨字段规则**: {{rules}} -- **边界**: {{constraints}} -- **验收**: {{acceptance}} -- **依赖表**: TBD(lite-design 自动补) -- **依赖接口**: TBD(lite-build-db 自动补) -- libgit2 0.22.2