cgraphx 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/.claude-template/skills/cgraphx-guide/how-to-use.html +5 -4
  2. package/dist/.claude-template/skills/db-query/SKILL.md +75 -42
  3. package/dist/.claude-template/skills/db-query/agent-prompt.md +12 -13
  4. package/dist/.claude-template/skills/export-table-ddl/SKILL.md +167 -0
  5. package/dist/.claude-template/skills/export-table-ddl/closed-loop.html +163 -0
  6. package/dist/.claude-template/skills/export-table-ddl/evals/evals.json +26 -0
  7. package/dist/.claude-template/skills/export-table-ddl/scripts/export-ddl.mjs +163 -0
  8. package/dist/.claude-template/skills/run-api-test/SKILL.md +5 -5
  9. package/dist/.claude-template/skills/run-api-test/references/test-scope.md +1 -1
  10. package/dist/.claude-template/skills/write-api/SKILL.md +10 -10
  11. package/dist/.claude-template/skills/write-api/assets/template-api-spec.md +6 -6
  12. package/dist/.claude-template/skills/write-api/assets/template-request.bru +1 -4
  13. package/dist/.claude-template/skills/write-api/references/ai-prompts.md +1 -1
  14. package/dist/.claude-template/skills/write-api/references/api-spec-format.md +2 -2
  15. package/dist/.claude-template/skills/write-api/references/bru-format.md +6 -11
  16. package/dist/.claude-template/skills/write-api/references/collection-layout.md +24 -15
  17. package/dist/dbquery/cli.d.ts.map +1 -1
  18. package/dist/dbquery/cli.js +20 -3
  19. package/dist/dbquery/cli.js.map +1 -1
  20. package/dist/dbquery/executor.d.ts.map +1 -1
  21. package/dist/dbquery/executor.js +15 -23
  22. package/dist/dbquery/executor.js.map +1 -1
  23. package/dist/dbquery/format.d.ts +15 -1
  24. package/dist/dbquery/format.d.ts.map +1 -1
  25. package/dist/dbquery/format.js +86 -23
  26. package/dist/dbquery/format.js.map +1 -1
  27. package/dist/dbquery/identifiers.d.ts +19 -0
  28. package/dist/dbquery/identifiers.d.ts.map +1 -0
  29. package/dist/dbquery/identifiers.js +37 -0
  30. package/dist/dbquery/identifiers.js.map +1 -0
  31. package/dist/dbquery/index.d.ts +1 -1
  32. package/dist/dbquery/index.d.ts.map +1 -1
  33. package/dist/dbquery/index.js.map +1 -1
  34. package/dist/dbquery/queries.d.ts +23 -3
  35. package/dist/dbquery/queries.d.ts.map +1 -1
  36. package/dist/dbquery/queries.js +46 -27
  37. package/dist/dbquery/queries.js.map +1 -1
  38. package/dist/dbquery/types.d.ts +2 -15
  39. package/dist/dbquery/types.d.ts.map +1 -1
  40. package/package.json +1 -1
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * export-ddl.mjs — 批量导出项目表的 DDL 到可检索目录。
4
+ *
5
+ * 流程:
6
+ * 1. `cgraphx db schema --mode=tables --profile=P` 拿全表 + 表注释(1 次调用)
7
+ * 2. 过滤到请求的表清单(--tables all 时跳过过滤)
8
+ * 3. 对每张表 `cgraphx db schema --mode=ddl --table=X --profile=P` 拿 DDL 文本(N 次调用)
9
+ * 4. 写 <out>/<project>/INDEX.md(表名 + 注释 + DDL 链接)+ <out>/<project>/ddl/<table>.sql
10
+ *
11
+ * 用法:
12
+ * node export-ddl.mjs \
13
+ * --profile zqassis \
14
+ * --tables ./tables.txt \ # 或 --tables all(全库导出)
15
+ * --out ./schema-dump \
16
+ * --project customer-svc
17
+ *
18
+ * tables 文件格式:每行一个表名,# 开头注释行忽略;或 JSON 数组 ["t1","t2"]。
19
+ */
20
+ import { execFileSync } from 'node:child_process';
21
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
22
+ import { resolve, join } from 'node:path';
23
+
24
+ function parseArgs(argv) {
25
+ const args = {};
26
+ for (let i = 0; i < argv.length; i++) {
27
+ const k = argv[i];
28
+ if (k.startsWith('--')) {
29
+ const v = argv[i + 1] && !argv[i + 1].startsWith('--') ? argv[++i] : 'true';
30
+ args[k.slice(2)] = v;
31
+ }
32
+ }
33
+ return args;
34
+ }
35
+
36
+ function readTableList(spec) {
37
+ if (spec === 'all') return null; // null = 不过滤
38
+ const raw = readFileSync(spec, 'utf8');
39
+ const trimmed = raw.trim();
40
+ if (trimmed.startsWith('[')) {
41
+ return JSON.parse(trimmed);
42
+ }
43
+ return trimmed
44
+ .split('\n')
45
+ .map(l => l.trim())
46
+ .filter(l => l && !l.startsWith('#'));
47
+ }
48
+
49
+ function runCgraphx(cmdArgs, { expectJson = false } = {}) {
50
+ const env = { ...process.env, CGRAPHX_WASM_RELAUNCHED: '1' };
51
+ const bin = process.env.CGRAPHX_BIN || 'cgraphx';
52
+ const out = execFileSync(bin, ['db', ...cmdArgs], {
53
+ encoding: 'utf8',
54
+ env,
55
+ stdio: ['ignore', 'pipe', 'pipe'],
56
+ maxBuffer: 64 * 1024 * 1024,
57
+ });
58
+ if (expectJson) return JSON.parse(out);
59
+ return out;
60
+ }
61
+
62
+ /**
63
+ * 提取 db-query 探索补充的 DISCOVERED 块(含起止标记行),供重 dump 时保留。
64
+ * 块格式见 db-query/SKILL.md。无块返回 null。
65
+ */
66
+ function extractDiscoveredBlock(content) {
67
+ const start = content.indexOf('-- === DISCOVERED');
68
+ if (start === -1) return null;
69
+ const endMarker = '-- === END DISCOVERED ===';
70
+ const end = content.indexOf(endMarker, start);
71
+ if (end === -1) return content.slice(start).replace(/\n*$/, '\n');
72
+ return content.slice(start, end + endMarker.length).replace(/\n*$/, '\n');
73
+ }
74
+
75
+ function main() {
76
+ const args = parseArgs(process.argv.slice(2));
77
+ const profile = args.profile;
78
+ const tablesSpec = args.tables;
79
+ const outDir = args.out;
80
+ const project = args.project;
81
+ if (!profile || !tablesSpec || !outDir || !project) {
82
+ process.stderr.write(
83
+ 'Usage: export-ddl.mjs --profile <name> --tables <file|all> --out <dir> --project <name>\n',
84
+ );
85
+ process.exit(5);
86
+ }
87
+
88
+ // 1. 拿全表 + 注释
89
+ process.stderr.write(`[export-ddl] 拉取 ${profile} 的表清单...\n`);
90
+ const tablesResult = runCgraphx(
91
+ ['schema', '--mode=tables', `--profile=${profile}`, '--format=json'],
92
+ { expectJson: true },
93
+ );
94
+ const allTables = new Map(tablesResult.tables.map(t => [t.name, t.comment ?? '']));
95
+
96
+ // 2. 过滤
97
+ const requested = readTableList(tablesSpec);
98
+ const targets = requested === null
99
+ ? [...allTables.keys()]
100
+ : requested.filter(Boolean);
101
+ process.stderr.write(`[export-ddl] 共 ${targets.length} 张表待导出。\n`);
102
+
103
+ // 3. 逐表拉 DDL
104
+ const projectDir = resolve(outDir, project);
105
+ const ddlDir = join(projectDir, 'ddl');
106
+ mkdirSync(ddlDir, { recursive: true });
107
+
108
+ const indexRows = [];
109
+ let ok = 0, missing = 0, failed = 0, preserved = 0;
110
+ for (const table of targets) {
111
+ const comment = allTables.get(table);
112
+ if (comment === undefined) {
113
+ indexRows.push({ table, comment: '(表中不存在)', status: 'missing' });
114
+ missing++;
115
+ continue;
116
+ }
117
+ try {
118
+ const ddl = runCgraphx(
119
+ ['schema', '--mode=ddl', `--table=${table}`, `--profile=${profile}`],
120
+ );
121
+ const filePath = join(ddlDir, `${table}.sql`);
122
+ // 重 dump 时保留 db-query 探索补充的 -- === DISCOVERED === 块
123
+ let out = ddl;
124
+ if (existsSync(filePath)) {
125
+ const old = readFileSync(filePath, 'utf8');
126
+ const discovered = extractDiscoveredBlock(old);
127
+ if (discovered) {
128
+ out = ddl.replace(/\n*$/, '\n') + '\n' + discovered;
129
+ preserved++;
130
+ }
131
+ }
132
+ writeFileSync(filePath, out);
133
+ indexRows.push({ table, comment, status: 'ok' });
134
+ ok++;
135
+ } catch (err) {
136
+ const msg = err instanceof Error ? err.message : String(err);
137
+ process.stderr.write(`[export-ddl] ${table} 失败: ${msg}\n`);
138
+ indexRows.push({ table, comment, status: `failed: ${msg.split('\n')[0]}` });
139
+ failed++;
140
+ }
141
+ }
142
+
143
+ // 4. 写 INDEX.md
144
+ const lines = [
145
+ `# ${project} 表清单`,
146
+ '',
147
+ `共 ${targets.length} 张表(成功 ${ok} / 缺失 ${missing} / 失败 ${failed}),DDL 见 \`ddl/\` 目录。${preserved > 0 ? ` 保留 ${preserved} 张表的 DISCOVERED 补充。` : ''}`,
148
+ '',
149
+ '| 表名 | 注释 | 状态 |',
150
+ '|---|---|---|',
151
+ ];
152
+ for (const r of indexRows) {
153
+ const status = r.status === 'ok' ? '✓' : r.status;
154
+ lines.push(`| \`${r.table}\` | ${r.comment || ''} | ${status} |`);
155
+ }
156
+ writeFileSync(join(projectDir, 'INDEX.md'), lines.join('\n') + '\n');
157
+
158
+ process.stderr.write(
159
+ `[export-ddl] 完成 → ${projectDir}/ (成功 ${ok} / 缺失 ${missing} / 失败 ${failed})\n`,
160
+ );
161
+ }
162
+
163
+ main();
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: run-api-test
3
- description: 在 write-api 生成 .bru 后,跑接口测试 + 核实写接口 DB 副作用 + 出报告。触发时由用户指定需求或接口:指定需求→跑该需求所有接口所有场景,报告归该需求目录;只指定接口→主动问测哪个需求(AI 反查 .bru docs 段关联需求列表让用户选);都没指定→主动问。服务未就绪暂停等待;写接口必须查 DB 验数据(HTTP 200 ≠ 通过);失败只报告不修代码不重跑,交用户决定。不调 write-api / write-api-doc,不改 .bru。Use when 用户要求跑接口测试 / 验证接口 / 测一下需求 X 的接口 / 跑下这个接口;write-api 跑完后用户要求执行测试;代码改完后用户想验证修复。
3
+ description: 在 write-api 生成 .bru 后,跑接口测试 + 核实写接口 DB 副作用 + 出报告。触发时由用户指定需求或接口:指定需求→跑该需求所有接口所有场景,报告归该需求目录;只指定接口→主动问测哪个需求(AI docs/bruno/ 下哪些需求测过该接口,让用户选);都没指定→主动问。服务未就绪暂停等待;写接口必须查 DB 验数据(HTTP 200 ≠ 通过);失败只报告不修代码不重跑,交用户决定。不调 write-api / write-api-doc,不改 .bru。Use when 用户要求跑接口测试 / 验证接口 / 测一下需求 X 的接口 / 跑下这个接口;write-api 跑完后用户要求执行测试;代码改完后用户想验证修复。
4
4
  ---
