AgentStack
SKILL verified MIT Self-run

Nestjs

skill-nimadorostkar-claude-skills-collection-nestjs · by nimadorostkar

Use when building NestJS services. Covers module structure, providers and scopes, validation pipes, guards and interceptors, TypeORM/Prisma integration, and testing.

No reviews yet
0 installs
9 views
0.0% view→install

Install

$ agentstack add skill-nimadorostkar-claude-skills-collection-nestjs

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Nestjs? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

NestJS

Purpose

Build NestJS applications where the module graph reflects the domain, validation happens at the edge, and cross-cutting concerns live in guards and interceptors rather than being copied into every controller.

When to Use

  • Building or reviewing a NestJS service.
  • Structuring modules, providers, and their scopes.
  • Implementing authentication, authorization, and request validation.
  • Writing unit and end-to-end tests for a Nest application.

Capabilities

  • Module and provider design, including dynamic modules.
  • Validation with class-validator and the global ValidationPipe.
  • Guards (authorization), interceptors (cross-cutting), filters (error mapping).
  • Data access with Prisma or TypeORM, correctly scoped.
  • Testing with the Nest testing module and Supertest.

Inputs

  • The domain boundaries the modules should follow.
  • The authentication scheme and the authorization model.
  • The persistence layer.

Outputs

  • Modules that encapsulate a domain and export only their public services.
  • A global validation pipe with whitelisting enabled.
  • Controllers that are thin, and services that contain the logic.

Workflow

  1. Model the modules on the domain — One module per bounded capability, exporting the services other modules may use. A module that exports everything is not a boundary.
  2. Enable strict validation globallywhitelist: true and forbidNonWhitelisted: true. Without these, a client can send extra fields and your DTO will happily carry them into the service.
  3. Push cross-cutting concerns out of controllers — Auth in a guard, logging and timing in an interceptor, error mapping in an exception filter.
  4. Keep providers stateless and singleton — Request-scoped providers cascade: anything that injects one becomes request-scoped too, and performance degrades quietly.
  5. Test at two levels — Unit tests for services with mocked dependencies, and end-to-end tests through the real HTTP stack with a real (containerized) database.

Best Practices

  • ValidationPipe without whitelist: true is decoration, not validation. Extra properties pass straight through.
  • transform: true on the pipe converts payloads into DTO class instances — otherwise your @Type decorators and defaults do nothing.
  • Circular module dependencies are a design smell. forwardRef is an escape hatch that hides a boundary you drew wrong.
  • Do not inject the repository into the controller. The controller's job is HTTP; the service's job is the domain.
  • Global exception filters map domain errors to HTTP status codes in one place. Throwing HttpException from a service couples the domain to the transport.
  • Use ConfigModule with a validation schema so a missing environment variable fails at boot.

Examples

Validation, guard, and thin controller:

// main.ts
app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,             // strip unknown properties
    forbidNonWhitelisted: true,  // and reject the request if any are present
    transform: true,             // instantiate the DTO class
  }),
);
export class CreateOrderDto {
  @IsUUID() customerId!: string;

  @IsArray()
  @ArrayMinSize(1)
  @ValidateNested({ each: true })
  @Type(() => OrderLineDto)
  lines!: OrderLineDto[];
}

@Controller("orders")
@UseGuards(JwtAuthGuard, TenantGuard)
export class OrdersController {
  constructor(private readonly orders: OrdersService) {}

  @Post()
  @HttpCode(HttpStatus.CREATED)
  create(@Body() dto: CreateOrderDto, @CurrentUser() user: User): Promise {
    return this.orders.place(user.tenantId, dto);
  }
}

Domain errors mapped centrally:

@Catch(DomainError)
export class DomainExceptionFilter implements ExceptionFilter {
  catch(error: DomainError, host: ArgumentsHost) {
    const status = {
      NOT_FOUND: 404,
      CONFLICT: 409,
      INVALID: 422,
    }[error.kind] ?? 400;

    host.switchToHttp().getResponse().status(status).json({
      type: `https://api.example.com/errors/${error.kind.toLowerCase()}`,
      title: error.message,
      status,
    });
  }
}

Notes

  • Request-scoped providers instantiate a new instance per request and force the entire injection chain above them to do the same. Measure before using one.
  • Nest's TestingModule lets you override any provider, which is almost always preferable to mocking a module's internals.
  • Interceptors run around the handler and can transform the response. That makes them the right place for a response envelope — and the wrong place for business logic.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.