library/specializations/web-development/skills/nestjs/SKILL.md
NestJS architecture including modules, dependency injection, guards, interceptors, and microservices patterns.
npx skillsauth add a5c-ai/babysitter nestjsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Expert assistance for building enterprise Node.js applications with NestJS.
Invoke this skill when you need to:
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | moduleName | string | Yes | Module name | | features | array | No | guards, pipes, interceptors | | database | string | No | prisma, typeorm, mongoose | | microservices | boolean | No | Enable microservices |
// src/users/users.module.ts
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { PrismaModule } from '../prisma/prisma.module';
@Module({
imports: [PrismaModule],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}
// src/users/users.controller.ts
import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
Query,
UseGuards,
HttpCode,
HttpStatus,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiResponse } from '@nestjs/swagger';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { UserResponseDto } from './dto/user-response.dto';
import { PaginationDto } from '../common/dto/pagination.dto';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../auth/guards/roles.guard';
import { Roles } from '../auth/decorators/roles.decorator';
import { CurrentUser } from '../auth/decorators/current-user.decorator';
@ApiTags('users')
@Controller('users')
@UseGuards(JwtAuthGuard, RolesGuard)
@ApiBearerAuth()
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
@ApiOperation({ summary: 'Get all users' })
@ApiResponse({ status: 200, type: [UserResponseDto] })
findAll(@Query() pagination: PaginationDto) {
return this.usersService.findAll(pagination);
}
@Get(':id')
@ApiOperation({ summary: 'Get user by ID' })
@ApiResponse({ status: 200, type: UserResponseDto })
findOne(@Param('id') id: string) {
return this.usersService.findById(id);
}
@Post()
@Roles('admin')
@ApiOperation({ summary: 'Create user' })
@ApiResponse({ status: 201, type: UserResponseDto })
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}
@Put(':id')
@ApiOperation({ summary: 'Update user' })
update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
return this.usersService.update(id, updateUserDto);
}
@Delete(':id')
@Roles('admin')
@HttpCode(HttpStatus.NO_CONTENT)
@ApiOperation({ summary: 'Delete user' })
remove(@Param('id') id: string) {
return this.usersService.delete(id);
}
}
// src/users/dto/create-user.dto.ts
import { IsEmail, IsString, MinLength, IsOptional, IsEnum } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class CreateUserDto {
@ApiProperty({ example: 'John Doe' })
@IsString()
name: string;
@ApiProperty({ example: '[email protected]' })
@IsEmail()
email: string;
@ApiProperty({ minLength: 8 })
@IsString()
@MinLength(8)
password: string;
@ApiProperty({ required: false, enum: ['user', 'admin'] })
@IsOptional()
@IsEnum(['user', 'admin'])
role?: string;
}
// src/users/users.service.ts
import { Injectable, NotFoundException, ConflictException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { PaginationDto } from '../common/dto/pagination.dto';
import * as bcrypt from 'bcryptjs';
@Injectable()
export class UsersService {
constructor(private readonly prisma: PrismaService) {}
async findAll(pagination: PaginationDto) {
const { page = 1, limit = 10, search } = pagination;
const skip = (page - 1) * limit;
const [users, total] = await Promise.all([
this.prisma.user.findMany({
where: search ? { name: { contains: search, mode: 'insensitive' } } : undefined,
skip,
take: limit,
select: {
id: true,
name: true,
email: true,
role: true,
createdAt: true,
},
}),
this.prisma.user.count({
where: search ? { name: { contains: search, mode: 'insensitive' } } : undefined,
}),
]);
return {
data: users,
meta: {
total,
page,
limit,
totalPages: Math.ceil(total / limit),
},
};
}
async findById(id: string) {
const user = await this.prisma.user.findUnique({
where: { id },
select: {
id: true,
name: true,
email: true,
role: true,
createdAt: true,
},
});
if (!user) {
throw new NotFoundException(`User with ID ${id} not found`);
}
return user;
}
async create(dto: CreateUserDto) {
const existing = await this.prisma.user.findUnique({
where: { email: dto.email },
});
if (existing) {
throw new ConflictException('Email already in use');
}
const hashedPassword = await bcrypt.hash(dto.password, 10);
return this.prisma.user.create({
data: {
...dto,
password: hashedPassword,
},
select: {
id: true,
name: true,
email: true,
role: true,
createdAt: true,
},
});
}
async update(id: string, dto: UpdateUserDto) {
await this.findById(id);
if (dto.password) {
dto.password = await bcrypt.hash(dto.password, 10);
}
return this.prisma.user.update({
where: { id },
data: dto,
select: {
id: true,
name: true,
email: true,
role: true,
createdAt: true,
},
});
}
async delete(id: string) {
await this.findById(id);
await this.prisma.user.delete({ where: { id } });
}
}
// src/auth/guards/jwt-auth.guard.ts
import { Injectable, ExecutionContext } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { Reflector } from '@nestjs/core';
import { IS_PUBLIC_KEY } from '../decorators/public.decorator';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
constructor(private reflector: Reflector) {
super();
}
canActivate(context: ExecutionContext) {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
if (isPublic) {
return true;
}
return super.canActivate(context);
}
}
// src/auth/guards/roles.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { ROLES_KEY } from '../decorators/roles.decorator';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<string[]>(ROLES_KEY, [
context.getHandler(),
context.getClass(),
]);
if (!requiredRoles) {
return true;
}
const { user } = context.switchToHttp().getRequest();
return requiredRoles.includes(user.role);
}
}
// src/auth/decorators/roles.decorator.ts
import { SetMetadata } from '@nestjs/common';
export const ROLES_KEY = 'roles';
export const Roles = (...roles: string[]) => SetMetadata(ROLES_KEY, roles);
// src/auth/decorators/current-user.decorator.ts
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const CurrentUser = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.user;
},
);
// src/common/interceptors/transform.interceptor.ts
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export interface Response<T> {
data: T;
meta?: Record<string, any>;
}
@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
return next.handle().pipe(
map((data) => {
if (data?.data && data?.meta) {
return data;
}
return { data };
}),
);
}
}
development
Model documentation skill for generating model cards following Google's model card framework.
development
MLflow integration skill for experiment tracking, model registry, and artifact management. Enables LLMs to log experiments, compare runs, manage model lifecycle, and retrieve artifacts through the MLflow API.
data-ai
LIME-based local explanation skill for individual predictions across tabular, text, and image data.
devops
Kubeflow Pipelines skill for ML workflow orchestration, component management, and Kubernetes-native ML.