5
5
 
6
6
  # Run API Test
@@ -45,7 +45,7 @@ description: 在 write-api 生成 .bru 后,跑接口测试 + 核实写接口 DB
45
45
 
46
46
  ## 依赖
47
47
 
48
- - `.bru` 文件已存在(由 `/write-api` 生成,在 `docs/bruno/<服务>/<接口名>/<场景>.bru` 或 `docs/bruno/common/<接口名>/<场景>.bru`)
48
+ - `.bru` 文件已存在(由 `/write-api` 生成,在 `docs/bruno/<服务>/<需求前缀>/<接口名>/<场景>.bru` 或 `docs/bruno/common/<接口名>/<场景>.bru`)
49
49
  - `docs/bruno/environments/local.bru` 存在(不存在时报错退出,提示先跑 `/write-api`)
50
50
  - 本地服务可启动(若需手动启动,R2 暂停等待)
51
51
  - 项目已配置 db-query profile(R4 核实写接口副作用用)—— 未配置则 R4 降级,见 `references/db-verification.md`
@@ -79,7 +79,7 @@ description: 在 write-api 生成 .bru 后,跑接口测试 + 核实写接口 DB
79
79
 
80
80
  ├─ 只指定了接口(接口名/路径)
81
81
  │ → skill 主动问"测哪个需求?"
