docs:添加架构重构文档

- 新增 ARCHITECTURE_REFACTORING.md 文档
- 记录项目架构重构计划和进度
This commit is contained in:
moyin
2026-01-14 13:17:53 +08:00
parent cf431c210a
commit a147883e05

View File

@@ -0,0 +1,295 @@
# 架构重构文档
## 重构目标
将现有的混合架构重构为清晰的4层架构实现更好的关注点分离和代码组织。
## 架构对比
### 重构前
```
src/
├── business/auth/ # 混合了Gateway和Business职责
│ ├── login.controller.ts # HTTP协议处理
│ ├── login.service.ts # 业务逻辑
│ ├── jwt_auth.guard.ts # 认证守卫
│ └── dto/ # 数据传输对象
└── core/login_core/ # 核心层
└── login_core.service.ts # 数据访问和基础设施
```
### 重构后
```
src/
├── gateway/auth/ # 网关层(新增)
│ ├── login.controller.ts # HTTP协议处理
│ ├── register.controller.ts # HTTP协议处理
│ ├── 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 # 数据访问和基础设施
```
## 4层架构说明
### 1. Transport Layer传输层- 可选
**位置**`src/transport/`
**职责**
- 底层网络通信和连接管理
- WebSocket服务器、TCP/UDP服务器
- 原生Socket连接池管理
**说明**对于HTTP应用NestJS已经提供了传输层无需额外实现。对于WebSocket等特殊协议可以在此层实现。
### 2. Gateway Layer网关层
**位置**`src/gateway/`
**职责**
- HTTP协议处理和请求响应
- 数据验证DTO
- 路由管理
- 认证守卫
- 错误转换(业务错误 → HTTP状态码
- API文档
**原则**
- ✅ 只做协议转换,不做业务逻辑
- ✅ 使用DTO进行数据验证
- ✅ 统一的错误处理
- ❌ 不直接访问数据库
- ❌ 不包含业务规则
**示例**
```typescript
@Controller('auth')
export class LoginController {
constructor(private readonly loginService: LoginService) {}
@Post('login')
async login(@Body() loginDto: LoginDto, @Res() res: Response): Promise<void> {
// 只做协议转换
const result = await this.loginService.login({
identifier: loginDto.identifier,
password: loginDto.password
});
// 转换为HTTP响应
this.handleResponse(result, res);
}
}
```
### 3. Business Layer业务层
**位置**`src/business/`
**职责**
- 业务逻辑实现
- 业务流程控制
- 服务协调
- 业务规则验证
- 事务管理
**原则**
- ✅ 实现所有业务逻辑
- ✅ 协调多个Core层服务
- ✅ 返回统一的业务响应
- ❌ 不处理HTTP协议
- ❌ 不直接访问数据库
**示例**
```typescript
@Injectable()
export class LoginService {
async login(loginRequest: LoginRequest): Promise<ApiResponse<LoginResponse>> {
try {
// 1. 调用核心服务进行认证
const authResult = await this.loginCoreService.login(loginRequest);
// 2. 业务逻辑验证Zulip账号
await this.validateAndUpdateZulipApiKey(authResult.user);
// 3. 生成JWT令牌
const tokenPair = await this.loginCoreService.generateTokenPair(authResult.user);
// 4. 返回业务响应
return {
success: true,
data: { user: this.formatUserInfo(authResult.user), ...tokenPair },
message: '登录成功'
};
} catch (error) {
return {
success: false,
message: error.message,
error_code: 'LOGIN_FAILED'
};
}
}
}
```
### 4. Core Layer核心层
**位置**`src/core/`
**职责**
- 数据访问(数据库、缓存)
- 基础设施Redis、消息队列
- 外部系统集成
- 技术实现细节
**原则**
- ✅ 提供技术基础设施
- ✅ 数据持久化和缓存
- ✅ 外部API集成
- ❌ 不包含业务逻辑
- ❌ 不处理HTTP协议
## 数据流向
```
客户端请求
Gateway Layer (Controller)
↓ 调用
Business Layer (Service)
↓ 调用
Core Layer (Data Access)
数据库/缓存/外部API
```
## 依赖关系
```
Gateway → Business → Core
```
- Gateway层依赖Business层
- Business层依赖Core层
- Core层不依赖任何业务层
- 依赖方向单向,不允许反向依赖
## 重构步骤
### 第一阶段:登录注册模块(已完成)
1. ✅ 创建`src/gateway/auth/`目录
2. ✅ 移动Controller到Gateway层
3. ✅ 移动DTO到Gateway层
4. ✅ 移动Guard到Gateway层
5. ✅ 创建`AuthGatewayModule`
6. ✅ 更新Business层模块移除Controller
7. ✅ 更新`app.module.ts`使用新的Gateway模块
8. ✅ 创建架构文档
### 第二阶段:其他业务模块(待进行)
- [ ] 重构`location_broadcast`模块
- [ ] 重构`user_mgmt`模块
- [ ] 重构`admin`模块
- [ ] 重构`zulip`模块
- [ ] 重构`notice`模块
### 第三阶段WebSocket模块待进行
- [ ] 创建`src/transport/websocket/`
- [ ] 实现原生WebSocket服务器
- [ ] 创建`src/gateway/location-broadcast/`
- [ ] 移动WebSocket Gateway到Gateway层
## 迁移指南
### 如何判断代码应该放在哪一层?
**Gateway层**
- 包含`@Controller()`装饰器
- 包含`@Get()`, `@Post()`等HTTP方法装饰器
- 包含`@Body()`, `@Param()`, `@Query()`等参数装饰器
- 包含DTO类`class LoginDto`
- 包含Guard类`class JwtAuthGuard`
**Business层**
- 包含`@Injectable()`装饰器
- 包含业务逻辑方法
- 协调多个服务
- 返回`ApiResponse<T>`格式的响应
**Core层**
- 包含数据库访问代码
- 包含Redis操作代码
- 包含外部API调用
- 包含技术实现细节
### 重构Checklist
对于每个模块:
1. [ ] 识别Controller文件
2. [ ] 创建对应的Gateway目录
3. [ ] 移动Controller到Gateway层
4. [ ] 移动DTO到Gateway层的`dto/`目录
5. [ ] 移动Guard到Gateway层
6. [ ] 创建Gateway Module
7. [ ] 更新Business Module移除Controller
8. [ ] 更新imports修正路径
9. [ ] 更新app.module.ts
10. [ ] 运行测试确保功能正常
## 最佳实践
### 1. 保持层级职责清晰
每一层只做自己职责范围内的事情,不要越界。
### 2. 使用统一的响应格式
Business层返回统一的`ApiResponse<T>`格式:
```typescript
interface ApiResponse<T = any> {
success: boolean;
data?: T;
message: string;
error_code?: string;
}
```
### 3. 错误处理分层
- Gateway层将业务错误转换为HTTP状态码
- Business层捕获异常并转换为业务错误
- Core层抛出技术异常
### 4. 依赖注入
使用NestJS的依赖注入系统通过Module配置依赖关系。
### 5. 文档完善
每个层级都应该有README文档说明职责和使用方法。
## 注意事项
1. **渐进式重构**:不要一次性重构所有模块,逐个模块进行
2. **保持测试**:重构后运行测试确保功能正常
3. **向后兼容**重构过程中保持API接口不变
4. **代码审查**:重构代码需要经过代码审查
5. **文档更新**:及时更新相关文档
## 参考资料
- [NestJS官方文档](https://docs.nestjs.com/)
- [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
- [Hexagonal Architecture](https://alistair.cockburn.us/hexagonal-architecture/)