Generate, develop, and maintain NestJS modules, controllers, services, guards, and other artifacts. Use when the user asks to create NestJS resources, add API endpoints, write guards or interceptors, configure Swagger, or work with the Fastify-based NestJS application.
| Task | Command |
|---|---|
| Generate a module | pnpm exec nest generate module <name> |
| Generate a controller | pnpm exec nest generate controller <name> |
| Generate a service | pnpm exec nest generate service <name> |
| Generate a full resource | pnpm exec nest generate resource <name> |
| Generate a guard | pnpm exec nest generate guard <name> |
| Generate an interceptor | pnpm exec nest generate interceptor <name> |
| Generate a pipe | pnpm exec nest generate pipe <name> |
| Start in dev mode | pnpm start:dev |
| Build | pnpm build |
| Run tests | pnpm test |
Default action: When adding a new feature, prefer to scaffold the full module, controller, and service in one step — then prune or extend as needed.
pnpm exec nest generate resource <name>Always check
package.jsonscripts before running — script names may vary betweenauth-serverandemail-service.
Before creating or modifying NestJS code, explore the project to understand:
app.module.ts to understand how existing feature modules are registered and which providers (Prisma, config, throttler, etc.) are available globallyDatabaseService is registered as a global provider or must be imported per feature moduleJwtAuthGuard (or equivalent) is bound globally via APP_GUARD or applied per-controller/routeclass-validator decorators and class-transformer are in use, and how @ApiProperty is applied alongside themServices run on the Fastify HTTP adapter (@nestjs/platform-fastify), not Express. Be aware of these differences:
FastifyRequest / FastifyReply instead of express.Request / express.Response when typing injected request/response objects@Res(), always pass { passthrough: true } to avoid breaking NestJS's response lifecycletypes/ folder within the moduleBefore writing any Swagger decorators, read nest-cli.json to check whether the @nestjs/swagger CLI plugin is registered under compilerOptions.plugins. This significantly changes what you need to write manually:
Plugin active — TypeScript types on DTO properties are automatically introspected and emitted as Swagger schema metadata. @ApiProperty decorators on DTO fields are optional; the plugin infers types, optionality, and class-validator constraints automatically. JSDoc comments on DTO fields are used as the Swagger description. Only add @ApiProperty explicitly when you need to override the inferred value (e.g. a custom example, enum, or description the plugin cannot derive).
Plugin not active — every DTO field requires an explicit @ApiProperty (or @ApiPropertyOptional) decorator; nothing is inferred from TypeScript types.
Use typed DTO classes as response types — avoid any or raw object shapes so Swagger generates accurate schemas
Maintain the established security conventions on every new endpoint:
@UseGuards(JwtAuthGuard) (or the project's equivalent guard) to all routes requiring an authenticated user; check whether a global APP_GUARD already covers all routes before adding per-route guardsThrottlerModule enforces three windows (1 s / 10 s / 1 min); add @SkipThrottle() only for internal health or status endpointsAccess-Control-* headers to individual routesUse class-validator and class-transformer for all request body DTOs:
ValidationPipe is applied globally — do not manually validate request bodies inside controllerspnpm test before committing to verify service and controller unit tests passpnpm lint after generating new files — ESLint enforces NestJS-specific rulesprisma skillnew — always inject them through NestJS's DI containerAppModule clean — register feature modules rather than importing providers directly into AppModule