Agent-skills-standard nestjs-controllers-services
Separate Controllers from Services and build Custom Decorators in NestJS. Use when defining NestJS controllers, services, or custom parameter decorators. (triggers: **/*.controller.ts, **/*.service.ts, Controller, Injectable, ExecutionContext, createParamDecorator)
install
source · Clone the upstream repo
git clone https://github.com/HoangNguyen0403/agent-skills-standard
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/HoangNguyen0403/agent-skills-standard "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/nestjs/nestjs-controllers-services" ~/.claude/skills/hoangnguyen0403-agent-skills-standard-nestjs-controllers-services && rm -rf "$T"
manifest:
skills/nestjs/nestjs-controllers-services/SKILL.mdsource content
NestJS Controllers & Services Standards
Priority: P0 (FOUNDATIONAL)
Controllers
- Role: Handler only. Delegate all logic to Services.
- Context:
helpers (ExecutionContext
) for platform-agnostic code.switchToHttp() - Custom Decorators:
- Avoid:
->@Request() req
(Not type-safe).req.user - Pattern: Create typed decorators like
,@CurrentUser()
.@DeviceIp()
import { RequestWithUser } from 'src/common/interfaces/request.interface'; export const CurrentUser = createParamDecorator( (data: unknown, ctx: ExecutionContext): User => { const request = ctx.switchToHttp().getRequest<RequestWithUser>(); return request.user; }, );
DTOs & Validation
- Strictness:
: Strip properties without decorators.whitelist: true- Critical:
: Throw error if unknown properties exist.forbidNonWhitelisted: true - Transformation:
: Auto-convert primitives (String '1' -> Number 1) and instantiate DTO classes.transform: true- Documentation:
- Swagger Plugin:
CLI plugin in@nestjs/swagger
auto-detects DTO properties — no manualnest-cli.json
.@ApiProperty()
Interceptors (Response Mapping)
- Map responses in Interceptors, not Controllers.
wraps success responses (e.g.map()
).{ data: T }- See API Standards for
andPageDto
.ApiResponse
maps low-level errors (DB constraints) tocatchError()
(e.g.HttpException
) before global filter.ConflictException
Services & Business Logic
- Singleton: Default.
- Stateless: No request-specific state in class properties unless
.Scope.REQUEST
Pipes & Validation
- Global: Register
globally.ValidationPipe - Route Params: Fail fast. Always use
,ParseIntPipe
on all ID parameters.ParseUUIDPipe
@Get(':id') findOne(@Param('id', ParseIntPipe) id: number) { ... }
Lifecycle Events
- Init: Use
for connection setup.OnModuleInit - Destroy: Use
for cleanup. (RequiresOnApplicationShutdown
).enableShutdownHooks()
Anti-Patterns
- No business logic in controllers: Delegate everything to Services; controllers only parse and respond.
- No req.user access: Create typed
decorator instead of accessing raw@CurrentUser()
.req - No REQUEST scope by default: Use SINGLETON; it makes entire injection chain request-scoped.