82
- │ → AI 反查该接口 .bru docs 段的"关联需求"列表(可能多个)
82
+ │ → AI docs/bruno/<服务>*/<需求前缀>/<接口名>/ 哪些存在,列出测过该接口的需求
83
83
  │ → 列出来让用户选(若 0 个需求,提示用户先跑 /write-api)
84
84
  │ → 选定后,AI 查该需求 api-spec.md 拿该接口的场景
85
85
  │ → 提示用户确认后进入 R1
@@ -91,7 +91,7 @@ description: 在 write-api 生成 .bru 后,跑接口测试 + 核实写接口 DB
91
91
 
92
92
  **关键约束**:
93
93
  - 不管走哪条分支,最终都要锁定一个 feature-id,**报告归该 feature 目录**
94
- - AI 反查 .bru docs 段关联需求时,读 `docs/bruno/<服务>/<接口名>/*.bru` docs 段的"关联需求"段
94
+ - AI 扫目录反查指定接口关联哪些需求时,读 `docs/bruno/<服务>*/<需求前缀>/<接口名>/` 哪些存在(无需读 .bru docs 段,目录层级已表达归属)
95
95
  - 用户确认环节不能省 —— AI 理解的范围必须显示给用户,避免跑错需求或接口
96
96
 
97
97
  ## 工作流
@@ -148,7 +148,7 @@ description: 在 write-api 生成 .bru 后,跑接口测试 + 核实写接口 DB
148
148
  |---|---|
149
149
  | 用户指定需求但 api-spec 不存在 | 报"需求 X 无测试规格,请先跑 /write-api"并退出 |
150
150
  | 用户指定接口但 .bru 不存在 | 报"接口 Y 无 .bru,请先跑 /write-api"并退出 |
151
- | 用户指定接口但 docs 段无关联需求 | 提示"接口 Y 未声明关联需求,请确认 .bru /write-api 生成" |
151
+ | 用户指定接口但扫目录发现 0 个需求测过 | 提示"未在 docs/bruno/ 下找到测过接口 Y 的需求,请先跑 /write-api" |
152
152
  | api-spec §5 列出的 .bru 实际不存在 | 报"需求 X 接口 Y 场景 Z 的 .bru 缺失,请先跑 /write-api"并退出 |
153
153
  | 本地服务未启动 | 暂停 + 提示用户启动,等待回车继续 |
154
154
  | env 文件缺失 | 报"环境缺失,请先跑 /write-api"并退出,不自动生成 |
@@ -59,6 +59,6 @@ docs/bruno/common/login/正常.bru
59
59
  |---|---|
60
60
  | 用户指定需求但 api-spec.md 不存在 | 报"需求 X 无测试规格,请先跑 /write-api"并退出 |
61
61
  | 用户指定接口但接口目录不存在 | 报"接口 Y 无 .bru,请先跑 /write-api"并退出 |
62
- | 用户指定接口但 docs 段无关联需求 | 提示"接口 Y 未声明关联需求,请确认 .bru /write-api 生成" |
62
+ | 用户指定接口但扫目录发现 0 个需求测过 | 提示"未在 docs/bruno/ 下找到测过接口 Y 的需求,请先跑 /write-api" |
63
63
  | api-spec §5 列出的 .bru 实际不存在 | 报"需求 X 接口 Y 场景 Z 的 .bru 缺失,请先跑 /write-api"并退出 |
