# 后端开发规范指南 本文档定义了基于四层架构的后端开发规范,包括架构规范、注释规范、日志规范、代码质量规范等。 ## 📋 目录 - [架构规范](#架构规范) - [注释规范](#注释规范) - [日志规范](#日志规范) - [异常处理规范](#异常处理规范) - [代码质量规范](#代码质量规范) - [最佳实践](#最佳实践) --- ## 🏗️ 架构规范 ### 四层架构原则 项目采用 **Gateway-Business-Core-Data** 四层架构,每层职责明确: ``` Gateway Layer (网关层) ↓ 依赖 Business Layer (业务层) ↓ 依赖 Core Layer (核心层) ↓ 依赖 Data Layer (数据层) ``` ### 各层职责 #### 🌐 Gateway Layer(网关层) **位置:** `src/gateway/` **职责:** - HTTP/WebSocket协议处理 - 请求参数验证(DTO) - 路由管理 - 认证守卫 - 错误转换 **规范:** ```typescript // ✅ 正确:只做协议转换 @Controller('auth') export class LoginController { constructor(private readonly loginService: LoginService) {} @Post('login') async login(@Body() dto: LoginDto, @Res() res: Response) { const result = await this.loginService.login(dto); this.handleResponse(result, res); } } // ❌ 错误:包含业务逻辑 @Controller('auth') export class LoginController { @Post('login') async login(@Body() dto: LoginDto) { const user = await this.usersService.findByEmail(dto.email); const isValid = await bcrypt.compare(dto.password, user.password); // ... 更多业务逻辑 } } ``` #### 🎯 Business Layer(业务层) **位置:** `src/business/` **职责:** - 业务逻辑实现 - 服务协调 - 业务规则验证 - 事务管理 **规范:** ```typescript // ✅ 正确:实现业务逻辑 @Injectable() export class LoginService { constructor( private readonly loginCoreService: LoginCoreService, private readonly emailService: EmailService, ) {} async login(dto: LoginDto): Promise> { try { // 1. 调用核心服务验证 const user = await this.loginCoreService.validateUser(dto); // 2. 业务逻辑:生成Token const tokens = await this.loginCoreService.generateTokens(user); // 3. 业务逻辑:发送登录通知 await this.emailService.sendLoginNotification(user.email); return { success: true, data: tokens }; } catch (error) { return { success: false, message: error.message }; } } } // ❌ 错误:直接访问数据库 @Injectable() export class LoginService { async login(dto: LoginDto) { const user = await this.userRepository.findOne({ email: dto.email }); // ... } } ``` #### ⚙️ Core Layer(核心层) **位置:** `src/core/` **职责:** - 数据访问 - 基础设施 - 外部系统集成 - 工具服务 **规范:** ```typescript // ✅ 正确:提供技术基础设施 @Injectable() export class LoginCoreService { constructor( @Inject('IUsersService') private readonly usersService: IUsersService, @Inject('IRedisService') private readonly redisService: IRedisService, ) {} async validateUser(dto: LoginDto): Promise { const user = await this.usersService.findByEmail(dto.email); if (!user) { throw new UnauthorizedException('用户不存在'); } const isValid = await bcrypt.compare(dto.password, user.password); if (!isValid) { throw new UnauthorizedException('密码错误'); } return user; } } // ❌ 错误:包含业务逻辑 @Injectable() export class LoginCoreService { async validateUser(dto: LoginDto) { // 发送邮件通知 - 这是业务逻辑,应该在Business层 await this.emailService.sendLoginNotification(user.email); } } ``` ### 模块组织规范 ```typescript // 模块命名:功能名.module.ts // 服务命名:功能名.service.ts // 控制器命名:功能名.controller.ts // 网关命名:功能名.gateway.ts // ✅ 正确的模块结构 src/ ├── gateway/ │ └── auth/ │ ├── login.controller.ts │ ├── register.controller.ts │ ├── jwt_auth.guard.ts │ ├── dto/ │ └── auth.gateway.module.ts ├── business/ │ └── auth/ │ ├── login.service.ts │ ├── register.service.ts │ └── auth.module.ts └── core/ └── login_core/ ├── login_core.service.ts └── login_core.module.ts ``` --- ## � 注释规规范 ### 文件头注释 ```typescript /** * 用户登录服务 * * 功能描述: * - 处理用户登录业务逻辑 * - 协调登录核心服务和邮件服务 * - 生成JWT令牌 * * 架构层级:Business Layer * * 依赖服务: * - LoginCoreService: 登录核心逻辑 * - EmailService: 邮件发送服务 * * @author 作者名 * @version 1.0.0 * @since 2025-01-01 */ ``` ### 类注释 ```typescript /** * 登录业务服务 * * 职责: * - 实现用户登录业务逻辑 * - 协调核心服务完成登录流程 * - 处理登录相关的业务规则 * * 主要方法: * - login() - 用户登录 * - verificationCodeLogin() - 验证码登录 * - refreshToken() - 刷新令牌 */ @Injectable() export class LoginService { // 实现 } ``` ### 方法注释(三级标准) ```typescript /** * 用户登录 * * 业务逻辑: * 1. 调用核心服务验证用户凭证 * 2. 生成访问令牌和刷新令牌 * 3. 发送登录成功通知邮件 * 4. 记录登录日志 * 5. 返回登录结果 * * @param dto 登录请求数据 * @returns 登录结果,包含用户信息和令牌 * @throws UnauthorizedException 用户名或密码错误 * @throws ForbiddenException 用户状态不允许登录 * * @example * ```typescript * const result = await loginService.login({ * identifier: 'user@example.com', * password: 'password123' * }); * ``` */ async login(dto: LoginDto): Promise> { // 实现 } ``` ### 修改记录规范 ```typescript /** * 最近修改: * - 2025-01-15: 架构重构 - 迁移到四层架构,分离网关层和业务层 * - 2025-01-10: 功能新增 - 添加验证码登录功能 * - 2025-01-08: Bug修复 - 修复Token刷新逻辑错误 * - 2025-01-05: 代码规范优化 - 统一异常处理格式 * - 2025-01-03: 性能优化 - 优化数据库查询性能 * * @version 2.0.0 * @lastModified 2025-01-15 */ ``` **修改记录原则:** - 只保留最近5次修改 - 包含日期、类型、描述 - 重大版本更新标注版本号 --- ## 📊 日志规范 ### 日志级别使用 ```typescript // ERROR - 系统错误,需要立即处理 this.logger.error('用户登录失败', { userId, error: error.message, stack: error.stack }); // WARN - 警告信息,需要关注 this.logger.warn('用户多次登录失败', { userId, attemptCount, ip: request.ip }); // INFO - 重要的业务操作 this.logger.info('用户登录成功', { userId, loginTime: new Date(), ip: request.ip }); // DEBUG - 调试信息(仅开发环境) this.logger.debug('验证用户密码', { userId, passwordHash: '***' }); ``` ### 日志格式规范 ```typescript // ✅ 正确:结构化日志 this.logger.info('操作描述', { userId: 'user123', action: 'login', timestamp: new Date(), metadata: { ip: '192.168.1.1' } }); // ❌ 错误:字符串拼接 this.logger.info(`用户${userId}登录成功`); ``` ### 敏感信息处理 ```typescript // ✅ 正确:隐藏敏感信息 this.logger.info('用户注册', { email: user.email, password: '***', // 密码不记录 apiKey: '***' // API密钥不记录 }); // ❌ 错误:暴露敏感信息 this.logger.info('用户注册', { email: user.email, password: user.password, // 危险! apiKey: user.apiKey // 危险! }); ``` --- ## ⚠️ 异常处理规范 ### 异常类型使用 ```typescript // 400 - 客户端请求错误 throw new BadRequestException('参数格式错误'); // 401 - 未授权 throw new UnauthorizedException('用户名或密码错误'); // 403 - 禁止访问 throw new ForbiddenException('用户状态不允许此操作'); // 404 - 资源不存在 throw new NotFoundException('用户不存在'); // 409 - 资源冲突 throw new ConflictException('用户名已存在'); // 500 - 服务器内部错误 throw new InternalServerErrorException('系统内部错误'); ``` ### 分层异常处理 ```typescript // Gateway Layer - 转换为HTTP响应 @Controller('auth') export class LoginController { @Post('login') async login(@Body() dto: LoginDto, @Res() res: Response) { const result = await this.loginService.login(dto); if (result.success) { res.status(HttpStatus.OK).json(result); } else { const statusCode = this.getErrorStatusCode(result); res.status(statusCode).json(result); } } } // Business Layer - 返回业务响应 @Injectable() export class LoginService { async login(dto: LoginDto): Promise> { try { const user = await this.loginCoreService.validateUser(dto); const tokens = await this.loginCoreService.generateTokens(user); return { success: true, data: tokens, message: '登录成功' }; } catch (error) { this.logger.error('登录失败', { dto, error: error.message }); return { success: false, message: error.message, error_code: 'LOGIN_FAILED' }; } } } // Core Layer - 抛出技术异常 @Injectable() export class LoginCoreService { async validateUser(dto: LoginDto): Promise { const user = await this.usersService.findByEmail(dto.email); if (!user) { throw new UnauthorizedException('用户不存在'); } const isValid = await bcrypt.compare(dto.password, user.password); if (!isValid) { throw new UnauthorizedException('密码错误'); } return user; } } ``` --- ## 🔍 代码质量规范 ### 代码检查清单 提交代码前确保: - [ ] **架构规范** - [ ] 代码放在正确的架构层 - [ ] 没有跨层直接调用(如Gateway直接调用Core) - [ ] 依赖方向正确(上层依赖下层) - [ ] 模块职责单一明确 - [ ] **注释完整性** - [ ] 文件头注释包含架构层级说明 - [ ] 类注释说明职责和主要方法 - [ ] 方法注释包含业务逻辑和技术实现 - [ ] 修改记录保持最近5次 - [ ] **代码质量** - [ ] 没有未使用的导入和变量 - [ ] 常量使用正确命名(UPPER_SNAKE_CASE) - [ ] 方法长度合理(不超过50行) - [ ] 单一职责原则 - [ ] **日志规范** - [ ] 关键操作记录日志 - [ ] 使用结构化日志格式 - [ ] 敏感信息已隐藏 - [ ] 日志级别使用正确 - [ ] **异常处理** - [ ] 所有异常情况都处理 - [ ] 异常类型使用正确 - [ ] 错误信息清晰明确 - [ ] 记录了错误日志 --- ## 💡 最佳实践 ### 1. 遵循四层架构 ```typescript // ✅ 正确:清晰的层次调用 // Gateway → Business → Core → Data // Gateway Layer @Controller('users') export class UsersController { constructor(private readonly usersService: UsersService) {} @Get(':id') async getUser(@Param('id') id: string) { return this.usersService.getUserById(id); } } // Business Layer @Injectable() export class UsersService { constructor(private readonly usersCoreService: UsersCoreService) {} async getUserById(id: string): Promise> { try { const user = await this.usersCoreService.findUserById(id); return { success: true, data: user }; } catch (error) { return { success: false, message: error.message }; } } } // Core Layer @Injectable() export class UsersCoreService { constructor( @Inject('IUsersService') private readonly usersDataService: IUsersService ) {} async findUserById(id: string): Promise { const user = await this.usersDataService.findOne(id); if (!user) { throw new NotFoundException('用户不存在'); } return user; } } ``` ### 2. 使用依赖注入接口 ```typescript // ✅ 正确:使用接口依赖注入 @Injectable() export class LoginCoreService { constructor( @Inject('IUsersService') private readonly usersService: IUsersService, @Inject('IRedisService') private readonly redisService: IRedisService, ) {} } // ❌ 错误:直接依赖具体实现 @Injectable() export class LoginCoreService { constructor( private readonly usersService: UsersService, private readonly redisService: RealRedisService, ) {} } ``` ### 3. 统一响应格式 ```typescript // 定义统一的响应接口 export interface ApiResponse { success: boolean; data?: T; message: string; error_code?: string; } // Business Layer 返回统一格式 async login(dto: LoginDto): Promise> { try { const result = await this.loginCoreService.validateUser(dto); return { success: true, data: result, message: '登录成功' }; } catch (error) { return { success: false, message: error.message, error_code: 'LOGIN_FAILED' }; } } ``` ### 4. 防御性编程 ```typescript async processPayment(dto: PaymentDto): Promise> { // 1. 参数验证 if (!dto.amount || dto.amount <= 0) { return { success: false, message: '支付金额必须大于0', error_code: 'INVALID_AMOUNT' }; } // 2. 业务规则验证 const user = await this.usersService.findOne(dto.userId); if (!user) { return { success: false, message: '用户不存在', error_code: 'USER_NOT_FOUND' }; } // 3. 状态检查 if (user.status !== UserStatus.ACTIVE) { return { success: false, message: '用户状态不允许支付', error_code: 'USER_INACTIVE' }; } // 4. 执行业务逻辑 return this.executePayment(dto); } ``` ### 5. 测试驱动开发 ```typescript // 先写测试 describe('LoginService', () => { it('should login successfully with valid credentials', async () => { const dto = { identifier: 'test@example.com', password: 'password123' }; const result = await loginService.login(dto); expect(result.success).toBe(true); expect(result.data).toHaveProperty('accessToken'); }); it('should return error with invalid credentials', async () => { const dto = { identifier: 'test@example.com', password: 'wrong' }; const result = await loginService.login(dto); expect(result.success).toBe(false); expect(result.error_code).toBe('LOGIN_FAILED'); }); }); // 再写实现 @Injectable() export class LoginService { async login(dto: LoginDto): Promise> { // 实现逻辑 } } ``` --- ## 🎯 总结 遵循开发规范能够: 1. **清晰的架构** - 四层架构确保职责分离 2. **高质量代码** - 完整的注释和规范的实现 3. **易于维护** - 清晰的文档和日志便于问题定位 4. **团队协作** - 统一的规范减少沟通成本 5. **系统稳定** - 完善的异常处理和防御性编程 **记住:好的代码不仅要能运行,更要符合架构设计、易于理解、便于维护和扩展。** --- ## 📚 相关文档 - [架构设计文档](../ARCHITECTURE.md) - 四层架构详解 - [架构重构文档](../ARCHITECTURE_REFACTORING.md) - 架构迁移指南 - [Git提交规范](./git_commit_guide.md) - 版本控制规范 - [测试指南](./TESTING.md) - 测试规范和最佳实践