V

Vendure GraphQL 审查

作者:鹿Sir开发工具v1

审查 Vendure 电商项目的 GraphQL resolver 与 schema 扩展,检查 RequestContext 缺失、权限装饰器遗漏、InputMaybe 处理不当、事务缺失、Shop API 泄露管理端数据等违规与反模式,输出分级审查报告。当用户需要评审 GraphQL 相关 PR、审计 Vendure API 代码质量时触发。触发词:GraphQL 审查、Vendure、resolver 审查、API 质量审计。

下载量
419
点赞
100
价格
免费

技能文档

---
name: meriley-vendure-graphql-reviewing
title: Vendure GraphQL 审查
category: 开发工具
description: 审查 Vendure 电商项目的 GraphQL resolver 与 schema 扩展,检查 RequestContext 缺失、权限装饰器遗漏、InputMaybe 处理不当、事务缺失、Shop API 泄露管理端数据等违规与反模式,输出分级审查报告。当用户需要评审 GraphQL 相关 PR、审计 Vendure API 代码质量时触发。触发词:GraphQL 审查、Vendure、resolver 审查、API 质量审计。
---

# Vendure GraphQL 审查

审计 Vendure 项目的 GraphQL resolver 与 schema 扩展,发现违规写法与反模式。

## 技能工作流

### 步骤1:定位 GraphQL 文件

```bash
# 查找 resolver 文件
find . -name "*.resolver.ts"

# 查找 schema 文件
find . -name "schema.ts" -o -name "*.graphql"
```

### 步骤2:运行自动化检查

```bash
# === 严重违规 ===

# 缺少 @Ctx() RequestContext
grep -rn "@Query\|@Mutation" --include="*.resolver.ts" -A 5 | grep -v "@Ctx()"

# 缺少 @Resolver 装饰器
grep -rn "export class.*Resolver" --include="*.resolver.ts" | grep -v "@Resolver"

# 缺少 @Allow 权限声明
grep -rn "@Query\|@Mutation" --include="*.resolver.ts" -A 3 | grep -v "@Allow"

# === 高优先级 ===

# 直接返回实体(应使用 DTO 或明确的类型)
grep -rn "Promise<.*Entity>" --include="*.resolver.ts"

# Mutation 缺少 @Transaction
grep -rn "@Mutation" --include="*.resolver.ts" -A 2 | grep -v "@Transaction"

# InputMaybe 未正确处理
grep -rn "!== undefined" --include="*.service.ts" | grep -v "&& .* !== null"

# === 中优先级 ===

# 硬编码权限字符串
grep -rn "@Allow(['\"]" --include="*.resolver.ts"

# 缺少错误处理
grep -rn "async.*@Ctx" --include="*.resolver.ts" -A 10 | grep -v "throw\|catch\|try"
```

### 步骤3:人工审查清单

#### Schema

- [ ] 使用 gql 模板字符串
- [ ] 所有 mutation 都有对应的 Input 类型
- [ ] 类型定义规范
- [ ] Admin API 与 Shop API 界限清晰
- [ ] Shop API 中不含敏感字段

#### Resolver

- [ ] 有 @Resolver() 装饰器
- [ ] 所有方法都有 @Ctx() ctx: RequestContext
- [ ] 有 @Allow() 且权限设置恰当
- [ ] mutation 上有 @Transaction()
- [ ] 通过注入 Service 访问数据(不直接操作数据库)

#### 安全

- [ ] Shop API 不暴露管理端数据
- [ ] 用户资源的所有者权限已校验
- [ ] 有输入校验
- [ ] 错误信息不泄露敏感内容

### 步骤4:分级定级

#### 严重(必须修复)

- 缺少 RequestContext 参数
- 没有任何权限装饰器
- Shop API 暴露管理端数据
- resolver 中直接访问数据库

#### 高(应当修复)

- mutation 缺少 @Transaction
- InputMaybe 未正确处理
- 没有错误处理
- 直接返回实体类型

#### 中(建议修复)

- 缺少输入校验
- 错误信息不友好
- 命名不一致

## 常见违规

### 1. 缺少 RequestContext

**违规:**

```typescript
@Query()
@Allow(Permission.ReadSettings)
async myQuery(): Promise<MyEntity[]> {  // 没有 ctx!
  return this.service.findAll();
}
```

**修复:**