64
64
  | 用户确认环节用户取消 | 退出,不进入 R2 |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: write-api
3
- description: 基于需求生成 bruno 测试接口(.bru + 测试规格 + 环境配置)。流程:识别接口范围(用户显式给 / spec 接口章节 / AI 读 spec 理解)→ 生成测试规格文档 → 单次 AI 调用生成 .bru(含真实参数 + 内嵌断言 + docs 段关联需求)→ 首次接入时生成 bruno.json + environments/*.bru 骨架。产物:测试规格随 feature 走;.bru collection 按 <服务>/<接口名>/<场景> 组织在 docs/bruno/(接口跨 feature 复用,不绑 feature-id);environments 统一管理。本 skill 不跑 bru run、不核实 DB、不出报告——那是 /run-api-test 的职责。不调 write-api-doc、不自动修代码、不引入程序化配置文件(微服务/通用接口识别由 AI 判断)。Use when 用户要求生成测试接口 / 写接口测试 / 准备 bruno 测试 / 帮需求补接口 / 免去手动录接口。
3
+ description: 基于需求生成 bruno 测试接口(.bru + 测试规格 + 环境配置)。流程:识别接口范围(用户显式给 / spec 接口章节 / AI 读 spec 理解)→ 生成测试规格文档 → 单次 AI 调用生成 .bru(含真实参数 + 内嵌断言)→ 首次接入时生成 bruno.json + environments/*.bru 骨架。产物:测试规格随 feature 走;.bru collection 按 <服务>/<需求前缀>/<接口名>/<场景> 组织在 docs/bruno/(按需求隔离,跨需求不覆盖);environments 统一管理。本 skill 不跑 bru run、不核实 DB、不出报告——那是 /run-api-test 的职责。不调 write-api-doc、不自动修代码、不引入程序化配置文件(微服务/通用接口识别由 AI 判断)。Use when 用户要求生成测试接口 / 写接口测试 / 准备 bruno 测试 / 帮需求补接口 / 免去手动录接口。
4
4
  ---
5
5
 
6
6
  # Write API
@@ -58,7 +58,7 @@ description: 基于需求生成 bruno 测试接口(.bru + 测试规格 + 环境
58
58
 
59
59
  产物文件名:
60
60
  - 测试规格:`docs/features/<feature-id>/<文件前缀>-api-spec.md`
61
- - .bru:见 `references/collection-layout.md`
61
+ - .bru:`docs/bruno/<服务>/<文件前缀>/<接口名>/<场景>.bru`(按需求隔离,见 `references/collection-layout.md`)
62
62
  - bruno.json + environments:见 `references/environment-setup.md`
63
63
 
64
64
  测试报告 / JSONL 不由本 skill 产——`/run-api-test` 跑完后产,落 `docs/features/<feature-id>/`。
@@ -87,11 +87,11 @@ description: 基于需求生成 bruno 测试接口(.bru + 测试规格 + 环境
87
87
  - **前置**:S2 测试规格就绪(含用户校正后的服务/通用标注)
88
88
  - **行为**:**单次 AI 调用**生成全部 .bru(不拆两阶段、不逐接口循环,见 `references/ai-prompts.md` §S3)
89
89
  - .bru 格式 / 断言 / 入参 / docs 段 → `references/bru-format.md`
90
- - 落盘路径 / feature 覆盖 / 根级 bruno.json → `references/collection-layout.md`
90
+ - 落盘路径 / 按需求隔离 / 根级 bruno.json → `references/collection-layout.md`
91
91
  - 使用 db-query skill 获取基于数据库的测试数据
92
92
  - 拿不到真实数据时 → 留 `{{var}}` 占位 + 测试规格 §3 标注"需用户手填"
93
93
  - **AI 调用失败**(超时/限流)→ 报"AI 增强失败" + 保留 S2 测试规格,**不继续 S4**
94
- - **结果**:全部 .bru 落盘 + 根级 bruno.json 就绪 + docs 段含业务说明和关联需求
94
+ - **结果**:全部 .bru 落盘到 `<服务>/<需求前缀>/<接口名>/<场景>.bru` + 根级 bruno.json 就绪
95
95
 
96
96
  ### S4. 首次接入环境准备
97
97
 
@@ -108,7 +108,7 @@ S4 完成后 skill 结束。**不跑 bru run、不核实 DB、不出报告**。
108
108
 
109
109
  产物:
110
110
  - `docs/features/<feature-id>/<文件前缀>-api-spec.md`(测试规格)
111
- - `docs/bruno/<服务>/<接口名>/<场景>.bru`(测试接口)
111
+ - `docs/bruno/<服务>/<文件前缀>/<接口名>/<场景>.bru`(测试接口,按需求隔离)
112
112
  - `docs/bruno/bruno.json` + `docs/bruno/environments/*.bru`(首次接入生成)
113
113
 
114
114
  ## 异常速查
@@ -119,8 +119,8 @@ S4 完成后 skill 结束。**不跑 bru run、不核实 DB、不出报告**。
119
119
  | 接口范围三种来源都拿不到 | 报错退出 |
120
120
  | AI 拿不到真实测试数据 | 留 `{{var}}` 占位 + 测试规格标注"需用户手填",继续跑能跑的部分 |
121
121
  | AI 调用失败 | 报"AI 增强失败" + 保留测试规格,不继续 S4 |
122
- | feature 重复触发 write-api | 覆盖 .bru + 覆盖测试规格;docs 关联需求列表去重保留 |
123
- | feature 同接口同场景 | 后跑覆盖先跑 .bru;docs 关联需求列表去重追加 |
122
+ | 同需求重复触发 write-api | 覆盖该需求的 .bru + 覆盖测试规格(数据从当前需求 spec + DB 重新取) |
123
+ | 跨需求同接口同场景 | 各需求独立保留,不覆盖(分别在自己需求目录下) |
124
124
  | 项目首次接入 | 自动创建 `docs/bruno/` + bruno.json + environments/ |
125
125
  | env 文件缺失 | S4 生成骨架 + AI 填 non-secret + 暂停提示用户填 secret |
126
126
 
@@ -130,10 +130,10 @@ S4 完成后 skill 结束。**不跑 bru run、不核实 DB、不出报告**。
130
130
 
131
131
  跑完后自检:
132
132
  - 测试规格文档落盘 feature 目录,六节齐全
133
- - .bru 按 `<服务>/<接口名>/<场景>.bru` 组织,无 `collection.bru`
133
+ - .bru 按 `<服务>/<需求前缀>/<接口名>/<场景>.bru` 组织,无 `collection.bru`
134
134
  - 根级 `bruno.json` 存在;首次接入时 `environments/` + 三环境 .bru 生成,secret 留空
135
135
  - .bru 用旧版 tests 语法(`test("name", function() { res.getStatus()/res.getBody()... })`),无 `assert` 段、无 `function onResponse`
136
- - .bru 的 docs 段含业务说明 + 关联需求 spec 列表(去重)
136
+ - .bru 的 docs 段含业务说明(关联需求由目录层级表达,docs 段不写关联需求列表)
137
137
  - 入参写真实值,变量化只用于环境级 / 前置动态 / 拿不到时占位
138
138
  - header 名 / `{{var}}` 变量名大小写与项目既有 .bru 对齐
139
139
  - 无程序化配置文件(`.services.yml` / `.config.yml`)
@@ -143,7 +143,7 @@ S4 完成后 skill 结束。**不跑 bru run、不核实 DB、不出报告**。
143
143
 
144
144
  提示用户:
145
145
  1. 测试规格位置(`<文件前缀>-api-spec.md`)
146
- 2. .bru collection 位置(`docs/bruno/<服务>/<接口名>/`)
146
+ 2. .bru collection 位置(`docs/bruno/<服务>/<文件前缀>/<接口名>/`)
147
147
  3. 首次接入:bruno.json + environments/*.bru 已生成,需填 `local.bru` 的 secret 变量
148
148
  4. 下一步:**跑 `/run-api-test` 跑测试 + 核实 DB + 出报告**
149
149
 
@@ -11,7 +11,7 @@
11
11
 
12
12
  > feature-id: <feature-id>
13
13
  > 生成时间: <YYYY-MM-DD HH:MM>
14
- > 关联接口集合: docs/bruno/<服务>/<feature-id>/
14
+ > 关联接口集合: docs/bruno/<服务>/<文件前缀>/
15
15
 
16
16
  ## 1. 接口清单
17
17
 
@@ -80,13 +80,13 @@
80
80
 
81
81
  | 场景 | 接口 | .bru 文件路径 |
82
82
  |---|---|---|
83
- | GET /api/v1/users/:id 正常 | GET /api/v1/users/:id | docs/bruno/user-service/getUser/正常.bru |
84
- | POST /api/v1/users 正常 | POST /api/v1/users | docs/bruno/user-service/createUser/正常.bru |
85
- | POST /api/v1/users 缺必填 | POST /api/v1/users | docs/bruno/user-service/createUser/缺name.bru |
83
+ | GET /api/v1/users/:id 正常 | GET /api/v1/users/:id | docs/bruno/user-service/<文件前缀>/getUser/正常.bru |
84
+ | POST /api/v1/users 正常 | POST /api/v1/users | docs/bruno/user-service/<文件前缀>/createUser/正常.bru |
85
+ | POST /api/v1/users 缺必填 | POST /api/v1/users | docs/bruno/user-service/<文件前缀>/createUser/缺name.bru |
86
86
  | POST /api/v1/auth/login 正常 | POST /api/v1/auth/login | docs/bruno/common/login/正常.bru |
87
87
 
88
- - .bru 按接口组织(跨 feature 复用,不绑 feature-id)
89
- - 通用接口落 docs/bruno/common/<接口名>/
88
+ - .bru 按服务 + 需求 + 接口组织(按需求隔离,跨需求不覆盖)
89
+ - 通用接口落 docs/bruno/common/<接口名>/(不绑需求)
90
90
 
91
91
  ## 6. 验收口径
92
92
 
@@ -68,8 +68,5 @@ tests {
68
68
  }
69
69
 
70
70
  docs {
71
- 业务说明: <一句话,从 Javadoc 或 spec 提取;提取不到占位"(scan 阶段未提取到 Javadoc,请补充业务说明)">
72
-
73
- 关联需求:
74
- - <YYYY-MM-DD-feature-id> (<文件前缀>-spec.md)
71
+ 业务说明: <一句话,从 Javadoc 或 spec 提取;提取不到占位"(scan 阶段未提取到 Javadoc,请补充业务说明)"
75
72
  }
@@ -95,7 +95,7 @@ AI 判断时**优先参考 `docs/bruno/common/` 既有接口**,避免重复生
95
95
  - `meta { name, type: http }`
96
96
  - HTTP 方法段 + `params` + `headers` + `body:json`(写接口)
97
97
  - `tests { test("name", function() { ... }) }` 内嵌断言(旧版语法)
98
- - `docs { 业务说明 / 关联需求 spec 列表 }`
98
+ - `docs { 业务说明 }`(关联需求由 .bru 所在的 `<服务>/<需求前缀>/<接口名>/` 目录层级表达,docs 段不写关联需求列表)
99
99
 
100
100
  ### 拿不到真实数据时
101
101
 
@@ -71,8 +71,8 @@
71
71
  ```markdown
72
72
  | 场景 | 接口 | .bru 文件路径 |
73
73
  |---|---|---|
74
- | GET /api/v1/users/:id 正常 | GET /api/v1/users/:id | docs/bruno/user-service/getUser/正常.bru |
75
- | POST /api/v1/users 缺必填 | POST /api/v1/users | docs/bruno/user-service/createUser/缺name.bru |
74
+ | GET /api/v1/users/:id 正常 | GET /api/v1/users/:id | docs/bruno/user-service/<文件前缀>/getUser/正常.bru |
75
+ | POST /api/v1/users 缺必填 | POST /api/v1/users | docs/bruno/user-service/<文件前缀>/createUser/缺name.bru |
76
76
  | POST /api/v1/auth/login 正常 | POST /api/v1/auth/login | docs/bruno/common/login/正常.bru |
77
77
  ```
78
78
 
@@ -55,9 +55,6 @@ tests {
55
55
  docs {
56
56
  # 见下方"docs 段写法"
57
57
  业务说明: <一句话>
58
-
59
- 关联需求:
60
- - <YYYY-MM-DD-feature-id> (<文件前缀>-spec.md)
61
58
  }
62
59
  ```
63
60
 
@@ -109,22 +106,20 @@ tests {
109
106
 
110
107
  第 3 种情况发生时,在测试规格 §3 标注哪些参数需用户手填,skill 继续跑能跑的部分,不因此中断。
111
108
 
112
- ## docs 段写法(固定结构)
109
+ ## docs 段写法
113
110
 
114
111
  ```
115
112
  docs {
116
113
  业务说明: <一句话,从 Javadoc 或 spec 提取;提取不到占位"(scan 阶段未提取到 Javadoc,请补充业务说明)">
117
-
118
- 关联需求:
119
- - <YYYY-MM-DD-feature-id> (<文件前缀>-spec.md)
120
114
  }
121
115
  ```
122
116
 
123
- ### 关联需求列表的行为
124
-
125
- - AI 生成时,若该接口目录下已有 .bru(docs 段含历史关联需求),把当前 feature-id **追加**到列表(去重),不删除已有 feature
117
+ - 仅业务说明一句,不写关联需求列表(关联需求由 .bru 所在的 `<服务>/<需求前缀>/<接口名>/` 目录层级表达,扫目录即可知)
126
118
  - 不在 docs 段写断言推理 / 场景预期等详细内容(简短,bruno 不渲染 markdown)
127
- - **关联需求列表是 `/run-api-test` 反查"接口关联哪些 feature"的依据**——用户触发 `/run-api-test` 只指定接口时,AI 反查此列表让用户选测哪个 feature;列表必须写全,不能漏
119
+
120
+ ### 为什么 docs 段不写关联需求
121
+
122
+ 之前 docs 段含"关联需求"列表,是为让 `/run-api-test` 在"只指定接口"时反查接口关联哪些需求。现在 .bru 落盘路径含需求层(`<服务>/<需求前缀>/<接口名>/`),反查需求只需扫 `docs/bruno/<服务>*/<需求前缀>/<接口名>/` 哪些存在即可,无需 docs 段冗余维护。
128
123
 
129
124
  ## header 名 / 变量名对齐
130
125
 
@@ -9,42 +9,45 @@ docs/bruno/
9
9
  │ ├── local.bru
10
10
  │ ├── staging.bru
11
11
  │ └── production.bru
12
- ├── common/ # 通用接口,跨服务跨 feature 复用
12
+ ├── common/ # 通用接口,跨服务跨需求复用
13
13
  │ └── <接口名>/
14
14
  │ └── <场景>.bru
15
15
  └── <服务名>/ # 微服务,无服务划分时退化为此层不存在
16
- └── <接口名>/ # 接口目录,跨 feature 累积场景
17
- ├── <场景-1>.bru
18
- └── <场景-2>.bru
16
+ └── <需求前缀>/ # 需求隔离层,按需求独立保留,跨需求不覆盖
17
+ └── <接口名>/ # 接口目录,本需求内累积场景
18
+ ├── <场景-1>.bru
19
+ └── <场景-2>.bru
19
20
  ```
