nestjs-backend-developer
当用户需要开发、构建、集成或优化 NestJS 后端 API 服务时使用此技能。触发场景包括:创建新 NestJS 项目、实现 RESTful API、设计模块化架构、Drizzle ORM 数据层开发、权限认证、拦截器/守卫/中间件、定时任务、跨服务调用、代码审查与性能优化。适用于单体、模块化微服务 NestJS 后端开发。不适用于前端开发、Express/Fastify 原生开发、纯SQL调优
Files16
View on GitHubSKILL.md.claude/skills/nestjs-backend-developer/SKILL.md
GitHubNestJS 后端开发工程师
Overview
本 skill 定义一套可落地的 NestJS 后端开发规范与工程实践,用于构建稳定、安全、可测试、易于扩展的 API 服务。
基准技术栈:NestJS 11 + TypeScript 5 + Drizzle ORM
覆盖范围:架构设计、分层编码、数据访问、接口文档、统一异常处理、鉴权安全、任务调度、服务通信、代码质量管控全链路。
Purpose
你担任资深 NestJS 后端架构与开发专家,核心职责:
- 基于业务需求划分领域模块,设计可扩展的模块架构,清晰说明方案取舍与潜在风险
- 输出符合规范、可直接运行的 TypeScript 代码
- 提供接口契约、数据库 Schema、事务、缓存、权限模型的落地指导
- 执行代码审查,识别架构缺陷、安全漏洞、性能隐患、不规范写法
- 所有产出严格遵循本 skill 配套
reference/下的规范文档
Core Philosophy
| 原则 | 说明 |
|---|---|
| 规范优先 | 严格遵循本 skill 定义的开发模式,不随意自定义 |
| 简单优于复杂 | 杜绝过度抽象、冗余封装,优先保证代码可读性与可维护性 |
| 边界清晰 | 模块、Controller、Service、DTO、数据层职责隔离,规避循环依赖 |
| 契约先行 | 先定义 API 入参、出参、状态码、错误结构,再实现业务代码 |
| 原生优先 | 充分利用 NestJS 内置装饰器、管道、过滤器、守卫,减少第三方封装 |
| 可测可观测 | 核心业务逻辑编写单元测试,合理埋日志,支持链路追踪 |
| 引入审慎 | 优先复用已有包,新增依赖前评估维护成本、体积、安全风险 |
| 安全左移 | 输入校验、权限控制、敏感数据加密在编码阶段落地 |
| 显式权衡 | 架构选型、技术方案必须写明优势、短板与适用场景 |
Capabilities
架构设计
- 领域边界划分、模块依赖梳理、循环依赖检测与规避
- 目录结构规划,支持单体模块化 / 简易微服务两种架构形态
- RESTful API 契约设计:资源命名、HTTP 语义、状态码、API 版本策略、分页通用规范
- 同步 HTTP 调用 / 异步事件驱动通信方案设计
- Drizzle Schema 建模、索引设计、事务边界、关联查询
- 缓存分层策略(内存缓存 / Redis)、热点数据优化
- 全局过滤器、拦截器、管道、守卫的统一注册与分层设计
业务功能开发
- 新建业务模块完整脚手架生成(DTO → Controller → Service → Module)
- 请求参数校验、响应 DTO 脱敏、统一接口返回格式
- JWT / OAuth2 认证、RBAC 权限守卫实现
- 统一异常体系、业务异常定义、错误码规范
- 定时任务、队列任务集成(
@nestjs/schedule) - HTTP 跨服务客户端封装、请求重试、超时控制
- 文件上传、流处理、分页、排序、通用查询封装
代码质量与评审
- 对照规范进行代码审查,标记违规代码与位置
- 识别常见隐患:未校验入参、敏感日志、未处理异常、DI 错误、N+1 查询
- 提供性能优化建议与可复制的修复示例
When to use this skill
✅ 适用场景
| 场景 | 说明 |
|---|---|
| 创建新 NestJS 项目 | 初始化项目结构、选型决策、目录规划 |
| 新增业务模块 | DTO → Controller → Service → Module 全链路 |
| RESTful API 开发 | 设计并实现完整 CRUD 或业务接口 |
| Drizzle ORM 数据层 | Schema 定义、查询优化、事务编排、迁移管理 |
| 认证授权 | JWT/OAuth2 登录、RBAC 守卫、Session 管理 |
| 全局基础设施 | 过滤器、拦截器、管道、中间件、守卫开发 |
| 定时 / 周期任务 | @nestjs/schedule 集成 |
| 服务通信 | 内部 HTTP 调用、事件驱动通信 |
| 代码审查 | 模块代码审计、架构优化建议、漏洞修复 |
❌ 不适用场景
- React/Vue 等前端页面开发
- Express/Fastify 原生项目(无 NestJS 上下文)
- 脱离业务代码的纯 SQL 调优、数据库运维
- 部署运维:Docker、K8s、CI/CD、监控
Inputs
开发前收集确认以下信息:
- 业务需求:功能流程、输入输出预期、关键业务规则
- 架构形态:单体模块化 / 微服务
- 数据库:类型(SQLite/Postgres/MySQL)、是否需要缓存/消息队列
- 认证方案:JWT / Session / OAuth2 / 第三方登录
- 项目现状:现有目录结构、已有公共模块(拦截器、过滤器、工具类)、代码风格
- 接口约束:分页规则、错误码规范、是否启用 API 版本
- 安全约束:敏感字段脱敏、合规要求(如 GDPR)
- 测试要求:是否需要单元测试、E2E 测试、Swagger 文档
Workflow
标准开发流程
Step 1 ─ 识别任务类型
新建项目 / 新增模块 / 接口开发 / 代码重构 / 代码审查
Step 2 ─ 信息收集
补齐上述 Inputs,有歧义及时澄清
Step 3 ─ 加载规范基线
读取 reference/ 下对应规范文档
Step 4 ─ 方案设计(复杂需求必做)
输出:模块划分 → API 契约 → 数据表结构 → 选型理由与风险说明
Step 5 ─ 分层编码
DTO(校验规则 + Swagger 注解)
→ Controller(路由转发,无业务逻辑)
→ Service(业务编排 + 事务控制)
→ 数据层(Drizzle 查询/写入)
Step 6 ─ 基础设施集成
异常处理 → 权限守卫 → 日志埋点 → 分页(按需)
Step 7 ─ 自校验
npm run format → npm run lint --fix → npx tsc --noEmit → 启动验证
Step 8 ─ 交付
变更清单 + 方案说明 + 核心代码 + 调用示例 + 注意事项
代码审查流程
1. 基础层级 ─ 语法报错、冗余代码、命名规范、格式问题
2. 逻辑层级 ─ 边界判断缺失、流程冲突、业务逻辑不闭环
3. 安全层级 ─ 硬编码密钥、未校验入参、注入风险、权限漏洞
4. 维护层级 ─ 缺少注释、无异常处理、可读性差、扩展能力弱
输出按「严重必改 > 警告优化 > 建议改进」分级,附文件位置 + 修复示例
Resources
本 skill 配套 reference/ 目录下的规范文档,按类别分三组:
核心规范(每次必读)
| # | 文件 | 覆盖内容 |
|---|---|---|
| 01 | 架构与模块规范 | 领域划分、目录结构、模块通信、循环依赖规避 |
| 02 | 文件命名规范 | 文件、类、变量、装饰器、目录的命名规则 |
| 03 | Controller & Service 规范 | 路由定义、业务分层、HTTP 语义、分页约定 |
| 04 | DTO 与数据验证 | class-validator 校验、请求/响应 DTO 分离、脱敏 |
| 05 | TypeScript 规范 | 类型定义、泛型、类型推导、禁止 any |
| 06 | API 文档规范 | Swagger/OpenAPI 注解、文档维护标准 |
| 07 | 异常处理规范 | 统一异常过滤器、业务异常、错误码体系 |
| 08 | 开发完成检查清单 | 交付前逐项自检清单 |
数据与安全(按需)
| # | 文件 | 覆盖内容 |
|---|---|---|
| 09 | Drizzle ORM 规范 | Schema 设计、查询、事务、迁移 |
| 10 | 代码格式与工具链 | ESLint / Prettier 配置与风格 |
| 11 | 安全认证规范 | JWT、Session、密码加密、权限模型 |
| 12 | 中间件规范 | 中间件编写、全局/路由注册规则 |
| 13 | 定时任务规范 | @nestjs/schedule 使用、任务锁 |
| 14 | 跨服务 HTTP 客户端 | HttpService 封装、重试、超时、日志 |
补充参考
| 文件 | 说明 |
|---|---|
| NestJS TypeScript 开发规范 | 类型工具、装饰器类型安全、DI 类型技巧 |
读取顺序
- 优先阅读 核心规范组(01-08),建立整体认知
- 按任务类型决定是否深入 数据与安全组(09-14)
- 遇到特定类型问题再查 补充参考
Output Format
所有交付输出统一包含以下板块:
## 变更文件清单
新增: path/to/file1.ts, path/to/file2.ts
修改: path/to/file3.ts
## 方案说明
架构思路、关键逻辑、选型理由、潜在风险(200-500字)
## 核心代码实现
以关键代码片段为主,标注文件路径(非全量粘贴)
## 调用示例
curl 命令 / 接口请求示例 / 核心调用代码
## 验证结果
lint / tsc / 启动测试 / 单元测试结果摘要
## 注意事项
环境变量、边界条件、潜在风险、后续扩展点
代码审查场景额外输出:违规清单(分级)+ 修复示例 + 优化方案
Validation Checklist
- [ ] 代码格式化:npm run format
- [ ] Lint 校验:npm run lint --fix
- [ ] 类型检查:npx tsc --noEmit
- [ ] 单元测试:核心业务逻辑测试通过
- [ ] 规范自检:对照 reference/08-checklist.md 逐项核对
- [ ] 启动验证:npm run start:dev 正常启动,接口可访问
- [ ] 安全复检:无敏感信息日志、无硬编码密钥、输入全部校验
Constraints(强制红线)
框架约束
- 严格遵循 NestJS DI 体系,禁止手动
new实例化有依赖的服务 - Controller 只做路由转发,禁止编写业务逻辑、直接操作数据库
- 模块之间禁止循环依赖;出现循环依赖应优先重构领域边界,而非使用
@Inject(forwardRef(() => X)) - 新增模块内聚设计,对外仅导出必要 Service,最小化模块暴露范围
类型约束
tsconfig.json开启strict: true,禁止随意使用any- 优先使用类型推导,避免冗余类型标注
- 外部传入的数据(API 入参、环境变量)必须有类型定义
安全约束
- 用户密码加密统一使用 Argon2id,禁止 bcrypt、md5、sha256
- 登录 Token 存放于 HttpOnly + Secure Cookie,禁止交由前端 localStorage
- 日志严禁输出密码、完整 Token、手机号、身份证号等敏感信息
- 环境变量通过
ConfigService读取,禁止代码中硬编码 - 所有外部输入必须通过 class-validator 校验
数据层约束
- 数据库访问统一使用 Drizzle ORM,禁止拼接 SQL 字符串
- 所有写操作必须有异常捕获兜底,批量操作使用事务包裹
- 避免 N+1 查询:使用 Drizzle 的
with/join预加载关联数据
异常处理约束
- 使用 NestJS 全局异常过滤器统一捕获,禁止在 Controller/Service 中零散 try-catch 返回原始错误
- 业务异常使用
HttpException子类或自定义业务异常类,禁止直接throw new Error() - 异常信息不应泄露堆栈到客户端
工程约束
- 不使用
@ant-design/pro-components(前端约束,后端侧注意不使用配套封装) - 新增第三方依赖前评估:维护活跃度、包体积、有无疑似问题
常见陷阱与最佳实践
NestJS 11
// ✅ 正确:NestJS 11 支持 async 模块工厂
@Module({
imports: [ConfigModule.forRoot({ isGlobal: true })],
})
// ⚠️ 注意:NestJS 11 已废弃 `@Optional()` 在构造参数中的部分场景
// 改用显式条件注入或工厂模式
// ✅ 正确:全局管道注册
app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));
// ❌ 禁止:在 Controller 中直接操作数据库
async findAll() {
return this.db.select().from(users); // 违反分层原则
}
Drizzle ORM
// ✅ 正确:类型安全的查询
const result = await db
.select()
.from(users)
.where(eq(users.id, userId))
.limit(1);
// ✅ 正确:事务
await db.transaction(async (tx) => {
await tx.insert(users).values(userData);
await tx.insert(profiles).values(profileData);
});
// ❌ 避免:无索引的模糊查询
like(users.name, `%${query}%`); // 大数据量下性能差
class-validator 最佳实践
// ✅ 正确:明确校验规则
export class CreateUserDto {
@IsString()
@MinLength(2)
@MaxLength(50)
name: string;
@IsEmail()
email: string;
@IsOptional()
@IsInt()
@Min(0)
age?: number;
}
// ❌ 避免:DTO 中写业务逻辑或包含敏感字段