docs:简化架构文档,突出四层架构核心设计
- 精简ARCHITECTURE.md,移除冗长的目录结构说明 - 突出四层架构的职责和原则 - 保留核心的架构图和依赖关系说明 - 简化双模式架构和模块依赖的描述 - 移除过于详细的扩展指南,保留核心内容
This commit is contained in:
1063
docs/ARCHITECTURE.md
1063
docs/ARCHITECTURE.md
File diff suppressed because it is too large
Load Diff
@@ -1,45 +1,220 @@
|
||||
# 后端开发规范指南
|
||||
|
||||
本文档定义了后端开发的核心规范,包括注释规范、日志规范、业务逻辑规范等,确保代码质量和团队协作效率。
|
||||
本文档定义了基于四层架构的后端开发规范,包括架构规范、注释规范、日志规范、代码质量规范等。
|
||||
|
||||
## 📋 目录
|
||||
|
||||
- [架构规范](#架构规范)
|
||||
- [注释规范](#注释规范)
|
||||
- [日志规范](#日志规范)
|
||||
- [业务逻辑规范](#业务逻辑规范)
|
||||
- [异常处理规范](#异常处理规范)
|
||||
- [代码质量规范](#代码质量规范)
|
||||
- [最佳实践](#最佳实践)
|
||||
|
||||
---
|
||||
|
||||
## 📝 注释规范
|
||||
## 🏗️ 架构规范
|
||||
|
||||
### 四层架构原则
|
||||
|
||||
项目采用 **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<ApiResponse<LoginResponse>> {
|
||||
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<User> {
|
||||
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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## <20> 注释规规范
|
||||
|
||||
### 文件头注释
|
||||
|
||||
每个 TypeScript 文件都必须包含完整的文件头注释:
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* 文件功能描述
|
||||
* 用户登录服务
|
||||
*
|
||||
* 功能描述:
|
||||
* - 主要功能点1
|
||||
* - 主要功能点2
|
||||
* - 主要功能点3
|
||||
* - 处理用户登录业务逻辑
|
||||
* - 协调登录核心服务和邮件服务
|
||||
* - 生成JWT令牌
|
||||
*
|
||||
* 职责分离:
|
||||
* - 职责描述1
|
||||
* - 职责描述2
|
||||
* 架构层级:Business Layer
|
||||
*
|
||||
* 最近修改:
|
||||
* - YYYY-MM-DD: 修改类型 - 具体修改内容描述
|
||||
* - YYYY-MM-DD: 修改类型 - 具体修改内容描述
|
||||
* 依赖服务:
|
||||
* - LoginCoreService: 登录核心逻辑
|
||||
* - EmailService: 邮件发送服务
|
||||
*
|
||||
* @author 作者名
|
||||
* @version x.x.x
|
||||
* @since 创建日期
|
||||
* @lastModified 最后修改日期
|
||||
* @version 1.0.0
|
||||
* @since 2025-01-01
|
||||
*/
|
||||
```
|
||||
|
||||
@@ -47,149 +222,75 @@
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* 类功能描述
|
||||
* 登录业务服务
|
||||
*
|
||||
* 职责:
|
||||
* - 主要职责1
|
||||
* - 主要职责2
|
||||
* - 实现用户登录业务逻辑
|
||||
* - 协调核心服务完成登录流程
|
||||
* - 处理登录相关的业务规则
|
||||
*
|
||||
* 主要方法:
|
||||
* - method1() - 方法1功能
|
||||
* - method2() - 方法2功能
|
||||
*
|
||||
* 使用场景:
|
||||
* - 场景描述
|
||||
* - login() - 用户登录
|
||||
* - verificationCodeLogin() - 验证码登录
|
||||
* - refreshToken() - 刷新令牌
|
||||
*/
|
||||
@Injectable()
|
||||
export class ExampleService {
|
||||
// 类实现
|
||||
export class LoginService {
|
||||
// 实现
|
||||
}
|
||||
```
|
||||
|
||||
### 方法注释(三级注释标准)
|
||||
### 方法注释(三级标准)
|
||||
|
||||
**必须包含以下三个级别的注释:**
|
||||
|
||||
#### 1. 功能描述级别
|
||||
```typescript
|
||||
/**
|
||||
* 用户登录验证
|
||||
*/
|
||||
```
|
||||
|
||||
#### 2. 业务逻辑级别
|
||||
```typescript
|
||||
/**
|
||||
* 用户登录验证
|
||||
* 用户登录
|
||||
*
|
||||
* 业务逻辑:
|
||||
* 1. 验证用户名或邮箱格式
|
||||
* 2. 查找用户记录
|
||||
* 3. 验证密码哈希值
|
||||
* 4. 检查用户状态是否允许登录
|
||||
* 5. 记录登录日志
|
||||
* 6. 返回认证结果
|
||||
*/
|
||||
```
|
||||
|
||||
#### 3. 技术实现级别
|
||||
```typescript
|
||||
/**
|
||||
* 用户登录验证
|
||||
* 1. 调用核心服务验证用户凭证
|
||||
* 2. 生成访问令牌和刷新令牌
|
||||
* 3. 发送登录成功通知邮件
|
||||
* 4. 记录登录日志
|
||||
* 5. 返回登录结果
|
||||
*
|
||||
* 业务逻辑:
|
||||
* 1. 验证用户名或邮箱格式
|
||||
* 2. 查找用户记录
|
||||
* 3. 验证密码哈希值
|
||||
* 4. 检查用户状态是否允许登录
|
||||
* 5. 记录登录日志
|
||||
* 6. 返回认证结果
|
||||
*
|
||||
* @param loginRequest 登录请求数据
|
||||
* @returns 认证结果,包含用户信息和认证状态
|
||||
* @throws UnauthorizedException 用户名或密码错误时
|
||||
* @throws ForbiddenException 用户状态不允许登录时
|
||||
* @param dto 登录请求数据
|
||||
* @returns 登录结果,包含用户信息和令牌
|
||||
* @throws UnauthorizedException 用户名或密码错误
|
||||
* @throws ForbiddenException 用户状态不允许登录
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const result = await loginService.validateUser({
|
||||
* const result = await loginService.login({
|
||||
* identifier: 'user@example.com',
|
||||
* password: 'password123'
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
async validateUser(loginRequest: LoginRequest): Promise<AuthResult> {
|
||||
// 实现代码
|
||||
async login(dto: LoginDto): Promise<ApiResponse<LoginResponse>> {
|
||||
// 实现
|
||||
}
|
||||
```
|
||||
|
||||
### 修改记录规范
|
||||
|
||||
#### 修改类型定义
|
||||
|
||||
- **代码规范优化** - 命名规范、注释规范、代码清理等
|
||||
- **功能新增** - 添加新的功能或方法
|
||||
- **功能修改** - 修改现有功能的实现
|
||||
- **Bug修复** - 修复代码缺陷
|
||||
- **性能优化** - 提升代码性能
|
||||
- **重构** - 代码结构调整但功能不变
|
||||
|
||||
#### 修改记录格式
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* 最近修改:
|
||||
* - 2025-01-07: 代码规范优化 - 清理未使用的导入(EmailSendResult, crypto)
|
||||
* - 2025-01-07: 代码规范优化 - 修复常量命名(saltRounds -> SALT_ROUNDS)
|
||||
* - 2025-01-07: 功能新增 - 添加用户验证码登录功能
|
||||
* - 2025-01-06: Bug修复 - 修复邮箱验证逻辑错误
|
||||
* - 2025-01-15: 架构重构 - 迁移到四层架构,分离网关层和业务层
|
||||
* - 2025-01-10: 功能新增 - 添加验证码登录功能
|
||||
* - 2025-01-08: Bug修复 - 修复Token刷新逻辑错误
|
||||
* - 2025-01-05: 代码规范优化 - 统一异常处理格式
|
||||
* - 2025-01-03: 性能优化 - 优化数据库查询性能
|
||||
*
|
||||
* @version 1.0.1 (修改后需要递增版本号)
|
||||
* @lastModified 2025-01-07
|
||||
* @version 2.0.0
|
||||
* @lastModified 2025-01-15
|
||||
*/
|
||||
```
|
||||
|
||||
#### 修改记录长度限制
|
||||
|
||||
**重要:为保持文件头注释简洁,修改记录只保留最近的5次修改。**
|
||||
|
||||
- ✅ **保留最新5条记录** - 便于快速了解最近变更
|
||||
- ✅ **超出时删除最旧记录** - 保持注释简洁
|
||||
- ✅ **重要修改可标注** - 重大版本更新可特别标注
|
||||
|
||||
```typescript
|
||||
// ✅ 正确示例:保持最新5条记录
|
||||
/**
|
||||
* 最近修改:
|
||||
* - 2025-01-07: 功能新增 - 添加用户头像上传功能
|
||||
* - 2025-01-06: Bug修复 - 修复邮箱验证逻辑错误
|
||||
* - 2025-01-05: 代码规范优化 - 统一异常处理格式
|
||||
* - 2025-01-04: 功能修改 - 优化用户状态管理逻辑
|
||||
* - 2025-01-03: 性能优化 - 优化数据库查询性能
|
||||
*
|
||||
* @version 1.3.0
|
||||
*/
|
||||
|
||||
// ❌ 错误示例:记录过多,注释冗长
|
||||
/**
|
||||
* 最近修改:
|
||||
* - 2025-01-07: 功能新增 - 添加用户头像上传功能
|
||||
* - 2025-01-06: Bug修复 - 修复邮箱验证逻辑错误
|
||||
* - 2025-01-05: 代码规范优化 - 统一异常处理格式
|
||||
* - 2025-01-04: 功能修改 - 优化用户状态管理逻辑
|
||||
* - 2025-01-03: 性能优化 - 优化数据库查询性能
|
||||
* - 2025-01-02: 重构 - 重构用户认证逻辑
|
||||
* - 2025-01-01: 功能新增 - 添加用户权限管理
|
||||
* - 2024-12-31: Bug修复 - 修复登录超时问题
|
||||
* // ... 更多记录导致注释过长
|
||||
*/
|
||||
```
|
||||
|
||||
#### 版本号递增规则
|
||||
|
||||
- **代码规范优化、Bug修复** → 修订版本 +1 (1.0.0 → 1.0.1)
|
||||
- **功能新增、功能修改** → 次版本 +1 (1.0.1 → 1.1.0)
|
||||
- **重构、架构变更** → 主版本 +1 (1.1.0 → 2.0.0)
|
||||
**修改记录原则:**
|
||||
- 只保留最近5次修改
|
||||
- 包含日期、类型、描述
|
||||
- 重大版本更新标注版本号
|
||||
|
||||
---
|
||||
|
||||
@@ -199,22 +300,37 @@ async validateUser(loginRequest: LoginRequest): Promise<AuthResult> {
|
||||
|
||||
```typescript
|
||||
// ERROR - 系统错误,需要立即处理
|
||||
this.logger.error('用户登录失败', { userId, error: error.message });
|
||||
this.logger.error('用户登录失败', {
|
||||
userId,
|
||||
error: error.message,
|
||||
stack: error.stack
|
||||
});
|
||||
|
||||
// WARN - 警告信息,需要关注但不影响系统运行
|
||||
this.logger.warn('用户多次登录失败', { userId, attemptCount });
|
||||
// WARN - 警告信息,需要关注
|
||||
this.logger.warn('用户多次登录失败', {
|
||||
userId,
|
||||
attemptCount,
|
||||
ip: request.ip
|
||||
});
|
||||
|
||||
// INFO - 重要的业务操作记录
|
||||
this.logger.info('用户登录成功', { userId, loginTime: new Date() });
|
||||
// INFO - 重要的业务操作
|
||||
this.logger.info('用户登录成功', {
|
||||
userId,
|
||||
loginTime: new Date(),
|
||||
ip: request.ip
|
||||
});
|
||||
|
||||
// DEBUG - 调试信息,仅在开发环境使用
|
||||
this.logger.debug('验证用户密码', { userId, hashedPassword: '***' });
|
||||
// DEBUG - 调试信息(仅开发环境)
|
||||
this.logger.debug('验证用户密码', {
|
||||
userId,
|
||||
passwordHash: '***'
|
||||
});
|
||||
```
|
||||
|
||||
### 日志格式规范
|
||||
|
||||
```typescript
|
||||
// ✅ 正确格式
|
||||
// ✅ 正确:结构化日志
|
||||
this.logger.info('操作描述', {
|
||||
userId: 'user123',
|
||||
action: 'login',
|
||||
@@ -222,68 +338,26 @@ this.logger.info('操作描述', {
|
||||
metadata: { ip: '192.168.1.1' }
|
||||
});
|
||||
|
||||
// ❌ 错误格式
|
||||
this.logger.info('用户登录');
|
||||
// ❌ 错误:字符串拼接
|
||||
this.logger.info(`用户${userId}登录成功`);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 业务逻辑规范
|
||||
|
||||
### 防御性编程
|
||||
### 敏感信息处理
|
||||
|
||||
```typescript
|
||||
async getUserById(userId: string): Promise<User> {
|
||||
// 1. 参数验证
|
||||
if (!userId) {
|
||||
throw new BadRequestException('用户ID不能为空');
|
||||
}
|
||||
// ✅ 正确:隐藏敏感信息
|
||||
this.logger.info('用户注册', {
|
||||
email: user.email,
|
||||
password: '***', // 密码不记录
|
||||
apiKey: '***' // API密钥不记录
|
||||
});
|
||||
|
||||
// 2. 业务逻辑验证
|
||||
const user = await this.usersService.findOne(userId);
|
||||
if (!user) {
|
||||
throw new NotFoundException('用户不存在');
|
||||
}
|
||||
|
||||
// 3. 状态检查
|
||||
if (user.status === UserStatus.DELETED) {
|
||||
throw new ForbiddenException('用户已被删除');
|
||||
}
|
||||
|
||||
// 4. 返回结果
|
||||
return user;
|
||||
}
|
||||
```
|
||||
|
||||
### 业务逻辑分层
|
||||
|
||||
```typescript
|
||||
// Controller 层 - 只处理HTTP请求和响应
|
||||
@Controller('users')
|
||||
export class UsersController {
|
||||
@Get(':id')
|
||||
async getUser(@Param('id') id: string) {
|
||||
return this.usersService.getUserById(id);
|
||||
}
|
||||
}
|
||||
|
||||
// Service 层 - 处理业务逻辑
|
||||
@Injectable()
|
||||
export class UsersService {
|
||||
async getUserById(id: string): Promise<User> {
|
||||
// 业务逻辑实现
|
||||
return this.usersCoreService.findUserById(id);
|
||||
}
|
||||
}
|
||||
|
||||
// Core 层 - 核心业务实现
|
||||
@Injectable()
|
||||
export class UsersCoreService {
|
||||
async findUserById(id: string): Promise<User> {
|
||||
// 核心逻辑实现
|
||||
}
|
||||
}
|
||||
// ❌ 错误:暴露敏感信息
|
||||
this.logger.info('用户注册', {
|
||||
email: user.email,
|
||||
password: user.password, // 危险!
|
||||
apiKey: user.apiKey // 危险!
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
@@ -312,38 +386,66 @@ throw new ConflictException('用户名已存在');
|
||||
throw new InternalServerErrorException('系统内部错误');
|
||||
```
|
||||
|
||||
### 异常处理模式
|
||||
### 分层异常处理
|
||||
|
||||
```typescript
|
||||
async createUser(userData: CreateUserDto): Promise<User> {
|
||||
try {
|
||||
// 1. 参数验证
|
||||
this.validateUserData(userData);
|
||||
// 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);
|
||||
|
||||
// 2. 业务逻辑检查
|
||||
await this.checkUserExists(userData.email);
|
||||
if (result.success) {
|
||||
res.status(HttpStatus.OK).json(result);
|
||||
} else {
|
||||
const statusCode = this.getErrorStatusCode(result);
|
||||
res.status(statusCode).json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 执行创建操作
|
||||
const user = await this.usersRepository.create(userData);
|
||||
// Business Layer - 返回业务响应
|
||||
@Injectable()
|
||||
export class LoginService {
|
||||
async login(dto: LoginDto): Promise<ApiResponse<LoginResponse>> {
|
||||
try {
|
||||
const user = await this.loginCoreService.validateUser(dto);
|
||||
const tokens = await this.loginCoreService.generateTokens(user);
|
||||
|
||||
// 4. 记录成功日志
|
||||
this.logger.info('用户创建成功', { userId: user.id });
|
||||
return {
|
||||
success: true,
|
||||
data: tokens,
|
||||
message: '登录成功'
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error('登录失败', { dto, error: error.message });
|
||||
|
||||
return user;
|
||||
} catch (error) {
|
||||
// 5. 记录错误日志
|
||||
this.logger.error('用户创建失败', {
|
||||
userData: { ...userData, password: '***' },
|
||||
error: error.message
|
||||
});
|
||||
return {
|
||||
success: false,
|
||||
message: error.message,
|
||||
error_code: 'LOGIN_FAILED'
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 重新抛出业务异常
|
||||
if (error instanceof BadRequestException) {
|
||||
throw error;
|
||||
// Core Layer - 抛出技术异常
|
||||
@Injectable()
|
||||
export class LoginCoreService {
|
||||
async validateUser(dto: LoginDto): Promise<User> {
|
||||
const user = await this.usersService.findByEmail(dto.email);
|
||||
|
||||
if (!user) {
|
||||
throw new UnauthorizedException('用户不存在');
|
||||
}
|
||||
|
||||
// 7. 转换为系统异常
|
||||
throw new InternalServerErrorException('用户创建失败');
|
||||
const isValid = await bcrypt.compare(dto.password, user.password);
|
||||
if (!isValid) {
|
||||
throw new UnauthorizedException('密码错误');
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -354,152 +456,233 @@ async createUser(userData: CreateUserDto): Promise<User> {
|
||||
|
||||
### 代码检查清单
|
||||
|
||||
在提交代码前,请确保:
|
||||
提交代码前确保:
|
||||
|
||||
- [ ] **架构规范**
|
||||
- [ ] 代码放在正确的架构层
|
||||
- [ ] 没有跨层直接调用(如Gateway直接调用Core)
|
||||
- [ ] 依赖方向正确(上层依赖下层)
|
||||
- [ ] 模块职责单一明确
|
||||
|
||||
- [ ] **注释完整性**
|
||||
- [ ] 文件头注释包含功能描述、修改记录、作者信息
|
||||
- [ ] 类注释包含职责、主要方法、使用场景
|
||||
- [ ] 方法注释包含三级注释(功能、业务逻辑、技术实现)
|
||||
- [ ] 修改现有文件时添加了修改记录和更新版本号
|
||||
- [ ] 修改记录只保留最近5次,保持注释简洁
|
||||
|
||||
- [ ] **业务逻辑完整性**
|
||||
- [ ] 所有参数都进行了验证
|
||||
- [ ] 所有异常情况都进行了处理
|
||||
- [ ] 关键操作都记录了日志
|
||||
- [ ] 业务逻辑考虑了所有边界情况
|
||||
- [ ] 文件头注释包含架构层级说明
|
||||
- [ ] 类注释说明职责和主要方法
|
||||
- [ ] 方法注释包含业务逻辑和技术实现
|
||||
- [ ] 修改记录保持最近5次
|
||||
|
||||
- [ ] **代码质量**
|
||||
- [ ] 没有未使用的导入和变量
|
||||
- [ ] 常量使用了正确的命名规范
|
||||
- [ ] 方法长度合理(建议不超过50行)
|
||||
- [ ] 单一职责原则,每个方法只做一件事
|
||||
- [ ] 常量使用正确命名(UPPER_SNAKE_CASE)
|
||||
- [ ] 方法长度合理(不超过50行)
|
||||
- [ ] 单一职责原则
|
||||
|
||||
- [ ] **安全性**
|
||||
- [ ] 敏感信息不在日志中暴露
|
||||
- [ ] 用户输入都进行了验证和清理
|
||||
- [ ] 权限检查在适当的位置进行
|
||||
- [ ] **日志规范**
|
||||
- [ ] 关键操作记录日志
|
||||
- [ ] 使用结构化日志格式
|
||||
- [ ] 敏感信息已隐藏
|
||||
- [ ] 日志级别使用正确
|
||||
|
||||
- [ ] **异常处理**
|
||||
- [ ] 所有异常情况都处理
|
||||
- [ ] 异常类型使用正确
|
||||
- [ ] 错误信息清晰明确
|
||||
- [ ] 记录了错误日志
|
||||
|
||||
---
|
||||
|
||||
## 💡 最佳实践
|
||||
|
||||
### 1. 注释驱动开发
|
||||
### 1. 遵循四层架构
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* 用户注册功能
|
||||
*
|
||||
* 业务逻辑:
|
||||
* 1. 验证邮箱格式和唯一性
|
||||
* 2. 验证密码强度
|
||||
* 3. 生成邮箱验证码
|
||||
* 4. 创建用户记录
|
||||
* 5. 发送验证邮件
|
||||
* 6. 返回注册结果
|
||||
*
|
||||
* @param registerData 注册数据
|
||||
* @returns 注册结果
|
||||
*/
|
||||
async registerUser(registerData: RegisterDto): Promise<RegisterResult> {
|
||||
// 先写注释,再写实现
|
||||
// 这样确保逻辑清晰,不遗漏步骤
|
||||
// ✅ 正确:清晰的层次调用
|
||||
// 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<ApiResponse<User>> {
|
||||
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<User> {
|
||||
const user = await this.usersDataService.findOne(id);
|
||||
if (!user) {
|
||||
throw new NotFoundException('用户不存在');
|
||||
}
|
||||
return user;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 错误优先处理
|
||||
### 2. 使用依赖注入接口
|
||||
|
||||
```typescript
|
||||
async processPayment(paymentData: PaymentDto): Promise<PaymentResult> {
|
||||
// 1. 先处理所有可能的错误情况
|
||||
if (!paymentData.amount || paymentData.amount <= 0) {
|
||||
throw new BadRequestException('支付金额必须大于0');
|
||||
}
|
||||
// ✅ 正确:使用接口依赖注入
|
||||
@Injectable()
|
||||
export class LoginCoreService {
|
||||
constructor(
|
||||
@Inject('IUsersService')
|
||||
private readonly usersService: IUsersService,
|
||||
@Inject('IRedisService')
|
||||
private readonly redisService: IRedisService,
|
||||
) {}
|
||||
}
|
||||
|
||||
if (!paymentData.userId) {
|
||||
throw new BadRequestException('用户ID不能为空');
|
||||
}
|
||||
|
||||
const user = await this.usersService.findOne(paymentData.userId);
|
||||
if (!user) {
|
||||
throw new NotFoundException('用户不存在');
|
||||
}
|
||||
|
||||
// 2. 再处理正常的业务逻辑
|
||||
return this.executePayment(paymentData);
|
||||
// ❌ 错误:直接依赖具体实现
|
||||
@Injectable()
|
||||
export class LoginCoreService {
|
||||
constructor(
|
||||
private readonly usersService: UsersService,
|
||||
private readonly redisService: RealRedisService,
|
||||
) {}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 日志驱动调试
|
||||
### 3. 统一响应格式
|
||||
|
||||
```typescript
|
||||
async complexBusinessLogic(data: ComplexData): Promise<Result> {
|
||||
this.logger.debug('开始执行复杂业务逻辑', { data });
|
||||
// 定义统一的响应接口
|
||||
export interface ApiResponse<T = any> {
|
||||
success: boolean;
|
||||
data?: T;
|
||||
message: string;
|
||||
error_code?: string;
|
||||
}
|
||||
|
||||
// Business Layer 返回统一格式
|
||||
async login(dto: LoginDto): Promise<ApiResponse<LoginResponse>> {
|
||||
try {
|
||||
// 步骤1
|
||||
const step1Result = await this.step1(data);
|
||||
this.logger.debug('步骤1完成', { step1Result });
|
||||
|
||||
// 步骤2
|
||||
const step2Result = await this.step2(step1Result);
|
||||
this.logger.debug('步骤2完成', { step2Result });
|
||||
|
||||
// 步骤3
|
||||
const finalResult = await this.step3(step2Result);
|
||||
this.logger.info('复杂业务逻辑执行成功', { finalResult });
|
||||
|
||||
return finalResult;
|
||||
const result = await this.loginCoreService.validateUser(dto);
|
||||
return {
|
||||
success: true,
|
||||
data: result,
|
||||
message: '登录成功'
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error('复杂业务逻辑执行失败', { data, error: error.message });
|
||||
throw error;
|
||||
return {
|
||||
success: false,
|
||||
message: error.message,
|
||||
error_code: 'LOGIN_FAILED'
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 版本管理最佳实践
|
||||
### 4. 防御性编程
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* 用户服务
|
||||
*
|
||||
* 最近修改:
|
||||
* - 2025-01-07: 功能新增 - 添加用户头像上传功能 (v1.2.0)
|
||||
* - 2025-01-06: Bug修复 - 修复邮箱验证逻辑错误 (v1.1.1)
|
||||
* - 2025-01-05: 代码规范优化 - 统一异常处理格式 (v1.1.0)
|
||||
* - 2025-01-04: 功能新增 - 添加用户状态管理 (v1.1.0)
|
||||
* - 2025-01-03: 重构 - 重构用户认证逻辑 (v2.0.0)
|
||||
*
|
||||
* @version 1.2.0
|
||||
* @lastModified 2025-01-07
|
||||
*/
|
||||
async processPayment(dto: PaymentDto): Promise<ApiResponse<PaymentResult>> {
|
||||
// 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次修改
|
||||
- ✅ **定期清理** - 超出5条时删除最旧记录
|
||||
- ✅ **重要标注** - 重大版本更新可特别标注版本号
|
||||
- ✅ **描述清晰** - 每条记录都要说明具体改动内容
|
||||
### 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<ApiResponse<LoginResponse>> {
|
||||
// 实现逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 总结
|
||||
|
||||
遵循后端开发规范能够:
|
||||
遵循开发规范能够:
|
||||
|
||||
1. **提高代码质量** - 通过完整的注释和规范的实现
|
||||
2. **提升团队效率** - 统一的规范减少沟通成本
|
||||
3. **降低维护成本** - 清晰的文档和日志便于问题定位
|
||||
4. **增强系统稳定性** - 完善的异常处理和防御性编程
|
||||
5. **促进知识传承** - 详细的修改记录和版本管理
|
||||
1. **清晰的架构** - 四层架构确保职责分离
|
||||
2. **高质量代码** - 完整的注释和规范的实现
|
||||
3. **易于维护** - 清晰的文档和日志便于问题定位
|
||||
4. **团队协作** - 统一的规范减少沟通成本
|
||||
5. **系统稳定** - 完善的异常处理和防御性编程
|
||||
|
||||
**记住:好的代码不仅要能运行,更要能被理解、维护和扩展。**
|
||||
**记住:好的代码不仅要能运行,更要符合架构设计、易于理解、便于维护和扩展。**
|
||||
|
||||
---
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [命名规范](./naming_convention.md) - 代码命名规范
|
||||
- [NestJS 使用指南](./nestjs_guide.md) - 框架最佳实践
|
||||
- [Git 提交规范](./git_commit_guide.md) - 版本控制规范
|
||||
- [AI 辅助开发规范](./AI辅助开发规范指南.md) - AI 辅助开发指南
|
||||
- [架构设计文档](../ARCHITECTURE.md) - 四层架构详解
|
||||
- [架构重构文档](../ARCHITECTURE_REFACTORING.md) - 架构迁移指南
|
||||
- [Git提交规范](./git_commit_guide.md) - 版本控制规范
|
||||
- [测试指南](./TESTING.md) - 测试规范和最佳实践
|
||||
|
||||
Reference in New Issue
Block a user