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 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 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 52  
53 53 完成后(V1 写入并通过 `validate-ddl.mjs` 校验),勾选:
54 54 - ` - [ ] sql/migrations/V1__initial_schema.sql 已生成`
55   -- ` - [ ] DDL 与 docs/03 全量一致`
  55 +- ` - [ ] DDL ↔ docs/03 5 维一致(validate-ddl.mjs)`
56 56  
57 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 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 87  
127 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 91 - `- [ ] A4 DB 初始化 — db-init`
132 92  
133 93 2. 立即调用 `Skill(downstream-gen)` 进入 A5,不等用户手动输入。
... ...
skills/plan/project-init/templates/docs-08-initial-template.md
... ... @@ -27,10 +27,9 @@
27 27  
28 28 - [ ] A4 DB 初始化 — db-init
29 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 32 - [ ] setup-test-db.mjs DROP+CREATE + apply V1 已执行
33   - - [ ] DDL ↔ docs/03 apply 后 5 维一致(validate-ddl.mjs)
34 33  
35 34 - [ ] A5 下游文档生成 — downstream-gen
36 35 - [ ] docs/02 开发计划已生成
... ...