AgentSkillsCN

nestjs

采用企业级设计模式、依赖注入、模块化架构,并提供全面的测试支持,基于NestJS TypeScript进行后端开发。 适用场景:(1) 当项目在package.json中引入了@nestjs/core,或存在nest-cli.json文件时;(2) 在创建模块、控制器、服务、守卫、管道、拦截器或过滤器时;(3) 实现JWT认证或基于角色的权限控制(RBAC/ABAC)时;(4) 集成TypeORM、Prisma或MikroORM进行数据库操作时;(5) 使用Jest编写单元测试,或借助supertest进行端到端测试时;(6) 配置Swagger/OpenAPI文档时;(7) 实施CQRS、事件溯源或微服务架构模式时。 自动识别:nest-cli.json、*.module.ts、*.controller.ts、*.service.ts、*.guard.ts,以及package.json中的@nestjs/*相关包,还有src/modules/目录结构。 不适用于:纯Express.js项目而未使用NestJS,前端React/Vue/Angular代码,或非TypeScript的Node.js项目,以及未通过NestJS封装的Fastify项目。

SKILL.md
--- frontmatter
name: nestjs
version: "2.1.0"
description: |
  NestJS TypeScript backend development with enterprise patterns, dependency injection,
  modular architecture, and comprehensive testing support.

  Use when: (1) Project has @nestjs/core in package.json or nest-cli.json exists,
  (2) Creating modules, controllers, services, guards, pipes, interceptors, or filters,
  (3) Implementing JWT authentication or role-based authorization (RBAC/ABAC),
  (4) Integrating TypeORM, Prisma, or MikroORM for database operations,
  (5) Writing unit tests with Jest or E2E tests with supertest,
  (6) Setting up Swagger/OpenAPI documentation,
  (7) Implementing CQRS, event sourcing, or microservices patterns.

  Auto-detects: nest-cli.json, *.module.ts, *.controller.ts, *.service.ts, *.guard.ts,
  @nestjs/* packages in package.json, src/modules/ directory structure.

  NOT for: Pure Express.js without NestJS, frontend React/Vue/Angular code,
  non-TypeScript Node.js projects, Fastify without NestJS wrapper.

related:
  - typescript
  - api-design
  - testing

NestJS Development Skill

Quick Reference

bash
# Scaffold a new module with CRUD
python scripts/scaffold.py user --crud

# Generate specific component
python scripts/generate.py controller user
python scripts/generate.py service user --repository

# Run tests with coverage
python scripts/test.py --coverage --threshold 80

Load Additional Resources

ScenarioReferenceDescription
Architecture decisionsreferences/architecture.mdClean arch, DDD, CQRS
Auth/Authorizationreferences/security.mdJWT, Passport, RBAC
Database integrationreferences/database.mdTypeORM, Prisma
Testing strategiesreferences/testing.mdUnit, E2E, mocking
Performancereferences/performance.mdCaching, queues

Core Patterns

Module Structure

typescript
// REQ-XXX: Feature module
@Module({
  imports: [TypeOrmModule.forFeature([User]), ConfigModule],
  controllers: [UserController],
  providers: [UserService, UserRepository],
  exports: [UserService],
})
export class UserModule {}

Service Pattern

typescript
@Injectable()
export class UserService {
  constructor(
    private readonly userRepository: UserRepository,
    private readonly eventEmitter: EventEmitter2,
  ) {}

  async create(dto: CreateUserDto): Promise<User> {
    const user = await this.userRepository.create(dto);
    this.eventEmitter.emit('user.created', user);
    return user;
  }
}

Controller Pattern

typescript
@ApiTags('users')
@Controller('users')
@UseGuards(JwtAuthGuard, RolesGuard)
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Post()
  @Roles(Role.ADMIN)
  @ApiOperation({ summary: 'Create user' })
  @ApiResponse({ status: 201, type: UserResponseDto })
  async create(@Body() dto: CreateUserDto): Promise<UserResponseDto> {
    return this.userService.create(dto);
  }
}

DTO with Validation

typescript
export class CreateUserDto {
  @ApiProperty({ example: 'john@example.com' })
  @IsEmail()
  @IsNotEmpty()
  email: string;

  @ApiProperty({ minLength: 8 })
  @IsString()
  @MinLength(8)
  @Matches(/^(?=.*[A-Za-z])(?=.*\d)/)
  password: string;
}

Guard Pattern

typescript
@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.getAllAndOverride<Role[]>(
      ROLES_KEY, [context.getHandler(), context.getClass()],
    );
    if (!requiredRoles) return true;
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles?.includes(role));
  }
}

Project Structure

code
src/
├── main.ts                    # Bootstrap
├── app.module.ts              # Root module
├── common/                    # Shared utilities
│   ├── decorators/           # @Roles, @User, @Public
│   ├── dto/                  # PaginationDto, ResponseDto
│   ├── filters/              # HttpExceptionFilter
│   ├── guards/               # JwtAuthGuard, RolesGuard
│   ├── interceptors/         # TransformInterceptor
│   └── pipes/                # ValidationPipe extensions
├── config/                    # Configuration
└── modules/                   # Feature modules
    └── {feature}/
        ├── {feature}.module.ts
        ├── {feature}.controller.ts
        ├── {feature}.service.ts
        ├── {feature}.repository.ts
        ├── dto/
        ├── entities/
        └── __tests__/

F5 Quality Gates

GateRequirementImplementation
D3ArchitectureModule structure documented
D4Detailed DesignDTOs, entities defined
G2.5Code ReviewNestJS best practices
G380% CoverageJest + supertest

Scripts

ScriptUsageGate
scaffold.pyscaffold.py <name> --crudD4
generate.pygenerate.py <type> <name>G2.5
test.pytest.py --coverageG3

Common Packages

json
{
  "@nestjs/core": "^10.0.0",
  "@nestjs/common": "^10.0.0",
  "@nestjs/config": "^3.0.0",
  "@nestjs/typeorm": "^10.0.0",
  "@nestjs/passport": "^10.0.0",
  "@nestjs/jwt": "^10.0.0",
  "@nestjs/swagger": "^7.0.0",
  "class-validator": "^0.14.0"
}