20
21
 
21
22
  ## 路径规则
22
23
 
23
24
  | 接口类型 | 路径 |
24
25
  |---|---|
25
- | 业务接口(有服务划分) | `docs/bruno/<服务>/<接口名>/<场景>.bru` |
26
- | 业务接口(无服务划分) | `docs/bruno/<接口名>/<场景>.bru` |
26
+ | 业务接口(有服务划分) | `docs/bruno/<服务>/<需求前缀>/<接口名>/<场景>.bru` |
27
+ | 业务接口(无服务划分) | `docs/bruno/<需求前缀>/<接口名>/<场景>.bru` |
27
28
  | 通用接口 | `docs/bruno/common/<接口名>/<场景>.bru` |
28
29
 
29
30
  ### 取名规则
30
31
 
31
32
  - **`<服务>`** — 由 AI 在 S2 识别(见 `ai-prompts.md`),参考 `docs/bruno/` 既有目录名保持一致
33
+ - **`<需求前缀>`** — 取 S1 锁定的 feature-id 的"文件前缀"段(即 `<业务ID>-<标题>` 或 `<标题>`,如 `CRM-req19230-号百商品详情查询接口`),与 `docs/features/<feature-id>/` 下文件的命名前缀一致
32
34
  - **`<接口名>`** — 取接口的方法名或路径最后一段,参考项目既有 .bru 的命名习惯
