Merge pull request 'feature/code-standard-auth-20260114' (#45) from feature/code-standard-auth-20260114 into main
Reviewed-on: #45
This commit was merged in pull request #45.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -49,3 +49,4 @@ redis-data/
|
||||
|
||||
config/
|
||||
docs/merge-requests
|
||||
docs/ai-reading/me.config.json
|
||||
295
docs/ARCHITECTURE_REFACTORING.md
Normal file
295
docs/ARCHITECTURE_REFACTORING.md
Normal 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/)
|
||||
@@ -4,28 +4,6 @@
|
||||
|
||||
## 核心贡献者
|
||||
|
||||
### 🏆 主要维护者
|
||||
|
||||
**moyin** - 主要维护者
|
||||
- Gitea: [@moyin](https://gitea.xinghangee.icu/moyin)
|
||||
- Email: xinghang_a@proton.me
|
||||
- 提交数: **112 commits**
|
||||
- 主要贡献:
|
||||
- 🚀 项目架构设计与初始化
|
||||
- 🔐 完整用户认证系统实现
|
||||
- 📧 邮箱验证系统设计与开发
|
||||
- 🗄️ Redis缓存服务(文件存储+真实Redis双模式)
|
||||
- 📝 完整的API文档系统(Swagger UI + OpenAPI)
|
||||
- 🧪 测试框架搭建与507个测试用例编写
|
||||
- 📊 高性能日志系统集成(Pino)
|
||||
- 🔧 项目配置优化与部署方案
|
||||
- 🐛 验证码TTL重置关键问题修复
|
||||
- 📚 完整的项目文档体系建设
|
||||
- 🏗️ **Zulip模块架构重构** - 业务功能模块化架构设计与实现
|
||||
- 📖 **架构文档重写** - 详细的架构设计文档和开发者指南
|
||||
- 🔄 **验证码冷却时间优化** - 自动清除机制设计与实现
|
||||
- 📋 **文档清理优化** - 项目文档结构化整理和维护体系建立
|
||||
|
||||
### 🌟 核心开发者
|
||||
|
||||
**angjustinl** - 核心开发者
|
||||
@@ -57,13 +35,35 @@
|
||||
- 📖 **技术栈文档更新** - 项目技术栈说明完善
|
||||
- 🔧 **项目配置优化** - 构建和开发环境配置改进
|
||||
|
||||
### 🏆 主要维护者
|
||||
|
||||
**moyin** - 主要维护者
|
||||
- Gitea: [@moyin](https://gitea.xinghangee.icu/moyin)
|
||||
- Email: xinghang_a@proton.me
|
||||
- 提交数: **112 commits**
|
||||
- 主要贡献:
|
||||
- 🚀 项目架构设计与初始化
|
||||
- 🔐 完整用户认证系统实现
|
||||
- 📧 邮箱验证系统设计与开发
|
||||
- 🗄️ Redis缓存服务(文件存储+真实Redis双模式)
|
||||
- 📝 完整的API文档系统(Swagger UI + OpenAPI)
|
||||
- 🧪 测试框架搭建与507个测试用例编写
|
||||
- 📊 高性能日志系统集成(Pino)
|
||||
- 🔧 项目配置优化与部署方案
|
||||
- 🐛 验证码TTL重置关键问题修复
|
||||
- 📚 完整的项目文档体系建设
|
||||
- 🏗️ **Zulip模块架构重构** - 业务功能模块化架构设计与实现
|
||||
- 📖 **架构文档重写** - 详细的架构设计文档和开发者指南
|
||||
- 🔄 **验证码冷却时间优化** - 自动清除机制设计与实现
|
||||
- 📋 **文档清理优化** - 项目文档结构化整理和维护体系建立
|
||||
|
||||
## 贡献统计
|
||||
|
||||
| 贡献者 | 提交数 | 主要领域 | 贡献占比 |
|
||||
|--------|--------|----------|----------|
|
||||
| moyin | 112 | 架构设计、核心功能、文档、测试、Zulip重构 | 86% |
|
||||
| jianuo | 11 | 管理员后台、日志系统、部署优化、配置管理 | 8% |
|
||||
| angjustinl | 7 | Zulip集成、功能优化、测试、重构 | 5% |
|
||||
| jianuo | 11 | 管理员后台、日志系统、部署优化、配置管理 | 8% |
|
||||
| moyin | 112 | 架构设计、核心功能、文档、测试、Zulip重构 | 86% |
|
||||
|
||||
## 🌟 最新重要贡献
|
||||
|
||||
|
||||
@@ -1,361 +1,397 @@
|
||||
# AI代码检查执行指南 - Whale Town 游戏服务器
|
||||
# AI Code Inspection Guide - Whale Town Game Server
|
||||
|
||||
## 🎯 执行前准备
|
||||
## 🎯 Pre-execution Setup
|
||||
|
||||
### 📋 必须收集的用户信息
|
||||
在开始任何检查之前,**必须**收集以下信息:
|
||||
- **用户当前日期**:用于修改记录和时间戳更新
|
||||
- **用户名称**:用于@author字段处理和修改记录
|
||||
### 🚀 User Information Setup
|
||||
**Before starting any inspection steps, run the user information script:**
|
||||
|
||||
### 🏗️ 项目特性识别
|
||||
本项目是**NestJS游戏服务器**,具有以下特点:
|
||||
- **双模式架构**:支持数据库模式和内存模式
|
||||
- **实时通信**:基于WebSocket的实时双向通信
|
||||
- **属性测试**:管理员模块使用fast-check进行随机化测试
|
||||
- **分层架构**:Core层(技术实现)+ Business层(业务逻辑)
|
||||
```bash
|
||||
# Enter AI-reading directory
|
||||
cd docs/ai-reading
|
||||
|
||||
## 🔄 执行原则
|
||||
|
||||
### 🚨 中间步骤开始规范(重要)
|
||||
**如果AI从任何中间步骤开始执行(非步骤1开始),必须首先完成以下准备工作:**
|
||||
|
||||
#### 📋 强制信息收集
|
||||
在执行任何中间步骤之前,AI必须:
|
||||
1. **收集用户当前日期**:用于修改记录和时间戳更新
|
||||
2. **收集用户名称**:用于@author字段处理和修改记录
|
||||
3. **确认项目特性**:识别这是NestJS游戏服务器项目的特点
|
||||
|
||||
#### 🔍 全局上下文获取
|
||||
AI必须先了解:
|
||||
- **项目架构**:双模式架构(数据库+内存)、分层结构(Core+Business)
|
||||
- **技术栈**:NestJS、WebSocket、Jest测试、fast-check属性测试
|
||||
- **文件结构**:当前项目的整体文件组织方式
|
||||
- **已有规范**:项目中已建立的命名、注释、测试等规范
|
||||
|
||||
#### 🎯 执行流程约束
|
||||
```
|
||||
中间步骤开始请求
|
||||
↓
|
||||
🚨 强制收集用户信息(日期、名称)
|
||||
↓
|
||||
🚨 强制识别项目特性和上下文
|
||||
↓
|
||||
🚨 强制了解目标步骤的具体要求
|
||||
↓
|
||||
开始执行指定步骤
|
||||
# Run user information setup script
|
||||
node tools/setup-user-info.js
|
||||
```
|
||||
|
||||
**⚠️ 违规处理:如果AI跳过信息收集直接执行中间步骤,用户应要求AI重新开始并完成准备工作。**
|
||||
#### Script Functions
|
||||
- Automatically get current date (YYYY-MM-DD format)
|
||||
- Check if config file exists or date matches
|
||||
- Prompt for username/nickname input if needed
|
||||
- Save to `me.config.json` file for AI inspection steps
|
||||
|
||||
### ⚠️ 强制要求
|
||||
- **分步执行**:每次只执行一个步骤,严禁跳步骤或合并执行
|
||||
- **等待确认**:每步完成后必须等待用户确认才能进行下一步
|
||||
- **修改验证**:每次修改文件后必须重新检查该步骤并提供验证报告
|
||||
- **🔥 修改后必须重新执行当前步骤**:如果在当前步骤中发生了任何修改行为(文件修改、重命名、移动等),AI必须立即重新执行该步骤的完整检查,不能直接进入下一步骤
|
||||
- **问题修复后重检**:如果当前步骤出现问题需要修改时,AI必须在解决问题后重新执行该步骤,确保没有其他遗漏的问题
|
||||
- **用户信息使用**:所有日期字段使用用户提供的真实日期,@author字段正确处理
|
||||
|
||||
### 🎯 执行流程
|
||||
```
|
||||
用户请求代码检查
|
||||
↓
|
||||
收集用户信息(日期、名称)
|
||||
↓
|
||||
识别项目特性
|
||||
↓
|
||||
执行步骤1 → 提供报告 → 等待确认
|
||||
↓
|
||||
[如果发生修改] → 🔥 立即重新执行步骤1 → 验证报告 → 等待确认
|
||||
↓
|
||||
执行步骤2 → 提供报告 → 等待确认
|
||||
↓
|
||||
[如果发生修改] → 🔥 立即重新执行步骤2 → 验证报告 → 等待确认
|
||||
↓
|
||||
执行步骤3 → 提供报告 → 等待确认
|
||||
↓
|
||||
[如果发生修改] → 🔥 立即重新执行步骤3 → 验证报告 → 等待确认
|
||||
↓
|
||||
执行步骤4 → 提供报告 → 等待确认
|
||||
↓
|
||||
[如果发生修改] → 🔥 立即重新执行步骤4 → 验证报告 → 等待确认
|
||||
↓
|
||||
执行步骤5 → 提供报告 → 等待确认
|
||||
↓
|
||||
[如果发生修改] → 🔥 立即重新执行步骤5 → 验证报告 → 等待确认
|
||||
↓
|
||||
执行步骤6 → 提供报告 → 等待确认
|
||||
↓
|
||||
[如果发生修改] → 🔥 立即重新执行步骤6 → 验证报告 → 等待确认
|
||||
↓
|
||||
执行步骤7 → 提供报告 → 等待确认
|
||||
↓
|
||||
[如果发生修改] → 🔥 立即重新执行步骤7 → 验证报告 → 等待确认
|
||||
|
||||
⚠️ 关键规则:任何步骤中发生修改行为后,必须立即重新执行该步骤!
|
||||
#### Config File Format
|
||||
```json
|
||||
{
|
||||
"date": "2026-01-13",
|
||||
"name": "Developer Name"
|
||||
}
|
||||
```
|
||||
|
||||
## 📚 步骤执行指导
|
||||
### 📋 Using Config in AI Inspection Steps
|
||||
When AI executes inspection steps, get user info from config file:
|
||||
|
||||
### 步骤1:命名规范检查
|
||||
**执行时读取:** `step1-naming-convention.md`
|
||||
**重点关注:** 文件夹结构扁平化、游戏服务器特殊文件类型
|
||||
**完成后:** 提供检查报告,等待用户确认
|
||||
```javascript
|
||||
// Read config file
|
||||
const fs = require('fs');
|
||||
const config = JSON.parse(fs.readFileSync('docs/ai-reading/me.config.json', 'utf-8'));
|
||||
|
||||
### 步骤2:注释规范检查
|
||||
**执行时读取:** `step2-comment-standard.md`
|
||||
**重点关注:** @author字段处理、修改记录更新、时间戳规则
|
||||
**完成后:** 提供检查报告,等待用户确认
|
||||
// Get user information
|
||||
const userDate = config.date; // e.g.: "2026-01-13"
|
||||
const userName = config.name; // e.g.: "John"
|
||||
|
||||
### 步骤3:代码质量检查
|
||||
**执行时读取:** `step3-code-quality.md`
|
||||
**重点关注:** TODO项处理、未使用代码清理
|
||||
**完成后:** 提供检查报告,等待用户确认
|
||||
// Use for modification records and @author fields
|
||||
const modifyRecord = `- ${userDate}: Code standard optimization - Clean unused imports (Modified by: ${userName})`;
|
||||
```
|
||||
|
||||
### 步骤4:架构分层检查
|
||||
**执行时读取:** `step4-architecture-layer.md`
|
||||
**重点关注:** Core层命名规范、依赖关系检查
|
||||
**完成后:** 提供检查报告,等待用户确认
|
||||
### 🏗️ Project Characteristics
|
||||
This project is a **NestJS Game Server** with the following features:
|
||||
- **Dual-mode Architecture**: Supports both database and memory modes
|
||||
- **Real-time Communication**: WebSocket-based real-time bidirectional communication
|
||||
- **Property Testing**: Admin modules use fast-check for randomized testing
|
||||
- **Layered Architecture**: Core layer (technical implementation) + Business layer (business logic)
|
||||
|
||||
### 步骤5:测试覆盖检查
|
||||
**执行时读取:** `step5-test-coverage.md`
|
||||
**重点关注:** 严格一对一测试映射、测试文件位置、测试执行验证
|
||||
**完成后:** 提供检查报告,等待用户确认
|
||||
## 🔄 Execution Principles
|
||||
|
||||
#### 🧪 测试文件调试规范
|
||||
**调试测试文件时必须遵循以下流程:**
|
||||
### 🚨 Mid-step Start Requirements (Important)
|
||||
**If AI starts execution from any intermediate step (not starting from step 1), must first complete the following preparation:**
|
||||
|
||||
1. **读取jest.config.js配置**
|
||||
- 查看jest.config.js了解测试环境配置
|
||||
- 确认testRegex模式和文件匹配规则
|
||||
- 了解moduleNameMapper和其他配置项
|
||||
#### 📋 Mandatory Information Collection
|
||||
Before executing any intermediate step, AI must:
|
||||
1. **Collect user current date**: For modification records and timestamp updates
|
||||
2. **Collect user name**: For @author field handling and modification records
|
||||
3. **Confirm project characteristics**: Identify NestJS game server project features
|
||||
|
||||
2. **使用package.json中的已有测试指令**
|
||||
- **禁止自定义jest命令**:必须使用package.json中scripts定义的测试命令
|
||||
- **常用测试指令**:
|
||||
- `npm run test` - 运行所有测试
|
||||
- `npm run test:unit` - 运行单元测试(.spec.ts文件)
|
||||
- `npm run test:integration` - 运行集成测试(.integration.spec.ts文件)
|
||||
- `npm run test:e2e` - 运行端到端测试(.e2e.spec.ts文件)
|
||||
- `npm run test:watch` - 监视模式运行测试
|
||||
- `npm run test:cov` - 运行测试并生成覆盖率报告
|
||||
- `npm run test:debug` - 调试模式运行测试
|
||||
- `npm run test:isolated` - 隔离运行测试
|
||||
#### 🔍 Global Context Acquisition
|
||||
AI must first understand:
|
||||
- **Project Architecture**: Dual-mode architecture (database+memory), layered structure (Core+Business)
|
||||
- **Tech Stack**: NestJS, WebSocket, Jest testing, fast-check property testing
|
||||
- **File Structure**: Overall file organization of current project
|
||||
- **Existing Standards**: Established naming, commenting, testing standards in project
|
||||
|
||||
3. **特定模块测试指令**
|
||||
- **Zulip模块测试**:
|
||||
- `npm run test:zulip` - 运行所有Zulip相关测试
|
||||
- `npm run test:zulip:unit` - 运行Zulip单元测试
|
||||
- `npm run test:zulip:integration` - 运行Zulip集成测试
|
||||
- `npm run test:zulip:e2e` - 运行Zulip端到端测试
|
||||
- `npm run test:zulip:performance` - 运行Zulip性能测试
|
||||
#### 🎯 Execution Flow Constraints
|
||||
```
|
||||
Mid-step Start Request
|
||||
↓
|
||||
🚨 Mandatory User Info Collection (date, name)
|
||||
↓
|
||||
🚨 Mandatory Project Characteristics & Context Identification
|
||||
↓
|
||||
🚨 Mandatory Understanding of Target Step Requirements
|
||||
↓
|
||||
Start Executing Specified Step
|
||||
```
|
||||
|
||||
4. **测试执行验证流程**
|
||||
**⚠️ Violation Handling: If AI skips information collection and directly executes intermediate steps, user should require AI to restart and complete preparation work.**
|
||||
|
||||
### ⚠️ Mandatory Requirements
|
||||
- **Step-by-step Execution**: Execute one step at a time, strictly no step skipping or merging
|
||||
- **Wait for Confirmation**: Must wait for user confirmation after each step before proceeding
|
||||
- **Modification Verification**: Must re-execute current step after any file modification
|
||||
- **🔥 Must Re-execute Current Step After Modification**: If any modification behavior occurs during current step (file modification, renaming, moving, etc.), AI must immediately re-execute the complete check of that step, cannot directly proceed to next step
|
||||
- **Re-check After Problem Fix**: If current step has problems requiring modification, AI must re-execute the step after solving problems to ensure no other issues are missed
|
||||
- **User Info Usage**: All date fields use user-provided real dates, @author fields handled correctly
|
||||
|
||||
### 🎯 Execution Flow
|
||||
```
|
||||
User Requests Code Inspection
|
||||
↓
|
||||
Collect User Info (date, name)
|
||||
↓
|
||||
Identify Project Characteristics
|
||||
↓
|
||||
Execute Step 1 → Provide Report → Wait for Confirmation
|
||||
↓
|
||||
[If Modification Occurs] → 🔥 Immediately Re-execute Step 1 → Verification Report → Wait for Confirmation
|
||||
↓
|
||||
Execute Step 2 → Provide Report → Wait for Confirmation
|
||||
↓
|
||||
[If Modification Occurs] → 🔥 Immediately Re-execute Step 2 → Verification Report → Wait for Confirmation
|
||||
↓
|
||||
Execute Step 3 → Provide Report → Wait for Confirmation
|
||||
↓
|
||||
[If Modification Occurs] → 🔥 Immediately Re-execute Step 3 → Verification Report → Wait for Confirmation
|
||||
↓
|
||||
Execute Step 4 → Provide Report → Wait for Confirmation
|
||||
↓
|
||||
[If Modification Occurs] → 🔥 Immediately Re-execute Step 4 → Verification Report → Wait for Confirmation
|
||||
↓
|
||||
Execute Step 5 → Provide Report → Wait for Confirmation
|
||||
↓
|
||||
[If Modification Occurs] → 🔥 Immediately Re-execute Step 5 → Verification Report → Wait for Confirmation
|
||||
↓
|
||||
Execute Step 6 → Provide Report → Wait for Confirmation
|
||||
↓
|
||||
[If Modification Occurs] → 🔥 Immediately Re-execute Step 6 → Verification Report → Wait for Confirmation
|
||||
↓
|
||||
Execute Step 7 → Provide Report → Wait for Confirmation
|
||||
↓
|
||||
[If Modification Occurs] → 🔥 Immediately Re-execute Step 7 → Verification Report → Wait for Confirmation
|
||||
|
||||
⚠️ Key Rule: After any modification behavior in any step, must immediately re-execute that step!
|
||||
```
|
||||
|
||||
## 📚 Step Execution Guide
|
||||
|
||||
### Step 1: Naming Convention Check
|
||||
**Read when executing:** `step1-naming-convention.md`
|
||||
**Focus on:** Folder structure flattening, game server special file types
|
||||
**After completion:** Provide inspection report, wait for user confirmation
|
||||
|
||||
### Step 2: Comment Standard Check
|
||||
**Read when executing:** `step2-comment-standard.md`
|
||||
**Focus on:** @author field handling, modification record updates, timestamp rules
|
||||
**After completion:** Provide inspection report, wait for user confirmation
|
||||
|
||||
### Step 3: Code Quality Check
|
||||
**Read when executing:** `step3-code-quality.md`
|
||||
**Focus on:** TODO item handling, unused code cleanup
|
||||
**After completion:** Provide inspection report, wait for user confirmation
|
||||
|
||||
### Step 4: Architecture Layer Check
|
||||
**Read when executing:** `step4-architecture-layer.md`
|
||||
**Focus on:** Core layer naming standards, dependency relationship checks
|
||||
**After completion:** Provide inspection report, wait for user confirmation
|
||||
|
||||
### Step 5: Test Coverage Check
|
||||
**Read when executing:** `step5-test-coverage.md`
|
||||
**Focus on:** Strict one-to-one test mapping, test file locations, test execution verification
|
||||
**After completion:** Provide inspection report, wait for user confirmation
|
||||
|
||||
#### 🧪 Test File Debugging Standards
|
||||
**When debugging test files, must follow this workflow:**
|
||||
|
||||
1. **Read jest.config.js Configuration**
|
||||
- Check jest.config.js to understand test environment configuration
|
||||
- Confirm testRegex patterns and file matching rules
|
||||
- Understand moduleNameMapper and other configuration items
|
||||
|
||||
2. **Use Existing Test Commands in package.json**
|
||||
- **Forbidden to customize jest commands**: Must use test commands defined in package.json scripts
|
||||
- **Common Test Commands**:
|
||||
- `npm run test` - Run all tests
|
||||
- `npm run test:unit` - Run unit tests (.spec.ts files)
|
||||
- `npm run test:integration` - Run integration tests (.integration.spec.ts files)
|
||||
- `npm run test:e2e` - Run end-to-end tests (.e2e.spec.ts files)
|
||||
- `npm run test:watch` - Run tests in watch mode
|
||||
- `npm run test:cov` - Run tests and generate coverage report
|
||||
- `npm run test:debug` - Run tests in debug mode
|
||||
- `npm run test:isolated` - Run tests in isolation
|
||||
|
||||
3. **Specific Module Test Commands**
|
||||
- **Zulip Module Tests**:
|
||||
- `npm run test:zulip` - Run all Zulip-related tests
|
||||
- `npm run test:zulip:unit` - Run Zulip unit tests
|
||||
- `npm run test:zulip:integration` - Run Zulip integration tests
|
||||
- `npm run test:zulip:e2e` - Run Zulip end-to-end tests
|
||||
- `npm run test:zulip:performance` - Run Zulip performance tests
|
||||
|
||||
4. **Test Execution Verification Workflow**
|
||||
```
|
||||
发现测试问题 → 读取jest.config.js → 选择合适的npm run test:xxx指令 → 执行测试 → 分析结果 → 修复问题 → 重新执行测试
|
||||
Discover Test Issue → Read jest.config.js → Choose Appropriate npm run test:xxx Command → Execute Test → Analyze Results → Fix Issues → Re-execute Test
|
||||
```
|
||||
|
||||
5. **测试指令选择原则**
|
||||
- **单个文件测试**:使用`npm run test -- 文件路径`
|
||||
- **特定类型测试**:使用对应的test:xxx指令
|
||||
- **调试测试**:优先使用`npm run test:debug`
|
||||
- **CI/CD环境**:使用`npm run test:isolated`
|
||||
5. **Test Command Selection Principles**
|
||||
- **Single File Test**: Use `npm run test -- file_path`
|
||||
- **Specific Type Test**: Use corresponding test:xxx command
|
||||
- **Debug Test**: Prioritize `npm run test:debug`
|
||||
- **CI/CD Environment**: Use `npm run test:isolated`
|
||||
|
||||
### 步骤6:功能文档生成
|
||||
**执行时读取:** `step6-documentation.md`
|
||||
**重点关注:** API接口文档、WebSocket事件文档
|
||||
**完成后:** 提供检查报告,等待用户确认
|
||||
### Step 6: Function Documentation Generation
|
||||
**Read when executing:** `step6-documentation.md`
|
||||
**Focus on:** API interface documentation, WebSocket event documentation
|
||||
**After completion:** Provide inspection report, wait for user confirmation
|
||||
|
||||
### 步骤7:代码提交
|
||||
**执行时读取:** `step7-code-commit.md`
|
||||
**重点关注:** Git变更校验、修改记录一致性检查、规范化提交流程
|
||||
**完成后:** 提供检查报告,等待用户确认
|
||||
### Step 7: Code Commit
|
||||
**Read when executing:** `step7-code-commit.md`
|
||||
**Focus on:** Git change verification, modification record consistency check, standardized commit process
|
||||
**After completion:** Provide inspection report, wait for user confirmation
|
||||
|
||||
## 📋 统一报告模板
|
||||
## 📋 Unified Report Template
|
||||
|
||||
每步完成后使用此模板报告:
|
||||
Use this template for reporting after each step completion:
|
||||
|
||||
```
|
||||
## 步骤X:[步骤名称]检查报告
|
||||
## Step X: [Step Name] Inspection Report
|
||||
|
||||
### 🔍 检查结果
|
||||
[发现的问题列表]
|
||||
### 🔍 Inspection Results
|
||||
[List of discovered issues]
|
||||
|
||||
### 🛠️ 修正方案
|
||||
[具体修正建议]
|
||||
### 🛠️ Correction Plan
|
||||
[Specific correction suggestions]
|
||||
|
||||
### ✅ 完成状态
|
||||
- 检查项1 ✓/✗
|
||||
- 检查项2 ✓/✗
|
||||
### ✅ Completion Status
|
||||
- Check Item 1 ✓/✗
|
||||
- Check Item 2 ✓/✗
|
||||
|
||||
**请确认修正方案,确认后进行下一步骤**
|
||||
**Please confirm correction plan, proceed to next step after confirmation**
|
||||
```
|
||||
|
||||
## 🚨 全局约束
|
||||
## 🚨 Global Constraints
|
||||
|
||||
### 📝 文件修改记录规范(重要)
|
||||
**每次执行完修改后,文件顶部都需要更新修改记录和相关信息**
|
||||
### 📝 File Modification Record Standards (Important)
|
||||
**After each modification execution, file headers need to update modification records and related information**
|
||||
|
||||
#### 修改类型定义
|
||||
- `代码规范优化` - 命名规范、注释规范、代码清理等
|
||||
- `功能新增` - 添加新的功能或方法
|
||||
- `功能修改` - 修改现有功能的实现
|
||||
- `Bug修复` - 修复代码缺陷
|
||||
- `性能优化` - 提升代码性能
|
||||
- `重构` - 代码结构调整但功能不变
|
||||
#### Modification Type Definitions
|
||||
- `Code Standard Optimization` - Naming standards, comment standards, code cleanup, etc.
|
||||
- `Feature Addition` - Adding new features or methods
|
||||
- `Feature Modification` - Modifying existing feature implementations
|
||||
- `Bug Fix` - Fixing code defects
|
||||
- `Performance Optimization` - Improving code performance
|
||||
- `Refactoring` - Code structure adjustment but functionality unchanged
|
||||
|
||||
#### 修改记录格式要求
|
||||
#### Modification Record Format Requirements
|
||||
```typescript
|
||||
/**
|
||||
* 最近修改:
|
||||
* - [用户日期]: 代码规范优化 - 清理未使用的导入 (修改者: [用户名称])
|
||||
* - 2024-01-06: Bug修复 - 修复邮箱验证逻辑错误 (修改者: 李四)
|
||||
* - 2024-01-05: 功能新增 - 添加用户验证码登录功能 (修改者: 王五)
|
||||
* Recent Modifications:
|
||||
* - [User Date]: Code Standard Optimization - Clean unused imports (Modified by: [User Name])
|
||||
* - 2024-01-06: Bug Fix - Fix email validation logic error (Modified by: Li Si)
|
||||
* - 2024-01-05: Feature Addition - Add user verification code login feature (Modified by: Wang Wu)
|
||||
*
|
||||
* @author [处理后的作者名称]
|
||||
* @author [Processed Author Name]
|
||||
* @version x.x.x
|
||||
* @since [创建日期]
|
||||
* @lastModified [用户日期]
|
||||
* @since [Creation Date]
|
||||
* @lastModified [User Date]
|
||||
*/
|
||||
```
|
||||
|
||||
#### 🔢 最近修改记录数量限制
|
||||
- **最多保留5条**:最近修改记录最多只保留最新的5条记录
|
||||
- **超出自动删除**:当添加新的修改记录时,如果超过5条,自动删除最旧的记录
|
||||
- **保持时间顺序**:记录按时间倒序排列,最新的在最上面
|
||||
- **完整记录保留**:每条记录必须包含完整的日期、修改类型、描述和修改者信息
|
||||
#### 🔢 Recent Modification Record Quantity Limit
|
||||
- **Maximum 5 Records**: Recent modification records keep maximum of 5 latest records
|
||||
- **Auto-delete When Exceeded**: When adding new modification records, if exceeding 5, automatically delete oldest records
|
||||
- **Maintain Time Order**: Records arranged in reverse chronological order, newest at top
|
||||
- **Complete Record Retention**: Each record must include complete date, modification type, description and modifier information
|
||||
|
||||
#### 版本号递增规则
|
||||
- **修订版本+1**:代码规范优化、Bug修复 (1.0.0 → 1.0.1)
|
||||
- **次版本+1**:功能新增、功能修改 (1.0.1 → 1.1.0)
|
||||
- **主版本+1**:重构、架构变更 (1.1.0 → 2.0.0)
|
||||
#### Version Number Increment Rules
|
||||
- **Patch Version +1**: Code standard optimization, bug fixes (1.0.0 → 1.0.1)
|
||||
- **Minor Version +1**: Feature addition, feature modification (1.0.1 → 1.1.0)
|
||||
- **Major Version +1**: Refactoring, architecture changes (1.1.0 → 2.0.0)
|
||||
|
||||
#### 时间更新规则
|
||||
- **仅检查不修改**:如果只是检查而没有实际修改文件内容,**不更新**@lastModified字段
|
||||
- **实际修改才更新**:只有真正修改了文件内容时才更新@lastModified字段和添加修改记录
|
||||
- **Git变更检测**:通过`git status`和`git diff`检查文件是否有实际变更,只有git显示文件被修改时才需要添加修改记录和更新时间戳
|
||||
#### Time Update Rules
|
||||
- **Check Only No Modification**: If only checking without actually modifying file content, **do not update** @lastModified field
|
||||
- **Update Only on Actual Modification**: Only update @lastModified field and add modification records when actually modifying file content
|
||||
- **Git Change Detection**: Check if files have actual changes through `git status` and `git diff`, only add modification records and update timestamps when git shows files are modified
|
||||
|
||||
#### 🚨 重要强调:纯检查步骤不更新修改记录
|
||||
**AI在执行代码检查步骤时,如果发现代码已经符合规范,无需任何修改,则:**
|
||||
- **禁止添加修改记录**:不要添加类似"AI代码检查步骤X:XXX检查和优化"的记录
|
||||
- **禁止更新时间戳**:不要更新@lastModified字段
|
||||
- **禁止递增版本号**:不要修改@version字段
|
||||
- **只有实际修改了代码内容、注释内容、结构等才需要更新修改记录**
|
||||
#### 🚨 Important Emphasis: Pure Check Steps Do Not Update Modification Records
|
||||
**When AI executes code inspection steps, if code already meets standards and needs no modification, then:**
|
||||
- **Forbidden to Add Modification Records**: Do not add records like "AI code inspection step X: XXX check and optimization"
|
||||
- **Forbidden to Update Timestamps**: Do not update @lastModified field
|
||||
- **Forbidden to Increment Version Numbers**: Do not modify @version field
|
||||
- **Only add modification records when actually modifying code content, comment content, structure, etc.**
|
||||
|
||||
**错误示例**:
|
||||
**Wrong Example**:
|
||||
```typescript
|
||||
// ❌ 错误:仅检查无修改却添加了修改记录
|
||||
// ❌ Wrong: Only checked without modification but added modification record
|
||||
/**
|
||||
* 最近修改:
|
||||
* - 2026-01-12: 代码规范优化 - AI代码检查步骤2:注释规范检查和优化 (修改者: moyin) // 这是错误的!
|
||||
* - 2026-01-07: 功能新增 - 添加用户验证功能 (修改者: 张三)
|
||||
* Recent Modifications:
|
||||
* - 2026-01-12: Code Standard Optimization - AI code inspection step 2: Comment standard check and optimization (Modified by: moyin) // This is wrong!
|
||||
* - 2026-01-07: Feature Addition - Add user verification feature (Modified by: Zhang San)
|
||||
*/
|
||||
```
|
||||
|
||||
**正确示例**:
|
||||
**Correct Example**:
|
||||
```typescript
|
||||
// ✅ 正确:检查发现符合规范,不添加修改记录
|
||||
// ✅ Correct: Check found compliance with standards, do not add modification records
|
||||
/**
|
||||
* 最近修改:
|
||||
* - 2026-01-07: 功能新增 - 添加用户验证功能 (修改者: 张三) // 保持原有记录不变
|
||||
* Recent Modifications:
|
||||
* - 2026-01-07: Feature Addition - Add user verification feature (Modified by: Zhang San) // Keep original records unchanged
|
||||
*/
|
||||
```
|
||||
|
||||
### @author字段处理规范
|
||||
- **保留原则**:人名必须保留,不得随意修改
|
||||
- **AI标识替换**:只有AI标识(kiro、ChatGPT、Claude、AI等)才可替换为用户名称
|
||||
- **判断示例**:`@author kiro` → 可替换,`@author 张三` → 必须保留
|
||||
### @author Field Handling Standards
|
||||
- **Retention Principle**: Human names must be retained, cannot be arbitrarily modified
|
||||
- **AI Identifier Replacement**: Only AI identifiers (kiro, ChatGPT, Claude, AI, etc.) can be replaced with user names
|
||||
- **Judgment Example**: `@author kiro` → Can replace, `@author Zhang San` → Must retain
|
||||
|
||||
### 游戏服务器特殊要求
|
||||
- **WebSocket文件**:Gateway文件必须有完整的连接、消息处理测试
|
||||
- **双模式服务**:内存服务和数据库服务都需要完整测试覆盖
|
||||
- **属性测试**:管理员模块使用fast-check进行属性测试
|
||||
- **测试分离**:严格区分单元测试、集成测试、E2E测试、性能测试
|
||||
### Game Server Special Requirements
|
||||
- **WebSocket Files**: Gateway files must have complete connection and message processing tests
|
||||
- **Dual-mode Services**: Both memory services and database services need complete test coverage
|
||||
- **Property Testing**: Admin modules use fast-check for property testing
|
||||
- **Test Separation**: Strictly distinguish unit tests, integration tests, E2E tests, performance tests
|
||||
|
||||
## 🔧 修改验证流程
|
||||
## 🔧 Modification Verification Process
|
||||
|
||||
### 🔥 修改后立即重新执行规则(重要)
|
||||
**任何步骤中发生修改行为后,AI必须立即重新执行该步骤,不能直接进入下一步骤!**
|
||||
### 🔥 Immediately Re-execute Rule After Modification (Important)
|
||||
**After any modification behavior occurs in any step, AI must immediately re-execute that step, cannot directly proceed to next step!**
|
||||
|
||||
#### 修改行为包括但不限于:
|
||||
- 文件内容修改(代码、注释、配置等)
|
||||
- 文件重命名
|
||||
- 文件移动
|
||||
- 文件删除
|
||||
- 新建文件
|
||||
- 文件夹结构调整
|
||||
#### Modification Behaviors Include But Not Limited To:
|
||||
- File content modification (code, comments, configuration, etc.)
|
||||
- File renaming
|
||||
- File moving
|
||||
- File deletion
|
||||
- New file creation
|
||||
- Folder structure adjustment
|
||||
|
||||
#### 强制执行流程:
|
||||
#### Mandatory Execution Process:
|
||||
```
|
||||
步骤执行中 → 发现问题 → 执行修改 → 🔥 立即重新执行该步骤 → 验证无遗漏 → 用户确认 → 下一步骤
|
||||
Step Execution → Discover Issues → Execute Modifications → 🔥 Immediately Re-execute That Step → Verify No Omissions → User Confirmation → Next Step
|
||||
```
|
||||
|
||||
### 问题修复后的重检流程
|
||||
当在任何步骤中发现问题并进行修改后,必须遵循以下流程:
|
||||
### Re-check Process After Problem Fix
|
||||
When issues are discovered and modifications made in any step, must follow this process:
|
||||
|
||||
1. **执行修改操作**
|
||||
- 根据发现的问题进行具体修改
|
||||
- 确保修改内容准确无误
|
||||
- **更新文件顶部的修改记录、版本号和@lastModified字段**
|
||||
1. **Execute Modification Operations**
|
||||
- Make specific modifications based on discovered issues
|
||||
- Ensure modification content is accurate
|
||||
- **Update file header modification records, version numbers and @lastModified fields**
|
||||
|
||||
2. **🔥 立即重新执行当前步骤**
|
||||
- **不能跳过这一步!**
|
||||
- 完整重新执行该步骤的所有检查项
|
||||
- 不能只检查修改的部分,必须全面重检
|
||||
2. **🔥 Immediately Re-execute Current Step**
|
||||
- **Cannot skip this step!**
|
||||
- Complete re-execution of all check items for that step
|
||||
- Cannot only check modified parts, must comprehensively re-check
|
||||
|
||||
3. **提供验证报告**
|
||||
- 确认之前发现的问题已解决
|
||||
- 确认没有引入新的问题
|
||||
- 确认没有遗漏其他问题
|
||||
3. **Provide Verification Report**
|
||||
- Confirm previously discovered issues are resolved
|
||||
- Confirm no new issues introduced
|
||||
- Confirm no other issues omitted
|
||||
|
||||
4. **等待用户确认**
|
||||
- 提供完整的验证报告
|
||||
- 等待用户确认后才能进行下一步骤
|
||||
4. **Wait for User Confirmation**
|
||||
- Provide complete verification report
|
||||
- Wait for user confirmation before proceeding to next step
|
||||
|
||||
### 验证报告模板
|
||||
### Verification Report Template
|
||||
```
|
||||
## 步骤X:修改验证报告
|
||||
## Step X: Modification Verification Report
|
||||
|
||||
### 🔧 已执行的修改操作
|
||||
- 修改类型:[文件修改/重命名/移动/删除等]
|
||||
- 修改内容:[具体修改描述]
|
||||
- 影响文件:[受影响的文件列表]
|
||||
### 🔧 Executed Modification Operations
|
||||
- Modification Type: [File modification/renaming/moving/deletion, etc.]
|
||||
- Modification Content: [Specific modification description]
|
||||
- Affected Files: [List of affected files]
|
||||
|
||||
### 📝 已更新的修改记录
|
||||
- 添加修改记录:[用户日期]: [修改类型] - [修改内容] (修改者: [用户名称])
|
||||
- 更新版本号:[旧版本] → [新版本]
|
||||
- 更新时间戳:@lastModified [用户日期]
|
||||
### 📝 Updated Modification Records
|
||||
- Added Modification Record: [User Date]: [Modification Type] - [Modification Content] (Modified by: [User Name])
|
||||
- Updated Version Number: [Old Version] → [New Version]
|
||||
- Updated Timestamp: @lastModified [User Date]
|
||||
|
||||
### 🔍 重新执行步骤X的完整检查结果
|
||||
[完整重新执行该步骤的所有检查项的结果]
|
||||
### 🔍 Re-executed Step X Complete Check Results
|
||||
[Complete re-execution results of all check items for that step]
|
||||
|
||||
### ✅ 验证状态
|
||||
- 原问题已解决 ✓
|
||||
- 修改记录已更新 ✓
|
||||
- 无新问题引入 ✓
|
||||
- 无其他遗漏问题 ✓
|
||||
- 步骤X检查完全通过 ✓
|
||||
### ✅ Verification Status
|
||||
- Original Issues Resolved ✓
|
||||
- Modification Records Updated ✓
|
||||
- No New Issues Introduced ✓
|
||||
- No Other Issues Omitted ✓
|
||||
- Step X Check Completely Passed ✓
|
||||
|
||||
**🔥 重要:本步骤已完成修改并重新验证,请确认后进行下一步骤**
|
||||
**🔥 Important: This step has completed modification and re-verification, please confirm before proceeding to next step**
|
||||
```
|
||||
|
||||
### 重检的重要性
|
||||
- **确保完整性**:避免修改过程中遗漏其他问题
|
||||
- **防止新问题**:确保修改没有引入新的问题
|
||||
- **保证质量**:每个步骤都达到完整的检查标准
|
||||
- **维护一致性**:确保整个检查过程的严谨性
|
||||
- **🔥 强制执行**:修改后必须重新执行,不能跳过这个环节
|
||||
### Importance of Re-checking
|
||||
- **Ensure Completeness**: Avoid omitting other issues during modification process
|
||||
- **Prevent New Issues**: Ensure modifications do not introduce new problems
|
||||
- **Maintain Quality**: Each step reaches complete inspection standards
|
||||
- **Maintain Consistency**: Ensure rigor throughout entire inspection process
|
||||
- **🔥 Mandatory Execution**: Cannot skip this step after modifications
|
||||
|
||||
## ⚡ 关键成功要素
|
||||
## ⚡ Key Success Factors
|
||||
|
||||
- **严格按步骤执行**:不跳步骤,不合并执行
|
||||
- **🔥 修改后立即重新执行**:任何修改行为后必须立即重新执行当前步骤,不能直接进入下一步
|
||||
- **问题修复后必须重检**:修改文件后必须重新执行整个步骤,确保无遗漏
|
||||
- **修改记录必须更新**:每次修改文件后都必须更新文件顶部的修改记录、版本号和时间戳
|
||||
- **真实修改验证**:通过工具验证修改效果
|
||||
- **用户信息准确使用**:日期和名称信息正确应用
|
||||
- **项目特性适配**:针对游戏服务器特点优化检查
|
||||
- **完整报告提供**:每步都提供详细的检查报告
|
||||
- **Strict Step-by-step Execution**: No step skipping, no merged execution
|
||||
- **🔥 Immediately Re-execute After Modification**: Must immediately re-execute current step after any modification behavior, cannot directly proceed to next step
|
||||
- **Must Re-check After Problem Fix**: Must re-execute entire step after file modification to ensure no omissions
|
||||
- **Must Update Modification Records**: Must update file header modification records, version numbers and timestamps after each file modification
|
||||
- **Real Modification Verification**: Verify modification effects through tools
|
||||
- **Accurate User Info Usage**: Correctly apply date and name information
|
||||
- **Project Characteristic Adaptation**: Optimize inspections for game server characteristics
|
||||
- **Complete Report Provision**: Provide detailed inspection reports for each step
|
||||
|
||||
---
|
||||
|
||||
**开始执行前,请确认已收集用户日期和名称信息!**
|
||||
**Before starting execution, please first run `node tools/setup-user-info.js` to set user information!**
|
||||
@@ -22,11 +22,63 @@
|
||||
## 📋 命名规范标准
|
||||
|
||||
### 文件和文件夹命名
|
||||
|
||||
#### 🚨 NestJS 框架文件命名规范(重要)
|
||||
**本项目使用 NestJS 框架,框架相关文件命名规则:**
|
||||
|
||||
**命名组成 = 文件名(snake_case) + 类型标识符(点分隔) + 扩展名**
|
||||
|
||||
```
|
||||
✅ 正确的 NestJS 文件命名:
|
||||
- login.controller.ts # 单词文件名 + .controller
|
||||
- user_profile.service.ts # snake_case文件名 + .service
|
||||
- auth_core.module.ts # snake_case文件名 + .module
|
||||
- login_request.dto.ts # snake_case文件名 + .dto
|
||||
- jwt_auth.guard.ts # snake_case文件名 + .guard
|
||||
- current_user.decorator.ts # snake_case文件名 + .decorator
|
||||
- user_profile.controller.spec.ts # snake_case文件名 + .controller.spec
|
||||
|
||||
❌ 错误的命名示例:
|
||||
- loginController.ts # 错误!应该是 login.controller.ts
|
||||
- user-profile.service.ts # 错误!应该是 user_profile.service.ts
|
||||
- authCore.module.ts # 错误!应该是 auth_core.module.ts
|
||||
- login_controller.ts # 错误!类型标识符应该用点分隔,不是下划线
|
||||
```
|
||||
|
||||
**关键规则:**
|
||||
1. **文件名部分**:使用 snake_case(如 `user_profile`、`auth_core`)
|
||||
2. **类型标识符**:使用点分隔(如 `.controller`、`.service`)
|
||||
3. **完整格式**:`文件名.类型标识符.ts`(如 `user_profile.service.ts`)
|
||||
|
||||
**NestJS 文件类型标识符(必须使用点分隔):**
|
||||
- `.controller.ts` - 控制器(如 `user_auth.controller.ts`)
|
||||
- `.service.ts` - 服务(如 `user_profile.service.ts`)
|
||||
- `.module.ts` - 模块(如 `auth_core.module.ts`)
|
||||
- `.dto.ts` - 数据传输对象(如 `login_request.dto.ts`)
|
||||
- `.entity.ts` - 实体(如 `user_account.entity.ts`)
|
||||
- `.interface.ts` - 接口(如 `game_config.interface.ts`)
|
||||
- `.guard.ts` - 守卫(如 `jwt_auth.guard.ts`)
|
||||
- `.interceptor.ts` - 拦截器(如 `response_transform.interceptor.ts`)
|
||||
- `.pipe.ts` - 管道(如 `validation_pipe.pipe.ts`)
|
||||
- `.filter.ts` - 过滤器(如 `http_exception.filter.ts`)
|
||||
- `.decorator.ts` - 装饰器(如 `current_user.decorator.ts`)
|
||||
- `.middleware.ts` - 中间件(如 `logger_middleware.middleware.ts`)
|
||||
- `.spec.ts` - 单元测试(如 `user_profile.service.spec.ts`)
|
||||
- `.e2e.spec.ts` - E2E 测试(如 `auth_flow.e2e.spec.ts`)
|
||||
|
||||
**命名规则说明:**
|
||||
1. **文件名使用 snake_case**:多个单词用下划线连接(如 `user_profile`、`auth_core`)
|
||||
2. **类型标识符使用点分隔**:遵循 NestJS/Angular 风格(如 `.controller`、`.service`)
|
||||
3. **组合格式**:`snake_case文件名.类型标识符.ts`
|
||||
4. **社区标准**:这是本项目结合 NestJS 规范和 snake_case 约定的标准做法
|
||||
|
||||
#### 普通文件和文件夹命名
|
||||
- **规则**:snake_case(下划线分隔),保持项目一致性
|
||||
- **适用范围**:非 NestJS 框架文件、工具类、配置文件、普通文件夹等
|
||||
- **示例**:
|
||||
```
|
||||
✅ 正确:user_controller.ts, admin_operation_log_service.ts
|
||||
❌ 错误:UserController.ts, user-service.ts, adminOperationLog.service.ts
|
||||
✅ 正确:user_utils.ts, admin_operation_log.ts, config_loader.ts
|
||||
❌ 错误:UserUtils.ts, user-utils.ts, adminOperationLog.ts
|
||||
```
|
||||
|
||||
### 变量和函数命名
|
||||
@@ -161,6 +213,14 @@ src/business/auth/
|
||||
2. **凭印象判断,不使用工具获取准确数据**
|
||||
3. **遗漏≤3个文件文件夹的识别**
|
||||
4. **忽略测试文件夹扁平化**:认为tests文件夹是"标准结构"
|
||||
5. **🚨 错误地要求修改 NestJS 框架文件命名**:
|
||||
- ❌ 错误:要求将 `login.controller.ts` 改为 `login_controller.ts`(类型标识符不能用下划线)
|
||||
- ❌ 错误:要求将 `userProfile.service.ts` 改为 `userProfile.service.ts`(文件名应该用 snake_case)
|
||||
- ✅ 正确:`user_profile.service.ts`(文件名用 snake_case + 类型标识符用点分隔)
|
||||
- **判断方法**:
|
||||
- 检查类型标识符是否用点分隔(`.controller`、`.service` 等)
|
||||
- 检查文件名本身是否用 snake_case
|
||||
- 完整格式:`snake_case文件名.类型标识符.ts`
|
||||
|
||||
## 🔍 检查执行步骤
|
||||
|
||||
|
||||
@@ -24,21 +24,142 @@
|
||||
### 项目分层结构
|
||||
```
|
||||
src/
|
||||
├── core/ # Core层:技术实现层
|
||||
│ ├── db/ # 数据访问
|
||||
│ ├── redis/ # 缓存服务
|
||||
│ └── utils/ # 工具服务
|
||||
├── gateway/ # Gateway层:网关层(HTTP协议处理)
|
||||
│ ├── auth/ # 认证网关
|
||||
│ ├── users/ # 用户网关
|
||||
│ └── admin/ # 管理网关
|
||||
├── business/ # Business层:业务逻辑层
|
||||
│ ├── auth/ # 认证业务
|
||||
│ ├── users/ # 用户业务
|
||||
│ └── admin/ # 管理业务
|
||||
├── core/ # Core层:技术实现层
|
||||
│ ├── db/ # 数据访问
|
||||
│ ├── redis/ # 缓存服务
|
||||
│ └── utils/ # 工具服务
|
||||
└── common/ # 公共层:通用组件
|
||||
```
|
||||
|
||||
### 4层架构说明
|
||||
|
||||
**Gateway Layer(网关层)**
|
||||
- 位置:`src/gateway/`
|
||||
- 职责:HTTP协议处理、数据验证、路由管理、认证守卫、错误转换
|
||||
- 依赖:Business层
|
||||
|
||||
**Business Layer(业务层)**
|
||||
- 位置:`src/business/`
|
||||
- 职责:业务逻辑实现、业务流程控制、服务协调、业务规则验证
|
||||
- 依赖:Core层
|
||||
|
||||
**Core Layer(核心层)**
|
||||
- 位置:`src/core/`
|
||||
- 职责:数据访问、基础设施、外部系统集成、技术实现细节
|
||||
- 依赖:无(或第三方库)
|
||||
|
||||
### 检查范围
|
||||
- **限制范围**:仅检查当前执行检查的文件夹
|
||||
- **不跨模块**:不考虑其他同层功能模块
|
||||
- **专注职责**:确保当前模块职责清晰
|
||||
- **按层检查**:根据文件夹所在层级应用对应的检查规则
|
||||
|
||||
## 🌐 Gateway层规范检查
|
||||
|
||||
### 职责定义
|
||||
**Gateway层专注HTTP协议处理,不包含业务逻辑**
|
||||
|
||||
### Gateway层协议处理示例
|
||||
```typescript
|
||||
// ✅ 正确:Gateway层只做协议转换
|
||||
@Controller('auth')
|
||||
export class LoginController {
|
||||
constructor(private readonly loginService: LoginService) {}
|
||||
|
||||
@Post('login')
|
||||
async login(@Body() loginDto: LoginDto, @Res() res: Response): Promise<void> {
|
||||
// 1. 接收HTTP请求,使用DTO验证
|
||||
// 2. 调用Business层服务
|
||||
const result = await this.loginService.login({
|
||||
identifier: loginDto.identifier,
|
||||
password: loginDto.password
|
||||
});
|
||||
|
||||
// 3. 将业务响应转换为HTTP响应
|
||||
this.handleResponse(result, res);
|
||||
}
|
||||
|
||||
private handleResponse(result: any, res: Response): void {
|
||||
if (result.success) {
|
||||
res.status(HttpStatus.OK).json(result);
|
||||
} else {
|
||||
const statusCode = this.getErrorStatusCode(result);
|
||||
res.status(statusCode).json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ 错误:Gateway层包含业务逻辑
|
||||
@Controller('auth')
|
||||
export class LoginController {
|
||||
@Post('login')
|
||||
async login(@Body() loginDto: LoginDto): Promise<any> {
|
||||
// 错误:在Controller中实现业务逻辑
|
||||
const user = await this.userRepository.findOne({
|
||||
where: { username: loginDto.identifier }
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new NotFoundException('用户不存在');
|
||||
}
|
||||
|
||||
const isValid = await bcrypt.compare(loginDto.password, user.password);
|
||||
if (!isValid) {
|
||||
throw new UnauthorizedException('密码错误');
|
||||
}
|
||||
|
||||
// ... 更多业务逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Gateway层依赖关系检查
|
||||
```typescript
|
||||
// ✅ 允许的导入
|
||||
import { Controller, Post, Body, Res } from '@nestjs/common'; # NestJS框架
|
||||
import { Response } from 'express'; # Express类型
|
||||
import { LoginService } from '../../business/auth/login.service'; # Business层服务
|
||||
import { LoginDto } from './dto/login.dto'; # 同层DTO
|
||||
import { JwtAuthGuard } from './jwt_auth.guard'; # 同层Guard
|
||||
|
||||
// ❌ 禁止的导入
|
||||
import { LoginCoreService } from '../../core/login_core/login_core.service'; # 跳过Business层直接调用Core层
|
||||
import { UsersRepository } from '../../core/db/users/users.repository'; # 直接访问数据层
|
||||
import { RedisService } from '../../core/redis/redis.service'; # 直接访问技术服务
|
||||
```
|
||||
|
||||
### Gateway层文件类型检查
|
||||
```typescript
|
||||
// ✅ Gateway层应该包含的文件类型
|
||||
- *.controller.ts # HTTP控制器
|
||||
- *.dto.ts # 数据传输对象
|
||||
- *.guard.ts # 认证/授权守卫
|
||||
- *.decorator.ts # 参数装饰器
|
||||
- *.interceptor.ts # 拦截器
|
||||
- *.filter.ts # 异常过滤器
|
||||
- *.gateway.module.ts # 网关模块
|
||||
|
||||
// ❌ Gateway层不应该包含的文件类型
|
||||
- *.service.ts # 业务服务(应在Business层)
|
||||
- *.repository.ts # 数据仓库(应在Core层)
|
||||
- *.entity.ts # 数据实体(应在Core层)
|
||||
```
|
||||
|
||||
### Gateway层职责检查清单
|
||||
- [ ] Controller方法是否只做协议转换?
|
||||
- [ ] 是否使用DTO进行数据验证?
|
||||
- [ ] 是否调用Business层服务而非Core层?
|
||||
- [ ] 是否有统一的错误处理机制?
|
||||
- [ ] 是否包含Swagger API文档?
|
||||
- [ ] 是否使用限流和超时保护?
|
||||
|
||||
## 🔧 Core层规范检查
|
||||
|
||||
@@ -202,6 +323,42 @@ import { DatabaseConnection } from '../../core/db/connection';
|
||||
|
||||
## 🚨 常见架构违规
|
||||
|
||||
### Gateway层违规示例
|
||||
```typescript
|
||||
// ❌ 错误:Gateway层包含业务逻辑
|
||||
@Controller('users')
|
||||
export class UserController {
|
||||
@Post('register')
|
||||
async register(@Body() registerDto: RegisterDto): Promise<User> {
|
||||
// 违规:在Controller中实现业务验证
|
||||
if (registerDto.age < 18) {
|
||||
throw new BadRequestException('用户年龄必须大于18岁');
|
||||
}
|
||||
|
||||
// 违规:在Controller中协调多个服务
|
||||
const user = await this.userCoreService.create(registerDto);
|
||||
await this.emailService.sendWelcomeEmail(user.email);
|
||||
await this.zulipService.createAccount(user);
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ 错误:Gateway层直接调用Core层
|
||||
@Controller('auth')
|
||||
export class LoginController {
|
||||
constructor(
|
||||
private readonly loginCoreService: LoginCoreService, // 违规:跳过Business层
|
||||
) {}
|
||||
|
||||
@Post('login')
|
||||
async login(@Body() loginDto: LoginDto): Promise<any> {
|
||||
// 违规:直接调用Core层服务
|
||||
return this.loginCoreService.login(loginDto);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Business层违规示例
|
||||
```typescript
|
||||
// ❌ 错误:Business层包含技术实现细节
|
||||
@@ -288,30 +445,49 @@ export class UsersBusinessService {
|
||||
## 🔍 检查执行步骤
|
||||
|
||||
1. **识别当前模块的层级**
|
||||
- 确定是Core层还是Business层
|
||||
- 确定是Gateway层、Business层还是Core层
|
||||
- 检查文件夹路径和命名
|
||||
- 根据层级应用对应的检查规则
|
||||
|
||||
2. **检查Core层命名规范**
|
||||
2. **Gateway层检查(如果是Gateway层)**
|
||||
- 检查是否只包含协议处理代码
|
||||
- 检查是否使用DTO进行数据验证
|
||||
- 检查是否只调用Business层服务
|
||||
- 检查是否有统一的错误处理
|
||||
- 检查文件类型是否符合Gateway层规范
|
||||
|
||||
3. **Business层检查(如果是Business层)**
|
||||
- 检查是否只包含业务逻辑
|
||||
- 检查是否协调多个Core层服务
|
||||
- 检查是否返回统一的业务响应
|
||||
- 检查是否不包含HTTP协议处理
|
||||
|
||||
4. **Core层检查(如果是Core层)**
|
||||
- 检查Core层命名规范
|
||||
- 业务支撑模块是否使用_core后缀
|
||||
- 通用工具模块是否不使用后缀
|
||||
- 根据模块职责判断命名正确性
|
||||
- 检查是否只包含技术实现
|
||||
|
||||
3. **检查职责分离**
|
||||
- Core层是否只包含技术实现
|
||||
5. **检查职责分离**
|
||||
- Gateway层是否只做协议转换
|
||||
- Business层是否只包含业务逻辑
|
||||
- Core层是否只包含技术实现
|
||||
- 是否有跨层职责混乱
|
||||
|
||||
4. **检查依赖关系**
|
||||
- Core层是否导入了Business层模块
|
||||
- Business层是否直接使用底层技术实现
|
||||
6. **检查依赖关系**
|
||||
- Gateway层是否只依赖Business层
|
||||
- Business层是否只依赖Core层
|
||||
- Core层是否不依赖业务层
|
||||
- 依赖注入是否正确使用
|
||||
|
||||
5. **检查架构违规**
|
||||
7. **检查架构违规**
|
||||
- 识别常见的分层违规模式
|
||||
- 检查技术实现和业务逻辑的边界
|
||||
- 检查协议处理和业务逻辑的边界
|
||||
- 确保架构清晰度
|
||||
|
||||
6. **游戏服务器特殊检查**
|
||||
8. **游戏服务器特殊检查**
|
||||
- WebSocket Gateway的分层正确性
|
||||
- 双模式服务的架构设计
|
||||
- 实时通信组件的职责分离
|
||||
|
||||
115
docs/ai-reading/tools/setup-user-info.js
Normal file
115
docs/ai-reading/tools/setup-user-info.js
Normal file
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* AI代码检查用户信息管理脚本
|
||||
*
|
||||
* 功能:获取当前日期和用户名称,保存到me.config.json供AI检查步骤使用
|
||||
*
|
||||
* @author AI助手
|
||||
* @version 1.0.0
|
||||
* @since 2026-01-13
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const readline = require('readline');
|
||||
|
||||
const configPath = path.join(__dirname, '..', 'me.config.json');
|
||||
|
||||
// 获取当前日期(YYYY-MM-DD格式)
|
||||
function getCurrentDate() {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
// 读取现有配置
|
||||
function readConfig() {
|
||||
try {
|
||||
if (!fs.existsSync(configPath)) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
||||
} catch (error) {
|
||||
console.error('❌ 读取配置文件失败:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 保存配置
|
||||
function saveConfig(config) {
|
||||
try {
|
||||
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
||||
console.log('✅ 配置已保存');
|
||||
} catch (error) {
|
||||
console.error('❌ 保存配置失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 提示用户输入名称
|
||||
function promptUserName() {
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
|
||||
return new Promise((resolve) => {
|
||||
rl.question('👤 请输入您的名称或昵称: ', (name) => {
|
||||
rl.close();
|
||||
resolve(name.trim());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 主执行逻辑
|
||||
async function main() {
|
||||
console.log('🚀 AI代码检查 - 用户信息设置');
|
||||
|
||||
const currentDate = getCurrentDate();
|
||||
console.log('📅 当前日期:', currentDate);
|
||||
|
||||
const existingConfig = readConfig();
|
||||
|
||||
// 如果配置存在且日期匹配,直接返回
|
||||
if (existingConfig && existingConfig.date === currentDate) {
|
||||
console.log('✅ 配置已是最新,当前用户:', existingConfig.name);
|
||||
return existingConfig;
|
||||
}
|
||||
|
||||
// 需要更新配置
|
||||
console.log('🔄 需要更新用户信息...');
|
||||
const userName = await promptUserName();
|
||||
|
||||
if (!userName) {
|
||||
console.error('❌ 用户名称不能为空');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const config = {
|
||||
date: currentDate,
|
||||
name: userName
|
||||
};
|
||||
|
||||
saveConfig(config);
|
||||
console.log('🎉 设置完成!', config);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
// 导出函数供其他脚本使用
|
||||
function getConfig() {
|
||||
return readConfig();
|
||||
}
|
||||
|
||||
// 如果直接运行此脚本
|
||||
if (require.main === module) {
|
||||
main().catch((error) => {
|
||||
console.error('❌ 脚本执行失败:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { getConfig, getCurrentDate };
|
||||
@@ -7,7 +7,7 @@ import { AppService } from './app.service';
|
||||
import { LoggerModule } from './core/utils/logger/logger.module';
|
||||
import { UsersModule } from './core/db/users/users.module';
|
||||
import { LoginCoreModule } from './core/login_core/login_core.module';
|
||||
import { AuthModule } from './business/auth/auth.module';
|
||||
import { AuthGatewayModule } from './gateway/auth/auth.gateway.module';
|
||||
import { ZulipModule } from './business/zulip/zulip.module';
|
||||
import { RedisModule } from './core/redis/redis.module';
|
||||
import { AdminModule } from './business/admin/admin.module';
|
||||
@@ -69,7 +69,7 @@ function isDatabaseConfigured(): boolean {
|
||||
// 根据数据库配置选择用户模块模式
|
||||
isDatabaseConfigured() ? UsersModule.forDatabase() : UsersModule.forMemory(),
|
||||
LoginCoreModule,
|
||||
AuthModule,
|
||||
AuthGatewayModule, // 使用网关层模块替代业务层模块
|
||||
ZulipModule,
|
||||
UserMgmtModule,
|
||||
AdminModule,
|
||||
|
||||
@@ -1,246 +1,330 @@
|
||||
<!--
|
||||
Auth 用户认证业务模块文档
|
||||
# 认证业务模块 (Auth Business Module)
|
||||
|
||||
功能描述:
|
||||
- 提供完整的用户认证业务模块文档
|
||||
- 详细说明登录、注册、密码管理等功能
|
||||
- 包含API接口、组件说明和使用指南
|
||||
- 提供架构设计和安全特性说明
|
||||
## 架构层级
|
||||
|
||||
职责分离:
|
||||
- 专注于业务模块的功能文档编写
|
||||
- 提供开发者参考和使用指南
|
||||
- 说明模块的设计理念和最佳实践
|
||||
**Business Layer(业务层)**
|
||||
|
||||
最近修改:
|
||||
- 2026-01-12: 代码规范优化 - 添加文档头注释,完善注释规范 (修改者: moyin)
|
||||
## 职责定位
|
||||
|
||||
@author moyin
|
||||
@version 1.0.1
|
||||
@since 2025-12-17
|
||||
@lastModified 2026-01-12
|
||||
-->
|
||||
业务层负责实现核心业务逻辑和流程控制:
|
||||
|
||||
# Auth 用户认证业务模块
|
||||
1. **业务流程**:实现完整的业务流程和规则
|
||||
2. **服务协调**:协调多个核心服务完成业务功能
|
||||
3. **数据转换**:将核心层数据转换为业务数据
|
||||
4. **业务验证**:实现业务规则验证
|
||||
5. **事务管理**:处理跨服务的事务逻辑
|
||||
|
||||
Auth 是应用的核心用户认证业务模块,提供完整的用户登录、注册、密码管理、JWT令牌认证和GitHub OAuth集成功能,支持邮箱验证、验证码登录、安全防护和Zulip账号同步,具备完善的业务流程控制、错误处理和安全审计能力。
|
||||
## 模块组成
|
||||
|
||||
## 用户认证功能
|
||||
```
|
||||
src/business/auth/
|
||||
├── login.service.ts # 登录业务服务
|
||||
├── register.service.ts # 注册业务服务
|
||||
├── auth.module.ts # 业务模块配置
|
||||
└── README.md # 模块文档
|
||||
```
|
||||
|
||||
### login()
|
||||
处理用户登录请求,支持用户名/邮箱/手机号登录,验证用户凭据并生成JWT令牌。
|
||||
## 对外提供的接口
|
||||
|
||||
### register()
|
||||
处理用户注册请求,支持邮箱验证,自动创建Zulip账号并建立关联。
|
||||
### LoginService
|
||||
|
||||
### githubOAuth()
|
||||
处理GitHub OAuth登录,支持新用户自动注册和现有用户绑定。
|
||||
#### login(loginRequest: LoginRequest): Promise<ApiResponse<LoginResponse>>
|
||||
处理用户登录请求,验证用户凭据并生成JWT令牌,支持Zulip账号验证和更新。
|
||||
|
||||
### verificationCodeLogin()
|
||||
支持邮箱或手机号验证码登录,提供无密码登录方式。
|
||||
#### githubOAuth(oauthRequest: GitHubOAuthRequest): Promise<ApiResponse<LoginResponse>>
|
||||
使用GitHub账户登录或注册,自动创建用户账号并生成JWT令牌。
|
||||
|
||||
## 密码管理功能
|
||||
#### verificationCodeLogin(loginRequest: VerificationCodeLoginRequest): Promise<ApiResponse<LoginResponse>>
|
||||
使用邮箱或手机号和验证码进行登录,无需密码即可完成认证。
|
||||
|
||||
### sendPasswordResetCode()
|
||||
发送密码重置验证码到用户邮箱或手机号,支持测试模式和真实发送模式。
|
||||
#### sendPasswordResetCode(identifier: string): Promise<ApiResponse<{verification_code?: string; is_test_mode?: boolean}>>
|
||||
向用户邮箱或手机发送密码重置验证码,支持测试模式和真实发送模式。
|
||||
|
||||
### resetPassword()
|
||||
使用验证码重置用户密码,包含密码强度验证和安全检查。
|
||||
#### resetPassword(resetRequest: PasswordResetRequest): Promise<ApiResponse>
|
||||
使用验证码重置用户密码,验证验证码有效性后更新密码。
|
||||
|
||||
### changePassword()
|
||||
修改用户密码,验证旧密码并应用新密码强度规则。
|
||||
#### changePassword(userId: bigint, oldPassword: string, newPassword: string): Promise<ApiResponse>
|
||||
修改用户密码,需要验证旧密码正确性后才能更新为新密码。
|
||||
|
||||
## 邮箱验证功能
|
||||
#### refreshAccessToken(refreshToken: string): Promise<ApiResponse<TokenPair>>
|
||||
使用有效的刷新令牌生成新的访问令牌,实现无感知的令牌续期。
|
||||
|
||||
### sendEmailVerification()
|
||||
发送邮箱验证码,用于注册时的邮箱验证和账户安全验证。
|
||||
#### sendLoginVerificationCode(identifier: string): Promise<ApiResponse<{verification_code?: string; is_test_mode?: boolean}>>
|
||||
向用户邮箱或手机发送登录验证码,用于验证码登录功能。
|
||||
|
||||
### verifyEmailCode()
|
||||
验证邮箱验证码,确认邮箱所有权并更新用户验证状态。
|
||||
### RegisterService
|
||||
|
||||
### resendEmailVerification()
|
||||
重新发送邮箱验证码,处理验证码过期或丢失的情况。
|
||||
#### register(registerRequest: RegisterRequest): Promise<ApiResponse<RegisterResponse>>
|
||||
处理用户注册请求,创建游戏账号和Zulip账号,支持邮箱验证和自动回滚。
|
||||
|
||||
### sendLoginVerificationCode()
|
||||
发送登录验证码,支持验证码登录功能。
|
||||
#### sendEmailVerification(email: string): Promise<ApiResponse<{verification_code?: string; is_test_mode?: boolean}>>
|
||||
向指定邮箱发送验证码,支持测试模式和真实发送模式。
|
||||
|
||||
## 调试和管理功能
|
||||
#### verifyEmailCode(email: string, code: string): Promise<ApiResponse>
|
||||
验证邮箱验证码的有效性,用于邮箱验证流程。
|
||||
|
||||
### debugVerificationCode()
|
||||
获取验证码调试信息,用于开发环境的测试和调试。
|
||||
#### resendEmailVerification(email: string): Promise<ApiResponse<{verification_code?: string; is_test_mode?: boolean}>>
|
||||
重新向指定邮箱发送验证码,用于验证码过期或未收到的情况。
|
||||
|
||||
## HTTP API接口
|
||||
## 依赖关系
|
||||
|
||||
### POST /auth/login
|
||||
用户登录接口,接受用户名/邮箱/手机号和密码,返回JWT令牌和用户信息。
|
||||
|
||||
### POST /auth/register
|
||||
用户注册接口,创建新用户账户并可选择性创建Zulip账号。
|
||||
|
||||
### POST /auth/github
|
||||
GitHub OAuth登录接口,处理GitHub第三方登录和账户绑定。
|
||||
|
||||
### POST /auth/forgot-password
|
||||
发送密码重置验证码接口,支持邮箱和手机号找回密码。
|
||||
|
||||
### POST /auth/reset-password
|
||||
重置密码接口,使用验证码验证身份并设置新密码。
|
||||
|
||||
### PUT /auth/change-password
|
||||
修改密码接口,需要验证旧密码并设置新密码。
|
||||
|
||||
### POST /auth/send-email-verification
|
||||
发送邮箱验证码接口,用于邮箱验证流程。
|
||||
|
||||
### POST /auth/verify-email
|
||||
验证邮箱验证码接口,确认邮箱所有权。
|
||||
|
||||
### POST /auth/resend-email-verification
|
||||
重新发送邮箱验证码接口,处理验证码重发需求。
|
||||
|
||||
### POST /auth/verification-code-login
|
||||
验证码登录接口,支持无密码登录方式。
|
||||
|
||||
### POST /auth/send-login-verification-code
|
||||
发送登录验证码接口,为验证码登录提供验证码。
|
||||
|
||||
### POST /auth/refresh-token
|
||||
刷新JWT令牌接口,使用刷新令牌获取新的访问令牌。
|
||||
|
||||
### POST /auth/debug-verification-code
|
||||
调试验证码接口,获取验证码状态和调试信息。
|
||||
|
||||
### POST /auth/debug-clear-throttle
|
||||
清除限流记录接口,仅用于开发环境调试。
|
||||
|
||||
## 认证和授权组件
|
||||
|
||||
### JwtAuthGuard
|
||||
JWT认证守卫,验证请求中的Bearer令牌并提取用户信息到请求上下文。
|
||||
|
||||
### CurrentUser
|
||||
当前用户装饰器,从请求上下文中提取认证用户信息,支持获取完整用户对象或特定属性。
|
||||
```
|
||||
Gateway Layer (auth.gateway.module)
|
||||
↓ 使用
|
||||
Business Layer (auth.module)
|
||||
↓ 依赖
|
||||
Core Layer (login_core.module, zulip_core.module)
|
||||
```
|
||||
|
||||
## 使用的项目内部依赖
|
||||
|
||||
### LoginCoreService (来自 core/login_core/login_core.service)
|
||||
登录核心服务,提供用户认证、密码管理、JWT令牌生成验证等核心功能实现。
|
||||
### LoginCoreService (来自 core/login_core)
|
||||
核心登录服务,提供用户认证、JWT令牌生成、密码验证、验证码管理等技术实现。
|
||||
|
||||
### ZulipAccountService (来自 core/zulip_core/services/zulip_account.service)
|
||||
Zulip账号服务,处理Zulip账号的创建、管理和API Key安全存储。
|
||||
### ZulipAccountService (来自 core/zulip_core)
|
||||
Zulip账号服务,提供Zulip账号创建、API Key管理、账号验证等功能。
|
||||
|
||||
### ZulipAccountsService (来自 core/db/zulip_accounts/zulip_accounts.service)
|
||||
Zulip账号数据服务,管理游戏用户与Zulip账号的关联关系数据。
|
||||
### ApiKeySecurityService (来自 core/zulip_core)
|
||||
API Key安全服务,负责Zulip API Key的加密存储和Redis缓存管理。
|
||||
|
||||
### ApiKeySecurityService (来自 core/zulip_core/services/api_key_security.service)
|
||||
API Key安全服务,负责Zulip API Key的加密存储和安全管理。
|
||||
### ZulipAccountsService (来自 core/db/zulip_accounts)
|
||||
Zulip账号数据访问服务,提供游戏账号与Zulip账号的关联管理。
|
||||
|
||||
### Users (来自 core/db/users/users.entity)
|
||||
用户实体类,定义用户数据结构和数据库映射关系。
|
||||
### Users (来自 core/db/users)
|
||||
用户实体,定义用户数据结构和数据库映射关系。
|
||||
|
||||
### UserStatus (来自 business/user_mgmt/user_status.enum)
|
||||
用户状态枚举,定义用户的激活、禁用、待验证等状态值。
|
||||
## 核心原则
|
||||
|
||||
### LoginDto, RegisterDto (本模块)
|
||||
登录和注册数据传输对象,提供完整的数据验证规则和类型定义。
|
||||
### 1. 专注业务逻辑,不处理HTTP协议
|
||||
|
||||
### LoginResponseDto, RegisterResponseDto (本模块)
|
||||
登录和注册响应数据传输对象,定义API响应的数据结构和格式。
|
||||
```typescript
|
||||
// ✅ 正确:返回统一的业务响应
|
||||
async login(loginRequest: LoginRequest): Promise<ApiResponse<LoginResponse>> {
|
||||
try {
|
||||
// 1. 调用核心服务进行认证
|
||||
const authResult = await this.loginCoreService.login(loginRequest);
|
||||
|
||||
### ThrottlePresets, TimeoutPresets (来自 core/security_core/decorators)
|
||||
安全防护预设配置,提供限流和超时控制的标准配置。
|
||||
// 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'
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 协调多个核心服务
|
||||
|
||||
```typescript
|
||||
async register(registerRequest: RegisterRequest): Promise<ApiResponse<RegisterResponse>> {
|
||||
// 1. 初始化Zulip管理员客户端
|
||||
await this.initializeZulipAdminClient();
|
||||
|
||||
// 2. 调用核心服务进行注册
|
||||
const authResult = await this.loginCoreService.register(registerRequest);
|
||||
|
||||
// 3. 创建Zulip账号
|
||||
await this.createZulipAccountForUser(authResult.user, registerRequest.password);
|
||||
|
||||
// 4. 生成JWT令牌
|
||||
const tokenPair = await this.loginCoreService.generateTokenPair(authResult.user);
|
||||
|
||||
// 5. 返回完整的业务响应
|
||||
return { success: true, data: { ... }, message: '注册成功' };
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 统一的响应格式
|
||||
|
||||
```typescript
|
||||
interface ApiResponse<T = any> {
|
||||
success: boolean;
|
||||
data?: T;
|
||||
message: string;
|
||||
error_code?: string;
|
||||
}
|
||||
```
|
||||
|
||||
## 业务服务
|
||||
|
||||
### LoginService
|
||||
|
||||
负责登录相关的业务逻辑:
|
||||
|
||||
- `login()` - 用户登录
|
||||
- `githubOAuth()` - GitHub OAuth登录
|
||||
- `verificationCodeLogin()` - 验证码登录
|
||||
- `sendPasswordResetCode()` - 发送密码重置验证码
|
||||
- `resetPassword()` - 重置密码
|
||||
- `changePassword()` - 修改密码
|
||||
- `refreshAccessToken()` - 刷新访问令牌
|
||||
- `sendLoginVerificationCode()` - 发送登录验证码
|
||||
|
||||
### RegisterService
|
||||
|
||||
负责注册相关的业务逻辑:
|
||||
|
||||
- `register()` - 用户注册
|
||||
- `sendEmailVerification()` - 发送邮箱验证码
|
||||
- `verifyEmailCode()` - 验证邮箱验证码
|
||||
- `resendEmailVerification()` - 重新发送邮箱验证码
|
||||
|
||||
## 核心特性
|
||||
|
||||
### 多种登录方式支持
|
||||
- 用户名/邮箱/手机号密码登录
|
||||
- GitHub OAuth第三方登录
|
||||
- 邮箱/手机号验证码登录
|
||||
- 自动识别登录标识符类型
|
||||
### Zulip集成
|
||||
- **自动创建Zulip账号**:注册时同步创建Zulip聊天账号
|
||||
- **API Key管理**:安全存储和验证Zulip API Key
|
||||
- **账号关联**:建立游戏账号与Zulip账号的映射关系
|
||||
- **失败回滚**:Zulip账号创建失败时自动回滚游戏账号
|
||||
|
||||
### JWT令牌管理
|
||||
- 访问令牌和刷新令牌双令牌机制
|
||||
- 令牌自动刷新和过期处理
|
||||
- 安全的令牌签名和验证
|
||||
- 用户信息载荷和权限控制
|
||||
- **双令牌机制**:访问令牌(短期)+ 刷新令牌(长期)
|
||||
- **无感知续期**:通过刷新令牌自动更新访问令牌
|
||||
- **令牌验证**:完整的令牌签名和过期时间验证
|
||||
|
||||
### Zulip集成支持
|
||||
- 注册时自动创建Zulip账号
|
||||
- 游戏用户与Zulip账号关联管理
|
||||
- API Key安全存储和加密
|
||||
- 注册失败时的回滚机制
|
||||
### 统一响应格式
|
||||
- **ApiResponse接口**:统一的业务响应格式
|
||||
- **错误代码**:标准化的错误代码定义
|
||||
- **成功/失败标识**:明确的success字段
|
||||
|
||||
### 邮箱验证系统
|
||||
- 注册时邮箱验证流程
|
||||
- 密码重置邮箱验证
|
||||
- 验证码生成和过期管理
|
||||
- 测试模式和生产模式支持
|
||||
### 数据转换和格式化
|
||||
- **用户信息格式化**:将Core层数据转换为业务数据
|
||||
- **BigInt处理**:自动将bigint类型转换为string
|
||||
- **敏感信息过滤**:响应中不包含密码等敏感数据
|
||||
|
||||
### 安全防护机制
|
||||
- 请求频率限制和防暴力破解
|
||||
- 密码强度验证和安全存储
|
||||
- 用户状态检查和权限控制
|
||||
- 详细的安全审计日志
|
||||
### 完整的错误处理
|
||||
- **业务异常捕获**:捕获所有业务逻辑异常
|
||||
- **详细日志记录**:记录操作ID、用户ID、错误信息、执行时间
|
||||
- **友好错误消息**:返回用户可理解的错误提示
|
||||
|
||||
### 业务流程控制
|
||||
- 完整的错误处理和异常管理
|
||||
- 统一的响应格式和状态码
|
||||
- 业务规则验证和数据完整性
|
||||
- 操作日志和性能监控
|
||||
## 业务流程示例
|
||||
|
||||
### 用户注册流程
|
||||
|
||||
```
|
||||
1. 接收注册请求
|
||||
↓
|
||||
2. 初始化Zulip管理员客户端
|
||||
↓
|
||||
3. 调用LoginCoreService.register()创建游戏用户
|
||||
↓
|
||||
4. 创建Zulip账号并建立关联
|
||||
├─ 创建Zulip账号
|
||||
├─ 获取API Key
|
||||
├─ 存储到Redis
|
||||
└─ 创建数据库关联记录
|
||||
↓
|
||||
5. 生成JWT令牌对
|
||||
↓
|
||||
6. 返回注册成功响应
|
||||
```
|
||||
|
||||
### 用户登录流程
|
||||
|
||||
```
|
||||
1. 接收登录请求
|
||||
↓
|
||||
2. 调用LoginCoreService.login()验证用户
|
||||
↓
|
||||
3. 验证并更新Zulip API Key
|
||||
├─ 查找Zulip账号关联
|
||||
├─ 从Redis获取API Key
|
||||
├─ 验证API Key有效性
|
||||
└─ 如果无效,重新生成
|
||||
↓
|
||||
4. 生成JWT令牌对
|
||||
↓
|
||||
5. 返回登录成功响应
|
||||
```
|
||||
|
||||
## 与其他层的交互
|
||||
|
||||
### 与Gateway层的交互
|
||||
|
||||
Gateway层调用Business层服务:
|
||||
|
||||
```typescript
|
||||
// Gateway Layer
|
||||
@Post('login')
|
||||
async login(@Body() loginDto: LoginDto, @Res() res: Response): Promise<void> {
|
||||
const result = await this.loginService.login({
|
||||
identifier: loginDto.identifier,
|
||||
password: loginDto.password
|
||||
});
|
||||
|
||||
this.handleResponse(result, res);
|
||||
}
|
||||
```
|
||||
|
||||
### 与Core层的交互
|
||||
|
||||
Business层调用Core层服务:
|
||||
|
||||
```typescript
|
||||
// Business Layer
|
||||
async login(loginRequest: LoginRequest): Promise<ApiResponse<LoginResponse>> {
|
||||
// 调用核心服务
|
||||
const authResult = await this.loginCoreService.login(loginRequest);
|
||||
const tokenPair = await this.loginCoreService.generateTokenPair(authResult.user);
|
||||
|
||||
// 返回业务响应
|
||||
return { success: true, data: { ... } };
|
||||
}
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **业务逻辑集中**:所有业务规则都在Business层实现
|
||||
2. **服务协调**:协调多个Core层服务完成复杂业务
|
||||
3. **错误处理**:捕获异常并转换为业务错误
|
||||
4. **日志记录**:记录关键业务操作和错误
|
||||
5. **事务管理**:处理跨服务的数据一致性
|
||||
6. **数据转换**:将Core层数据转换为业务数据
|
||||
|
||||
## 潜在风险
|
||||
|
||||
### Zulip账号创建失败风险
|
||||
- Zulip服务不可用时注册流程可能失败
|
||||
- 网络异常导致账号创建不完整
|
||||
- 建议实现重试机制和降级策略,允许跳过Zulip账号创建
|
||||
- **风险描述**:注册流程中Zulip账号创建可能失败
|
||||
- **影响范围**:导致注册流程中断,已创建的游戏账号需要回滚
|
||||
- **缓解措施**:完整的事务回滚机制和错误日志记录
|
||||
|
||||
### 验证码发送依赖风险
|
||||
- 邮件服务配置错误导致验证码无法发送
|
||||
- 测试模式下验证码泄露到日志中
|
||||
- 建议完善邮件服务监控和测试模式安全控制
|
||||
### API Key验证失败风险
|
||||
- **风险描述**:登录时Zulip API Key可能已失效或不存在
|
||||
- **影响范围**:用户无法使用Zulip聊天功能
|
||||
- **缓解措施**:API Key验证失败不影响登录流程,记录警告日志,尝试重新生成
|
||||
|
||||
### JWT令牌安全风险
|
||||
- 令牌泄露可能导致账户被盗用
|
||||
- 刷新令牌长期有效增加安全风险
|
||||
- 建议实现令牌黑名单机制和异常登录检测
|
||||
### 跨服务事务一致性风险
|
||||
- **风险描述**:涉及多个Core层服务的协调操作,部分操作成功部分失败
|
||||
- **影响范围**:数据不一致,如游戏账号创建成功但Zulip账号创建失败
|
||||
- **缓解措施**:明确的操作顺序、完整的错误处理、自动回滚机制
|
||||
|
||||
### 并发操作风险
|
||||
- 同时注册相同用户名可能导致数据冲突
|
||||
- 高并发场景下验证码生成可能重复
|
||||
- 建议加强数据库唯一性约束和分布式锁机制
|
||||
### 业务逻辑复杂度风险
|
||||
- **风险描述**:登录和注册流程涉及多个步骤和服务,代码复杂度高
|
||||
- **影响范围**:增加维护难度,容易引入bug
|
||||
- **缓解措施**:详细的注释、完整的测试覆盖(41个测试用例)、清晰的日志记录
|
||||
|
||||
### 第三方服务依赖风险
|
||||
- GitHub OAuth服务不可用影响第三方登录
|
||||
- Zulip服务异常影响账号同步功能
|
||||
- 建议实现服务降级和故障转移机制
|
||||
### 验证码发送失败风险
|
||||
- **风险描述**:邮件服务不可用或配置错误导致验证码无法发送
|
||||
- **影响范围**:用户无法完成邮箱验证、密码重置、验证码登录
|
||||
- **缓解措施**:测试模式支持、详细的错误日志、邮件服务健康检查
|
||||
|
||||
### 密码安全风险
|
||||
- 弱密码策略可能导致账户安全问题
|
||||
- 密码重置流程可能被恶意利用
|
||||
- 建议加强密码策略和增加二次验证机制
|
||||
## 注意事项
|
||||
|
||||
## 补充信息
|
||||
|
||||
### 版本信息
|
||||
- 模块版本:1.0.2
|
||||
- 最后修改:2026-01-07
|
||||
- 作者:moyin
|
||||
- 创建时间:2025-12-17
|
||||
|
||||
### 架构优化记录
|
||||
- 2026-01-07:将JWT技术实现从Business层移至Core层,符合分层架构原则
|
||||
- 2026-01-07:完成代码规范优化,统一注释格式和文件命名规范
|
||||
- 2026-01-07:完善测试覆盖,确保所有公共方法都有对应的单元测试
|
||||
|
||||
### 已知限制
|
||||
- 短信验证码功能尚未实现,目前仅支持邮箱验证码
|
||||
- Zulip账号创建失败时的重试机制有待完善
|
||||
- 多设备登录管理和会话控制功能待开发
|
||||
|
||||
### 改进建议
|
||||
- 实现短信验证码发送功能,完善多渠道验证
|
||||
- 增加社交登录支持(微信、QQ等)
|
||||
- 实现多因素认证(MFA)提升账户安全
|
||||
- 添加登录设备管理和异常登录检测
|
||||
- 完善Zulip集成的错误处理和重试机制
|
||||
- Business层不应该处理HTTP协议
|
||||
- Business层不应该直接访问数据库(通过Core层)
|
||||
- Business层不应该包含技术实现细节
|
||||
- 所有业务逻辑都应该有完善的错误处理
|
||||
- 关键业务操作都应该有日志记录
|
||||
|
||||
@@ -1,32 +1,38 @@
|
||||
/**
|
||||
* 用户认证业务模块
|
||||
*
|
||||
* 架构层级:Business Layer(业务层)
|
||||
*
|
||||
* 功能描述:
|
||||
* - 整合所有用户认证相关功能
|
||||
* - 用户登录、注册、密码管理
|
||||
* - GitHub OAuth集成
|
||||
* - 邮箱验证功能
|
||||
* - JWT令牌管理和验证
|
||||
* - 整合所有用户认证相关的业务逻辑
|
||||
* - 用户登录、注册、密码管理业务流程
|
||||
* - GitHub OAuth业务集成
|
||||
* - 邮箱验证业务功能
|
||||
* - Zulip账号关联业务
|
||||
*
|
||||
* 职责分离:
|
||||
* - 专注于认证业务模块的依赖注入和配置
|
||||
* - 整合核心服务和业务服务
|
||||
* - 提供JWT模块的统一配置
|
||||
* - 专注于业务逻辑实现和流程控制
|
||||
* - 整合核心服务完成业务功能
|
||||
* - 不包含HTTP协议处理(由Gateway层负责)
|
||||
* - 不包含数据访问细节(由Core层负责)
|
||||
*
|
||||
* 依赖关系:
|
||||
* - 依赖 Core Layer 的 LoginCoreModule
|
||||
* - 依赖 Core Layer 的 ZulipCoreModule
|
||||
* - 被 Gateway Layer 的 AuthGatewayModule 使用
|
||||
*
|
||||
* 最近修改:
|
||||
* - 2026-01-14: 架构重构 - 移除Controller,专注于业务逻辑层
|
||||
* - 2026-01-07: 代码规范优化 - 文件夹扁平化,移除单文件文件夹结构
|
||||
* - 2026-01-07: 代码规范优化 - 更新注释规范,修正文件引用路径
|
||||
*
|
||||
* @author moyin
|
||||
* @version 1.0.2
|
||||
* @version 2.0.0
|
||||
* @since 2025-12-24
|
||||
* @lastModified 2026-01-07
|
||||
* @lastModified 2026-01-14
|
||||
*/
|
||||
|
||||
import { Module } from '@nestjs/common';
|
||||
import { LoginController } from './login.controller';
|
||||
import { LoginService } from './login.service';
|
||||
import { RegisterController } from './register.controller';
|
||||
import { RegisterService } from './register.service';
|
||||
import { LoginCoreModule } from '../../core/login_core/login_core.module';
|
||||
import { ZulipCoreModule } from '../../core/zulip_core/zulip_core.module';
|
||||
@@ -35,16 +41,21 @@ import { UsersModule } from '../../core/db/users/users.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
// 导入核心层模块
|
||||
LoginCoreModule,
|
||||
ZulipCoreModule,
|
||||
ZulipAccountsModule.forRoot(),
|
||||
UsersModule,
|
||||
],
|
||||
controllers: [LoginController, RegisterController],
|
||||
providers: [
|
||||
// 业务服务
|
||||
LoginService,
|
||||
RegisterService,
|
||||
],
|
||||
exports: [
|
||||
// 导出业务服务供Gateway层使用
|
||||
LoginService,
|
||||
RegisterService,
|
||||
],
|
||||
exports: [LoginService, RegisterService],
|
||||
})
|
||||
export class AuthModule {}
|
||||
@@ -2,38 +2,30 @@
|
||||
* 用户认证业务模块导出
|
||||
*
|
||||
* 功能概述:
|
||||
* - 用户登录和注册
|
||||
* - 用户登录和注册业务逻辑
|
||||
* - GitHub OAuth集成
|
||||
* - 密码管理(忘记密码、重置密码、修改密码)
|
||||
* - 邮箱验证功能
|
||||
* - JWT Token管理
|
||||
*
|
||||
* 职责分离:
|
||||
* - 专注于模块导出和接口暴露
|
||||
* - 提供统一的模块入口点
|
||||
* - 专注于业务层模块导出
|
||||
* - 提供统一的业务服务入口点
|
||||
* - 简化外部模块的引用方式
|
||||
*
|
||||
* 最近修改:
|
||||
* - 2026-01-14: 架构重构 - 移除Controller和DTO导出(已移至Gateway层)(修改者: moyin)
|
||||
* - 2026-01-07: 代码规范优化 - 文件夹扁平化,移除单文件文件夹结构
|
||||
* - 2026-01-07: 代码规范优化 - 更新注释规范
|
||||
*
|
||||
* @author moyin
|
||||
* @version 1.0.2
|
||||
* @version 2.0.0
|
||||
* @since 2025-12-17
|
||||
* @lastModified 2026-01-07
|
||||
* @lastModified 2026-01-14
|
||||
*/
|
||||
|
||||
// 模块
|
||||
export * from './auth.module';
|
||||
|
||||
// 控制器
|
||||
export * from './login.controller';
|
||||
export * from './register.controller';
|
||||
|
||||
// 服务
|
||||
// 服务(业务层)
|
||||
export { LoginService } from './login.service';
|
||||
export { RegisterService } from './register.service';
|
||||
|
||||
// DTO
|
||||
export * from './login.dto';
|
||||
export * from './login_response.dto';
|
||||
@@ -51,8 +51,8 @@ import {
|
||||
ApiBearerAuth,
|
||||
ApiBody,
|
||||
} from '@nestjs/swagger';
|
||||
import { JwtAuthGuard } from '../../auth/jwt_auth.guard';
|
||||
import { CurrentUser } from '../../auth/current_user.decorator';
|
||||
import { JwtAuthGuard } from '../../../gateway/auth/jwt_auth.guard';
|
||||
import { CurrentUser } from '../../../gateway/auth/current_user.decorator';
|
||||
import { JwtPayload } from '../../../core/login_core/login_core.service';
|
||||
|
||||
// 导入业务服务
|
||||
|
||||
@@ -51,8 +51,8 @@ import {
|
||||
ApiBearerAuth,
|
||||
ApiBody,
|
||||
} from '@nestjs/swagger';
|
||||
import { JwtAuthGuard, AuthenticatedRequest } from '../auth/jwt_auth.guard';
|
||||
import { CurrentUser } from '../auth/current_user.decorator';
|
||||
import { JwtAuthGuard, AuthenticatedRequest } from '../../gateway/auth/jwt_auth.guard';
|
||||
import { CurrentUser } from '../../gateway/auth/current_user.decorator';
|
||||
import { JwtPayload } from '../../core/login_core/login_core.service';
|
||||
|
||||
// 导入业务服务
|
||||
|
||||
@@ -13,8 +13,8 @@ import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagg
|
||||
import { NoticeService } from './notice.service';
|
||||
import { CreateNoticeDto } from './dto/create-notice.dto';
|
||||
import { NoticeResponseDto } from './dto/notice-response.dto';
|
||||
import { JwtAuthGuard } from '../auth/jwt_auth.guard';
|
||||
import { CurrentUser } from '../auth/current_user.decorator';
|
||||
import { JwtAuthGuard } from '../../gateway/auth/jwt_auth.guard';
|
||||
import { CurrentUser } from '../../gateway/auth/current_user.decorator';
|
||||
|
||||
@ApiTags('通知管理')
|
||||
@Controller('api/notices')
|
||||
|
||||
@@ -29,7 +29,7 @@ import { ChatController } from './chat.controller';
|
||||
import { ZulipService } from './zulip.service';
|
||||
import { MessageFilterService } from './services/message_filter.service';
|
||||
import { CleanWebSocketGateway } from './clean_websocket.gateway';
|
||||
import { JwtAuthGuard } from '../auth/jwt_auth.guard';
|
||||
import { JwtAuthGuard } from '../../gateway/auth/jwt_auth.guard';
|
||||
|
||||
// Mock JwtAuthGuard
|
||||
const mockJwtAuthGuard = {
|
||||
|
||||
@@ -40,7 +40,7 @@ import {
|
||||
ApiBearerAuth,
|
||||
ApiQuery,
|
||||
} from '@nestjs/swagger';
|
||||
import { JwtAuthGuard } from '../auth/jwt_auth.guard';
|
||||
import { JwtAuthGuard } from '../../gateway/auth/jwt_auth.guard';
|
||||
import { ZulipService } from './zulip.service';
|
||||
import { CleanWebSocketGateway } from './clean_websocket.gateway';
|
||||
import {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { HttpException, HttpStatus } from '@nestjs/common';
|
||||
import { ZulipAccountsController } from './zulip_accounts.controller';
|
||||
import { JwtAuthGuard } from '../auth/jwt_auth.guard';
|
||||
import { JwtAuthGuard } from '../../gateway/auth/jwt_auth.guard';
|
||||
import { AppLoggerService } from '../../core/utils/logger/logger.service';
|
||||
import { ZulipAccountsBusinessService } from './services/zulip_accounts_business.service';
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ import {
|
||||
ApiQuery,
|
||||
} from '@nestjs/swagger';
|
||||
import { Request } from 'express';
|
||||
import { JwtAuthGuard } from '../auth/jwt_auth.guard';
|
||||
import { JwtAuthGuard } from '../../gateway/auth/jwt_auth.guard';
|
||||
import { ZulipAccountsService } from '../../core/db/zulip_accounts/zulip_accounts.service';
|
||||
import { ZulipAccountsMemoryService } from '../../core/db/zulip_accounts/zulip_accounts_memory.service';
|
||||
import { AppLoggerService } from '../../core/utils/logger/logger.service';
|
||||
|
||||
338
src/gateway/auth/README.md
Normal file
338
src/gateway/auth/README.md
Normal file
@@ -0,0 +1,338 @@
|
||||
# 认证网关模块 (Auth Gateway Module)
|
||||
|
||||
认证网关模块是系统的HTTP API入口,负责处理所有认证相关的HTTP请求,包括用户登录、注册、密码管理、邮箱验证等功能,提供统一的API接口和完善的安全保护机制。
|
||||
|
||||
## 架构层级
|
||||
|
||||
**Gateway Layer(网关层)**
|
||||
|
||||
## 职责定位
|
||||
|
||||
网关层是系统的HTTP API入口,负责:
|
||||
|
||||
1. **协议处理**:处理HTTP请求和响应
|
||||
2. **数据验证**:使用DTO进行请求参数验证
|
||||
3. **路由管理**:定义API端点和路由规则
|
||||
4. **认证守卫**:JWT令牌验证和权限检查
|
||||
5. **错误转换**:将业务错误转换为HTTP状态码
|
||||
6. **API文档**:提供Swagger API文档
|
||||
|
||||
## 模块组成
|
||||
|
||||
```
|
||||
src/gateway/auth/
|
||||
├── login.controller.ts # 登录API控制器
|
||||
├── login.controller.spec.ts # 登录控制器测试
|
||||
├── register.controller.ts # 注册API控制器
|
||||
├── register.controller.spec.ts # 注册控制器测试
|
||||
├── jwt_auth.guard.ts # JWT认证守卫
|
||||
├── jwt_auth.guard.spec.ts # JWT认证守卫测试
|
||||
├── current_user.decorator.ts # 当前用户装饰器
|
||||
├── jwt_usage_example.ts # JWT使用示例(开发参考)
|
||||
├── dto/ # 数据传输对象
|
||||
│ ├── login.dto.ts # 登录相关DTO
|
||||
│ └── login_response.dto.ts # 响应DTO
|
||||
├── auth.gateway.module.ts # 网关模块配置
|
||||
└── README.md # 模块文档
|
||||
```
|
||||
|
||||
## 依赖关系
|
||||
|
||||
```
|
||||
Gateway Layer (auth.gateway.module)
|
||||
↓ 依赖
|
||||
Business Layer (auth.module)
|
||||
↓ 依赖
|
||||
Core Layer (login_core.module)
|
||||
```
|
||||
|
||||
## 核心原则
|
||||
|
||||
### 1. 只做协议转换,不做业务逻辑
|
||||
|
||||
```typescript
|
||||
// ✅ 正确:只做HTTP协议处理
|
||||
@Post('login')
|
||||
async login(@Body() loginDto: LoginDto, @Res() res: Response): Promise<void> {
|
||||
const result = await this.loginService.login({
|
||||
identifier: loginDto.identifier,
|
||||
password: loginDto.password
|
||||
});
|
||||
|
||||
this.handleResponse(result, res);
|
||||
}
|
||||
|
||||
// ❌ 错误:在Controller中包含业务逻辑
|
||||
@Post('login')
|
||||
async login(@Body() loginDto: LoginDto): Promise<any> {
|
||||
// 验证用户
|
||||
const user = await this.userService.findByIdentifier(loginDto.identifier);
|
||||
// 检查密码
|
||||
const isValid = await this.comparePassword(loginDto.password, user.password);
|
||||
// ... 更多业务逻辑
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 统一的错误处理
|
||||
|
||||
```typescript
|
||||
private handleResponse(result: any, res: Response, successStatus: HttpStatus = HttpStatus.OK): void {
|
||||
if (result.success) {
|
||||
res.status(successStatus).json(result);
|
||||
return;
|
||||
}
|
||||
|
||||
const statusCode = this.getErrorStatusCode(result);
|
||||
res.status(statusCode).json(result);
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 使用DTO进行数据验证
|
||||
|
||||
```typescript
|
||||
export class LoginDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
identifier: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
password: string;
|
||||
}
|
||||
```
|
||||
|
||||
## 对外提供的接口
|
||||
|
||||
### LoginController
|
||||
|
||||
#### login(loginDto: LoginDto, res: Response): Promise<void>
|
||||
处理用户登录请求,支持用户名、邮箱或手机号多种方式登录。
|
||||
|
||||
#### githubOAuth(githubDto: GitHubOAuthDto, res: Response): Promise<void>
|
||||
处理GitHub OAuth登录请求,支持使用GitHub账户登录或注册。
|
||||
|
||||
#### refreshToken(refreshTokenDto: RefreshTokenDto, res: Response): Promise<void>
|
||||
刷新访问令牌,使用有效的刷新令牌生成新的访问令牌。
|
||||
|
||||
#### forgotPassword(forgotPasswordDto: ForgotPasswordDto, res: Response): Promise<void>
|
||||
发送密码重置验证码到用户邮箱或手机。
|
||||
|
||||
#### resetPassword(resetPasswordDto: ResetPasswordDto, res: Response): Promise<void>
|
||||
使用验证码重置用户密码。
|
||||
|
||||
#### changePassword(changePasswordDto: ChangePasswordDto, res: Response): Promise<void>
|
||||
修改用户密码,需要提供旧密码验证。
|
||||
|
||||
#### verificationCodeLogin(verificationCodeLoginDto: VerificationCodeLoginDto, res: Response): Promise<void>
|
||||
使用邮箱或手机号和验证码进行登录,无需密码。
|
||||
|
||||
#### sendLoginVerificationCode(sendLoginVerificationCodeDto: SendLoginVerificationCodeDto, res: Response): Promise<void>
|
||||
向用户邮箱或手机发送登录验证码。
|
||||
|
||||
#### debugVerificationCode(sendEmailVerificationDto: SendEmailVerificationDto, res: Response): Promise<void>
|
||||
获取验证码的详细调试信息,仅用于开发环境。
|
||||
|
||||
### RegisterController
|
||||
|
||||
#### register(registerDto: RegisterDto, res: Response): Promise<void>
|
||||
处理用户注册请求,创建新用户账户。
|
||||
|
||||
#### sendEmailVerification(sendEmailVerificationDto: SendEmailVerificationDto, res: Response): Promise<void>
|
||||
向指定邮箱发送验证码。
|
||||
|
||||
#### verifyEmail(emailVerificationDto: EmailVerificationDto, res: Response): Promise<void>
|
||||
使用验证码验证邮箱。
|
||||
|
||||
#### resendEmailVerification(sendEmailVerificationDto: SendEmailVerificationDto, res: Response): Promise<void>
|
||||
重新向指定邮箱发送验证码。
|
||||
|
||||
### JwtAuthGuard
|
||||
|
||||
#### canActivate(context: ExecutionContext): Promise<boolean>
|
||||
验证请求中的JWT令牌,提取用户信息并添加到请求上下文。
|
||||
|
||||
### CurrentUser Decorator
|
||||
|
||||
#### CurrentUser(data?: keyof JwtPayload): ParameterDecorator
|
||||
从请求上下文中提取当前认证用户信息的参数装饰器。
|
||||
|
||||
## 对外API接口
|
||||
|
||||
### POST /auth/login
|
||||
用户登录接口,支持用户名、邮箱或手机号多种方式登录,返回JWT令牌。
|
||||
|
||||
### POST /auth/github
|
||||
GitHub OAuth登录接口,使用GitHub账户登录或注册。
|
||||
|
||||
### POST /auth/verification-code-login
|
||||
验证码登录接口,使用邮箱或手机号和验证码进行登录,无需密码。
|
||||
|
||||
### POST /auth/refresh-token
|
||||
刷新访问令牌接口,使用有效的刷新令牌生成新的访问令牌。
|
||||
|
||||
### POST /auth/forgot-password
|
||||
发送密码重置验证码接口,向用户邮箱或手机发送密码重置验证码。
|
||||
|
||||
### POST /auth/reset-password
|
||||
重置密码接口,使用验证码重置用户密码。
|
||||
|
||||
### PUT /auth/change-password
|
||||
修改密码接口,用户修改自己的密码,需要提供旧密码验证。
|
||||
|
||||
### POST /auth/send-login-verification-code
|
||||
发送登录验证码接口,向用户邮箱或手机发送登录验证码。
|
||||
|
||||
### POST /auth/debug-verification-code
|
||||
调试验证码信息接口,获取验证码的详细调试信息,仅用于开发环境。
|
||||
|
||||
### POST /auth/register
|
||||
用户注册接口,创建新用户账户。
|
||||
|
||||
### POST /auth/send-email-verification
|
||||
发送邮箱验证码接口,向指定邮箱发送验证码。
|
||||
|
||||
### POST /auth/verify-email
|
||||
验证邮箱接口,使用验证码验证邮箱。
|
||||
|
||||
### POST /auth/resend-email-verification
|
||||
重新发送邮箱验证码接口,重新向指定邮箱发送验证码。
|
||||
|
||||
## 使用的项目内部依赖
|
||||
|
||||
### LoginService (来自 business/auth/login.service)
|
||||
登录业务服务,提供用户登录、密码管理、令牌刷新等业务逻辑。
|
||||
|
||||
### RegisterService (来自 business/auth/register.service)
|
||||
注册业务服务,提供用户注册、邮箱验证等业务逻辑。
|
||||
|
||||
### LoginCoreService (来自 core/login_core/login_core.service)
|
||||
登录核心服务,提供JWT令牌验证和生成等技术实现。
|
||||
|
||||
### JwtPayload (来自 core/login_core/login_core.service)
|
||||
JWT令牌载荷类型定义,包含用户ID、用户名、角色等信息。
|
||||
|
||||
### ThrottlePresets (来自 core/security_core/throttle.decorator)
|
||||
限流预设配置,提供登录、注册、发送验证码等场景的限流规则。
|
||||
|
||||
### TimeoutPresets (来自 core/security_core/timeout.decorator)
|
||||
超时预设配置,提供不同场景的超时时间设置。
|
||||
|
||||
## 核心特性
|
||||
|
||||
### 统一的响应处理机制
|
||||
- 智能错误状态码映射:根据错误代码和消息自动选择合适的HTTP状态码
|
||||
- 统一响应格式:所有API返回统一的JSON格式
|
||||
- 错误信息标准化:提供清晰的错误代码和消息
|
||||
|
||||
### 完善的安全保护
|
||||
- JWT令牌认证:使用JWT进行用户身份验证
|
||||
- 限流保护:防止API滥用和暴力破解
|
||||
- 超时控制:防止长时间阻塞和资源占用
|
||||
- 请求验证:使用DTO和class-validator进行严格的数据验证
|
||||
|
||||
### 完整的API文档
|
||||
- Swagger集成:自动生成交互式API文档
|
||||
- 详细的接口说明:每个API都有完整的描述和示例
|
||||
- 请求响应示例:提供清晰的数据格式说明
|
||||
|
||||
### 灵活的认证方式
|
||||
- 多种登录方式:支持用户名、邮箱、手机号登录
|
||||
- 验证码登录:支持无密码的验证码登录
|
||||
- OAuth集成:支持GitHub OAuth登录
|
||||
- 令牌刷新:支持无感知的令牌续期
|
||||
|
||||
## 使用示例
|
||||
|
||||
### JWT认证完整示例
|
||||
|
||||
本模块提供了完整的JWT认证使用示例文件 `jwt_usage_example.ts`,展示了以下场景:
|
||||
|
||||
1. **公开接口**:无需认证的接口
|
||||
2. **受保护接口**:需要JWT令牌的接口
|
||||
3. **用户信息获取**:使用 `@CurrentUser()` 装饰器
|
||||
4. **特定属性提取**:使用 `@CurrentUser('username')` 获取特定字段
|
||||
5. **角色权限检查**:基于用户角色的访问控制
|
||||
|
||||
详细代码请参考 `src/gateway/auth/jwt_usage_example.ts` 文件。
|
||||
|
||||
### 在其他模块中使用认证守卫
|
||||
|
||||
```typescript
|
||||
import { Controller, Get, UseGuards } from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../gateway/auth/jwt_auth.guard';
|
||||
import { CurrentUser } from '../gateway/auth/current_user.decorator';
|
||||
|
||||
@Controller('profile')
|
||||
export class ProfileController {
|
||||
@Get()
|
||||
@UseGuards(JwtAuthGuard)
|
||||
getProfile(@CurrentUser() user: any) {
|
||||
return { user };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 与业务层的交互
|
||||
|
||||
网关层通过依赖注入使用业务层服务:
|
||||
|
||||
```typescript
|
||||
constructor(
|
||||
private readonly loginService: LoginService,
|
||||
private readonly registerService: RegisterService
|
||||
) {}
|
||||
```
|
||||
|
||||
业务层返回统一的响应格式:
|
||||
|
||||
```typescript
|
||||
interface ApiResponse<T = any> {
|
||||
success: boolean;
|
||||
data?: T;
|
||||
message: string;
|
||||
error_code?: string;
|
||||
}
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **保持Controller轻量**:只做请求响应处理
|
||||
2. **使用DTO验证**:所有输入都要经过DTO验证
|
||||
3. **统一错误处理**:使用统一的错误处理方法
|
||||
4. **完善API文档**:使用Swagger装饰器
|
||||
5. **限流保护**:使用Throttle装饰器防止滥用
|
||||
6. **超时控制**:使用Timeout装饰器防止长时间阻塞
|
||||
|
||||
## 潜在风险
|
||||
|
||||
### 限流配置不当风险
|
||||
- 限流阈值过低可能影响正常用户使用
|
||||
- 限流阈值过高无法有效防止攻击
|
||||
- 缓解措施:根据实际业务场景调整限流参数,监控限流触发情况
|
||||
|
||||
### JWT令牌安全风险
|
||||
- 令牌泄露可能导致账户被盗用
|
||||
- 令牌过期时间设置不当影响用户体验
|
||||
- 缓解措施:使用HTTPS传输,合理设置令牌过期时间,实现令牌刷新机制
|
||||
|
||||
### 验证码安全风险
|
||||
- 验证码被暴力破解
|
||||
- 验证码发送频率过高导致资源浪费
|
||||
- 缓解措施:限制验证码发送频率,增加验证码复杂度,设置验证码有效期
|
||||
|
||||
### API滥用风险
|
||||
- 恶意用户频繁调用API消耗服务器资源
|
||||
- 自动化工具批量注册账户
|
||||
- 缓解措施:实施限流策略,添加人机验证,监控异常请求模式
|
||||
|
||||
### 错误信息泄露风险
|
||||
- 详细的错误信息可能泄露系统实现细节
|
||||
- 帮助攻击者了解系统弱点
|
||||
- 缓解措施:生产环境使用通用错误消息,详细日志仅记录在服务器端
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 网关层不应该直接访问数据库
|
||||
- 网关层不应该包含复杂的业务逻辑
|
||||
- 网关层不应该直接调用Core层服务(Guard除外)
|
||||
- 所有业务逻辑都应该在Business层实现
|
||||
52
src/gateway/auth/auth.gateway.module.ts
Normal file
52
src/gateway/auth/auth.gateway.module.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* 认证网关模块
|
||||
*
|
||||
* 架构层级:Gateway Layer(网关层)
|
||||
*
|
||||
* 功能描述:
|
||||
* - 整合所有认证相关的网关组件
|
||||
* - 提供HTTP API接口
|
||||
* - 配置认证守卫和中间件
|
||||
* - 处理请求验证和响应格式化
|
||||
*
|
||||
* 职责分离:
|
||||
* - 专注于HTTP协议处理和API网关功能
|
||||
* - 依赖业务层服务,不包含业务逻辑
|
||||
* - 提供统一的API入口和文档
|
||||
*
|
||||
* 依赖关系:
|
||||
* - 依赖 Business Layer 的 AuthModule
|
||||
* - 提供 Controller 和 Guard
|
||||
*
|
||||
* @author moyin
|
||||
* @version 2.0.0
|
||||
* @since 2026-01-14
|
||||
* @lastModified 2026-01-14
|
||||
*/
|
||||
|
||||
import { Module } from '@nestjs/common';
|
||||
import { LoginController } from './login.controller';
|
||||
import { RegisterController } from './register.controller';
|
||||
import { JwtAuthGuard } from './jwt_auth.guard';
|
||||
import { AuthModule } from '../../business/auth/auth.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
// 导入业务层模块
|
||||
AuthModule,
|
||||
],
|
||||
controllers: [
|
||||
// 网关层控制器
|
||||
LoginController,
|
||||
RegisterController,
|
||||
],
|
||||
providers: [
|
||||
// 认证守卫
|
||||
JwtAuthGuard,
|
||||
],
|
||||
exports: [
|
||||
// 导出守卫供其他模块使用
|
||||
JwtAuthGuard,
|
||||
],
|
||||
})
|
||||
export class AuthGatewayModule {}
|
||||
@@ -7,12 +7,13 @@
|
||||
* - 测试认证失败的异常处理
|
||||
*
|
||||
* 最近修改:
|
||||
* - 2026-01-14: 架构重构 - 从business层移动到gateway层 (修改者: moyin)
|
||||
* - 2026-01-12: 代码规范优化 - 创建缺失的守卫测试文件 (修改者: moyin)
|
||||
*
|
||||
* @author moyin
|
||||
* @version 1.0.0
|
||||
* @version 1.1.0
|
||||
* @since 2026-01-12
|
||||
* @lastModified 2026-01-12
|
||||
* @lastModified 2026-01-14
|
||||
*/
|
||||
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
@@ -1,6 +1,8 @@
|
||||
/**
|
||||
* JWT 使用示例
|
||||
*
|
||||
* 架构层级:Gateway Layer(网关层)
|
||||
*
|
||||
* 功能描述:
|
||||
* - 展示如何在控制器中使用 JWT 认证守卫和当前用户装饰器
|
||||
* - 提供完整的JWT认证使用示例和最佳实践
|
||||
@@ -11,14 +13,20 @@
|
||||
* - 提供开发者参考的代码示例
|
||||
* - 展示认证守卫和装饰器的最佳实践
|
||||
*
|
||||
* 架构说明:
|
||||
* - 本文件位于Gateway层,符合Controller的架构定位
|
||||
* - JWT Guard和装饰器位于同层(src/gateway/auth)
|
||||
* - 本文件作为使用示例参考
|
||||
*
|
||||
* 最近修改:
|
||||
* - 2026-01-14: 架构优化 - 将文件从Business层移至Gateway层,符合架构分层原则 (Modified by: moyin)
|
||||
* - 2026-01-14: 代码规范优化 - 修正导入路径,指向Gateway层 (Modified by: moyin)
|
||||
* - 2026-01-07: 代码规范优化 - 文件夹扁平化,移除单文件文件夹结构
|
||||
* - 2026-01-07: 代码规范优化 - 文件重命名为snake_case格式,更新注释规范
|
||||
*
|
||||
* @author moyin
|
||||
* @version 1.0.2
|
||||
* @version 1.2.0
|
||||
* @since 2025-01-05
|
||||
* @lastModified 2026-01-07
|
||||
* @lastModified 2026-01-14
|
||||
*/
|
||||
|
||||
import { Controller, Get, UseGuards, Post, Body } from '@nestjs/common';
|
||||
@@ -7,19 +7,20 @@
|
||||
* - 测试错误处理和异常情况
|
||||
*
|
||||
* 最近修改:
|
||||
* - 2026-01-14: 架构重构 - 从business层移动到gateway层 (修改者: moyin)
|
||||
* - 2026-01-12: 代码规范优化 - 创建缺失的控制器测试文件 (修改者: moyin)
|
||||
*
|
||||
* @author moyin
|
||||
* @version 1.0.0
|
||||
* @version 1.1.0
|
||||
* @since 2026-01-12
|
||||
* @lastModified 2026-01-12
|
||||
* @lastModified 2026-01-14
|
||||
*/
|
||||
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { Response } from 'express';
|
||||
import { HttpStatus } from '@nestjs/common';
|
||||
import { LoginController } from './login.controller';
|
||||
import { LoginService } from './login.service';
|
||||
import { LoginService } from '../../business/auth/login.service';
|
||||
|
||||
describe('LoginController', () => {
|
||||
let controller: LoginController;
|
||||
@@ -1,47 +1,79 @@
|
||||
/**
|
||||
* 登录控制器
|
||||
* 登录网关控制器
|
||||
*
|
||||
* 架构层级:Gateway Layer(网关层)
|
||||
*
|
||||
* 功能描述:
|
||||
* - 处理登录相关的HTTP请求和响应
|
||||
* - 提供RESTful API接口
|
||||
* - 数据验证和格式化
|
||||
* - 协议处理和错误响应
|
||||
*
|
||||
* 职责分离:
|
||||
* - 专注于HTTP请求处理和响应格式化
|
||||
* - 调用业务服务完成具体功能
|
||||
* - 专注于HTTP协议处理和请求响应
|
||||
* - 调用业务层服务完成具体功能
|
||||
* - 处理API文档和参数验证
|
||||
* - 不包含业务逻辑,只做数据转换和路由
|
||||
*
|
||||
* 依赖关系:
|
||||
* - 依赖 Business Layer 的 LoginService
|
||||
* - 使用 DTO 进行数据验证
|
||||
* - 使用 Guard 进行认证保护
|
||||
*
|
||||
* API端点:
|
||||
* - POST /auth/login - 用户登录
|
||||
* - POST /auth/register - 用户注册
|
||||
* - POST /auth/github - GitHub OAuth登录
|
||||
* - POST /auth/forgot-password - 发送密码重置验证码
|
||||
* - POST /auth/reset-password - 重置密码
|
||||
* - PUT /auth/change-password - 修改密码
|
||||
* - POST /auth/refresh-token - 刷新访问令牌
|
||||
*
|
||||
* 最近修改:
|
||||
* - 2026-01-07: 代码规范优化 - 文件夹扁平化,移除单文件文件夹结构
|
||||
* - 2026-01-07: 代码规范优化 - 更新注释规范,修正文件引用路径
|
||||
* - POST /auth/verification-code-login - 验证码登录
|
||||
* - POST /auth/send-login-verification-code - 发送登录验证码
|
||||
*
|
||||
* @author moyin
|
||||
* @version 1.0.2
|
||||
* @since 2025-12-17
|
||||
* @lastModified 2026-01-07
|
||||
* @version 2.0.0
|
||||
* @since 2026-01-14
|
||||
* @lastModified 2026-01-14
|
||||
*/
|
||||
|
||||
import { Controller, Post, Put, Body, HttpCode, HttpStatus, ValidationPipe, UsePipes, Logger, Res } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiResponse as SwaggerApiResponse, ApiBody } from '@nestjs/swagger';
|
||||
import {
|
||||
Controller,
|
||||
Post,
|
||||
Put,
|
||||
Body,
|
||||
HttpCode,
|
||||
HttpStatus,
|
||||
ValidationPipe,
|
||||
UsePipes,
|
||||
Logger,
|
||||
Res
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
ApiTags,
|
||||
ApiOperation,
|
||||
ApiResponse as SwaggerApiResponse,
|
||||
ApiBody
|
||||
} from '@nestjs/swagger';
|
||||
import { Response } from 'express';
|
||||
import { LoginService, ApiResponse, LoginResponse } from './login.service';
|
||||
import { LoginDto, GitHubOAuthDto, ForgotPasswordDto, ResetPasswordDto, ChangePasswordDto, VerificationCodeLoginDto, SendLoginVerificationCodeDto, RefreshTokenDto, SendEmailVerificationDto } from './login.dto';
|
||||
import { LoginService } from '../../business/auth/login.service';
|
||||
import {
|
||||
LoginDto,
|
||||
GitHubOAuthDto,
|
||||
ForgotPasswordDto,
|
||||
ResetPasswordDto,
|
||||
ChangePasswordDto,
|
||||
VerificationCodeLoginDto,
|
||||
SendLoginVerificationCodeDto,
|
||||
RefreshTokenDto,
|
||||
SendEmailVerificationDto
|
||||
} from './dto/login.dto';
|
||||
import {
|
||||
LoginResponseDto,
|
||||
GitHubOAuthResponseDto,
|
||||
ForgotPasswordResponseDto,
|
||||
CommonResponseDto,
|
||||
RefreshTokenResponseDto
|
||||
} from './login_response.dto';
|
||||
} from './dto/login_response.dto';
|
||||
import { Throttle, ThrottlePresets } from '../../core/security_core/throttle.decorator';
|
||||
import { Timeout, TimeoutPresets } from '../../core/security_core/timeout.decorator';
|
||||
|
||||
@@ -68,10 +100,10 @@ export class LoginController {
|
||||
/**
|
||||
* 通用响应处理方法
|
||||
*
|
||||
* 业务逻辑:
|
||||
* 1. 根据业务结果设置HTTP状态码
|
||||
* 2. 处理不同类型的错误响应
|
||||
* 3. 统一响应格式和错误处理
|
||||
* 职责:
|
||||
* - 根据业务结果设置HTTP状态码
|
||||
* - 处理不同类型的错误响应
|
||||
* - 统一响应格式和错误处理
|
||||
*
|
||||
* @param result 业务服务返回的结果
|
||||
* @param res Express响应对象
|
||||
@@ -84,7 +116,6 @@ export class LoginController {
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据错误代码获取状态码
|
||||
const statusCode = this.getErrorStatusCode(result);
|
||||
res.status(statusCode).json(result);
|
||||
}
|
||||
@@ -97,12 +128,10 @@ export class LoginController {
|
||||
* @private
|
||||
*/
|
||||
private getErrorStatusCode(result: any): HttpStatus {
|
||||
// 优先使用错误代码映射
|
||||
if (result.error_code && ERROR_STATUS_MAP[result.error_code as keyof typeof ERROR_STATUS_MAP]) {
|
||||
return ERROR_STATUS_MAP[result.error_code as keyof typeof ERROR_STATUS_MAP];
|
||||
}
|
||||
|
||||
// 根据消息内容判断
|
||||
if (result.message?.includes('已存在') || result.message?.includes('已被注册')) {
|
||||
return HttpStatus.CONFLICT;
|
||||
}
|
||||
@@ -115,7 +144,6 @@ export class LoginController {
|
||||
return HttpStatus.NOT_FOUND;
|
||||
}
|
||||
|
||||
// 默认返回400
|
||||
return HttpStatus.BAD_REQUEST;
|
||||
}
|
||||
|
||||
@@ -123,7 +151,7 @@ export class LoginController {
|
||||
* 用户登录
|
||||
*
|
||||
* @param loginDto 登录数据
|
||||
* @returns 登录结果
|
||||
* @param res Express响应对象
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '用户登录',
|
||||
@@ -168,7 +196,7 @@ export class LoginController {
|
||||
* GitHub OAuth登录
|
||||
*
|
||||
* @param githubDto GitHub OAuth数据
|
||||
* @returns 登录结果
|
||||
* @param res Express响应对象
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: 'GitHub OAuth登录',
|
||||
@@ -207,7 +235,6 @@ export class LoginController {
|
||||
*
|
||||
* @param forgotPasswordDto 忘记密码数据
|
||||
* @param res Express响应对象
|
||||
* @returns 发送结果
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '发送密码重置验证码',
|
||||
@@ -251,7 +278,7 @@ export class LoginController {
|
||||
* 重置密码
|
||||
*
|
||||
* @param resetPasswordDto 重置密码数据
|
||||
* @returns 重置结果
|
||||
* @param res Express响应对象
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '重置密码',
|
||||
@@ -292,7 +319,7 @@ export class LoginController {
|
||||
* 修改密码
|
||||
*
|
||||
* @param changePasswordDto 修改密码数据
|
||||
* @returns 修改结果
|
||||
* @param res Express响应对象
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '修改密码',
|
||||
@@ -315,8 +342,6 @@ export class LoginController {
|
||||
@Put('change-password')
|
||||
@UsePipes(new ValidationPipe({ transform: true }))
|
||||
async changePassword(@Body() changePasswordDto: ChangePasswordDto, @Res() res: Response): Promise<void> {
|
||||
// 实际应用中应从JWT令牌中获取用户ID
|
||||
// 这里为了演示,使用请求体中的用户ID
|
||||
const userId = BigInt(changePasswordDto.user_id);
|
||||
|
||||
const result = await this.loginService.changePassword(
|
||||
@@ -332,7 +357,7 @@ export class LoginController {
|
||||
* 验证码登录
|
||||
*
|
||||
* @param verificationCodeLoginDto 验证码登录数据
|
||||
* @returns 登录结果
|
||||
* @param res Express响应对象
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '验证码登录',
|
||||
@@ -359,11 +384,16 @@ export class LoginController {
|
||||
@Post('verification-code-login')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@UsePipes(new ValidationPipe({ transform: true }))
|
||||
async verificationCodeLogin(@Body() verificationCodeLoginDto: VerificationCodeLoginDto): Promise<ApiResponse<LoginResponse>> {
|
||||
return await this.loginService.verificationCodeLogin({
|
||||
async verificationCodeLogin(
|
||||
@Body() verificationCodeLoginDto: VerificationCodeLoginDto,
|
||||
@Res() res: Response
|
||||
): Promise<void> {
|
||||
const result = await this.loginService.verificationCodeLogin({
|
||||
identifier: verificationCodeLoginDto.identifier,
|
||||
verificationCode: verificationCodeLoginDto.verification_code
|
||||
});
|
||||
|
||||
this.handleResponse(result, res);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -371,11 +401,10 @@ export class LoginController {
|
||||
*
|
||||
* @param sendLoginVerificationCodeDto 发送验证码数据
|
||||
* @param res Express响应对象
|
||||
* @returns 发送结果
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '发送登录验证码',
|
||||
description: '向用户邮箱或手机发送登录验证码。邮件使用专门的登录验证码模板,内容明确标识为登录验证而非密码重置。'
|
||||
description: '向用户邮箱或手机发送登录验证码'
|
||||
})
|
||||
@ApiBody({ type: SendLoginVerificationCodeDto })
|
||||
@SwaggerApiResponse({
|
||||
@@ -410,63 +439,15 @@ export class LoginController {
|
||||
this.handleResponse(result, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调试验证码信息
|
||||
* 仅用于开发和调试
|
||||
*
|
||||
* @param sendEmailVerificationDto 邮箱信息
|
||||
* @returns 验证码调试信息
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '调试验证码信息',
|
||||
description: '获取验证码的详细调试信息(仅开发环境)'
|
||||
})
|
||||
@ApiBody({ type: SendEmailVerificationDto })
|
||||
@Post('debug-verification-code')
|
||||
@UsePipes(new ValidationPipe({ transform: true }))
|
||||
async debugVerificationCode(@Body() sendEmailVerificationDto: SendEmailVerificationDto, @Res() res: Response): Promise<void> {
|
||||
const result = await this.loginService.debugVerificationCode(sendEmailVerificationDto.email);
|
||||
|
||||
// 调试接口总是返回200
|
||||
res.status(HttpStatus.OK).json(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除限流记录(仅开发环境)
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '清除限流记录',
|
||||
description: '清除所有限流记录(仅开发环境使用)'
|
||||
})
|
||||
@Post('debug-clear-throttle')
|
||||
async clearThrottle(@Res() res: Response): Promise<void> {
|
||||
// 注入ThrottleGuard并清除记录
|
||||
// 这里需要通过依赖注入获取ThrottleGuard实例
|
||||
res.status(HttpStatus.OK).json({
|
||||
success: true,
|
||||
message: '限流记录已清除'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新访问令牌
|
||||
*
|
||||
* 功能描述:
|
||||
* 使用有效的刷新令牌生成新的访问令牌,实现无感知的令牌续期
|
||||
*
|
||||
* 业务逻辑:
|
||||
* 1. 验证刷新令牌的有效性和格式
|
||||
* 2. 检查用户状态是否正常
|
||||
* 3. 生成新的JWT令牌对
|
||||
* 4. 返回新的访问令牌和刷新令牌
|
||||
*
|
||||
* @param refreshTokenDto 刷新令牌数据
|
||||
* @param res Express响应对象
|
||||
* @returns 新的令牌对
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '刷新访问令牌',
|
||||
description: '使用有效的刷新令牌生成新的访问令牌,实现无感知的令牌续期。建议在访问令牌即将过期时调用此接口。'
|
||||
description: '使用有效的刷新令牌生成新的访问令牌'
|
||||
})
|
||||
@ApiBody({ type: RefreshTokenDto })
|
||||
@SwaggerApiResponse({
|
||||
@@ -495,73 +476,28 @@ export class LoginController {
|
||||
@Post('refresh-token')
|
||||
@UsePipes(new ValidationPipe({ transform: true }))
|
||||
async refreshToken(@Body() refreshTokenDto: RefreshTokenDto, @Res() res: Response): Promise<void> {
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
this.logRefreshTokenStart();
|
||||
const result = await this.loginService.refreshAccessToken(refreshTokenDto.refresh_token);
|
||||
this.handleRefreshTokenResponse(result, res, startTime);
|
||||
} catch (error) {
|
||||
this.handleRefreshTokenError(error, res, startTime);
|
||||
}
|
||||
const result = await this.loginService.refreshAccessToken(refreshTokenDto.refresh_token);
|
||||
this.handleResponse(result, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录令牌刷新开始日志
|
||||
* @private
|
||||
* 调试验证码信息(仅开发环境)
|
||||
*
|
||||
* @param sendEmailVerificationDto 邮箱信息
|
||||
* @param res Express响应对象
|
||||
*/
|
||||
private logRefreshTokenStart(): void {
|
||||
this.logger.log('令牌刷新请求', {
|
||||
operation: 'refreshToken',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理令牌刷新响应
|
||||
* @private
|
||||
*/
|
||||
private handleRefreshTokenResponse(result: any, res: Response, startTime: number): void {
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
if (result.success) {
|
||||
this.logger.log('令牌刷新成功', {
|
||||
operation: 'refreshToken',
|
||||
duration,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
res.status(HttpStatus.OK).json(result);
|
||||
} else {
|
||||
this.logger.warn('令牌刷新失败', {
|
||||
operation: 'refreshToken',
|
||||
error: result.message,
|
||||
errorCode: result.error_code,
|
||||
duration,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
this.handleResponse(result, res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理令牌刷新异常
|
||||
* @private
|
||||
*/
|
||||
private handleRefreshTokenError(error: unknown, res: Response, startTime: number): void {
|
||||
const duration = Date.now() - startTime;
|
||||
const err = error as Error;
|
||||
|
||||
this.logger.error('令牌刷新异常', {
|
||||
operation: 'refreshToken',
|
||||
error: err.message,
|
||||
duration,
|
||||
timestamp: new Date().toISOString(),
|
||||
}, err.stack);
|
||||
|
||||
res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
|
||||
success: false,
|
||||
message: '服务器内部错误',
|
||||
error_code: 'INTERNAL_SERVER_ERROR'
|
||||
});
|
||||
@ApiOperation({
|
||||
summary: '调试验证码信息',
|
||||
description: '获取验证码的详细调试信息(仅开发环境)'
|
||||
})
|
||||
@ApiBody({ type: SendEmailVerificationDto })
|
||||
@Post('debug-verification-code')
|
||||
@UsePipes(new ValidationPipe({ transform: true }))
|
||||
async debugVerificationCode(
|
||||
@Body() sendEmailVerificationDto: SendEmailVerificationDto,
|
||||
@Res() res: Response
|
||||
): Promise<void> {
|
||||
const result = await this.loginService.debugVerificationCode(sendEmailVerificationDto.email);
|
||||
res.status(HttpStatus.OK).json(result);
|
||||
}
|
||||
}
|
||||
@@ -7,19 +7,20 @@
|
||||
* - 测试邮箱验证流程
|
||||
*
|
||||
* 最近修改:
|
||||
* - 2026-01-14: 架构重构 - 从business层移动到gateway层 (修改者: moyin)
|
||||
* - 2026-01-12: 代码规范优化 - 创建缺失的控制器测试文件 (修改者: moyin)
|
||||
*
|
||||
* @author moyin
|
||||
* @version 1.0.0
|
||||
* @version 1.1.0
|
||||
* @since 2026-01-12
|
||||
* @lastModified 2026-01-12
|
||||
* @lastModified 2026-01-14
|
||||
*/
|
||||
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { Response } from 'express';
|
||||
import { HttpStatus } from '@nestjs/common';
|
||||
import { RegisterController } from './register.controller';
|
||||
import { RegisterService } from './register.service';
|
||||
import { RegisterService } from '../../business/auth/register.service';
|
||||
|
||||
describe('RegisterController', () => {
|
||||
let controller: RegisterController;
|
||||
@@ -1,5 +1,7 @@
|
||||
/**
|
||||
* 注册控制器
|
||||
* 注册网关控制器
|
||||
*
|
||||
* 架构层级:Gateway Layer(网关层)
|
||||
*
|
||||
* 功能描述:
|
||||
* - 处理用户注册相关的HTTP请求和响应
|
||||
@@ -8,9 +10,14 @@
|
||||
* - 邮箱验证功能
|
||||
*
|
||||
* 职责分离:
|
||||
* - 专注于HTTP请求处理和响应格式化
|
||||
* - 调用注册业务服务完成具体功能
|
||||
* - 专注于HTTP协议处理和请求响应
|
||||
* - 调用业务层服务完成具体功能
|
||||
* - 处理API文档和参数验证
|
||||
* - 不包含业务逻辑,只做数据转换和路由
|
||||
*
|
||||
* 依赖关系:
|
||||
* - 依赖 Business Layer 的 RegisterService
|
||||
* - 使用 DTO 进行数据验证
|
||||
*
|
||||
* API端点:
|
||||
* - POST /auth/register - 用户注册
|
||||
@@ -18,26 +25,41 @@
|
||||
* - POST /auth/verify-email - 验证邮箱验证码
|
||||
* - POST /auth/resend-email-verification - 重新发送邮箱验证码
|
||||
*
|
||||
* 最近修改:
|
||||
* - 2026-01-12: 代码分离 - 从login.controller.ts中分离注册相关功能
|
||||
*
|
||||
* @author moyin
|
||||
* @version 1.0.0
|
||||
* @since 2026-01-12
|
||||
* @lastModified 2026-01-12
|
||||
* @version 2.0.0
|
||||
* @since 2026-01-14
|
||||
* @lastModified 2026-01-14
|
||||
*/
|
||||
|
||||
import { Controller, Post, Body, HttpCode, HttpStatus, ValidationPipe, UsePipes, Logger, Res } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiResponse as SwaggerApiResponse, ApiBody } from '@nestjs/swagger';
|
||||
import {
|
||||
Controller,
|
||||
Post,
|
||||
Body,
|
||||
HttpStatus,
|
||||
ValidationPipe,
|
||||
UsePipes,
|
||||
Logger,
|
||||
Res
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
ApiTags,
|
||||
ApiOperation,
|
||||
ApiResponse as SwaggerApiResponse,
|
||||
ApiBody
|
||||
} from '@nestjs/swagger';
|
||||
import { Response } from 'express';
|
||||
import { RegisterService, ApiResponse, RegisterResponse } from './register.service';
|
||||
import { RegisterDto, EmailVerificationDto, SendEmailVerificationDto } from './login.dto';
|
||||
import { RegisterService } from '../../business/auth/register.service';
|
||||
import {
|
||||
RegisterDto,
|
||||
EmailVerificationDto,
|
||||
SendEmailVerificationDto
|
||||
} from './dto/login.dto';
|
||||
import {
|
||||
RegisterResponseDto,
|
||||
CommonResponseDto,
|
||||
TestModeEmailVerificationResponseDto,
|
||||
SuccessEmailVerificationResponseDto
|
||||
} from './login_response.dto';
|
||||
} from './dto/login_response.dto';
|
||||
import { Throttle, ThrottlePresets } from '../../core/security_core/throttle.decorator';
|
||||
import { Timeout, TimeoutPresets } from '../../core/security_core/timeout.decorator';
|
||||
|
||||
@@ -61,10 +83,10 @@ export class RegisterController {
|
||||
/**
|
||||
* 通用响应处理方法
|
||||
*
|
||||
* 业务逻辑:
|
||||
* 1. 根据业务结果设置HTTP状态码
|
||||
* 2. 处理不同类型的错误响应
|
||||
* 3. 统一响应格式和错误处理
|
||||
* 职责:
|
||||
* - 根据业务结果设置HTTP状态码
|
||||
* - 处理不同类型的错误响应
|
||||
* - 统一响应格式和错误处理
|
||||
*
|
||||
* @param result 业务服务返回的结果
|
||||
* @param res Express响应对象
|
||||
@@ -77,7 +99,6 @@ export class RegisterController {
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据错误代码获取状态码
|
||||
const statusCode = this.getErrorStatusCode(result);
|
||||
res.status(statusCode).json(result);
|
||||
}
|
||||
@@ -90,12 +111,10 @@ export class RegisterController {
|
||||
* @private
|
||||
*/
|
||||
private getErrorStatusCode(result: any): HttpStatus {
|
||||
// 优先使用错误代码映射
|
||||
if (result.error_code && ERROR_STATUS_MAP[result.error_code as keyof typeof ERROR_STATUS_MAP]) {
|
||||
return ERROR_STATUS_MAP[result.error_code as keyof typeof ERROR_STATUS_MAP];
|
||||
}
|
||||
|
||||
// 根据消息内容判断
|
||||
if (result.message?.includes('已存在') || result.message?.includes('已被注册')) {
|
||||
return HttpStatus.CONFLICT;
|
||||
}
|
||||
@@ -104,7 +123,6 @@ export class RegisterController {
|
||||
return HttpStatus.NOT_FOUND;
|
||||
}
|
||||
|
||||
// 默认返回400
|
||||
return HttpStatus.BAD_REQUEST;
|
||||
}
|
||||
|
||||
@@ -112,11 +130,11 @@ export class RegisterController {
|
||||
* 用户注册
|
||||
*
|
||||
* @param registerDto 注册数据
|
||||
* @returns 注册结果
|
||||
* @param res Express响应对象
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '用户注册',
|
||||
description: '创建新用户账户。如果提供邮箱,需要先调用发送验证码接口获取验证码,然后在注册时提供验证码进行验证。'
|
||||
description: '创建新用户账户'
|
||||
})
|
||||
@ApiBody({ type: RegisterDto })
|
||||
@SwaggerApiResponse({
|
||||
@@ -158,7 +176,6 @@ export class RegisterController {
|
||||
*
|
||||
* @param sendEmailVerificationDto 发送验证码数据
|
||||
* @param res Express响应对象
|
||||
* @returns 发送结果
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '发送邮箱验证码',
|
||||
@@ -199,7 +216,7 @@ export class RegisterController {
|
||||
* 验证邮箱验证码
|
||||
*
|
||||
* @param emailVerificationDto 邮箱验证数据
|
||||
* @returns 验证结果
|
||||
* @param res Express响应对象
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '验证邮箱验证码',
|
||||
@@ -231,7 +248,6 @@ export class RegisterController {
|
||||
*
|
||||
* @param sendEmailVerificationDto 发送验证码数据
|
||||
* @param res Express响应对象
|
||||
* @returns 发送结果
|
||||
*/
|
||||
@ApiOperation({
|
||||
summary: '重新发送邮箱验证码',
|
||||
Reference in New Issue
Block a user