Claude Agent Skill · by Affaan M

Nestjs Patterns

Install Nestjs Patterns skill for Claude Code from affaan-m/everything-claude-code.

Works with Paperclip

How Nestjs Patterns fits into a Paperclip company.

Nestjs Patterns drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.

S
SaaS FactoryPaired

Pre-configured AI company — 18 agents, 18 skills, one-time purchase.

$27$59
Explore pack
Source file
SKILL.md230 lines
Expand
---name: nestjs-patternsdescription: NestJS architecture patterns for modules, controllers, providers, DTO validation, guards, interceptors, config, and production-grade TypeScript backends.origin: ECC--- # NestJS Development Patterns Production-grade NestJS patterns for modular TypeScript backends. ## When to Activate - Building NestJS APIs or services- Structuring modules, controllers, and providers- Adding DTO validation, guards, interceptors, or exception filters- Configuring environment-aware settings and database integrations- Testing NestJS units or HTTP endpoints ## Project Structure ```textsrc/├── app.module.ts├── main.ts├── common/│   ├── filters/│   ├── guards/│   ├── interceptors/│   └── pipes/├── config/│   ├── configuration.ts│   └── validation.ts├── modules/│   ├── auth/│   │   ├── auth.controller.ts│   │   ├── auth.module.ts│   │   ├── auth.service.ts│   │   ├── dto/│   │   ├── guards/│   │   └── strategies/│   └── users/│       ├── dto/│       ├── entities/│       ├── users.controller.ts│       ├── users.module.ts│       └── users.service.ts└── prisma/ or database/``` - Keep domain code inside feature modules.- Put cross-cutting filters, decorators, guards, and interceptors in `common/`.- Keep DTOs close to the module that owns them. ## Bootstrap and Global Validation ```tsasync function bootstrap() {  const app = await NestFactory.create(AppModule, { bufferLogs: true });   app.useGlobalPipes(    new ValidationPipe({      whitelist: true,      forbidNonWhitelisted: true,      transform: true,      transformOptions: { enableImplicitConversion: true },    }),  );   app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)));  app.useGlobalFilters(new HttpExceptionFilter());   await app.listen(process.env.PORT ?? 3000);}bootstrap();``` - Always enable `whitelist` and `forbidNonWhitelisted` on public APIs.- Prefer one global validation pipe instead of repeating validation config per route. ## Modules, Controllers, and Providers ```ts@Module({  controllers: [UsersController],  providers: [UsersService],  exports: [UsersService],})export class UsersModule {} @Controller('users')export class UsersController {  constructor(private readonly usersService: UsersService) {}   @Get(':id')  getById(@Param('id', ParseUUIDPipe) id: string) {    return this.usersService.getById(id);  }   @Post()  create(@Body() dto: CreateUserDto) {    return this.usersService.create(dto);  }} @Injectable()export class UsersService {  constructor(private readonly usersRepo: UsersRepository) {}   async create(dto: CreateUserDto) {    return this.usersRepo.create(dto);  }}``` - Controllers should stay thin: parse HTTP input, call a provider, return response DTOs.- Put business logic in injectable services, not controllers.- Export only the providers other modules genuinely need. ## DTOs and Validation ```tsexport class CreateUserDto {  @IsEmail()  email!: string;   @IsString()  @Length(2, 80)  name!: string;   @IsOptional()  @IsEnum(UserRole)  role?: UserRole;}``` - Validate every request DTO with `class-validator`.- Use dedicated response DTOs or serializers instead of returning ORM entities directly.- Avoid leaking internal fields such as password hashes, tokens, or audit columns. ## Auth, Guards, and Request Context ```ts@UseGuards(JwtAuthGuard, RolesGuard)@Roles('admin')@Get('admin/report')getAdminReport(@Req() req: AuthenticatedRequest) {  return this.reportService.getForUser(req.user.id);}``` - Keep auth strategies and guards module-local unless they are truly shared.- Encode coarse access rules in guards, then do resource-specific authorization in services.- Prefer explicit request types for authenticated request objects. ## Exception Filters and Error Shape ```ts@Catch()export class HttpExceptionFilter implements ExceptionFilter {  catch(exception: unknown, host: ArgumentsHost) {    const response = host.switchToHttp().getResponse<Response>();    const request = host.switchToHttp().getRequest<Request>();     if (exception instanceof HttpException) {      return response.status(exception.getStatus()).json({        path: request.url,        error: exception.getResponse(),      });    }     return response.status(500).json({      path: request.url,      error: 'Internal server error',    });  }}``` - Keep one consistent error envelope across the API.- Throw framework exceptions for expected client errors; log and wrap unexpected failures centrally. ## Config and Environment Validation ```tsConfigModule.forRoot({  isGlobal: true,  load: [configuration],  validate: validateEnv,});``` - Validate env at boot, not lazily at first request.- Keep config access behind typed helpers or config services.- Split dev/staging/prod concerns in config factories instead of branching throughout feature code. ## Persistence and Transactions - Keep repository / ORM code behind providers that speak domain language.- For Prisma or TypeORM, isolate transactional workflows in services that own the unit of work.- Do not let controllers coordinate multi-step writes directly. ## Testing ```tsdescribe('UsersController', () => {  let app: INestApplication;   beforeAll(async () => {    const moduleRef = await Test.createTestingModule({      imports: [UsersModule],    }).compile();     app = moduleRef.createNestApplication();    app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));    await app.init();  });});``` - Unit test providers in isolation with mocked dependencies.- Add request-level tests for guards, validation pipes, and exception filters.- Reuse the same global pipes/filters in tests that you use in production. ## Production Defaults - Enable structured logging and request correlation ids.- Terminate on invalid env/config instead of booting partially.- Prefer async provider initialization for DB/cache clients with explicit health checks.- Keep background jobs and event consumers in their own modules, not inside HTTP controllers.- Make rate limiting, auth, and audit logging explicit for public endpoints.