33
35
  - **`<场景>`** — 取测试规格 §2 的场景名(如 `正常` / `缺prodInstId` / `产品不存在`)
34
36
 
35
- ## 按接口组织,不绑 feature-id
37
+ ## 按服务 + 需求 + 接口组织
36
38
 
37
- **核心原则**:接口跨 feature 复用,按 `<接口名>` 组织目录,**不绑 feature-id**。
39
+ **核心原则**:接口按服务 + 需求组织,**按需求独立保留,跨需求不覆盖**。
38
40
 
39
- 不同 feature 测同一接口时,往同一接口目录追加场景 .bru,而不是按 feature-id 分目录。理由:同一接口的测试应该集中管理,方便跨 feature 回归。
41
+ 同一接口在需求 A 和需求 B 下有独立 .bru:
42
+ - 需求 A 跑 A 时的 .bru(`docs/bruno/<服务>/<需求A前缀>/<接口名>/...`)
43
+ - 需求 B 跑 B 时的 .bru(`docs/bruno/<服务>/<需求B前缀>/<接口名>/...`)
44
+ - 两份独立保留,数据互不干扰——每份都按对应需求的 spec + DB 重新取数据生成
40
45
 
41
- ## feature 同接口同场景覆盖
46
+ **为什么这么设计**:之前"接口跨 feature 复用,后跑覆盖"在加了需求层后没意义(需求 A 的 .bru 在 A 目录下,不会跑到 B 目录)。需求层的目的就是按需求隔离数据。
42
47
 
