nestjs-expert by jeffallan/claude-skills
npx skills add https://github.com/jeffallan/claude-skills --skill nestjs-expert资深 NestJS 专家,在企业级、可扩展的 TypeScript 后端应用方面拥有深厚的专业知识。
npm run lint、npm run test,并使用 nest info 确认依赖注入图根据上下文加载详细指导:
| 主题 | 参考 | 加载时机 |
|---|---|---|
| 控制器 | references/controllers-routing.md |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 创建控制器、路由、Swagger 文档时 |
| 服务 | references/services-di.md | 服务、依赖注入、提供者相关时 |
| 数据传输对象 | references/dtos-validation.md | 验证、class-validator、DTO 相关时 |
| 身份验证 | references/authentication.md | JWT、Passport、守卫、授权相关时 |
| 测试 | references/testing-patterns.md | 单元测试、端到端测试、模拟相关时 |
| Express 迁移 | references/migration-from-express.md | 从 Express.js 迁移到 NestJS 时 |
// create-user.dto.ts
import { IsEmail, IsString, MinLength } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class CreateUserDto {
@ApiProperty({ example: 'user@example.com' })
@IsEmail()
email: string;
@ApiProperty({ example: 'strongPassword123', minLength: 8 })
@IsString()
@MinLength(8)
password: string;
}
// users.controller.ts
import { Body, Controller, Post, HttpCode, HttpStatus } from '@nestjs/common';
import { ApiCreatedResponse, ApiTags } from '@nestjs/swagger';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
@ApiTags('users')
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Post()
@HttpCode(HttpStatus.CREATED)
@ApiCreatedResponse({ description: 'User created successfully.' })
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}
}
// users.service.ts
import { Injectable, ConflictException, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';
import { CreateUserDto } from './dto/create-user.dto';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private readonly usersRepository: Repository<User>,
) {}
async create(createUserDto: CreateUserDto): Promise<User> {
const existing = await this.usersRepository.findOneBy({ email: createUserDto.email });
if (existing) {
throw new ConflictException('Email already registered');
}
const user = this.usersRepository.create(createUserDto);
return this.usersRepository.save(user);
}
async findOne(id: number): Promise<User> {
const user = await this.usersRepository.findOneBy({ id });
if (!user) {
throw new NotFoundException(`User #${id} not found`);
}
return user;
}
}
// users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService], // 仅当其他模块需要此服务时才导出
})
export class UsersModule {}
// users.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { ConflictException } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
const mockRepo = {
findOneBy: jest.fn(),
create: jest.fn(),
save: jest.fn(),
};
describe('UsersService', () => {
let service: UsersService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UsersService,
{ provide: getRepositoryToken(User), useValue: mockRepo },
],
}).compile();
service = module.get<UsersService>(UsersService);
jest.clearAllMocks();
});
it('throws ConflictException when email already exists', async () => {
mockRepo.findOneBy.mockResolvedValue({ id: 1, email: 'user@example.com' });
await expect(
service.create({ email: 'user@example.com', password: 'pass1234' }),
).rejects.toThrow(ConflictException);
});
});
@Injectable() 和构造函数注入 — 切勿使用 new 实例化服务class-validator 装饰器验证所有输入,并全局启用 ValidationPipereq.body 传递给服务NotFoundException、ConflictException 等)@ApiTags、@ApiOperation 和响应装饰器记录所有端点Test.createTestingModule 为每个服务方法编写单元测试ConfigModule 和 process.env 存储所有配置值;切勿硬编码ValidationPipeany 类型,除非绝对必要且有文档说明forwardRef()实现 NestJS 功能时,请按以下顺序提供:
.module.ts).controller.ts).service.ts)class-validator 装饰器的 DTO (dto/*.dto.ts)*.service.spec.ts)NestJS, TypeScript, TypeORM, Prisma, Passport, JWT, class-validator, class-transformer, Swagger/OpenAPI, Jest, Supertest, Guards, Interceptors, Pipes, Filters
每周安装量
1.0K
代码仓库
GitHub 星标数
7.3K
首次出现
2026年1月20日
安全审计
安装于
opencode857
gemini-cli845
codex815
github-copilot792
cursor760
claude-code758
Senior NestJS specialist with deep expertise in enterprise-grade, scalable TypeScript backend applications.
npm run lint, npm run test, and confirm DI graph with nest infoLoad detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Controllers | references/controllers-routing.md | Creating controllers, routing, Swagger docs |
| Services | references/services-di.md | Services, dependency injection, providers |
| DTOs | references/dtos-validation.md | Validation, class-validator, DTOs |
| Authentication | references/authentication.md | JWT, Passport, guards, authorization |
| Testing | references/testing-patterns.md | Unit tests, E2E tests, mocking |
| Express Migration | references/migration-from-express.md | Migrating from Express.js to NestJS |
// create-user.dto.ts
import { IsEmail, IsString, MinLength } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class CreateUserDto {
@ApiProperty({ example: 'user@example.com' })
@IsEmail()
email: string;
@ApiProperty({ example: 'strongPassword123', minLength: 8 })
@IsString()
@MinLength(8)
password: string;
}
// users.controller.ts
import { Body, Controller, Post, HttpCode, HttpStatus } from '@nestjs/common';
import { ApiCreatedResponse, ApiTags } from '@nestjs/swagger';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
@ApiTags('users')
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Post()
@HttpCode(HttpStatus.CREATED)
@ApiCreatedResponse({ description: 'User created successfully.' })
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}
}
// users.service.ts
import { Injectable, ConflictException, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';
import { CreateUserDto } from './dto/create-user.dto';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private readonly usersRepository: Repository<User>,
) {}
async create(createUserDto: CreateUserDto): Promise<User> {
const existing = await this.usersRepository.findOneBy({ email: createUserDto.email });
if (existing) {
throw new ConflictException('Email already registered');
}
const user = this.usersRepository.create(createUserDto);
return this.usersRepository.save(user);
}
async findOne(id: number): Promise<User> {
const user = await this.usersRepository.findOneBy({ id });
if (!user) {
throw new NotFoundException(`User #${id} not found`);
}
return user;
}
}
// users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService], // export only when other modules need this service
})
export class UsersModule {}
// users.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { ConflictException } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
const mockRepo = {
findOneBy: jest.fn(),
create: jest.fn(),
save: jest.fn(),
};
describe('UsersService', () => {
let service: UsersService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UsersService,
{ provide: getRepositoryToken(User), useValue: mockRepo },
],
}).compile();
service = module.get<UsersService>(UsersService);
jest.clearAllMocks();
});
it('throws ConflictException when email already exists', async () => {
mockRepo.findOneBy.mockResolvedValue({ id: 1, email: 'user@example.com' });
await expect(
service.create({ email: 'user@example.com', password: 'pass1234' }),
).rejects.toThrow(ConflictException);
});
});
@Injectable() and constructor injection for all services — never instantiate services with newclass-validator decorators on DTOs and enable ValidationPipe globallyreq.body to servicesNotFoundException, ConflictException, etc.) in services@ApiTags, @ApiOperation, and response decoratorsTest.createTestingModuleValidationPipeany type unless absolutely necessary and documentedforwardRef() only as a last resortWhen implementing a NestJS feature, provide in this order:
.module.ts).controller.ts).service.ts)class-validator decorators (dto/*.dto.ts)*.service.spec.ts)NestJS, TypeScript, TypeORM, Prisma, Passport, JWT, class-validator, class-transformer, Swagger/OpenAPI, Jest, Supertest, Guards, Interceptors, Pipes, Filters
Weekly Installs
1.0K
Repository
GitHub Stars
7.3K
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode857
gemini-cli845
codex815
github-copilot792
cursor760
claude-code758
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装
ConfigModule and process.env; never hardcode them