```typescript
@Query()
@Allow(Permission.ReadSettings)
async myQuery(@Ctx() ctx: RequestContext): Promise<MyEntity[]> {
  return this.service.findAll(ctx);
}
```

### 2. 缺少权限装饰器

**违规:**

```typescript
@Query()
async myQuery(@Ctx() ctx: RequestContext): Promise<MyEntity[]> {
  // 没有 @Allow —— 任何人都能调用!
  return this.service.findAll(ctx);
}
```

**修复:**

```typescript
@Query()
@Allow(Permission.ReadSettings)  // 显式声明权限
async myQuery(@Ctx() ctx: RequestContext): Promise<MyEntity[]> {
  return this.service.findAll(ctx);
}
```

### 3. InputMaybe 缺陷

**违规:**

```typescript
// 只检查了 undefined,null 会直接穿透!
if (input.name !== undefined) {
  entity.name = input.name;
}
```

**修复:**

```typescript
// 同时检查 undefined 和 null
if (input.name !== undefined && input.name !== null) {
  entity.name = input.name;
}
```

### 4. 缺少事务

**违规:**

```typescript
@Mutation()
@Allow(Permission.UpdateSettings)
async updateData(@Ctx() ctx: RequestContext, @Args() args): Promise<MyEntity> {
  // 没有 @Transaction —— 出错时可能只更新了一半!
  await this.service.updateA(ctx, args);
  await this.service.updateB(ctx, args);  // 这步失败,A 已生效
}
```

**修复:**

```typescript
@Mutation()
@Transaction()  // 原子操作
@Allow(Permission.UpdateSettings)
async updateData(@Ctx() ctx: RequestContext, @Args() args): Promise<MyEntity> {
  await this.service.updateA(ctx, args);
  await this.service.updateB(ctx, args);
}
```

### 5. Shop API 泄露管理端数据

**违规:**

```typescript
// Shop schema
const shopSchema = gql`
  type User {
    id: ID!
    email: String!
    internalNotes: String! # 仅管理端该有的字段被暴露了!
  }
`;
```

**修复:**

```typescript
// Shop schema —— 只保留有限字段
const shopSchema = gql`
  type User {
    id: ID!
    email: String!
    # 排除 internalNotes
  }
`;
```

## 快速体检命令

```bash
# GraphQL 一体化审计
echo "=== CRITICAL: Missing @Ctx ===" && \
grep -rn "@Query\|@Mutation" --include="*.resolver.ts" -A 5 | grep -v "@Ctx" | head -20 && \
echo "" && \
echo "=== HIGH: Missing @Allow ===" && \
grep -rn "@Query\|@Mutation" --include="*.resolver.ts" -A 3 | grep -v "@Allow" | head -20 && \
echo "" && \
echo "=== MEDIUM: InputMaybe issues ===" && \
grep -rn "!== undefined" --include="*.ts" | grep -v "&& .* !== null" | head -20
```

## 审查报告模板

```markdown
## GraphQL 审查报告:[组件名称]

### 总体评价

[GraphQL 代码质量概述]

### 严重问题(必须修复)

- [ ] [问题] - `file:line`

### 高优先级

- [ ] [问题] - `file:line`

### 通过项

- [x] 所有 resolver 均有 @Resolver 装饰器
- [x] RequestContext 传递一致
- [x] 权限均已声明

### 改进建议

- [建议]
```

使用说明

# Vendure GraphQL 审查

审计 Vendure 电商项目的 GraphQL resolver 与 schema 扩展,自动发现 RequestContext 缺失、权限遗漏、事务缺失、数据泄露等违规写法,输出分级审查报告。

## 使用

在 Vendure 项目目录下让 AI 执行审查:

```text
帮我审查这个项目的 GraphQL 层,重点检查 resolver 是否缺少
RequestContext 和权限装饰器,mutation 是否缺少事务。
```

输出包含:严重/高/中三级问题清单(带 file:line 定位)、通过项核对表与改进建议。

## 工作原理

1. 用 find/grep 定位 `*.resolver.ts` 与 schema 文件,批量扫描八类常见违规
2. 按 Schema / Resolver / 安全三张人工清单做逐项核对
3. 按严重程度分级汇总,套用统一报告模板输出

如何安装此技能?

访问技能市场,点击「安装」按钮,按提示将技能包放入 AI 编程助手的 skills 目录即可。

浏览技能市场

支持平台:Qoder · QoderWork · Claude · Codex 等 AI 编程助手