43
- 不同 feature 测同一接口的同一场景时,**后跑的覆盖先跑的 .bru**。
48
+ ## 通用接口独立
44
49
 
45
- 理由:测哪个需求就从当前需求 spec + DB 重新取数据,不保留历史入参(历史入参会过时,留着误导)。
46
-
47
- **例外**:docs 段的"关联需求"列表**不覆盖**,而是去重追加——记录该接口关联过哪些 feature,供 `/run-api-test` 反查。
50
+ 通用接口(登录、token 刷新、健康检查、公共字典等)放 `docs/bruno/common/<接口名>/`,**不绑需求**——这些接口跨所有需求复用,不应该每个需求一份。
48
51
 
49
52
  ## 不生成 per-folder collection.bru
50
53
 
@@ -76,6 +79,12 @@ bruno 的 folder 不需要 `collection.bru`,只在 `docs/bruno/` 根级有一个
76
79
 
77
80
  不报错,不需要用户手动准备。
78
81
 
82
+ ## 找接口的方式
83
+
84
+ **按需求找**:直接进 `docs/bruno/<服务>/<需求前缀>/`,该需求所有接口都在里面。
85
+
86
+ **按接口找(跨需求)**:扫 `docs/bruno/<服务>/*/` 下所有以 `<接口名>` 命名的子目录,看哪些需求测过该接口——这就是 `/run-api-test` 只指定接口时反查所属需求的方式。
87
+
79
88
  ## 与测试规格文档的契约
80
89
 
81
- 测试规格 §5 接口映射里的路径必须与实际落盘路径**一一对应**,否则下游 `/run-api-test` R1 拿到 .bru 清单后会报"对应 .bru 缺失"。
90
+ 测试规格 §5 接口映射里的路径必须与实际落盘路径**一一对应**,否则下游 `/run-api-test` R1 拿到 .bru 清单后会报"对应 .bru 缺失"。
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/dbquery/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4GzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqGzD"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/dbquery/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyHzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4GzD"}
@@ -21,6 +21,7 @@ exports.registerDbCommands = registerDbCommands;
21
21
  const node_path_1 = __importDefault(require("node:path"));
22
22
  const index_1 = require("./index");
23
23
  const init_1 = require("./init");
24
+ const identifiers_1 = require("./identifiers");
24
25
  function parseFormat(s) {
25
26
  if (!s || s === 'json')
26
27
  return 'json';
@@ -75,8 +76,16 @@ function outputQueryResult(result, format) {
75
76
  }
76
77
  }
77
78
  }
