@devflow-tools/plugin-graphql 0.12.6 → 0.13.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.
@@ -0,0 +1,7 @@
1
+ import type { AnalysisResult } from './types.js';
2
+ export declare function diagnoseBug(input: {
3
+ projectRoot: string;
4
+ errorMessage: string;
5
+ stackTrace?: string;
6
+ }): AnalysisResult;
7
+ //# sourceMappingURL=diagnose-bug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnose-bug.d.ts","sourceRoot":"","sources":["../../src/analyzers/diagnose-bug.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,wBAAgB,WAAW,CAAC,KAAK,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CA+DrH"}
@@ -0,0 +1,80 @@
1
+ import { readFileSync } from 'fs';
2
+ import { readdirSync, statSync } from 'fs';
3
+ import { join, relative } from 'path';
4
+ export function diagnoseBug(input) {
5
+ const { projectRoot, errorMessage } = input;
6
+ const rootCauses = [];
7
+ const files = scanProjectFiles(projectRoot);
8
+ for (const file of files) {
9
+ const content = readFileSync(file, 'utf-8');
10
+ const relPath = relative(projectRoot, file);
11
+ const lines = content.split('\n');
12
+ // Check for N+1 queries (field resolvers without DataLoader)
13
+ if (/Cannot return null for non-nullable/.test(errorMessage)) {
14
+ for (let i = 0; i < lines.length; i++) {
15
+ if (/@Resolver|@Query|@Mutation|@FieldResolver/.test(lines[i])) {
16
+ rootCauses.push({
17
+ probability: 'medium',
18
+ description: 'Resolver 可能返回 null 给 non-nullable 字段',
19
+ file: relPath,
20
+ line: i + 1,
21
+ fix: '检查数据源,确保 non-nullable 字段不返回 null',
22
+ });
23
+ }
24
+ }
25
+ }
26
+ // Check for missing await
27
+ for (let i = 0; i < lines.length; i++) {
28
+ if (/async\s+\w+\(/.test(lines[i])) {
29
+ const nextLines = lines.slice(i + 1, i + 10).join('\n');
30
+ if (/\.findMany|\.findFirst|\.find/.test(nextLines) && !/await/.test(nextLines)) {
31
+ rootCauses.push({
32
+ probability: 'high',
33
+ description: 'async resolver 中可能缺少 await',
34
+ file: relPath,
35
+ line: i + 1,
36
+ fix: '在数据库查询前添加 await',
37
+ });
38
+ }
39
+ }
40
+ }
41
+ }
42
+ return {
43
+ success: true,
44
+ summary: `分析错误 "${errorMessage.substring(0, 50)}...",发现 ${rootCauses.length} 个可能原因`,
45
+ data: { rootCauses },
46
+ findings: rootCauses.map(rc => ({
47
+ severity: rc.probability === 'high' ? 'critical' : 'warning',
48
+ category: 'bug-root-cause',
49
+ title: rc.description,
50
+ description: rc.evidence ?? rc.description,
51
+ file: rc.file,
52
+ line: rc.line,
53
+ suggestion: rc.fix,
54
+ })),
55
+ };
56
+ }
57
+ function scanProjectFiles(root) {
58
+ const files = [];
59
+ function walk(dir) {
60
+ try {
61
+ for (const entry of readdirSync(dir)) {
62
+ if (['node_modules', 'dist', 'build', '.git'].includes(entry))
63
+ continue;
64
+ const fullPath = join(dir, entry);
65
+ try {
66
+ const stat = statSync(fullPath);
67
+ if (stat.isDirectory())
68
+ walk(fullPath);
69
+ else if (/\.(tsx?|graphql|gql)$/.test(entry))
70
+ files.push(fullPath);
71
+ }
72
+ catch { }
73
+ }
74
+ }
75
+ catch { }
76
+ }
77
+ walk(root);
78
+ return files;
79
+ }
80
+ //# sourceMappingURL=diagnose-bug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnose-bug.js","sourceRoot":"","sources":["../../src/analyzers/diagnose-bug.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface AnalysisResult {
2
+ success: boolean;
3
+ summary: string;
4
+ findings?: Finding[];
5
+ metrics?: Record<string, number | string>;
6
+ data?: unknown;
7
+ error?: string;
8
+ }
9
+ export interface Finding {
10
+ severity: 'critical' | 'warning' | 'info' | 'suggestion';
11
+ category: string;
12
+ title: string;
13
+ description: string;
14
+ file?: string;
15
+ line?: number;
16
+ suggestion?: string;
17
+ codeSnippet?: string;
18
+ }
19
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analyzers/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,CAAC;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/analyzers/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { DevFlowPlugin } from "@devflow-tools/sdk";
2
+ export declare const graphqlPlugin: DevFlowPlugin;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,eAAO,MAAM,aAAa,EAAE,aAohC3B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,1038 @@
1
+ export const graphqlPlugin = {
2
+ meta: {
3
+ name: "graphql",
4
+ version: "0.1.0",
5
+ description: "GraphQL 专家 — Schema 设计、N+1 检测、Resolver 优化、安全审计",
6
+ icon: "◈",
7
+ tags: ["backend", "graphql", "apollo", "api", "schema"],
8
+ },
9
+ knowledge: {
10
+ sources: [
11
+ {
12
+ name: "graphql-docs",
13
+ urls: [
14
+ "https://graphql.org/learn/",
15
+ "https://www.apollographql.com/docs/apollo-server/",
16
+ "https://graphql.org/learn/schema/",
17
+ ],
18
+ pluginName: "graphql",
19
+ version: "2024",
20
+ },
21
+ ],
22
+ },
23
+ memory: {
24
+ project: {
25
+ stack: ["GraphQL", "Apollo Server", "TypeGraphQL", "DataLoader"],
26
+ conventions: [
27
+ { key: "schema", value: "Schema-first 设计,使用 SDL 定义类型和操作", source: "manual", confidence: 0.9 },
28
+ { key: "resolvers", value: "Resolver 保持简洁,业务逻辑在 Service 层", source: "manual", confidence: 0.9 },
29
+ { key: "n+1", value: "使用 DataLoader 解决 N+1 查询问题", source: "manual", confidence: 0.95 },
30
+ { key: "errors", value: "使用 Union Types 或自定义 Error Type 处理错误", source: "manual", confidence: 0.8 },
31
+ ],
32
+ },
33
+ global: [
34
+ {
35
+ id: "graphql:schema-design",
36
+ source: "graphql",
37
+ title: "Schema 设计原则",
38
+ content: "Type 设计面向 UI 需求而非数据库结构。使用 Connection 模式实现分页。Mutation 命名使用动词。字段可以为 null 除非明确 Non-Null。Input Types 用于 Mutation 参数。",
39
+ embedding: [],
40
+ },
41
+ {
42
+ id: "graphql:n+1-solution",
43
+ source: "graphql",
44
+ title: "N+1 问题与 DataLoader",
45
+ content: "DataLoader 将多个单独的数据请求合并为一个批量请求。每个请求创建新的 DataLoader 实例。使用 cacheKeyFn 自定义缓存键。通过 prime() 方法手动填充缓存。",
46
+ embedding: [],
47
+ },
48
+ {
49
+ id: "graphql:security",
50
+ source: "graphql",
51
+ title: "GraphQL 安全策略",
52
+ content: "限制查询深度防止嵌套攻击。限制查询复杂度(cost analysis)。限制列表长度。使用 Persisted Queries 防止任意查询。速率限制基于用户或 IP。",
53
+ embedding: [],
54
+ },
55
+ {
56
+ id: "graphql:resolver-patterns",
57
+ source: "graphql",
58
+ title: "Resolver 设计模式",
59
+ content: "Resolver 链:Parent → Field Resolver 逐层解析。使用 info 参数获取查询字段选择。顶层 Resolver 处理 Query/Mutation,字段级 Resolver 处理嵌套关系。",
60
+ embedding: [],
61
+ },
62
+ ],
63
+ },
64
+ workflow: {
65
+ steps: [],
66
+ templates: [
67
+ // ── 新建 GraphQL Type + Resolver + DataLoader ──
68
+ {
69
+ name: "new-type",
70
+ description: "新建 GraphQL Type + Resolver + DataLoader",
71
+ version: "2.0.0",
72
+ steps: [
73
+ {
74
+ id: "analyze-ui-needs",
75
+ title: "分析前端 UI 字段需求",
76
+ instruction: [
77
+ "## 分析前端 UI 字段需求",
78
+ "",
79
+ "Schema 设计应当面向 UI 需求而非数据库结构。先弄清前端需要哪些字段,再反推 Schema。",
80
+ "",
81
+ "**执行动作**:",
82
+ "1. 列出目标页面 / 组件,并收集其数据需求(字段、列表、筛选、排序)",
83
+ "2. 扫描前端代码以确认字段使用模式:",
84
+ " ```bash",
85
+ " grep -rn 'query\\|useQuery\\|gql' src/ --include='*.tsx' --include='*.ts' | head -30",
86
+ " ```",
87
+ "3. 识别以下需求维度:",
88
+ " - **单对象查询**(如 `user(id: ID!)`)",
89
+ " - **列表查询**(是否分页?筛选?排序?)",
90
+ " - **Mutation 操作**(Create / Update / Delete)",
91
+ " - **实时订阅**(是否需要 Subscription?)",
92
+ "4. 绘制字段 → UI 组件映射表",
93
+ "5. 记录字段类型(Scalar / Enum / 嵌套 Type)",
94
+ "",
95
+ "**产出格式**:",
96
+ "```",
97
+ "ui_components: [{ name, data_requirements: ['field1', 'field2'] }]",
98
+ "queries_needed: [{ name, args, return_type }]",
99
+ "mutations_needed: [{ name, input_type, return_type }]",
100
+ "subscriptions_needed: []",
101
+ "field_type_map: { field_name: 'Scalar | Enum | NestedType' }",
102
+ "```",
103
+ ].join("\n"),
104
+ suggestedTools: ["Read", "Bash"],
105
+ output: "前端 UI 字段需求清单、Query/Mutation 设计草案",
106
+ },
107
+ {
108
+ id: "define-type",
109
+ title: "定义 Type、Query、Mutation(SDL)",
110
+ instruction: [
111
+ "## 在 Schema 中定义 Type、Query、Mutation",
112
+ "",
113
+ "基于 `analyze-ui-needs` 的需求,使用 SDL 编写 GraphQL Schema。",
114
+ "",
115
+ "**执行动作**:",
116
+ "1. 定义 Object Type:",
117
+ " - 字段命名使用 camelCase",
118
+ " - 字段可空性遵循\"默认 nullable\"原则,只有当业务明确保证非空时使用 `!`",
119
+ " - ID 字段使用 `ID!` 类型",
120
+ "2. 定义 Query 入口:",
121
+ " - 单对象查询:`user(id: ID!): User`",
122
+ " - 列表查询使用 Connection 模式:`users(first: Int, after: String): UserConnection!`",
123
+ "3. 定义 Mutation 入口:",
124
+ " - Mutation 命名使用动词(`createUser`、`updateUser`、`deleteUser`)",
125
+ " - Mutation 返回 Union Type 或自定义 Result Type 处理错误",
126
+ "4. 定义 Enum 类型用于有限值集合",
127
+ "5. 为每个字段 / 操作添加描述:",
128
+ " ```graphql",
129
+ " type User {",
130
+ " \"\"\"用户唯一标识\"\"\"",
131
+ " id: ID!",
132
+ " \"\"\"用户显示名称\"\"\"",
133
+ " name: String!",
134
+ " }",
135
+ " ```",
136
+ "6. 将 SDL 写入对应文件(如 `schema/types/user.graphql` 或 TypeGraphQL class)",
137
+ "",
138
+ "**产出格式**:",
139
+ "```graphql",
140
+ "type User {",
141
+ " id: ID!",
142
+ " name: String!",
143
+ " email: String",
144
+ " posts(first: Int, after: String): PostConnection!",
145
+ "}",
146
+ "",
147
+ "type Query {",
148
+ " user(id: ID!): User",
149
+ " users(first: Int, after: String): UserConnection!",
150
+ "}",
151
+ "",
152
+ "type Mutation {",
153
+ " createUser(input: CreateUserInput!): CreateUserResult!",
154
+ "}",
155
+ "```",
156
+ ].join("\n"),
157
+ suggestedTools: ["Read", "Write", "Edit"],
158
+ output: "SDL Type + Query + Mutation 定义",
159
+ depends: ["analyze-ui-needs"],
160
+ },
161
+ {
162
+ id: "define-inputs",
163
+ title: "定义 Input Types",
164
+ instruction: [
165
+ "## 定义 Input Types(创建 / 更新操作的参数)",
166
+ "",
167
+ "Mutation 的参数必须使用 Input Types,不要直接散列多个参数。",
168
+ "",
169
+ "**执行动作**:",
170
+ "1. 为每个 Mutation 定义 Input Type:",
171
+ " - 命名规范:`<Action><Type>Input`(如 `CreateUserInput`)",
172
+ " - 必填字段使用 `!` 标记",
173
+ " - 可选字段使用 nullable",
174
+ "2. 对于更新操作,所有字段都应为可选(支持部分更新):",
175
+ " ```graphql",
176
+ " input UpdateUserInput {",
177
+ " name: String",
178
+ " email: String",
179
+ " }",
180
+ " ```",
181
+ "3. 对于 Create/Update 返回结果,定义 Result Union Type:",
182
+ " ```graphql",
183
+ " union CreateUserResult = CreateUserSuccess | CreateUserError",
184
+ " type CreateUserSuccess { user: User! }",
185
+ " type CreateUserError { code: CreateUserErrorCode! message: String! }",
186
+ " enum CreateUserErrorCode { EMAIL_TAKEN INVALID_INPUT }",
187
+ " ```",
188
+ "4. 将 Input Types 写入 Schema 文件",
189
+ "",
190
+ "**产出格式**:",
191
+ "```graphql",
192
+ "input CreateUserInput {",
193
+ " name: String!",
194
+ " email: String!",
195
+ "}",
196
+ "",
197
+ "union CreateUserResult = CreateUserSuccess | CreateUserError",
198
+ "```",
199
+ ].join("\n"),
200
+ suggestedTools: ["Read", "Write", "Edit"],
201
+ output: "Input Types 和 Result Union Types 定义",
202
+ depends: ["define-type"],
203
+ },
204
+ {
205
+ id: "create-resolver",
206
+ title: "实现 Resolver 函数",
207
+ instruction: [
208
+ "## 实现 Resolver 函数",
209
+ "",
210
+ "Resolver 遵循 Parent → Field Resolver 的逐层解析模式。",
211
+ "",
212
+ "**执行动作**:",
213
+ "1. 为 Query / Mutation 实现顶层 Resolver:",
214
+ " - 顶层 Resolver 负责接收参数、调用 Service 层、返回数据",
215
+ " - 保持 Resolver 简洁,业务逻辑放在 Service 层",
216
+ "2. 为嵌套字段实现字段级 Resolver(如 `User.posts`):",
217
+ " - 字段 Resolver 签名:`(parent, args, context, info) => ...`",
218
+ " - 使用 `parent.id` 作为关联查询的 key",
219
+ "3. 对于 Apollo Server,Resolver Map 结构:",
220
+ " ```typescript",
221
+ " export const resolvers = {",
222
+ " Query: {",
223
+ " user: (_, { id }, { dataSources }) => dataSources.userAPI.getUser(id),",
224
+ " },",
225
+ " User: {",
226
+ " posts: (parent, args, { dataSources }) =>",
227
+ " dataSources.postAPI.getPostsByUser(parent.id, args),",
228
+ " },",
229
+ " };",
230
+ " ```",
231
+ "4. 对于 TypeGraphQL,使用装饰器:",
232
+ " ```typescript",
233
+ " @Resolver(() => User)",
234
+ " export class UserResolver {",
235
+ " @Query(() => User, { nullable: true })",
236
+ " user(@Arg('id') id: string) { ... }",
237
+ "",
238
+ " @FieldResolver(() => [Post])",
239
+ " posts(@Root() user: User) { ... }",
240
+ " }",
241
+ " ```",
242
+ "5. 将 Resolver 文件放置在 `resolvers/<type>.resolver.ts`",
243
+ "",
244
+ "**产出格式**:",
245
+ "```",
246
+ "resolvers_created: [{ file, queries: [...], mutations: [...], field_resolvers: [...] }]",
247
+ "service_layer_used: true|false",
248
+ "```",
249
+ ].join("\n"),
250
+ suggestedTools: ["Read", "Write", "Edit"],
251
+ output: "Resolver 实现(顶层 + 字段级)",
252
+ depends: ["define-type"],
253
+ },
254
+ {
255
+ id: "add-dataloader",
256
+ title: "添加 DataLoader 批量加载",
257
+ instruction: [
258
+ "## 添加 DataLoader 避免 N+1 查询",
259
+ "",
260
+ "每个关联字段的 Resolver 都应当通过 DataLoader 批量加载数据,避免循环中逐个查询。",
261
+ "",
262
+ "**执行动作**:",
263
+ "1. 为每个关联关系创建 DataLoader:",
264
+ " ```typescript",
265
+ " import DataLoader from 'dataloader';",
266
+ "",
267
+ " export const createPostLoader = () =>",
268
+ " new DataLoader<string, Post[]>(async (userIds) => {",
269
+ " const posts = await db.post.findMany({",
270
+ " where: { authorId: { in: userIds as string[] } },",
271
+ " });",
272
+ " // 按 userId 分组",
273
+ " const grouped = new Map<string, Post[]>();",
274
+ " for (const userId of userIds) grouped.set(userId, []);",
275
+ " for (const post of posts) grouped.get(post.authorId)?.push(post);",
276
+ " return userIds.map((id) => grouped.get(id) ?? []);",
277
+ " });",
278
+ " ```",
279
+ "2. 在 Context 中创建 DataLoader 实例(每个请求一个):",
280
+ " ```typescript",
281
+ " const context = () => ({",
282
+ " loaders: {",
283
+ " postsByUser: createPostLoader(),",
284
+ " userById: createUserLoader(),",
285
+ " },",
286
+ " });",
287
+ " ```",
288
+ "3. 在字段 Resolver 中使用 DataLoader:",
289
+ " ```typescript",
290
+ " posts: (parent, args, context) => context.loaders.postsByUser.load(parent.id),",
291
+ " ```",
292
+ "4. 注意 DataLoader 的 `batchLoadFn` 必须返回与 keys 数组长度相同的结果数组",
293
+ "5. 使用 `cacheKeyFn` 自定义缓存键(如 Date 对象转为字符串)",
294
+ "",
295
+ "**产出格式**:",
296
+ "```",
297
+ "dataloaders_created: [{ name, file, batch_key, return_type }]",
298
+ "context_integration: true|false",
299
+ "```",
300
+ ].join("\n"),
301
+ suggestedTools: ["Read", "Write", "Edit"],
302
+ output: "DataLoader 实现与 Context 集成",
303
+ depends: ["create-resolver"],
304
+ },
305
+ {
306
+ id: "add-auth",
307
+ title: "添加字段级权限控制",
308
+ instruction: [
309
+ "## 添加字段级权限控制",
310
+ "",
311
+ "GraphQL 的权限控制应在 Resolver 层实现,结合 Context 中的用户信息。",
312
+ "",
313
+ "**执行动作**:",
314
+ "1. 在 Resolver 中检查用户权限:",
315
+ " ```typescript",
316
+ " user: (_, { id }, context) => {",
317
+ " if (!context.user) throw new AuthenticationError('未登录');",
318
+ " if (context.user.role !== 'ADMIN' && context.user.id !== id) {",
319
+ " throw new ForbiddenError('无权查看');",
320
+ " }",
321
+ " return context.loaders.userById.load(id);",
322
+ " }",
323
+ " ```",
324
+ "2. 对于 Mutation,验证用户对目标资源的所有权或管理员权限",
325
+ "3. 字段级权限(敏感字段如 email)使用 middleware 或字段 Resolver 检查",
326
+ "4. 使用 GraphQL Shield(或类似库)定义权限规则:",
327
+ " ```typescript",
328
+ " const permissions = shield({",
329
+ " Query: { user: isAuthenticated },",
330
+ " Mutation: { deleteUser: isAdmin },",
331
+ " User: { email: isOwner },",
332
+ " });",
333
+ " ```",
334
+ "5. 将权限规则放置在 `permissions.ts` 文件中",
335
+ "",
336
+ "**产出格式**:",
337
+ "```",
338
+ "auth_rules: [{ operation, rule: 'isAuthenticated|isOwner|isAdmin', reason }]",
339
+ "middleware_applied: true|false",
340
+ "```",
341
+ ].join("\n"),
342
+ suggestedTools: ["Read", "Write", "Edit"],
343
+ output: "字段级权限规则与中间件",
344
+ depends: ["create-resolver"],
345
+ },
346
+ { id: "type-check", stepTemplate: "type-check", depends: ["create-resolver", "define-inputs"] },
347
+ { id: "integration-test", stepTemplate: "run-tests", depends: ["type-check"] },
348
+ ],
349
+ triggers: [
350
+ { type: "cli", command: "new:type" },
351
+ { type: "mcp", tool: "new_graphql_type" },
352
+ ],
353
+ },
354
+ // ── N+1 检测与修复 ──
355
+ {
356
+ name: "n+1-detect",
357
+ description: "N+1 检测与修复:扫描 Resolver → 识别批量模式 → 加 DataLoader",
358
+ version: "2.0.0",
359
+ steps: [
360
+ { id: "scan-resolvers", stepTemplate: "scan-resolvers" },
361
+ {
362
+ id: "detect-n+1",
363
+ title: "检测潜在的 N+1 查询模式",
364
+ instruction: [
365
+ "## 检测 N+1 查询模式",
366
+ "",
367
+ "基于 `scan-resolvers` 的 Resolver 列表,识别循环中逐个查询数据库的 N+1 模式。",
368
+ "",
369
+ "**N+1 特征模式**:",
370
+ "1. 在列表字段的 Resolver 中,对每个父元素单独查询关联数据",
371
+ "2. 代码中出现 `for (const item of items) { await db.xxx(item.id) }`",
372
+ "3. `.map` 中执行异步查询",
373
+ "",
374
+ "**执行动作**:",
375
+ "1. 检查字段 Resolver 中是否有循环 + 数据库查询:",
376
+ " ```bash",
377
+ " grep -rn 'for.*await\\|\\.map.*await\\|for.*db\\.\\|\\.map.*db\\.' src/ --include='*.ts' -B 2 -A 3 | head -50",
378
+ " ```",
379
+ "2. 检查是否在列表 Resolver 内调用了 Service 层方法(可能隐含循环查询):",
380
+ " ```bash",
381
+ " grep -rn 'FieldResolver\\|@ResolveField' src/ --include='*.ts' -A 10 | head -50",
382
+ " ```",
383
+ "3. 检查 DataLoader 使用情况:",
384
+ " ```bash",
385
+ " grep -rn 'DataLoader\\|dataloader\\|new DataLoader' src/ --include='*.ts'",
386
+ " ```",
387
+ "4. 标记所有未使用 DataLoader 的关联字段为 N+1 风险",
388
+ "5. 对每个风险点标注严重等级(Critical / Warning)",
389
+ "",
390
+ "**产出格式**:",
391
+ "```",
392
+ "n+1_risks: [",
393
+ " { file, line, resolver_name, parent_type, field_name, severity: 'critical'|'warning',",
394
+ " pattern: '循环查询|map 查询|串行 await', estimated_calls: N }",
395
+ "]",
396
+ "dataloader_coverage: { covered_fields: N, uncovered_fields: N }",
397
+ "```",
398
+ ].join("\n"),
399
+ suggestedTools: ["Bash", "Read"],
400
+ output: "N+1 风险清单(位置、模式、严重等级)",
401
+ depends: ["scan-resolvers"],
402
+ },
403
+ {
404
+ id: "measure-impact",
405
+ title: "评估 N+1 问题的性能影响",
406
+ instruction: [
407
+ "## 评估 N+1 问题的性能影响",
408
+ "",
409
+ "量化每个 N+1 风险在实际场景下会产生的查询次数和延迟。",
410
+ "",
411
+ "**执行动作**:",
412
+ "1. 对每个 N+1 风险,估算查询次数:",
413
+ " - 列表平均长度(如 `users` 列表 50 条)",
414
+ " - 每条触发 1 次关联查询 → 总计 50 次查询",
415
+ "2. 估算单查询延迟(参考 ORM 文档 / 历史日志):",
416
+ " - 假设单查询 5ms,则 50 次串行 = 250ms",
417
+ "3. 对比使用 DataLoader 后的查询次数:",
418
+ " - 批量查询:1 次 IN 查询 ≈ 10ms",
419
+ "4. 计算优化倍数和延迟节省",
420
+ "5. 按性能收益排序优化优先级",
421
+ "",
422
+ "**产出格式**:",
423
+ "```",
424
+ "impact_analysis: [",
425
+ " { resolver, list_size: N, queries_before: N, queries_after: 1,",
426
+ " latency_before_ms: N, latency_after_ms: N, speedup: Nx, priority: 'P0'|'P1'|'P2' }",
427
+ "]",
428
+ "total_queries_saved_per_request: N",
429
+ "```",
430
+ ].join("\n"),
431
+ suggestedTools: ["Read", "Bash"],
432
+ output: "N+1 性能影响量化报告",
433
+ depends: ["detect-n+1"],
434
+ },
435
+ {
436
+ id: "create-dataloaders",
437
+ title: "创建 DataLoader 实例",
438
+ instruction: [
439
+ "## 为每个 N+1 模式创建对应的 DataLoader",
440
+ "",
441
+ "基于 `detect-n+1` 识别的所有风险,创建对应的 DataLoader。",
442
+ "",
443
+ "**执行动作**:",
444
+ "1. 对每个 N+1 模式,设计对应的 DataLoader:",
445
+ " - `postsByUser` → key: userId, batch: `WHERE authorId IN (...)`",
446
+ " - `commentsByPost` → key: postId, batch: `WHERE postId IN (...)`",
447
+ " - `userById` → key: userId, batch: `WHERE id IN (...)`",
448
+ "2. 编写 batch 函数:",
449
+ " - 使用 `IN (...)` 或 `ANY(...)` 查询一次性加载所有",
450
+ " - 返回数组必须与 keys 数组长度相同、顺序对应",
451
+ " - 对缺失值返回 `null`(单值)或 `[]`(列表)",
452
+ "3. 在 Context 工厂函数中创建 DataLoader 实例(每请求一个新实例):",
453
+ " ```typescript",
454
+ " export const createContext = () => ({",
455
+ " loaders: {",
456
+ " postsByUser: createPostsByUserLoader(),",
457
+ " userById: createUserByIdLoader(),",
458
+ " },",
459
+ " });",
460
+ " ```",
461
+ "4. 放置 DataLoader 文件在 `dataloaders/` 目录",
462
+ "",
463
+ "**产出格式**:",
464
+ "```",
465
+ "dataloaders_created: [",
466
+ " { name, file, key_type, batch_query, return_type }",
467
+ "]",
468
+ "context_file: src/context.ts",
469
+ "```",
470
+ ].join("\n"),
471
+ suggestedTools: ["Read", "Write", "Edit"],
472
+ output: "DataLoader 实现清单",
473
+ depends: ["detect-n+1"],
474
+ },
475
+ {
476
+ id: "refactor-resolvers",
477
+ title: "重构 Resolver 使用 DataLoader",
478
+ instruction: [
479
+ "## 重构 Resolver 使用 DataLoader 批量加载",
480
+ "",
481
+ "将 `detect-n+1` 识别的 N+1 字段,从循环查询改为 DataLoader 调用。",
482
+ "",
483
+ "**执行动作**:",
484
+ "1. 对每个 N+1 字段,使用 Edit 工具精准修改 Resolver:",
485
+ " - 旧代码:",
486
+ " ```typescript",
487
+ " posts: async (parent) => {",
488
+ " return await db.post.findMany({ where: { authorId: parent.id } });",
489
+ " }",
490
+ " ```",
491
+ " - 新代码:",
492
+ " ```typescript",
493
+ " posts: (parent, _, context) => context.loaders.postsByUser.load(parent.id),",
494
+ " ```",
495
+ "2. 在字段级 Resolver 列表中批量替换",
496
+ "3. 确保所有相关 Resolver 的 context 类型包含 `loaders` 字段",
497
+ "4. 更新 Context 类型定义:",
498
+ " ```typescript",
499
+ " interface GraphQLContext {",
500
+ " user?: User;",
501
+ " loaders: {",
502
+ " postsByUser: DataLoader<string, Post[]>;",
503
+ " userById: DataLoader<string, User>;",
504
+ " };",
505
+ " }",
506
+ " ```",
507
+ "5. 不修改不涉及 N+1 的 Resolver",
508
+ "",
509
+ "**产出格式**:",
510
+ "```",
511
+ "resolvers_refactored: [{ file, field, old_pattern, new_pattern }]",
512
+ "context_type_updated: true|false",
513
+ "```",
514
+ ].join("\n"),
515
+ suggestedTools: ["Read", "Edit"],
516
+ output: "重构后的 Resolver 清单",
517
+ depends: ["create-dataloaders"],
518
+ },
519
+ {
520
+ id: "benchmark",
521
+ title: "对比优化前后的查询次数和响应时间",
522
+ instruction: [
523
+ "## 对比优化前后的查询次数和响应时间",
524
+ "",
525
+ "验证 DataLoader 重构确实减少了数据库查询。",
526
+ "",
527
+ "**执行动作**:",
528
+ "1. 运行 TypeScript 类型检查确保重构无类型错误:",
529
+ " ```bash",
530
+ " npx tsc --noEmit",
531
+ " ```",
532
+ "2. 运行集成测试验证功能未破坏:",
533
+ " ```bash",
534
+ " npm test 2>&1",
535
+ " ```",
536
+ "3. 如果项目有 Apollo Server 的查询日志插件,对比优化前后的查询次数:",
537
+ " ```bash",
538
+ " grep -rn 'willSendResponse\\|requestDidStart\\|plugins' src/ --include='*.ts' | head -20",
539
+ " ```",
540
+ "4. 使用 GraphiQL / Apollo Sandbox 手动测试典型查询并观察耗时",
541
+ "5. 统计 DataLoader 命中缓存的次数",
542
+ "",
543
+ "**产出格式**:",
544
+ "```",
545
+ "type_check: passed | failed",
546
+ "tests: passed | failed",
547
+ "query_count_before: N",
548
+ "query_count_after: N",
549
+ "latency_before_ms: N",
550
+ "latency_after_ms: N",
551
+ "speedup: Nx",
552
+ "```",
553
+ ].join("\n"),
554
+ suggestedTools: ["Bash", "Read"],
555
+ output: "优化前后性能对比数据",
556
+ depends: ["refactor-resolvers"],
557
+ },
558
+ ],
559
+ triggers: [{ type: "cli", command: "fix:n+1" }],
560
+ },
561
+ // ── Schema 设计审查 ──
562
+ {
563
+ name: "schema-review",
564
+ description: "Schema 设计审查:类型设计 → 分页模式 → 安全风险评估",
565
+ version: "2.0.0",
566
+ steps: [
567
+ {
568
+ id: "audit-types",
569
+ title: "审查 Type 设计",
570
+ instruction: [
571
+ "## 审查 Type 设计(字段命名、可空性、嵌套层级)",
572
+ "",
573
+ "**检查项**:",
574
+ "1. **字段命名规范**:",
575
+ " - 使用 camelCase(GraphQL 规范)",
576
+ " - 命名具有业务含义,避免泛化(如 `data`、`info`)",
577
+ " - Boolean 字段使用 `is/has/can` 前缀",
578
+ "2. **可空性合理性**:",
579
+ " - ID 字段应为 `ID!`",
580
+ " - 业务保证非空的字段使用 `!`",
581
+ " - 关联字段是否合理 nullable(如 `user: User` vs `user: User!`)",
582
+ "3. **嵌套层级**:",
583
+ " - 嵌套 >3 层的字段应考虑扁平化或独立 Type",
584
+ "4. **Scalar 使用**:",
585
+ " - 日期字段使用自定义 Scalar(DateTime)而非 String",
586
+ " - URL、Email 使用自定义 Scalar",
587
+ " - Money 使用 Decimal 或自定义 Scalar",
588
+ "5. **描述完整性**:",
589
+ " - 每个 Type 和关键字段是否有 `\"\"\"...\"\"\"` 描述",
590
+ "",
591
+ "**执行动作**:",
592
+ "```bash",
593
+ "grep -rn 'type \\|interface \\|enum \\|union ' src/ --include='*.graphql' --include='*.ts' | head -50",
594
+ "```",
595
+ "",
596
+ "**产出格式**:",
597
+ "```",
598
+ "type_issues: [",
599
+ " { type, field, issue: 'naming|nullable|nesting|scalar|description',",
600
+ " severity: 'critical'|'warning'|'suggestion', fix: '...' }",
601
+ "]",
602
+ "```",
603
+ ].join("\n"),
604
+ suggestedTools: ["Bash", "Read"],
605
+ output: "Type 设计问题清单",
606
+ },
607
+ {
608
+ id: "check-pagination",
609
+ title: "检查分页实现",
610
+ instruction: [
611
+ "## 检查分页实现是否符合 Connection 规范",
612
+ "",
613
+ "GraphQL 官方推荐的列表分页模式是 Relay Connection 规范。",
614
+ "",
615
+ "**Connection 规范要素**:",
616
+ "1. 返回 `XxxConnection` 类型而非裸列表",
617
+ "2. Connection 包含 `edges: [XxxEdge!]!`",
618
+ "3. Edge 包含 `node: Xxx!` 和 `cursor: String!`",
619
+ "4. Connection 包含 `pageInfo: PageInfo!`",
620
+ "5. PageInfo 包含 `hasNextPage!`、`hasPreviousPage!`、`startCursor`、`endCursor`",
621
+ "6. 查询参数使用 `first/after`(向前)和 `last/before`(向后)",
622
+ "",
623
+ "**执行动作**:",
624
+ "```bash",
625
+ "grep -rn 'Connection\\|Edge\\|PageInfo\\|first:\\|after:' src/ --include='*.graphql' --include='*.ts' | head -30",
626
+ "```",
627
+ "",
628
+ "**检查**:",
629
+ "- 所有返回列表的 Query 是否使用 Connection 模式?",
630
+ "- 是否有裸列表返回(`[User!]!`)应改为 Connection?",
631
+ "- PageInfo 字段是否完整?",
632
+ "- cursor 是否稳定(基于 ID 而非 index)?",
633
+ "",
634
+ "**产出格式**:",
635
+ "```",
636
+ "pagination_issues: [",
637
+ " { query, current_approach: 'raw-list|offset|cursor',",
638
+ " issue: 'missing-connection|missing-page-info|unstable-cursor', severity: '...' }",
639
+ "]",
640
+ "```",
641
+ ].join("\n"),
642
+ suggestedTools: ["Bash", "Read"],
643
+ output: "分页规范合规性报告",
644
+ },
645
+ {
646
+ id: "check-naming",
647
+ title: "检查 Mutation/Query 命名规范",
648
+ instruction: [
649
+ "## 检查 Mutation/Query 命名规范",
650
+ "",
651
+ "**命名规范**:",
652
+ "1. **Query**:使用资源名或动词 + 资源名",
653
+ " - 单对象:`user`、`post`",
654
+ " - 列表:`users`、`posts`(或 `userConnection`)",
655
+ " - 搜索:`searchUsers`、`findPosts`",
656
+ "2. **Mutation**:使用动词 + 资源名",
657
+ " - 创建:`createUser`、`createPost`",
658
+ " - 更新:`updateUser`、`updatePost`",
659
+ " - 删除:`deleteUser`、`deletePost`",
660
+ " - 动作:`publishPost`、`archiveUser`",
661
+ "3. **避免反模式**:",
662
+ " - ❌ `getUser`(Query 不需要 get 前缀)",
663
+ " - ❌ `setUser`(语义模糊)",
664
+ " - ❌ `userCreate`(动词应在前)",
665
+ " - ❌ `modifyXxx`(使用具体的 create/update/delete)",
666
+ "",
667
+ "**执行动作**:",
668
+ "```bash",
669
+ "grep -rn 'type Query\\|type Mutation' src/ --include='*.graphql' --include='*.ts' -A 30 | head -60",
670
+ "```",
671
+ "",
672
+ "**产出格式**:",
673
+ "```",
674
+ "naming_issues: [",
675
+ " { operation, current_name, issue: 'missing-verb|verb-after-noun|ambiguous',",
676
+ " suggestion: '...' }",
677
+ "]",
678
+ "```",
679
+ ].join("\n"),
680
+ suggestedTools: ["Bash", "Read"],
681
+ output: "命名规范问题清单",
682
+ },
683
+ {
684
+ id: "security-audit",
685
+ title: "安全审计",
686
+ instruction: [
687
+ "## 安全审计(深度限制、复杂度限制、字段级权限)",
688
+ "",
689
+ "**检查项**:",
690
+ "1. **查询深度限制**:",
691
+ " - 是否配置了 `queryDepthLimit`(建议 ≤ 7)",
692
+ " - 防止嵌套攻击:`{ user { posts { author { posts { ... } } } } }`",
693
+ "2. **查询复杂度限制**:",
694
+ " - 是否配置了 `queryComplexity`(cost analysis)",
695
+ " - 每个字段应赋予 cost(默认 1,列表字段更高)",
696
+ "3. **列表长度限制**:",
697
+ " - Connection 查询是否限制 `first` 参数上限(建议 ≤ 100)",
698
+ "4. **字段级权限**:",
699
+ " - 敏感字段(email、phone、password)是否有权限控制",
700
+ " - Mutation 是否验证资源所有权",
701
+ "5. **Persisted Queries**:",
702
+ " - 生产环境是否启用 APQ 或 Persisted Queries 防止任意查询",
703
+ "6. **速率限制**:",
704
+ " - 是否配置基于用户 / IP 的请求速率限制",
705
+ "7. **Introspection**:",
706
+ " - 生产环境是否禁用 Introspection(除非明确需要)",
707
+ "",
708
+ "**执行动作**:",
709
+ "```bash",
710
+ "grep -rn 'depthLimit\\|complexityLimit\\|validationPlugins\\|rateLimit\\|introspection' src/ --include='*.ts' | head -30",
711
+ "```",
712
+ "",
713
+ "**产出格式**:",
714
+ "```",
715
+ "security_issues: [",
716
+ " { category: 'depth|complexity|list-limit|field-auth|persisted-queries|rate-limit|introspection',",
717
+ " severity: 'critical'|'warning'|'suggestion', current_state, recommendation }",
718
+ "]",
719
+ "```",
720
+ ].join("\n"),
721
+ suggestedTools: ["Bash", "Read"],
722
+ output: "安全风险清单(按严重程度)",
723
+ },
724
+ { id: "generate-report", stepTemplate: "generate-report", depends: ["audit-types", "check-pagination", "check-naming", "security-audit"] },
725
+ {
726
+ id: "apply-fixes",
727
+ title: "应用推荐修复",
728
+ instruction: [
729
+ "## 应用推荐修复",
730
+ "",
731
+ "根据 `generate-report` 的 Critical / Warning 项,逐项应用代码修复。",
732
+ "",
733
+ "**执行动作**:",
734
+ "1. **Critical 优先修复**:",
735
+ " - 安全问题(深度限制、速率限制)",
736
+ " - 字段级权限缺失",
737
+ " - N+1 风险",
738
+ "2. **Warning 次优先**:",
739
+ " - 命名规范修正",
740
+ " - 分页模式改为 Connection",
741
+ " - 字段可空性调整",
742
+ "3. **Suggestion 选择性应用**:",
743
+ " - 描述补全",
744
+ " - 自定义 Scalar 替换",
745
+ "4. 使用 Edit 工具精准修改,不做无关重构",
746
+ "5. 修复后运行类型检查和测试",
747
+ "",
748
+ "**产出格式**:",
749
+ "```",
750
+ "fixes_applied: [",
751
+ " { category, file, changes_summary, severity }",
752
+ "]",
753
+ "fixes_skipped: [{ category, reason: '需业务决策|破坏性变更' }]",
754
+ "```",
755
+ ].join("\n"),
756
+ suggestedTools: ["Read", "Edit", "Bash"],
757
+ output: "应用的修复清单",
758
+ depends: ["generate-report"],
759
+ },
760
+ ],
761
+ triggers: [{ type: "cli", command: "review:schema" }],
762
+ },
763
+ // ── GraphQL Bug 诊断 ──
764
+ {
765
+ name: "bug-diagnosis",
766
+ description: "GraphQL Bug 诊断:查询分析 → Resolver 链追踪 → 修复",
767
+ version: "2.0.0",
768
+ steps: [
769
+ {
770
+ id: "capture-query",
771
+ title: "收集出错查询和变量",
772
+ instruction: [
773
+ "## 收集出错查询和变量",
774
+ "",
775
+ "完整记录触发 Bug 的 GraphQL 查询、变量和响应。",
776
+ "",
777
+ "**执行动作**:",
778
+ "1. 复制完整的 GraphQL 查询(包含所有字段选择):",
779
+ " ```graphql",
780
+ " query GetUser($id: ID!) {",
781
+ " user(id: $id) {",
782
+ " id",
783
+ " name",
784
+ " posts { title }",
785
+ " }",
786
+ " }",
787
+ " ```",
788
+ "2. 记录查询变量:`{ \"id\": \"abc123\" }`",
789
+ "3. 复制完整的错误响应:",
790
+ " ```json",
791
+ " {",
792
+ " \"errors\": [{",
793
+ " \"message\": \"Cannot read property 'name' of null\",",
794
+ " \"path\": [\"user\", \"name\"],",
795
+ " \"extensions\": { \"code\": \"INTERNAL_SERVER_ERROR\" }",
796
+ " }],",
797
+ " \"data\": { \"user\": null }",
798
+ " }",
799
+ " ```",
800
+ "4. 记录触发来源(前端组件 / API 调用 / GraphiQL)",
801
+ "5. 记录复现频率(必现 / 偶发)和开始时间",
802
+ "",
803
+ "**产出格式**:",
804
+ "```",
805
+ "query: <完整 GraphQL 查询字符串>",
806
+ "variables: { ... }",
807
+ "error_response: { errors: [...], data: {...} }",
808
+ "error_path: ['user', 'name']",
809
+ "error_code: INTERNAL_SERVER_ERROR | GRAPHQL_VALIDATION_FAILED | ...",
810
+ "reproduction: 'always' | 'intermittent'",
811
+ "```",
812
+ ].join("\n"),
813
+ suggestedTools: ["Read"],
814
+ output: "完整的错误查询、变量、响应、错误路径",
815
+ },
816
+ {
817
+ id: "trace-resolver-chain",
818
+ title: "追踪 Resolver 调用链",
819
+ instruction: [
820
+ "## 追踪 Resolver 调用链(Parent → Field 逐层)",
821
+ "",
822
+ "基于 `capture-query` 的查询结构,沿着 Resolver 链追踪数据流。",
823
+ "",
824
+ "**执行动作**:",
825
+ "1. 解析查询结构,识别 Resolver 链:",
826
+ " - 顶层 Resolver:`Query.user` → 接收 `id` 参数",
827
+ " - 字段 Resolver:`User.posts` → 接收 `parent`(user 对象)",
828
+ "2. 对每个 Resolver,使用 Read 工具查看其实现:",
829
+ " ```bash",
830
+ " grep -rn 'Query:\\|user:\\|posts:' src/ --include='*.ts' | head -20",
831
+ " ```",
832
+ "3. 追踪每一层的数据转换:",
833
+ " - 顶层 Resolver 返回什么数据?",
834
+ " - 字段 Resolver 接收的 `parent` 包含哪些字段?",
835
+ " - 字段 Resolver 是否依赖 parent 中可能缺失的字段?",
836
+ "4. 根据 `error_path` 定位出错的具体 Resolver",
837
+ "5. 标记可疑代码行(解构 undefined、访问 null 属性)",
838
+ "",
839
+ "**产出格式**:",
840
+ "```",
841
+ "resolver_chain: [",
842
+ " { level: 0, operation: 'Query.user', file, line, parent_input: 'args.id' },",
843
+ " { level: 1, operation: 'User.posts', file, line, parent_input: 'parent.id' }",
844
+ "]",
845
+ "error_location: { resolver: 'User.posts', file, line, suspected_cause: '...' }",
846
+ "```",
847
+ ].join("\n"),
848
+ suggestedTools: ["Bash", "Read"],
849
+ output: "Resolver 调用链、错误定位、可疑代码",
850
+ depends: ["capture-query"],
851
+ },
852
+ {
853
+ id: "check-nullability",
854
+ title: "检查字段可空性",
855
+ instruction: [
856
+ "## 检查字段可空性是否导致 Null 传播",
857
+ "",
858
+ "GraphQL 的 Null 传播机制:当非空字段返回 null 时,错误会冒泡到最近的 nullable 父字段。",
859
+ "",
860
+ "**执行动作**:",
861
+ "1. 查看 Schema 中错误路径上每个字段的可空性:",
862
+ " ```bash",
863
+ " grep -rn 'type User\\|name:\\|posts:' src/ --include='*.graphql' --include='*.ts' -A 5 | head -30",
864
+ " ```",
865
+ "2. 分析 Null 传播路径:",
866
+ " - 如果 `User.name!` 返回 null,错误冒泡到 `user` 字段",
867
+ " - 如果 `user: User!` 也非空,错误继续冒泡到 `data`,结果为 `data: null`",
868
+ "3. 检查字段 Resolver 是否在数据缺失时返回 null:",
869
+ " - 数据库查询返回 null 时,Resolver 是否正确处理?",
870
+ " - 关联数据不存在时,是否应该返回 null 而非抛出异常?",
871
+ "4. 评估可空性设计是否合理:",
872
+ " - 业务上可能缺失的字段应当 nullable",
873
+ " - 必须存在的字段保持 non-null,但 Resolver 应有兜底",
874
+ "5. 检查 Union Type 错误处理是否完善",
875
+ "",
876
+ "**产出格式**:",
877
+ "```",
878
+ "nullability_analysis: [",
879
+ " { field_path, schema_type: 'String!|String', resolver_returns_null: true|false,",
880
+ " null_propagation_target: 'user|data', issue: 'unnecessary-non-null|missing-null-handling' }",
881
+ "]",
882
+ "```",
883
+ ].join("\n"),
884
+ suggestedTools: ["Bash", "Read"],
885
+ output: "字段可空性分析与 Null 传播路径",
886
+ depends: ["trace-resolver-chain"],
887
+ },
888
+ {
889
+ id: "check-dataloader",
890
+ title: "检查 DataLoader 批处理",
891
+ instruction: [
892
+ "## 检查 DataLoader 是否正确批处理",
893
+ "",
894
+ "DataLoader 的常见错误会导致数据丢失、顺序错乱或缓存污染。",
895
+ "",
896
+ "**检查项**:",
897
+ "1. **batchLoadFn 返回值顺序**:",
898
+ " - 返回的数组必须与 keys 数组长度相同",
899
+ " - 数组顺序必须与 keys 顺序一一对应",
900
+ "2. **缺失值处理**:",
901
+ " - 单值查找:缺失返回 `null`(不是 `undefined`)",
902
+ " - 列表查找:缺失返回 `[]`",
903
+ "3. **缓存键一致性**:",
904
+ " - 类型相同的 key 应一致(字符串 vs 数字)",
905
+ " - 复杂对象使用 `cacheKeyFn` 序列化",
906
+ "4. **每请求新实例**:",
907
+ " - DataLoader 必须在每个请求的 Context 中创建新实例",
908
+ " - 全局单例会导致跨请求缓存污染",
909
+ "5. **prime() 使用**:",
910
+ " - 当数据已通过其他途径加载时,使用 `prime(id, data)` 预填缓存",
911
+ "",
912
+ "**执行动作**:",
913
+ "```bash",
914
+ "grep -rn 'new DataLoader\\|DataLoader<' src/ --include='*.ts' -A 15 | head -50",
915
+ "```",
916
+ "",
917
+ "**产出格式**:",
918
+ "```",
919
+ "dataloader_issues: [",
920
+ " { loader_name, issue: 'order-mismatch|missing-null|cache-pollution|global-instance',",
921
+ " file, line, fix: '...' }",
922
+ "]",
923
+ "```",
924
+ ].join("\n"),
925
+ suggestedTools: ["Bash", "Read"],
926
+ output: "DataLoader 批处理问题清单",
927
+ depends: ["trace-resolver-chain"],
928
+ },
929
+ {
930
+ id: "search-docs",
931
+ title: "搜索 GraphQL/Apollo 文档",
932
+ instruction: [
933
+ "## 搜索 GraphQL/Apollo 文档",
934
+ "",
935
+ "根据错误类型,查阅 GraphQL 官方文档和项目知识库。",
936
+ "",
937
+ "**执行动作**:",
938
+ "1. 根据错误代码确定搜索方向:",
939
+ " - `GRAPHQL_VALIDATION_FAILED` → 查询语法 / Schema 不匹配",
940
+ " - `INTERNAL_SERVER_ERROR` → Resolver 异常",
941
+ " - `BAD_USER_INPUT` → 参数校验",
942
+ " - `PERSISTED_QUERY_NOT_FOUND` → APQ 配置问题",
943
+ "2. 使用知识库工具查询:",
944
+ " - 调用 `devflow_knowledge_query` 查询项目记忆中的类似问题",
945
+ " - 调用 `devflow_knowledge_search` 查询 GraphQL 文档",
946
+ "3. 关键文档主题:",
947
+ " - [Error handling](https://www.apollographql.com/docs/apollo-server/data/errors/)",
948
+ " - [DataLoader best practices](https://github.com/graphql/dataloader)",
949
+ " - [Schema design](https://graphql.org/learn/schema/)",
950
+ "4. 整理 2-3 条最相关的参考建议",
951
+ "",
952
+ "**产出格式**:",
953
+ "```",
954
+ "knowledge_hits: [",
955
+ " { source: 'graphql-docs|project-memory', title, url, summary }",
956
+ "]",
957
+ "recommended_pattern: <推荐的处理方式>",
958
+ "```",
959
+ ].join("\n"),
960
+ suggestedTools: ["Read", "Bash"],
961
+ output: "相关文档参考和推荐处理模式",
962
+ },
963
+ { id: "generate-fix", stepTemplate: "generate-fix", depends: ["trace-resolver-chain", "check-nullability", "check-dataloader", "search-docs"] },
964
+ {
965
+ id: "test-query",
966
+ title: "用原查询验证修复",
967
+ instruction: [
968
+ "## 用原查询验证修复",
969
+ "",
970
+ "使用触发 Bug 的原始查询验证修复有效且未引入新问题。",
971
+ "",
972
+ "**执行动作**:",
973
+ "1. 运行 TypeScript 类型检查:",
974
+ " ```bash",
975
+ " npx tsc --noEmit",
976
+ " ```",
977
+ "2. 运行集成测试套件:",
978
+ " ```bash",
979
+ " npm test 2>&1",
980
+ " ```",
981
+ "3. 启动本地 GraphQL Server(如有):",
982
+ " ```bash",
983
+ " npm run dev 2>&1 &",
984
+ " ```",
985
+ "4. 使用原查询 + 原变量在 GraphiQL / curl 中测试:",
986
+ " ```bash",
987
+ " curl -X POST http://localhost:4000/graphql \\",
988
+ " -H 'Content-Type: application/json' \\",
989
+ " -d '{\"query\": \"<原查询>\", \"variables\": <原变量>}'",
990
+ " ```",
991
+ "5. 验证响应中:",
992
+ " - `errors` 数组为空或符合预期(业务错误)",
993
+ " - `data` 结构正确",
994
+ "6. 测试边缘情况(缺失数据、无效 ID、权限不足)",
995
+ "",
996
+ "**产出格式**:",
997
+ "```",
998
+ "type_check: passed | failed",
999
+ "tests: passed | failed",
1000
+ "original_query_result: { errors: [], data: {...} }",
1001
+ "edge_cases: [{ input, expected, actual, status: 'ok'|'fail' }]",
1002
+ "fix_verified: true | false",
1003
+ "```",
1004
+ ].join("\n"),
1005
+ suggestedTools: ["Bash", "Read"],
1006
+ output: "修复验证结果(类型检查、测试、原查询复现)",
1007
+ depends: ["generate-fix"],
1008
+ },
1009
+ ],
1010
+ triggers: [
1011
+ { type: "cli", command: "bug" },
1012
+ { type: "mcp", tool: "diagnose_bug" },
1013
+ ],
1014
+ },
1015
+ ],
1016
+ },
1017
+ prompt: {
1018
+ system: "你是一个 GraphQL 专家。使用 Schema-First 设计,Apollo Server 实现。遇到问题先查文档,不凭空猜测。",
1019
+ rules: [
1020
+ "使用 Schema-First 设计(SDL)定义类型和操作",
1021
+ "Resolver 保持简洁,业务逻辑在 Service 层",
1022
+ "使用 DataLoader 解决 N+1 查询问题",
1023
+ "Mutation 命名使用动词(create/update/delete)",
1024
+ "使用 Connection 模式实现分页",
1025
+ "限制查询深度和复杂度防止滥用",
1026
+ "遇到不确定的 Schema 设计时先查 GraphQL 官方规范",
1027
+ ],
1028
+ },
1029
+ tools: [
1030
+ {
1031
+ name: "graphql_diagnose_bug",
1032
+ description: "GraphQL Bug 诊断:查询分析 → Resolver 链追踪 → 修复",
1033
+ inputSchema: { type: "object", properties: { projectRoot: { type: "string" }, errorMessage: { type: "string" }, stackTrace: { type: "string" } }, required: ["projectRoot", "errorMessage"] },
1034
+ handler: async (input) => { const { diagnoseBug } = await import('./analyzers/diagnose-bug.js'); return diagnoseBug(input); },
1035
+ },
1036
+ ],
1037
+ };
1038
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/plugin-graphql",
3
- "version": "0.12.6",
3
+ "version": "0.13.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -26,5 +26,5 @@
26
26
  "files": [
27
27
  "dist"
28
28
  ],
29
- "gitHead": "d544427472016eb332c6c2107f0fc98d8ae59c14"
29
+ "gitHead": "6e5878a1ab2bba3a21bd42a5f7e236d4f7375d4f"
30
30
  }