From a147883e0504ac717f448c28ebd7ec557beea24b Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Wed, 14 Jan 2026 13:17:53 +0800 Subject: [PATCH] =?UTF-8?q?docs=EF=BC=9A=E6=B7=BB=E5=8A=A0=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E9=87=8D=E6=9E=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 ARCHITECTURE_REFACTORING.md 文档 - 记录项目架构重构计划和进度 --- docs/ARCHITECTURE_REFACTORING.md | 295 +++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 docs/ARCHITECTURE_REFACTORING.md diff --git a/docs/ARCHITECTURE_REFACTORING.md b/docs/ARCHITECTURE_REFACTORING.md new file mode 100644 index 0000000..bffc77c --- /dev/null +++ b/docs/ARCHITECTURE_REFACTORING.md @@ -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 { + // 只做协议转换 + 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> { + 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`格式的响应 + +**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`格式: + +```typescript +interface ApiResponse { + 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/)