Commit 62d2fb9e50440ed5a52ca435a6eef91331d66239

Authored by zichun
1 parent e4cb883e

db-init: drop step-B connectivity probe; converge duplicate A4 checkboxes

- step B: remove the inline `node -e` mysql SELECT-1 probe (3rd copy of the
  YAML parser + a connection test C.1 setup-test-db.mjs already performs);
  keep only the cheap 5-field non-empty/placeholder credential check, fold
  the Glob existence check into Read, drop now-unused Glob from allowed-tools
- checkboxes: A.3 → `DDL ↔ docs/03 5 维一致(validate-ddl.mjs)`; drop the
  misleading "apply 后 5 维一致" item in D (apply does not change V1, nothing
  re-validates); rename the creds checkbox to "5 项非空校验通过"
- sync the A4 block in docs-08-initial-template.md (5 → 4 sub-items)
- update frontmatter description to match the new flow
skills/plan/db-init/SKILL.md
1 --- 1 ---
2 name: db-init 2 name: db-init
3 -description: A4 DB 初始化——LLM 解析 docs/03-数据库设计文档.md → 生成 sql/migrations/V1__initial_schema.sql(DDL only,Flyway 初始 migration)→ 用 lib/validate-ddl.mjs 全量校验 DDL ↔ docs/03 一致性 → 验证 MySQL 连接 → 调 scripts/setup-test-db.mjs DROP+CREATE 空库 → 用 lib/apply-ddl.mjs apply V1。 3 +description: A4 DB 初始化——LLM 解析 docs/03-数据库设计文档.md → 生成 sql/migrations/V1__initial_schema.sql(DDL only,Flyway 初始 migration)→ 用 lib/validate-ddl.mjs 全量校验 DDL ↔ docs/03 一致性 → 校验 config-vars.yaml DB 凭据 5 项非空 → 调 scripts/setup-test-db.mjs DROP+CREATE 空库(连不上即失败)→ 用 lib/apply-ddl.mjs apply V1。
4 user-invocable: false 4 user-invocable: false
5 -allowed-tools: Read Write Edit Glob Skill Bash(node *) 5 +allowed-tools: Read Write Edit Skill Bash(node *)
6 --- 6 ---
7 7
8 **所有输出必须使用中文。** 8 **所有输出必须使用中文。**
@@ -52,54 +52,15 @@ node "${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs" \ @@ -52,54 +52,15 @@ node "${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs" \
52 52
53 完成后(V1 写入并通过 `validate-ddl.mjs` 校验),勾选: 53 完成后(V1 写入并通过 `validate-ddl.mjs` 校验),勾选:
54 - ` - [ ] sql/migrations/V1__initial_schema.sql 已生成` 54 - ` - [ ] sql/migrations/V1__initial_schema.sql 已生成`
55 -- ` - [ ] DDL 与 docs/03 全量一致` 55 +- ` - [ ] DDL ↔ docs/03 5 维一致(validate-ddl.mjs)`
56 56
57 ### B. 数据库环境检查 57 ### B. 数据库环境检查
58 58
59 -用 `Glob` 确认 `config-vars.yaml` 存在(不存在 → 提示重跑 A1 `scope-lock` 并停下)。用 `Read` 读其 `database:` 段,校验 `host` / `port` / `user` / `password` / `schema` 5 项均非空且非 `【人工填写` 占位——任一缺失 → 打印缺失字段并停下。 59 +用 `Read` 读 `config-vars.yaml` 的 `database:` 段(文件缺失 → 提示重跑 A1 `scope-lock` 并停下),校验 `host` / `port` / `user` / `password` / `schema` 5 项均非空且非 `【人工填写` 占位——任一缺失 → 打印缺失字段并停下。
60 60
61 -用解析出的值跑连通性自检。必须用 Node `spawnSync('mysql', args, {shell:false})`,不要把密码拼进 shell 命令;空密码也要传 `--password=`,避免 `mysql -p` 进入交互式等待。下面的 `node -e` 内联了与 `lib/yaml-config.mjs` 同规则的极简 YAML 读取(2 层 map + 标量),仅读 `database:` 段: 61 +连通性无需在此单独探测:步骤 C.1 的 `setup-test-db.mjs` 会用同一份凭据连同一个 MySQL 跑 `DROP+CREATE`,连不上即报错(认证 / 主机不可达 / 端口拒接);且 `DROP DATABASE IF EXISTS` 在连不上时不破坏任何东西,由 C.1 失败即可。
62 62
63 -```bash  
64 -node -e '  
65 -const { spawnSync } = require("node:child_process");  
66 -const { readFileSync } = require("node:fs");  
67 -const SQ = String.fromCharCode(39), DQ = String.fromCharCode(34);  
68 -function parseScalar(raw) {  
69 - let s = String(raw).trim();  
70 - if (s === "" || s[0] === "#") return "";  
71 - const q = s[0];  
72 - if (q === SQ || q === DQ) { const e = s.indexOf(q, 1); if (e !== -1) return s.slice(1, e); }  
73 - const h = s.indexOf(" #"); if (h !== -1) s = s.slice(0, h).trim();  
74 - return s;  
75 -}  
76 -const cfg = {}; let sec = null;  
77 -for (const raw of readFileSync("config-vars.yaml", "utf8").split(/\r?\n/)) {  
78 - const t = raw.trim(); if (!t || t[0] === "#") continue;  
79 - const c = raw.indexOf(":"); if (c < 0) continue;  
80 - const k = raw.slice(0, c).trim(); if (!k) continue;  
81 - const ind = raw.length - raw.replace(/^\s+/, "").length;  
82 - const v = parseScalar(raw.slice(c + 1));  
83 - if (ind === 0) { if (v === "") { sec = {}; cfg[k] = sec; } else { cfg[k] = v; sec = null; } }  
84 - else if (sec) { sec[k] = v; }  
85 -}  
86 -const db = cfg.database || {};  
87 -const args = [  
88 - `--host=${db.host}`,  
89 - `--port=${db.port || "3306"}`,  
90 - `--user=${db.user}`,  
91 - `--password=${db.password || ""}`,  
92 - "-e",  
93 - "SELECT 1;"  
94 -];  
95 -const r = spawnSync("mysql", args, { stdio: "inherit" });  
96 -process.exit(r.status === null ? 1 : r.status);  
97 -'  
98 -```  
99 -  
100 -成功 → 进入步骤 C;失败 → 打印具体错误(认证 / 主机不可达 / 端口拒接)并停下。  
101 -  
102 -勾选:` - [ ] config-vars.yaml DB 凭据已验证(mysql -e "SELECT 1" OK)` 63 +勾选:` - [ ] config-vars.yaml DB 凭据 5 项非空校验通过`
103 64
104 ### C. 自动导入 MySQL 65 ### C. 自动导入 MySQL
105 66
@@ -126,8 +87,7 @@ node &quot;${CLAUDE_PLUGIN_ROOT}/lib/apply-ddl.mjs&quot; config-vars.yaml sql/migrations/V @@ -126,8 +87,7 @@ node &quot;${CLAUDE_PLUGIN_ROOT}/lib/apply-ddl.mjs&quot; config-vars.yaml sql/migrations/V
126 87
127 ### D. 勾选 docs/08 进度 + 进入 A5 88 ### D. 勾选 docs/08 进度 + 进入 A5
128 89
129 -1. 勾选(A4 子项 + A4 顶层;DDL ↔ docs/03 5 维一致已由 A.3 校验过,V1 文件自此未变):  
130 - - ` - [ ] DDL ↔ docs/03 apply 后 5 维一致(validate-ddl.mjs)` 90 +1. 勾选 A4 顶层(5 维一致已由 A.3 的 `validate-ddl.mjs` 校验过,apply 不改 V1,无需复校):
131 - `- [ ] A4 DB 初始化 — db-init` 91 - `- [ ] A4 DB 初始化 — db-init`
132 92
133 2. 立即调用 `Skill(downstream-gen)` 进入 A5,不等用户手动输入。 93 2. 立即调用 `Skill(downstream-gen)` 进入 A5,不等用户手动输入。
skills/plan/project-init/templates/docs-08-initial-template.md
@@ -27,10 +27,9 @@ @@ -27,10 +27,9 @@
27 27
28 - [ ] A4 DB 初始化 — db-init 28 - [ ] A4 DB 初始化 — db-init
29 - [ ] sql/migrations/V1__initial_schema.sql 已生成 29 - [ ] sql/migrations/V1__initial_schema.sql 已生成
30 - - [ ] DDL 与 docs/03 全量一致  
31 - - [ ] config-vars.yaml DB 凭据已验证(mysql -e "SELECT 1" OK) 30 + - [ ] DDL ↔ docs/03 5 维一致(validate-ddl.mjs)
  31 + - [ ] config-vars.yaml DB 凭据 5 项非空校验通过
32 - [ ] setup-test-db.mjs DROP+CREATE + apply V1 已执行 32 - [ ] setup-test-db.mjs DROP+CREATE + apply V1 已执行
33 - - [ ] DDL ↔ docs/03 apply 后 5 维一致(validate-ddl.mjs)  
34 33
35 - [ ] A5 下游文档生成 — downstream-gen 34 - [ ] A5 下游文档生成 — downstream-gen
36 - [ ] docs/02 开发计划已生成 35 - [ ] docs/02 开发计划已生成