From 73c9775039610086ff4bf95e035cd8b52da983c6 Mon Sep 17 00:00:00 2001 From: zichun Date: Mon, 25 May 2026 14:40:58 +0800 Subject: [PATCH] feat(lite): merge plan phase into lite-design + lite-build-db, move REQ ordering into docs/08 §二 --- skills/plan/db-design-gen/SKILL.md | 102 ------------------------------------------------------------------------------------------------------ skills/plan/db-design-gen/banners/flow.txt | 17 ----------------- skills/plan/db-design-gen/templates/docs-03-header-template.md | 28 ---------------------------- skills/plan/db-design-gen/templates/docs-03-table-template.md | 27 --------------------------- skills/plan/db-init/SKILL.md | 154 ---------------------------------------------------------------------------------------------------------------------------------------------------------- skills/plan/db-init/banners/flow.txt | 17 ----------------- skills/plan/db-init/scripts/validate.sh | 96 ------------------------------------------------------------------------------------------------ skills/plan/downstream-gen/SKILL.md | 139 ------------------------------------------------------------------------------------------------------------------------------------------- skills/plan/downstream-gen/banners/flow.txt | 17 ----------------- skills/plan/downstream-gen/templates/docs-02-template.md | 26 -------------------------- skills/plan/downstream-gen/templates/docs-05-endpoint-template.md | 12 ------------ skills/plan/downstream-gen/templates/docs-05-header-template.md | 30 ------------------------------ skills/plan/downstream-gen/templates/docs-06-module-pagelist-template.md | 9 --------- skills/plan/downstream-gen/templates/docs-08-module-row-template.md | 6 ------ skills/plan/downstream-gen/templates/docs-10-header-template.md | 16 ---------------- 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/skeleton-gen/SKILL.md | 162 ------------------------------------------------------------------------------------------------------------------------------------------------------------------ skills/plan/skeleton-gen/banners/flow.txt | 17 ----------------- skills/plan/skeleton-gen/scripts/merge-gitignore.sh | 39 --------------------------------------- skills/plan/skeleton-gen/templates/docs-04-skeleton-template.md | 69 --------------------------------------------------------------------- skills/plan/skeleton-gen/templates/docs-06-static-template.md | 42 ------------------------------------------ skills/plan/skeleton-gen/templates/docs-07-env-template.md | 26 -------------------------- skills/plan/skeleton-gen/templates/docs-09-structure-template.md | 45 --------------------------------------------- skills/plan/skeleton-gen/templates/env-local-template | 25 ------------------------- skills/plan/skeleton-gen/templates/gitignore-append-template | 32 -------------------------------- skills/plan/skeleton-gen/templates/scripts-setup-test-db-template.sh | 65 ----------------------------------------------------------------- skills/plan/skeleton-gen/templates/scripts-test-template.sh | 40 ---------------------------------------- skills/plan/skeleton-gen/templates/styles-tokens-template.css | 43 ------------------------------------------- 41 files changed, 951 insertions(+), 1301 deletions(-) delete mode 100644 skills/plan/db-design-gen/SKILL.md delete mode 100644 skills/plan/db-design-gen/banners/flow.txt delete mode 100644 skills/plan/db-design-gen/templates/docs-03-header-template.md delete mode 100644 skills/plan/db-design-gen/templates/docs-03-table-template.md delete mode 100644 skills/plan/db-init/SKILL.md delete mode 100644 skills/plan/db-init/banners/flow.txt delete mode 100644 skills/plan/db-init/scripts/validate.sh delete mode 100644 skills/plan/downstream-gen/SKILL.md delete mode 100644 skills/plan/downstream-gen/banners/flow.txt delete mode 100644 skills/plan/downstream-gen/templates/docs-02-template.md delete mode 100644 skills/plan/downstream-gen/templates/docs-05-endpoint-template.md delete mode 100644 skills/plan/downstream-gen/templates/docs-05-header-template.md delete mode 100644 skills/plan/downstream-gen/templates/docs-06-module-pagelist-template.md delete mode 100644 skills/plan/downstream-gen/templates/docs-08-module-row-template.md delete mode 100644 skills/plan/downstream-gen/templates/docs-10-header-template.md create mode 100644 skills/plan/lite-build-db/SKILL.md create mode 100644 skills/plan/lite-build-db/scripts/validate.sh create mode 100644 skills/plan/lite-build-db/templates/docs-05-endpoint-template.md create mode 100644 skills/plan/lite-build-db/templates/docs-05-header-template.md create mode 100644 skills/plan/lite-build-db/templates/docs-08-module-row-template.md create mode 100644 skills/plan/lite-design/SKILL.md create mode 100755 skills/plan/lite-design/scripts/merge-gitignore.sh create mode 100644 skills/plan/lite-design/templates/docs-03-header-template.md create mode 100644 skills/plan/lite-design/templates/docs-03-table-template.md create mode 100644 skills/plan/lite-design/templates/docs-04-skeleton-template.md create mode 100644 skills/plan/lite-design/templates/env-local-template create mode 100644 skills/plan/lite-design/templates/gitignore-append-template create mode 100644 skills/plan/lite-design/templates/scripts-setup-test-db-template.sh create mode 100644 skills/plan/lite-design/templates/scripts-test-template.sh delete mode 100644 skills/plan/skeleton-gen/SKILL.md delete mode 100644 skills/plan/skeleton-gen/banners/flow.txt delete mode 100755 skills/plan/skeleton-gen/scripts/merge-gitignore.sh delete mode 100644 skills/plan/skeleton-gen/templates/docs-04-skeleton-template.md delete mode 100644 skills/plan/skeleton-gen/templates/docs-06-static-template.md delete mode 100644 skills/plan/skeleton-gen/templates/docs-07-env-template.md delete mode 100644 skills/plan/skeleton-gen/templates/docs-09-structure-template.md delete mode 100644 skills/plan/skeleton-gen/templates/env-local-template delete mode 100644 skills/plan/skeleton-gen/templates/gitignore-append-template delete mode 100644 skills/plan/skeleton-gen/templates/scripts-setup-test-db-template.sh delete mode 100644 skills/plan/skeleton-gen/templates/scripts-test-template.sh delete mode 100644 skills/plan/skeleton-gen/templates/styles-tokens-template.css diff --git a/skills/plan/db-design-gen/SKILL.md b/skills/plan/db-design-gen/SKILL.md deleted file mode 100644 index b4a23ee..0000000 --- a/skills/plan/db-design-gen/SKILL.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -name: db-design-gen -description: A3 DB 设计 + REQ 回填——基于 docs/01-需求清单//REQ-*.md 正向设计 docs/03-数据库设计文档.md(业务实体 → 表 + 字段 + 索引 + 外键 + 业务注记),并把回填值写入 REQ 卡片的「依赖表: TBD(A3 自动补)」与模块头的「涉及表: TBD(A3 自动补)」占位。生成完毕停下等人工审阅。 -user-invocable: false -allowed-tools: Read Write Edit Grep Glob Bash(cat *) ---- - -**所有输出必须使用中文。** - -# db-design-gen - -## 前置条件 - -- A1 `scope-lock` 已完成:`docs/01-需求清单//_module.md` + `docs/01-需求清单//REQ-*.md` 已生成,含 `TBD(A3 自动补)` 占位。 -- A2 `skeleton-gen` 已完成:`docs/04-技术规范.md § 一+` 命名规范已生成(本 skill 推导表/字段命名时严格遵循)。 - -## 执行步骤 - -### 步骤 0:打印当前位置流程图 - -用 `Bash` 执行 `cat` 命令向用户展示当前位置流程图(stdout 即 ASCII 框图): - -```bash -cat "${CLAUDE_PLUGIN_ROOT}/skills/plan/db-design-gen/banners/flow.txt" -``` - -### A. 读取设计输入 - -读: - -- `docs/04-技术规范.md` -- `docs/01-需求清单/index.md` 模块索引 -- `docs/01-需求清单/*/REQ-*.md` 所有 REQ 卡片 - -### B. 推导 schema - -基于步骤 A 读到的 REQ + 命名规范,**正向推导**业务实体 → 表 + 字段 + 索引 + 外键。要求: - -1. 严格套用 `docs/04` 的命名规范 -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 细节(如:枚举值范围 / 字段长度上限 / 必填性),先按合理默认推导并在该字段「业务含义」列加 `【人工填写:需用户审阅】` 标注,待步骤 E 用户审阅时调整;**不打断本次推导**。 - -### C. 渲染 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-数据库设计文档.md 已生成` - -### D. 回填模块头 + REQ 卡片的 TBD 字段 - -1. 列出 `docs/01-需求清单/*/_module.md`(模块头)和 `docs/01-需求清单/*/REQ-*.md`(REQ 卡片)。 -2. 在这些文件中搜索 `TBD(A3 自动补)` 的并回填。 不动 `TBD(A5 自动补)` -3. 打印回填统计:`A3 回填 处模块"涉及表" + 处 REQ"依赖表"`。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] docs/01 各 REQ 卡片"依赖表" + 模块头"涉及表" 已回填` - -### E. 勾选 A3 顶层 + 停下等人工审阅 - -1. 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选 A3 顶层(A3 两个子项已在 C / D 步骤分别勾选): - - `- [ ] A3 DB 设计 + REQ 回填 — db-design-gen` - -2. 打印停下横幅并**停下**: - - ``` - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - [db-design-gen] ✅ A3 DB 设计完成 - - 产出: - ✓ docs/03-数据库设计文档.md - ✓ docs/01-需求清单//REQ-*.md 依赖表已回填 + _module.md 涉及表已回填 - - ⏸ 现在请你审阅 docs/03。 - 重点关注: - - 业务实体覆盖是否完整 - - 字段类型 / 长度 / 是否可空 / 默认值是否合理 - - 索引是否覆盖主要查询模式 - - 外键 ON DELETE / ON UPDATE 策略是否符合业务 - - 字段「业务含义」列含 `【人工填写:需用户审阅】` 标注的位置需逐一确认 - - 审阅完成后,再运行: - /erp-workflow:plan-start - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ``` - - **停止**,不调用任何下游 skill。 - -## 参考 - -- `${CLAUDE_SKILL_DIR}/templates/docs-03-header-template.md` -- `${CLAUDE_SKILL_DIR}/templates/docs-03-table-template.md` -- `docs/04-技术规范.md` § 一+(命名规范输入) -- `docs/01-需求清单//_module.md`(模块头:回填 `涉及表`) -- `docs/01-需求清单//REQ-*.md`(REQ 输入 + 回填 `依赖表`) diff --git a/skills/plan/db-design-gen/banners/flow.txt b/skills/plan/db-design-gen/banners/flow.txt deleted file mode 100644 index 1d4c9ac..0000000 --- a/skills/plan/db-design-gen/banners/flow.txt +++ /dev/null @@ -1,17 +0,0 @@ -┌────────────────────────────────────────────────────────┐ -│ 📋 阶段 A:规划(一次性) │ -│ │ -│ A0 初始化项目 │ -│ ↓ │ -│ A1 锁范围(生成 REQ 卡片) → 人工审核 │ -│ ↓ │ -│ A2 生成骨架 │ -│ ↓ │ -│ ▶ A3 生成 DB 设计 → 人工审核 │ -│ ↓ │ -│ A4 初始化 DB │ -│ ↓ │ -│ A5 生成下游文档 │ -│ │ -│ 规划阶段到此结束 │ -└────────────────────────────────────────────────────────┘ diff --git a/skills/plan/db-design-gen/templates/docs-03-header-template.md b/skills/plan/db-design-gen/templates/docs-03-header-template.md deleted file mode 100644 index 6ef65d9..0000000 --- a/skills/plan/db-design-gen/templates/docs-03-header-template.md +++ /dev/null @@ -1,28 +0,0 @@ -# 03-数据库设计文档 - -- **Schema**: `{{schema_name}}` -- **Migration 清单**: `sql/migrations/V*.sql`(由 Flyway 顺序 apply) -- **生成方式**: 由 A3 `db-design-gen` 基于 `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/db-design-gen/templates/docs-03-table-template.md b/skills/plan/db-design-gen/templates/docs-03-table-template.md deleted file mode 100644 index d05c5be..0000000 --- a/skills/plan/db-design-gen/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/db-init/SKILL.md b/skills/plan/db-init/SKILL.md deleted file mode 100644 index b4b9a0b..0000000 --- a/skills/plan/db-init/SKILL.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -name: db-init -description: A4 DB 初始化——LLM 解析 docs/03-数据库设计文档.md → 生成 sql/migrations/V1__initial_schema.sql(DDL only,Flyway 初始 migration)→ 全量校验 DDL ↔ docs/03 一致性 → 验证 MySQL 连接 → 调 scripts/setup-test-db.sh 复用三层防护并 DROP+CREATE 空库 → apply V1。 -user-invocable: false -allowed-tools: Read Write Edit Glob Skill Bash(mkdir *) Bash(mysql *) Bash(set *) Bash(. .env.local) Bash(grep *) Bash(bash *) Bash(./scripts/setup-test-db.sh) Bash(cat *) ---- - -**所有输出必须使用中文。** - -# db-init - -## 执行步骤 - -### 步骤 0:打印当前位置流程图 - -用 `Bash` 执行 `cat` 命令向用户展示当前位置流程图(stdout 即 ASCII 框图): - -```bash -cat "${CLAUDE_PLUGIN_ROOT}/skills/plan/db-init/banners/flow.txt" -``` - -### 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: 由 A4 db-init 从 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` 中勾选: -- ` - [ ] sql/migrations/V1__initial_schema.sql 已生成` -- ` - [ ] DDL 与 docs/03 全量一致` - -### B. 数据库环境检查 - -#### B.1 检查 .env.local 凭据 - -用 `Glob` 检查 `.env.local` 是否存在;不存在 → 提示用户重新运行 A2 `skeleton-gen` 重建并停下。 - -用 `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`,**停下**。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] .env.local 凭据已验证(mysql -e "SELECT 1" OK)` - -### 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` 中勾选: -- ` - [ ] setup-test-db.sh 防护通过 + DROP+CREATE + apply V1 已执行` - -#### 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/08 进度 + 进入 A5 - - -1. 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选(A4 子项 + A4 顶层): - - ` - [ ] SHOW TABLES 行数 == docs/03 表数量` - - `- [ ] A4 DB 初始化 — db-init` - -2. 立即调用 `Skill(downstream-gen)` 进入 A5,不等用户手动输入。 - -## 参考 - -- `${CLAUDE_SKILL_DIR}/scripts/validate.sh`(A.3 表名 + 每表列名集合校验脚本) -- `docs/03-数据库设计文档.md`(DDL 翻译输入,SSoT) -- `.env.local`(DB 凭据) -- 产物:`sql/migrations/V1__initial_schema.sql`(由 Flyway 在 Spring Boot 启动时验证 / apply) diff --git a/skills/plan/db-init/banners/flow.txt b/skills/plan/db-init/banners/flow.txt deleted file mode 100644 index b8cba75..0000000 --- a/skills/plan/db-init/banners/flow.txt +++ /dev/null @@ -1,17 +0,0 @@ -┌────────────────────────────────────────────────────────┐ -│ 📋 阶段 A:规划(一次性) │ -│ │ -│ A0 初始化项目 │ -│ ↓ │ -│ A1 锁范围(生成 REQ 卡片) → 人工审核 │ -│ ↓ │ -│ A2 生成骨架 │ -│ ↓ │ -│ A3 生成 DB 设计 → 人工审核 │ -│ ↓ │ -│ ▶ A4 初始化 DB │ -│ ↓ │ -│ A5 生成下游文档 │ -│ │ -│ 规划阶段到此结束 │ -└────────────────────────────────────────────────────────┘ diff --git a/skills/plan/db-init/scripts/validate.sh b/skills/plan/db-init/scripts/validate.sh deleted file mode 100644 index bed28ad..0000000 --- a/skills/plan/db-init/scripts/validate.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/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/downstream-gen/SKILL.md b/skills/plan/downstream-gen/SKILL.md deleted file mode 100644 index ffbf6f5..0000000 --- a/skills/plan/downstream-gen/SKILL.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -name: downstream-gen -description: A5 下游文档生成——基于 docs/01 和 docs/03 推导,一次性生成 docs/02 + docs/05 + docs/06 § 三 + docs/10,回填 REQ 卡片依赖接口,把模块清单追加到 docs/08 § 二。 -user-invocable: false -allowed-tools: Read Write Edit Glob Grep Skill AskUserQuestion Bash(cat *) Bash(cp *) ---- - -**所有输出必须使用中文。** - -# downstream-gen - -## 执行步骤 - -### 步骤 0:打印当前位置流程图 - -用 `Bash` 执行 `cat` 命令向用户展示当前位置流程图(stdout 即 ASCII 框图): - -```bash -cat "${CLAUDE_PLUGIN_ROOT}/skills/plan/downstream-gen/banners/flow.txt" -``` - -### A. docs/02 — 开发计划(含 REQ 级开发顺序清单) - -**清单颗粒度**:一行一个 REQ,同一模块的 REQ 必须**连续排列**。 - -1. 构建**模块依赖 DAG**。 -3. 对**每个模块内部**构建 REQ 间依赖,得到模块内 REQ 顺序。 -4. 合成 `req_order[]`:按 `module_topo_order[]` 依次铺开每个模块内的 REQ 序列(**同模块 REQ 连续**)。 -5. **环依赖打破**: - - **模块级**:若模块 DAG 存在环(module_A ↔ module_B),按启发式(字母序 / 被依赖次数多者先)破环排出 `module_topo_order`,并在**参与环的模块里第一个 REQ** 的 `note` 字段填入原因(如 "A↔B 互依赖:先做 A 的骨架")。 - - **REQ 级(同模块内)**:若模块内 REQ 互依赖,同样破环,`note` 填原因。 - - 非环 REQ `note` 留 `—`。 -6. 为 `req_order[]` 每项生成字段: - - `index`:行号(从 1 开始) - - `req_id`:如 `REQ-SYS-001` - - `module_id`:该 REQ 所属模块,如 `module_sys` - - `rationale`(**选中理由**):依赖驱动的简短描述,如 `所属模块无依赖,基础模块` / `依赖 REQ-SYS-001 已在前` / `所属模块依赖 module_sys 已在前` - - `note`(**备注**):默认 `—`;仅环依赖打破场景填原因 -7. 读取并填充 `${CLAUDE_SKILL_DIR}/templates/docs-02-template.md`。 -8. 写入 `docs/02-开发计划.md`。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] docs/02 开发计划已生成` - -### B. docs/05 — API 接口契约 - -1. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-05-header-template.md`,写入 `docs/05-API接口契约.md` 头部。 -2. 对所有模块的每个 REQ:读取并推断 `${CLAUDE_SKILL_DIR}/templates/docs-05-endpoint-template.md`,追加到 docs/05。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] docs/05 API 契约已生成` - -### B2. 回填模块头 + REQ 卡片的 TBD(A5) 字段 - -1. 在`docs/01-需求清单/*/_module.md`(模块头)和 `docs/01-需求清单/*/REQ-*.md`(REQ 卡片)中搜索并回填 `TBD(A5 自动补)` -2. 打印回填统计:`A5 回填 处模块"依赖模块" + 处 REQ"依赖接口"`。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] REQ 卡片依赖接口已回填` - -### C. docs/06 — 页面清单 - -对每个有前端页面的模块:读取并填充 `${CLAUDE_SKILL_DIR}/templates/docs-06-module-pagelist-template.md`,追加到 `docs/06-UI交互规范.md` § 三。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] docs/06 § 三 页面清单已填入` - -### D. docs/08 — 追加模块清单 - -读 `${CLAUDE_SKILL_DIR}/templates/docs-08-module-row-template.md`,按 `module_id` 字母序为每个模块渲染 bullet(模块元数据 + REQ 子项清单,REQ 序保持步骤 A 模块内顺序),追加到 docs/08。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] 下方模块列表已填入` - -### E. docs/10 — 验收清单(项目级 SOP) - -```bash -cp "${CLAUDE_SKILL_DIR}/templates/docs-10-header-template.md" docs/10-验收检查清单.md -``` - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] docs/10 验收清单已生成` - -### F. 验证 + 勾选 docs/08 进度 + 结束 Plan - -1. 一致性检查 + 自主修复循环(最多 3 轮,docs/01 是 REQ SSoT 不动): - - **检查项**: - - 每个 docs/01 REQ 都出现在 docs/05(作为接口,如适用) - - `docs/02 § 二` 的 `module_id` 集合 = `docs/08 § 二` 的 `module_id` 集合 - - **不一致 → 按差异类型自主修复**: - - **REQ 缺 docs/05 endpoint** → 按步骤 B 规则为该 REQ 推测,并追加到 docs/05 - - **module_id 缺 docs/08 § 二** → 按步骤 D 规则渲染该模块 bullet(含 REQ 子项),按 `module_id` 字母序插入正确位置 - - **module_id 缺 docs/02 § 二** → 重算该模块的 `req_order` 段(步骤 A 子流程),按拓扑序插入 docs/02 § 二 - - 修复后重跑检查;通过 → 进入 2;3 轮仍失败 → 停下,打印最终残留差异 + 已尝试的 3 轮修复摘要让用户介入。 - -2. **最终占位符扫描**(覆盖 Plan 阶段全部产出): - - a. **`TBD` → 自动补齐**:Grep 搜索 `TBD(A3 自动补)` 和 `TBD(A5 自动补)`。有命中则就地补填(A3 残留 → 查 docs/03 填 `依赖表`;A5 残留 → 查 docs/05 按 REQ-ID 填 `依赖接口`),再 Grep 确认 0 命中;仍残留报错停下。 - - b. **`【人工填写:...】` → QA 循环等用户补**: - - 循环执行直到搜索不到 `【人工填写:` 且用户选「继续」: - - 0 命中 → 直接放行进入步骤 3 - - 有命中 → 打印残留清单(`<文件:行号> — <内容摘要>`),用 `AskUserQuestion` 弹「继续」/「有疑问想先沟通」二选一;用户回答后重扫验证再决定放行 / 继续循环 - - **每次弹 QA 前都重扫一次**——保证用户看到的 N 是最新的,避免「用户以为填完但实际还有残留」直接放行。 - -3. 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 勾选 A5 父项: - - `- [ ] A5 下游文档生成 — downstream-gen` - -4. 打印 Plan 阶段终止横幅并**停下**(不自动进入 B 阶段): - - ``` - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - [downstream-gen] ✅ Plan 阶段(A0~A5)全部完成 - - 所有规划文档已就绪,docs/08 § 一 全部勾选。 - - ⚠️ 进入 B 阶段前必须完成: - 1. 审核 docs/01~10 + 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 进入 B 阶段 - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ``` - -## 参考 - -- `${CLAUDE_SKILL_DIR}/templates/docs-02-template.md` -- `${CLAUDE_SKILL_DIR}/templates/docs-05-header-template.md` -- `${CLAUDE_SKILL_DIR}/templates/docs-05-endpoint-template.md` -- `${CLAUDE_SKILL_DIR}/templates/docs-06-module-pagelist-template.md`(追加到 docs/06 § 三) -- `${CLAUDE_SKILL_DIR}/templates/docs-08-module-row-template.md`(模块 bullet 行模板) -- `${CLAUDE_SKILL_DIR}/templates/docs-10-header-template.md` diff --git a/skills/plan/downstream-gen/banners/flow.txt b/skills/plan/downstream-gen/banners/flow.txt deleted file mode 100644 index f53fce1..0000000 --- a/skills/plan/downstream-gen/banners/flow.txt +++ /dev/null @@ -1,17 +0,0 @@ -┌────────────────────────────────────────────────────────┐ -│ 📋 阶段 A:规划(一次性) │ -│ │ -│ A0 初始化项目 │ -│ ↓ │ -│ A1 锁范围(生成 REQ 卡片) → 人工审核 │ -│ ↓ │ -│ A2 生成骨架 │ -│ ↓ │ -│ A3 生成 DB 设计 → 人工审核 │ -│ ↓ │ -│ A4 初始化 DB │ -│ ↓ │ -│ ▶ A5 生成下游文档 │ -│ │ -│ 规划阶段到此结束 │ -└────────────────────────────────────────────────────────┘ diff --git a/skills/plan/downstream-gen/templates/docs-02-template.md b/skills/plan/downstream-gen/templates/docs-02-template.md deleted file mode 100644 index 9eed94e..0000000 --- a/skills/plan/downstream-gen/templates/docs-02-template.md +++ /dev/null @@ -1,26 +0,0 @@ -# 02-开发计划 - -## 一、模块依赖表 - -| 模块 ID | 模块名 | 依赖模块 | 依赖表 | -|---|---|---|---| -{{#each modules}} -| {{id}} | {{name}} | {{deps}} | {{tables}} | -{{/each}} - -## 二、开发顺序清单(CC 分发权威) - -> 本清单由 A5 `downstream-gen` 一次性生成。**每行是一个 REQ**,不是模块。CC 按表格行序从上到下扫描,对每个 REQ 所属模块查 `docs/08 § 二` 的 `里程碑:` 字段 + 本地 `git tag -l 'milestone/'`:tag 存在则跳过,否则(`—` / tag 不存在)选为当前模块;`module-start` 会把该模块的所有 REQ 一次做完。 -> -> **约束**:同一模块的所有 REQ 必须**连续排列**。允许打破依赖拓扑(如环依赖、业务必须先做),但必须在「备注」列写明原因。 - -| # | REQ | 所属模块 | 选中理由 | 备注 | -|---|-----|---------|---------|------| -{{#each req_order}} -| {{index}} | **{{req_id}}** | {{module_id}} | {{rationale}} | {{note}} | -{{/each}} - -> **后端模块全部打里程碑后**:milestone-tag 自动回调 `coding-start` → coding-start 检测到 `backend_done=true && frontend_done=false` → 派发 `frontend-start`。`frontend-start` 步骤 1 自带 prototype/ 门禁(≥ 1 个 `*.html` mockup,缺失则 AskUserQuestion 提示用户补齐)。前端阶段以业务功能(不是 HTML 文件数)为粒度拆分 FE,每个 FE 跑一次 feature 循环(fe-feature-*),最后整个阶段打 1 个里程碑 tag(分支 `frontend-phase`,记录在 `docs/08 § 三 整体里程碑`)。 - -## 三、关键说明 -{{notes}} diff --git a/skills/plan/downstream-gen/templates/docs-05-endpoint-template.md b/skills/plan/downstream-gen/templates/docs-05-endpoint-template.md deleted file mode 100644 index 91a1fda..0000000 --- a/skills/plan/downstream-gen/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/downstream-gen/templates/docs-05-header-template.md b/skills/plan/downstream-gen/templates/docs-05-header-template.md deleted file mode 100644 index e89cc3d..0000000 --- a/skills/plan/downstream-gen/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}} - -## 接口清单 -(各模块接口段落见下方,由 `downstream-gen` 按 REQ 填入) diff --git a/skills/plan/downstream-gen/templates/docs-06-module-pagelist-template.md b/skills/plan/downstream-gen/templates/docs-06-module-pagelist-template.md deleted file mode 100644 index 36f18a5..0000000 --- a/skills/plan/downstream-gen/templates/docs-06-module-pagelist-template.md +++ /dev/null @@ -1,9 +0,0 @@ -### {{module_id}} {{module_name}} - -{{#each pages}} -- **{{page_name}}** (`{{route}}`) - - 类型: {{page_type}} (列表页 / 表单页 / 详情页 / 树形管理页) - - 对应 REQ: {{req_ids}} - - 入口菜单: {{menu_path}} - - 主要交互: {{interactions}} -{{/each}} diff --git a/skills/plan/downstream-gen/templates/docs-08-module-row-template.md b/skills/plan/downstream-gen/templates/docs-08-module-row-template.md deleted file mode 100644 index edd15f1..0000000 --- a/skills/plan/downstream-gen/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/downstream-gen/templates/docs-10-header-template.md b/skills/plan/downstream-gen/templates/docs-10-header-template.md deleted file mode 100644 index 3a9c860..0000000 --- a/skills/plan/downstream-gen/templates/docs-10-header-template.md +++ /dev/null @@ -1,16 +0,0 @@ -# 10-验收检查清单 - -通用验收项(全项目适用): - -- [ ] `scripts/test.sh` 本地全绿 -- [ ] 所有 schema 改动都有对应 `sql/migrations/V_n__.sql` -- [ ] 所有新接口在 `docs/05` 中有契约定义 -- [ ] 所有新功能代码注释含 REQ-XXX-NNN -- [ ] 统一响应格式 `{code, message, data, timestamp}` -- [ ] 异常走全局处理器,不暴露堆栈到前端 -- [ ] 前端不存敏感信息到 localStorage - -> 本文档仅维护项目级验收 SOP。粒度更细的验收信息分散在: -> - **每 REQ 的业务验收点**:`docs/01-需求清单//.md § 验收` -> - **每模块的实测验收(数据 / UI / 自动化用例位置)**:由 B 阶段 `module-report` 在该模块完成时填入模块完成报告 -> - **REQ 开发进度(feature-review approve 状态)**:`docs/08 § 二` diff --git a/skills/plan/lite-build-db/SKILL.md b/skills/plan/lite-build-db/SKILL.md new file mode 100644 index 0000000..7a51dc1 --- /dev/null +++ b/skills/plan/lite-build-db/SKILL.md @@ -0,0 +1,255 @@ +--- +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 `;列尾用 `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: 由计划 ③ 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__.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 回填 处模块"依赖模块" + 处 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(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.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/lite-build-db/scripts/validate.sh b/skills/plan/lite-build-db/scripts/validate.sh new file mode 100644 index 0000000..bed28ad --- /dev/null +++ b/skills/plan/lite-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/lite-build-db/templates/docs-05-endpoint-template.md b/skills/plan/lite-build-db/templates/docs-05-endpoint-template.md new file mode 100644 index 0000000..91a1fda --- /dev/null +++ b/skills/plan/lite-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/lite-build-db/templates/docs-05-header-template.md b/skills/plan/lite-build-db/templates/docs-05-header-template.md new file mode 100644 index 0000000..e89cc3d --- /dev/null +++ b/skills/plan/lite-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}} + +## 接口清单 +(各模块接口段落见下方,由 `downstream-gen` 按 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 new file mode 100644 index 0000000..edd15f1 --- /dev/null +++ b/skills/plan/lite-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/lite-design/SKILL.md b/skills/plan/lite-design/SKILL.md new file mode 100644 index 0000000..7c09dd2 --- /dev/null +++ b/skills/plan/lite-design/SKILL.md @@ -0,0 +1,174 @@ +--- +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 § 零)为 4 个命令槽推断命令后写到 `scripts/test.sh`(lite 版精简为 4 槽): + +- `{{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 回填 处模块"涉及表" + 处 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.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/lite-design/scripts/merge-gitignore.sh b/skills/plan/lite-design/scripts/merge-gitignore.sh new file mode 100755 index 0000000..cfff18c --- /dev/null +++ b/skills/plan/lite-design/scripts/merge-gitignore.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# merge-gitignore.sh +# 把模板里的忽略规则合并到项目根的 .gitignore: +# - 若 .gitignore 不存在 → 直接 cp 模板(含注释头和结构) +# - 若已存在 → 逐行判重,只追加模板里缺失的规则行(跳过注释/空行) +# +# 用法:merge-gitignore.sh [] +# template_path 模板文件绝对路径(由 skeleton-gen 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/lite-design/templates/docs-03-header-template.md b/skills/plan/lite-design/templates/docs-03-header-template.md new file mode 100644 index 0000000..6ef65d9 --- /dev/null +++ b/skills/plan/lite-design/templates/docs-03-header-template.md @@ -0,0 +1,28 @@ +# 03-数据库设计文档 + +- **Schema**: `{{schema_name}}` +- **Migration 清单**: `sql/migrations/V*.sql`(由 Flyway 顺序 apply) +- **生成方式**: 由 A3 `db-design-gen` 基于 `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/lite-design/templates/docs-03-table-template.md b/skills/plan/lite-design/templates/docs-03-table-template.md new file mode 100644 index 0000000..d05c5be --- /dev/null +++ b/skills/plan/lite-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/lite-design/templates/docs-04-skeleton-template.md b/skills/plan/lite-design/templates/docs-04-skeleton-template.md new file mode 100644 index 0000000..17cfda0 --- /dev/null +++ b/skills/plan/lite-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/lite-design/templates/env-local-template b/skills/plan/lite-design/templates/env-local-template new file mode 100644 index 0000000..c16e67f --- /dev/null +++ b/skills/plan/lite-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/lite-design/templates/gitignore-append-template b/skills/plan/lite-design/templates/gitignore-append-template new file mode 100644 index 0000000..ac39aa6 --- /dev/null +++ b/skills/plan/lite-design/templates/gitignore-append-template @@ -0,0 +1,32 @@ +# ==== ERP 插件推荐忽略项(skeleton-gen 追加) ==== +# 本地运行时配置(含真实凭据,严禁入库) +.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 new file mode 100644 index 0000000..41a3970 --- /dev/null +++ b/skills/plan/lite-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/lite-design/templates/scripts-test-template.sh b/skills/plan/lite-design/templates/scripts-test-template.sh new file mode 100644 index 0000000..861a224 --- /dev/null +++ b/skills/plan/lite-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 +# 由 test-gate 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/skeleton-gen/SKILL.md b/skills/plan/skeleton-gen/SKILL.md deleted file mode 100644 index 4930347..0000000 --- a/skills/plan/skeleton-gen/SKILL.md +++ /dev/null @@ -1,162 +0,0 @@ ---- -name: skeleton-gen -description: A2 骨架生成——基于 docs/04 § 零 技术栈 + docs/01-需求清单/index.md 模块索引,生成项目专属的架构文档(docs/04 § 一+、docs/06、docs/07、docs/09)和工具脚本。固定工具文件走 cp,架构文档由 LLM 按大纲生成。 -user-invocable: false -allowed-tools: Read Write Edit Skill Grep Glob AskUserQuestion Bash(mkdir *) Bash(cp *) Bash(touch *) Bash(chmod *) Bash(cat *) Bash(bash *) ---- - -**所有输出必须使用中文。** - -# skeleton-gen - -## 执行步骤 - -### 步骤 0:打印当前位置流程图 - -用 `Bash` 执行 `cat` 命令向用户展示当前位置流程图(stdout 即 ASCII 框图): - -```bash -cat "${CLAUDE_PLUGIN_ROOT}/skills/plan/skeleton-gen/banners/flow.txt" -``` - -### A. 读取锁定的输入 - -用 `Read` 读取: -- `docs/04-技术规范.md` § 零 技术栈表 -- `docs/01-需求清单/index.md` 需求索引 -- `docs/01-需求清单/` 需求卡片 - -后续所有内容都基于它们推导。 - -### B.1 生成 3 个全新架构文档(docs/06 / 07 / 09) - -对下表每个目标文件: -1. 读取对应的大纲模板 -2. 基于步骤 A 的输入,按大纲生成项目专属内容 -3. 剥掉 HTML 注释(注释是给 LLM 的提示,不应出现在最终文档里) -4. 写入目标路径 - -| 目标文件 | 大纲模板 | -|---|---| -| `docs/06-UI交互规范.md`(§ 一 ~ 四,§ 五 占位) | `${CLAUDE_SKILL_DIR}/templates/docs-06-static-template.md` | -| `docs/07-环境配置.md` | `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md` | -| `docs/09-项目目录结构.md` | `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md` | - -项目专属标识(根包名 / 命名空间)保留 `【人工填写:<说明>】` 占位,等人工在 docs/09 顶部补填一次后,其他文件复用。 - -### B.2 追加 docs/04 § 一+(保留 § 零 不覆盖) - -docs/04 已由 scope-lock 写入 § 零。本步骤追加 § 一 ~ 三。 - -1. 读取 `docs/04-技术规范.md`(现有 § 零 完整内容)。 -2. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`。 -3. 基于技术栈,按大纲生成 § 一 ~ 三 的项目专属内容,剥掉 HTML 注释。 -4. 拼接原有内容和新生成内容,写回 `docs/04-技术规范.md`。 - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] 架构文档已生成(docs/04 § 一+、docs/06、docs/07、docs/09)` - -### C. 生成工具脚本 - -#### C.1 复制 - -```bash -mkdir -p scripts sql/migrations src/styles -touch sql/migrations/.gitkeep -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 -cp "${CLAUDE_SKILL_DIR}/templates/styles-tokens-template.css" src/styles/tokens.css -``` - -#### C.2 渲染 scripts/test.sh - -读取 `${CLAUDE_SKILL_DIR}/templates/scripts-test-template.sh`,基于步骤 A 的技术栈(docs/04 § 零)为 7 个占位推断命令后写到 `scripts/test.sh`: - -- `{{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 → 三槽全填 `:`(运行期 `[ -d X ]` 守卫对接;语法合法即可) -> - `{{e2e_cmd}}` 通常仅前端,按上述前端规则或填 `echo "[test.sh] e2e 略"` -> -> 表结构异常(列名变更 / 无中文前缀)时停下,用 `AskUserQuestion` 让用户显式确认每 stack 命令。 - -#### C.3 赋权 - -```bash -chmod +x scripts/*.sh -``` - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] 工具脚本已生成(scripts/*.sh、.env.local)` -- ` - [ ] 样式 token 骨架已生成(src/styles/tokens.css)` - -### D. 追加 .gitignore 忽略项 - -调用脚本完成合并: - -```bash -bash "${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh" "${CLAUDE_SKILL_DIR}/templates/gitignore-append-template" -``` - -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- ` - [ ] .gitignore 已配置` - -### E. 占位符补填 + QA 闸门 - -#### E.1 扫描 + 分组 - -用 `Grep` 在以下 8 个路径扫 `【人工填写:`,记录命中(文件 / 行号 / 说明): -- `docs/04-技术规范.md` / `docs/06-UI交互规范.md` / `docs/07-环境配置.md` / `docs/09-项目目录结构.md` -- `scripts/*.sh` / `.gitignore` -- `.env.local` - -分两组: -- **敏感组**:`.env.local` 路径命中(凭据 / 密钥)。**不弹 QA**(凭据不进会话),E.3 提示用户自填。 -- **非敏感组**:其余文件。按说明文字聚合为「根占位」(相同说明 = 同一值,多处共用)或「派生占位」(说明表达派生关系,如"后端 java 根包路径"派生自"根包名")。 - -无命中 → 跳 E.4。 - -#### E.2 问根占位 + 推派生 + 批量 Edit - -- 每个根占位用 `AskUserQuestion` 问(给合理默认值 + 自由输入),用 `Edit` 批量替换所有命中位置 -- 派生占位**不问**,CC 基于根占位值推断后 `Edit`;不能可靠推断则回退当独立根占位问 - -#### E.3 敏感占位提示(不弹 QA) - -若敏感组非空:打印提示横幅,列出 `.env.local` 待填字段名 + 告诉用户"直接编辑文件,凭据不进会话"。 - -#### E.4 验证 + QA 闸门 - -循环直到两条件**同时**满足: -(a) `Grep` 重新扫 8 路径,0 命中 -(b) 用户 `AskUserQuestion` 选「继续」 - -每次弹 QA 前重扫;有残留则打印残留位置清单(文件:行号 — 说明)+ 再弹 QA。 - -QA 横幅涵盖:产出文件清单(docs/04 / 06 / 07 / 09 + scripts/*.sh + .env.local + .gitignore)、占位状态(N=0 或待填清单)、「继续」/「有疑问先沟通」两选项。 - -通过后(N=0 且用户选「继续」),用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: -- `- [ ] A2 骨架生成 — skeleton-gen` - -### F. 进入 A3 - -输出 `skeleton-gen: 完成`,立即调用 `Skill(db-design-gen)`。 - -## 参考 - -- `docs/04-技术规范.md` § 零(技术栈输入) -- `docs/01-需求清单/index.md`(模块索引输入) -- `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`(大纲) -- `${CLAUDE_SKILL_DIR}/templates/docs-06-static-template.md`(大纲) -- `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md`(大纲) -- `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md`(大纲) -- `${CLAUDE_SKILL_DIR}/templates/scripts-test-template.sh`(推断命令填充 7 槽:backend/frontend × build/lint/test + e2e;缺席 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}/templates/styles-tokens-template.css`(0 槽位,样式 token 骨架) -- `${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh`(.gitignore 逐行判重合并脚本) diff --git a/skills/plan/skeleton-gen/banners/flow.txt b/skills/plan/skeleton-gen/banners/flow.txt deleted file mode 100644 index 798f4a9..0000000 --- a/skills/plan/skeleton-gen/banners/flow.txt +++ /dev/null @@ -1,17 +0,0 @@ -┌────────────────────────────────────────────────────────┐ -│ 📋 阶段 A:规划(一次性) │ -│ │ -│ A0 初始化项目 │ -│ ↓ │ -│ A1 锁范围(生成 REQ 卡片) → 人工审核 │ -│ ↓ │ -│ ▶ A2 生成骨架 │ -│ ↓ │ -│ A3 生成 DB 设计 → 人工审核 │ -│ ↓ │ -│ A4 初始化 DB │ -│ ↓ │ -│ A5 生成下游文档 │ -│ │ -│ 规划阶段到此结束 │ -└────────────────────────────────────────────────────────┘ diff --git a/skills/plan/skeleton-gen/scripts/merge-gitignore.sh b/skills/plan/skeleton-gen/scripts/merge-gitignore.sh deleted file mode 100755 index cfff18c..0000000 --- a/skills/plan/skeleton-gen/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 模板文件绝对路径(由 skeleton-gen 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/skeleton-gen/templates/docs-04-skeleton-template.md b/skills/plan/skeleton-gen/templates/docs-04-skeleton-template.md deleted file mode 100644 index 7f2c116..0000000 --- a/skills/plan/skeleton-gen/templates/docs-04-skeleton-template.md +++ /dev/null @@ -1,69 +0,0 @@ - - -## 一、后端规范 - -### 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 配置与安全 - diff --git a/skills/plan/skeleton-gen/templates/docs-06-static-template.md b/skills/plan/skeleton-gen/templates/docs-06-static-template.md deleted file mode 100644 index 467bf32..0000000 --- a/skills/plan/skeleton-gen/templates/docs-06-static-template.md +++ /dev/null @@ -1,42 +0,0 @@ - - -# 06-UI交互规范 - -> 本项目所有页面布局以项目根 `prototype/` 目录下的静态 HTML mockup 为权威。前端阶段(fe-feature-*)实现时直接以 prototype/ HTML 推导组件树与样式。本文件仅承载跨页面通用规则与 Design Tokens。 - -## 一、通用交互规则 - -### 1.1 操作反馈 - - -### 1.2 数据展示 - - -### 1.3 权限控制(前端) - - -## 二、Design Tokens - - - -### 2.1 全局调色板 - - -### 2.2 组件级状态色 - - -### 2.3 引用约定 - - -## 三、页面清单 -(由 `downstream-gen` 按模块追加段落) diff --git a/skills/plan/skeleton-gen/templates/docs-07-env-template.md b/skills/plan/skeleton-gen/templates/docs-07-env-template.md deleted file mode 100644 index 3a3306f..0000000 --- a/skills/plan/skeleton-gen/templates/docs-07-env-template.md +++ /dev/null @@ -1,26 +0,0 @@ - - -# 07-环境配置 - -## 一、依赖清单 - - - -## 二、端口约定 - - - -## 三、环境变量 - -运行时凭据(数据库连接、JWT 密钥等)全部放在仓库根的 `.env.local`,不入 git。 -字段清单与占位符见该文件,真实值由开发者本地填写。 - -## 四、常用命令 - - diff --git a/skills/plan/skeleton-gen/templates/docs-09-structure-template.md b/skills/plan/skeleton-gen/templates/docs-09-structure-template.md deleted file mode 100644 index d913c08..0000000 --- a/skills/plan/skeleton-gen/templates/docs-09-structure-template.md +++ /dev/null @@ -1,45 +0,0 @@ - - -# 09-项目目录结构 - -## 一、仓库顶层 - - - -## 二、后端目录 - - - -## 三、前端目录 - - - -## 四、docs/ 结构 - -``` -docs/ -├── 01-需求清单/ # 每模块一子目录(_module.md 模块头 + REQ-*.md 卡片) -├── 02-开发计划.md -├── 03-数据库设计文档.md -├── 04-技术规范.md -├── 05-API接口契约.md -├── 06-UI交互规范.md -├── 07-环境配置.md -├── 08-模块任务管理.md -├── 09-项目目录结构.md -├── 10-验收检查清单.md -└── superpowers/ # CC 运行时产物 -``` - -## 五、命名与放置约定 - - diff --git a/skills/plan/skeleton-gen/templates/env-local-template b/skills/plan/skeleton-gen/templates/env-local-template deleted file mode 100644 index c16e67f..0000000 --- a/skills/plan/skeleton-gen/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/skeleton-gen/templates/gitignore-append-template b/skills/plan/skeleton-gen/templates/gitignore-append-template deleted file mode 100644 index ac39aa6..0000000 --- a/skills/plan/skeleton-gen/templates/gitignore-append-template +++ /dev/null @@ -1,32 +0,0 @@ -# ==== ERP 插件推荐忽略项(skeleton-gen 追加) ==== -# 本地运行时配置(含真实凭据,严禁入库) -.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/skeleton-gen/templates/scripts-setup-test-db-template.sh b/skills/plan/skeleton-gen/templates/scripts-setup-test-db-template.sh deleted file mode 100644 index 41a3970..0000000 --- a/skills/plan/skeleton-gen/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=\" \"" >&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/skeleton-gen/templates/scripts-test-template.sh b/skills/plan/skeleton-gen/templates/scripts-test-template.sh deleted file mode 100644 index 861a224..0000000 --- a/skills/plan/skeleton-gen/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 -# 由 test-gate 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/skeleton-gen/templates/styles-tokens-template.css b/skills/plan/skeleton-gen/templates/styles-tokens-template.css deleted file mode 100644 index bc8a542..0000000 --- a/skills/plan/skeleton-gen/templates/styles-tokens-template.css +++ /dev/null @@ -1,43 +0,0 @@ -/* - * src/styles/tokens.css — Design Tokens - * 命名规范见 docs/04-技术规范.md § 2.5 - * 色值锁定见 docs/06-UI交互规范.md § 四 - * - * 命名格式:--color--- - * 组件域:form / table-row / table-header / ... - * 作用:bg(背景)/ fg(前景/字体)/ border - * 状态:edit / readonly / hover / selected(无状态时省略) - * - * 约束: - * - 组件样式中只用 var(--color-xxx),禁止硬编码 hex / rgba - * - 修改色值只改本文件,不允许在组件级覆盖 - * - 新增 token 须先登记到 docs/06 § 4.1 / 4.2,再补到此处 - */ - -:root { - /* === 1. 全局调色板(与 Ant Design 主题对齐) === */ - --color-primary: #1890ff; - --color-success: #52c41a; - --color-warning: #faad14; - --color-error: #ff4d4f; - --color-text: rgba(0, 0, 0, 0.85); - --color-text-secondary: rgba(0, 0, 0, 0.45); - --color-border: #d9d9d9; - --color-bg-base: #f0f2f5; - - /* === 2. 组件级状态色(与 docs/06 § 4.2 一一对应) === */ - - /* form:输入框 / 备注框 / 时间框 / 下拉框共用 */ - --color-form-bg-edit: #ffffff; - --color-form-bg-readonly: #f1f2f8; - --color-form-bg-hover: #f5f5f5; /* 仅下拉框使用 */ - --color-form-fg: #000000; - - /* table */ - --color-table-row-bg-selected: #86d5fb; - --color-table-row-bg-hover: #fff7e6; - --color-table-row-bg-readonly: #f1f2f8; /* = rgb(241, 242, 248) */ - --color-table-row-fg: #000000; - --color-table-header-bg: #f5f5f5; - --color-table-header-fg: rgba(0, 0, 0, 0.85); /* = #000000D9 */ -} -- libgit2 0.22.2