AI Skill Report Card
Reviewing NestJS Applications
Quick Start
TypeScript// Example review checklist for a NestJS controller @Controller('users') export class UsersController { // ✓ Good: Proper validation, guards, and error handling @Get(':id') @UseGuards(JwtAuthGuard) @UsePipes(ValidationPipe) async getUser(@Param('id', ParseIntPipe) id: number): Promise<UserDto> { return this.usersService.findOne(id); } }
Workflow
Progress:
- Security Review - Check authentication, authorization, input validation
- API Design - Verify REST conventions, error responses, documentation
- Performance - Identify database queries, caching, async patterns
- Code Quality - Review structure, typing, testing, dependencies
- Documentation - Ensure proper OpenAPI specs and README
1. Security Review
- Authentication: JWT guards properly implemented
- Authorization: Role/permission guards on sensitive endpoints
- Input Validation: Class-validator decorators on all DTOs
- SQL Injection: TypeORM query builders, no raw queries
- CORS: Proper origin configuration
- Rate Limiting: Throttler module configured
- Environment: Secrets in
.env, validation schema
2. API Design Review
- HTTP Methods: Correct verb usage (GET/POST/PUT/PATCH/DELETE)
- Status Codes: Proper 2xx/4xx/5xx responses
- Error Handling: Global exception filter with structured errors
- Versioning: API versioning strategy if needed
- OpenAPI: Swagger decorators for documentation
3. Performance Review
- Database:
- N+1 query problems
- Missing indexes
- Eager vs lazy loading
- Caching: Redis integration where appropriate
- Async Operations: Proper Promise handling
- Memory Leaks: Event listener cleanup
4. Code Quality Review
- Module Structure: Proper imports/exports, feature modules
- Dependency Injection: Constructor injection, proper scopes
- TypeScript: Strict mode, proper typing
- Testing: Unit tests for services, e2e for controllers
- Logging: Structured logging with context
Examples
Example 1: Security Issue Input:
TypeScript@Post('users') async createUser(@Body() userData: any) { return this.usersService.create(userData); }
Output:
TypeScript// Issues found: // 1. Missing input validation (any type) // 2. No authentication guard // 3. No authorization check @Post('users') @UseGuards(JwtAuthGuard, RolesGuard) @Roles(Role.Admin) @UsePipes(ValidationPipe) async createUser(@Body() userData: CreateUserDto): Promise<UserDto> { return this.usersService.create(userData); }
Example 2: Performance Issue Input:
TypeScript@Get('posts') async getAllPosts() { const posts = await this.postsRepository.find(); for (const post of posts) { post.author = await this.usersService.findOne(post.authorId); } return posts; }
Output:
TypeScript// Issue: N+1 query problem // Fix: Use relations or join query @Get('posts') async getAllPosts(): Promise<PostDto[]> { return this.postsRepository.find({ relations: ['author'], select: { author: { id: true, name: true, email: true } } }); }
Best Practices
- Security First: Always check auth/validation before functionality
- Type Safety: Use strict TypeScript, avoid
any - Error Handling: Implement global exception filters
- Testing Strategy: Unit tests for business logic, e2e for API contracts
- Database Optimization: Monitor query performance, use indexes
- Documentation: Keep OpenAPI specs updated
- Environment Configuration: Use ConfigModule with validation
Common Pitfalls
- Missing Validation: Accepting
anytype in DTOs - Circular Dependencies: Poor module organization
- Blocking Operations: Using sync methods in async context
- Memory Leaks: Not cleaning up event listeners
- Over-eager Loading: Loading unnecessary relations
- Missing Error Context: Generic error messages
- Hardcoded Values: Magic numbers/strings instead of constants
- Poor Exception Handling: Catching and ignoring errors