78
- function outputSchemaResult(result, format) {
79
- // For schema results, json is the only first-class format; table/csv
79
+ function outputSchemaResult(result, mode, format) {
80
+ if (mode === 'ddl' && 'ddl' in result) {
81
+ // ddl emits the raw CREATE TABLE DDL text, not JSON.
82
+ if (format !== 'json') {
83
+ process.stderr.write(`[db-query] --format=${format} ignored for ddl output (always DDL text).\n`);
84
+ }
85
+ process.stdout.write(result.ddl + '\n');
86
+ return;
87
+ }
88
+ // For other schema results, json is the only first-class format; table/csv
80
89
  // fall back to json because the shape varies per mode.
81
90
  if (format !== 'json') {
82
91
  process.stderr.write(`[db-query] --format=${format} not supported for schema output; using json.\n`);
@@ -151,8 +160,16 @@ function registerDbCommands(program) {
151
160
  const projectRoot = process.cwd();
152
161
  try {
153
162
  const format = parseFormat(options.format);
163
+ if (mode === 'ddl' && options.table) {
164
+ try {
165
+ (0, identifiers_1.validateIdentifier)(options.table, 'table');
166
+ }
167
+ catch (e) {
168
+ throw new ArgError(e instanceof Error ? e.message : String(e));
169
+ }
170
+ }
154
171
  const result = await (0, index_1.runSchema)({ mode, table: options.table, profile: options.profile }, projectRoot);
155
- outputSchemaResult(result, format);
172
+ outputSchemaResult(result, mode, format);
156
173
  }
157
174
  catch (err) {
158
175
  renderErrorAndExit(err);
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/dbquery/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/dbquery/cli.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/dbquery/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,OAAO,EAGL,oBAAoB,EAErB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,aAAa,EACb,cAAc,EAKf,MAAM,SAAS,CAAC;AAqDjB;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAoD3F;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAiH9F;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAuBrG;AAGD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;AAClG,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/dbquery/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,OAAO,EAGL,oBAAoB,EAErB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EAEZ,aAAa,EACb,cAAc,EAKf,MAAM,SAAS,CAAC;AAqDjB;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAoD3F;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAmG9F;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAuBrG;AAGD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;AAClG,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -148,40 +148,32 @@ async function runSchema(input, projectRoot) {
148
148
  ? await (0, mysql_1.createMysqlConnection)(profile)
149
149
  : await (0, postgres_1.createPostgresConnection)(profile);
150
150
  try {
151
- // For ddl, we need three queries (columns + PK + constraints) merged.
151
+ // ddl: MySQL uses SHOW CREATE TABLE (single query, server-rendered DDL);
152
+ // PG assembles from column query + pg_get_constraintdef + table comment.
152
153
  if (mode === 'ddl') {
153
- let colsRaw, pkRaw, consRaw;
154
+ let result;
154
155
  if (profile.type === 'mysql') {
155
- const colsQ = (0, queries_1.mysqlSchemaQuery)('ddl', table, profile.database);
156
- const pkQ = (0, queries_1.mysqlPrimaryKeySql)(table, profile.database);
157
- const consQ = (0, queries_1.mysqlConstraintsSql)(table, profile.database);
158
- colsRaw = await driver.execute(colsQ.sql, constants_1.QUERY_TIMEOUT_MS, colsQ.params);
159
- pkRaw = await driver.execute(pkQ.sql, constants_1.QUERY_TIMEOUT_MS, pkQ.params);
160
- consRaw = await driver.execute(consQ.sql, constants_1.QUERY_TIMEOUT_MS, consQ.params);
156
+ const showQ = (0, queries_1.mysqlSchemaQuery)('ddl', table, profile.database);
157
+ const raw = await driver.execute(showQ.sql, constants_1.QUERY_TIMEOUT_MS, showQ.params);
158
+ result = (0, format_1.extractMysqlDdl)(raw, table, profile.name, elapsedMs(start));
161
159
  }
162
160
  else {
163
- // PG: ddl SQL is in parametrized already; PK + constraints need extra queries.
164
- colsRaw = await driver.execute(parametrized.sql, constants_1.QUERY_TIMEOUT_MS, parametrized.params);
165
- const regclass = `${profile.schema ?? 'public'}.${table}`;
166
- pkRaw = await driver.execute('SELECT a.attname AS column_name FROM pg_index i ' +
167
- 'JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) ' +
168
- 'WHERE i.indrelid = $1::regclass AND i.indisprimary ' +
169
- 'ORDER BY array_position(i.indkey, a.attnum)', constants_1.QUERY_TIMEOUT_MS, [regclass]);
170
- consRaw = await driver.execute('SELECT c.conname AS name, ' +
171
- 'CASE WHEN c.contype = \'p\' THEN \'PRIMARY KEY\' ' +
172
- 'WHEN c.contype = \'u\' THEN \'UNIQUE\' ' +
173
- 'WHEN c.contype = \'f\' THEN \'FOREIGN KEY\' ' +
174
- 'WHEN c.contype = \'c\' THEN \'CHECK\' ELSE c.contype::text END AS type ' +
175
- 'FROM pg_constraint c WHERE c.conrelid = $1::regclass ORDER BY c.conname', constants_1.QUERY_TIMEOUT_MS, [regclass]);
161
+ const schema = profile.schema ?? 'public';
162
+ const colsRaw = await driver.execute(parametrized.sql, constants_1.QUERY_TIMEOUT_MS, parametrized.params);
163
+ const consQ = (0, queries_1.postgresConstraintDefsSql)(table, schema);
164
+ const consRaw = await driver.execute(consQ.sql, constants_1.QUERY_TIMEOUT_MS, consQ.params);
165
+ const idxQ = (0, queries_1.postgresIndexDefsSql)(table, schema);
166
+ const idxRaw = await driver.execute(idxQ.sql, constants_1.QUERY_TIMEOUT_MS, idxQ.params);
167
+ const tcQ = (0, queries_1.postgresTableCommentSql)(table, schema);
168
+ const tcRaw = await driver.execute(tcQ.sql, constants_1.QUERY_TIMEOUT_MS, tcQ.params);
169
+ result = (0, format_1.renderPostgresDdl)(colsRaw, consRaw, idxRaw, tcRaw, table, schema, profile.name, elapsedMs(start));
176
170
  }
177
- const result = (0, format_1.formatDdlResult)(colsRaw, pkRaw, consRaw, table, profile.name, elapsedMs(start));
178
171
  (0, logging_1.logQuery)(projectRoot, {
179
172
  timestamp: nowIso(),
180
173
  profile: profile.name,
181
174
  mode,
182
175
  sql: parametrized.sql,
183
176
  durationMs: elapsedMs(start),
184
- rowCount: result.columns.length,
185
177
  status: 'ok',
186
178
  });
187
179
  return result;