关于 nestjs-code-review
面向 NestJS 项目维护者,提供按严重程度分类的代码审查流程,检查模块组织、依赖注入、控制器、服务、安全与测试,并要求关键发现具备可复现证据。
主要功能
- 01检查模块边界与循环依赖
- 02审查依赖注入和控制器设计
- 03检查服务逻辑与安全实践
- 04评估测试覆盖与模拟方式
- 05按严重程度输出可执行建议
适用场景
- 01合并拉取请求前审查 NestJS 改动
- 02检查控制器和服务实现
- 03验证模块架构与授权模式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ giuseppe-trisciuoglio/ developer-kit --skill nestjs-code-review安装后在 Claude Code 中输入/nestjs-code-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/anti-patterns.mdchecklist.mdpatterns.md详细介绍
NestJS 代码审查
概述
为 NestJS 应用提供结构化代码审查。审查结果按严重程度分类(严重、警告、建议),并附有可执行的改进建议。深度分析由 nestjs-code-review-expert Agent 负责。
适用场景
- “审查 NestJS 代码”、“NestJS 代码审查”、“检查我的 NestJS 控制器/服务”
- 合并拉取请求前或实现新功能后
- 验证 NestJS 装饰器、DI 模式和守卫实现
- 验证 NestJS 模块和提供者的架构
- 审查 DTO、管道、拦截器和数据库集成(TypeORM、Prisma、Drizzle)
使用说明
-
确定范围:确定需要审查的 NestJS 文件和模块。使用
glob和grep查找目标区域内的控制器、服务、模块、守卫、拦截器和管道。 -
分析模块结构:验证模块组织是否恰当——每个功能都应有自己的模块,并明确列出导入项、控制器、提供者和导出项。检查是否存在循环依赖,并确认模块边界设置合理。
-
审查依赖注入:验证所有可注入服务是否使用构造函数注入。检查提供者的作用域(单例、请求级、瞬态)是否符合预期生命周期。确保没有绕过 DI 容器直接实例化对象。
-
评估控制器:审查 HTTP 方法的使用、路由命名、状态码、请求/响应 DTO、验证管道和 OpenAPI 装饰器。确认控制器保持精简——业务逻辑应放在服务中。
-
评估服务和业务逻辑:检查服务是否恰当地封装业务逻辑。验证错误处理、事务管理,以及与基础设施关注点的分离是否合理。留意过于庞大或职责过多的服务方法。
-
检查安全性:审查守卫实现、身份验证/授权模式、使用 class-validator 进行的输入验证,以及针对常见漏洞(注入、XSS、CSRF)的防护。
-
审查测试:评估控制器、服务、守卫和管道的测试覆盖率。验证模拟策略是否恰当,以及测试验证的是行为而非实现细节。
-
验证审查结果(必要检查点):定稿前,验证每项严重和警告级问题都有可复现的证据(文件路径、行号、准确代码片段)和具体、可执行的修复方案。删除或降低仅涉及风格偏好、过于主观或缺乏具体修复方案的问题。
-
生成审查报告:生成结构化报告,包含按严重程度分类的审查结果(严重、警告、建议)、积极评价,以及附有代码示例的优先级建议。
示例
示例 1:审查控制器
// ❌ Bad: Fat controller with business logic and missing validation
@Controller('users')
export class UserController {
constructor(private readonly userRepo: Repository<User>) {}
@Post()
async create(@Body() body: any) {
const user = this.userRepo.create(body);
return this.userRepo.save(user);
}
}
// ✅ Good: Thin controller with proper DTOs, validation, and service delegation
@Controller('users')
@ApiTags('Users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Post()
@HttpCode(HttpStatus.CREATED)
@ApiOperation({ summary: 'Create a new user' })
@ApiResponse({ status: 201, type: UserResponseDto })
async create(
@Body(ValidationPipe) createUserDto: CreateUserDto,
): Promise<UserResponseDto> {
return this.userService.create(createUserDto);
}
}
示例 2:审查依赖注入
// ❌ Bad: Direct instantiation bypasses DI
@Injectable()
export class OrderService {
private readonly logger = new Logger();
private readonly emailService = new EmailService();
async createOrder(dto: CreateOrderDto) {
this.emailService.send(dto.email, 'Order created');
}
}
// ✅ Good: Proper constructor injection
@Injectable()
export class OrderService {
private readonly logger = new Logger(OrderService.name);
constructor(
private readonly orderRepository: OrderRepository,
private readonly emailService: EmailService,
) {}
async createOrder(dto: CreateOrderDto): Promise<Order> {
const order = await this.orderRepository.create(dto);
await this.emailService.send(dto.email, 'Order created');
return order;
}
}
示例 3:审查错误处理
// ❌ Bad: Generic error handling with information leakage
@Get(':id')
async findOne(@Param('id') id: string) {
try {
return await this.service.findOne(id);
} catch (error) {
throw new HttpException(error.message, 500);
}
}
// ✅ Good: Domain-specific exceptions with proper HTTP mapping
@Get(':id')
async findOne(@Param('id', ParseUUIDPipe) id: string): Promise<UserResponseDto> {
const user = await this.userService.findOne(id);
if (!user) {
throw new NotFoundException(`User with ID ${id} not found`);
}
return user;
}
示例 4:审查守卫实现
// ❌ Bad: Authorization logic in controller
@Get('admin/dashboard')
async getDashboard(@Req() req: Request) {
if (req.user.role !== 'admin') {
throw new ForbiddenException();
}
return this.dashboardService.getData();
}
// ✅ Good: Guard-based authorization with decorator
@Get('admin/dashboard')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(Role.ADMIN)
async getDashboard(): Promise<DashboardDto> {
return this.dashboardService.getData();
}
示例 5:审查模块组织
// ❌ Bad: Monolithic module with everything
@Module({
imports: [TypeOrmModule.forFeature([User, Order, Product, Review])],
controllers: [UserController, OrderController, ProductController],
providers: [UserService, OrderService, ProductService, ReviewService],
})
export class AppModule {}
// ✅ Good: Feature-based module organization
@Module({
imports: [UserModule, OrderModule, ProductModule],
})
export class AppModule {}
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UserController],
providers: [UserService, UserRepository],
exports: [UserService],
})
export class UserModule {}
审查输出格式
所有代码审查结果均按以下结构组织:
1. 总结
简要概述整体质量评分(1-10)和关键观察结果。
2. 严重问题(必须修复)
可能导致安全漏洞、数据损坏或生产环境故障的问题。
3. 警告(应当修复)
违反最佳实践、降低可维护性或可能引发错误的问题。
4. 建议(可考虑改进)
提升代码可读性、性能或开发者体验的改进。
5. 积极评价
值得认可和鼓励的良好实现模式和实践。
6. 建议措施
按优先级列出后续步骤,并为影响最大的改进提供代码示例。
最佳实践
- 控制器应保持精简——将所有业务逻辑交给服务处理
- 所有请求和响应负载都应使用带有 class-validator 的 DTO
- 使用
ParseUUIDPipe、ParseIntPipe等进行参数验证 - 使用继承自
HttpException的领域专用异常类 - 将代码组织到边界清晰、导出明确的功能模块中
- 优先使用构造函数注入——不要使用
new实例化可注入服务 - 使用守卫进行身份验证和授权,不要在代码中内联检查
- 使用拦截器处理横切关注点(日志记录、缓存、转换)
- 为所有端点添加 OpenAPI 装饰器(
@ApiTags、@ApiOperation、@ApiResponse) - 为服务编写单元测试,为控制器编写集成测试
限制和警告
- 不要强制使用单一 ORM——代码库可能使用 TypeORM、Prisma、Drizzle 或 MikroORM
- 即使现有项目约定与 NestJS 默认规范不同,也应遵循现有约定
- 聚焦于高置信度的问题——避免将风格偏好误报为问题
- 检查微服务模式时,应考虑特定于传输层的限制
- 除非存在严重问题,否则不要建议重写架构
参考资料
详细的审查清单和模式文档见 references/ 目录:
references/patterns.md— NestJS 最佳实践模式及示例references/anti-patterns.md— 审查时应标记的常见 NestJS 反模式references/checklist.md— 按领域整理的综合审查清单