From f7c3983cc15e3d9d25505a8a6fa1748d5ac3063f Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Wed, 14 Jan 2026 12:00:19 +0800 Subject: [PATCH 1/9] =?UTF-8?q?refactor(auth):=20=E7=A7=BB=E9=99=A4Control?= =?UTF-8?q?ler=EF=BC=8C=E4=B8=93=E6=B3=A8=E4=BA=8E=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 范围:src/business/auth/ 涉及文件: - src/business/auth/auth.module.ts - src/business/auth/README.md 主要改进: - 移除LoginController和RegisterController的导入和声明 - 调整模块结构,专注于业务逻辑层 - 更新README文档,明确Business Layer职责定位 - 完善依赖关系说明和架构层级描述 - 版本号从1.0.2升级到2.0.0(架构重构) --- src/business/auth/README.md | 468 ++++++++++++++++++------------- src/business/auth/auth.module.ts | 41 ++- 2 files changed, 302 insertions(+), 207 deletions(-) diff --git a/src/business/auth/README.md b/src/business/auth/README.md index 04b63c0..f800c15 100644 --- a/src/business/auth/README.md +++ b/src/business/auth/README.md @@ -1,246 +1,330 @@ - +业务层负责实现核心业务逻辑和流程控制: -# 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> +处理用户登录请求,验证用户凭据并生成JWT令牌,支持Zulip账号验证和更新。 -### verificationCodeLogin() -支持邮箱或手机号验证码登录,提供无密码登录方式。 +#### githubOAuth(oauthRequest: GitHubOAuthRequest): Promise> +使用GitHub账户登录或注册,自动创建用户账号并生成JWT令牌。 -## 密码管理功能 +#### verificationCodeLogin(loginRequest: VerificationCodeLoginRequest): Promise> +使用邮箱或手机号和验证码进行登录,无需密码即可完成认证。 -### sendPasswordResetCode() -发送密码重置验证码到用户邮箱或手机号,支持测试模式和真实发送模式。 +#### sendPasswordResetCode(identifier: string): Promise> +向用户邮箱或手机发送密码重置验证码,支持测试模式和真实发送模式。 -### resetPassword() -使用验证码重置用户密码,包含密码强度验证和安全检查。 +#### resetPassword(resetRequest: PasswordResetRequest): Promise +使用验证码重置用户密码,验证验证码有效性后更新密码。 -### changePassword() -修改用户密码,验证旧密码并应用新密码强度规则。 +#### changePassword(userId: bigint, oldPassword: string, newPassword: string): Promise +修改用户密码,需要验证旧密码正确性后才能更新为新密码。 -## 邮箱验证功能 +#### refreshAccessToken(refreshToken: string): Promise> +使用有效的刷新令牌生成新的访问令牌,实现无感知的令牌续期。 -### sendEmailVerification() -发送邮箱验证码,用于注册时的邮箱验证和账户安全验证。 +#### sendLoginVerificationCode(identifier: string): Promise> +向用户邮箱或手机发送登录验证码,用于验证码登录功能。 -### verifyEmailCode() -验证邮箱验证码,确认邮箱所有权并更新用户验证状态。 +### RegisterService -### resendEmailVerification() -重新发送邮箱验证码,处理验证码过期或丢失的情况。 +#### register(registerRequest: RegisterRequest): Promise> +处理用户注册请求,创建游戏账号和Zulip账号,支持邮箱验证和自动回滚。 -### sendLoginVerificationCode() -发送登录验证码,支持验证码登录功能。 +#### sendEmailVerification(email: string): Promise> +向指定邮箱发送验证码,支持测试模式和真实发送模式。 -## 调试和管理功能 +#### verifyEmailCode(email: string, code: string): Promise +验证邮箱验证码的有效性,用于邮箱验证流程。 -### debugVerificationCode() -获取验证码调试信息,用于开发环境的测试和调试。 +#### resendEmailVerification(email: string): Promise> +重新向指定邮箱发送验证码,用于验证码过期或未收到的情况。 -## 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> { + 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' + }; + } +} +``` -### ThrottlePresets, TimeoutPresets (来自 core/security_core/decorators) -安全防护预设配置,提供限流和超时控制的标准配置。 +### 2. 协调多个核心服务 + +```typescript +async register(registerRequest: RegisterRequest): Promise> { + // 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 { + 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 { + 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> { + // 调用核心服务 + 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集成的错误处理和重试机制 \ No newline at end of file +- Business层不应该处理HTTP协议 +- Business层不应该直接访问数据库(通过Core层) +- Business层不应该包含技术实现细节 +- 所有业务逻辑都应该有完善的错误处理 +- 关键业务操作都应该有日志记录 diff --git a/src/business/auth/auth.module.ts b/src/business/auth/auth.module.ts index 0f0ebe5..782b9f5 100644 --- a/src/business/auth/auth.module.ts +++ b/src/business/auth/auth.module.ts @@ -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 {} \ No newline at end of file -- 2.25.1 From 73e3e0153c56e16dfa55b1d8a4a00352ce46c3f6 Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Wed, 14 Jan 2026 13:07:11 +0800 Subject: [PATCH 2/9] =?UTF-8?q?refactor(auth):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E8=AE=A4=E8=AF=81=E6=A8=A1=E5=9D=97=E6=9E=B6=E6=9E=84=20-=20?= =?UTF-8?q?=E5=B0=86Gateway=E5=B1=82=E7=BB=84=E4=BB=B6=E4=BB=8EBusiness?= =?UTF-8?q?=E5=B1=82=E5=88=86=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 范围:src/gateway/auth/, src/business/auth/, src/app.module.ts 涉及文件: - 新增:src/gateway/auth/ 目录及所有文件 - 移动:Controller、Guard、Decorator、DTO从business层移至gateway层 - 修改:src/business/auth/index.ts(移除Gateway层组件导出) - 修改:src/app.module.ts(使用AuthGatewayModule替代AuthModule) 主要改进: - 明确Gateway层和Business层的职责边界 - Controller、Guard、Decorator属于Gateway层职责 - Business层专注于业务逻辑和服务 - 符合分层架构设计原则 --- src/app.module.ts | 4 +- src/business/auth/index.ts | 24 +- .../location_broadcast.controller.ts | 4 +- .../location_broadcast.controller.ts | 4 +- src/business/notice/notice.controller.ts | 4 +- src/business/zulip/chat.controller.spec.ts | 2 +- src/business/zulip/chat.controller.ts | 2 +- .../zulip/zulip_accounts.controller.spec.ts | 2 +- .../zulip/zulip_accounts.controller.ts | 2 +- src/gateway/auth/README.md | 338 ++++++++++++++++++ src/gateway/auth/auth.gateway.module.ts | 52 +++ .../auth/current_user.decorator.ts | 0 .../auth => gateway/auth/dto}/login.dto.ts | 0 .../auth/dto}/login_response.dto.ts | 0 .../auth/jwt_auth.guard.spec.ts | 7 +- .../auth/jwt_auth.guard.ts | 0 .../auth/jwt_usage_example.ts | 14 +- .../auth/login.controller.spec.ts | 9 +- .../auth/login.controller.ts | 236 +++++------- .../auth/register.controller.spec.ts | 9 +- .../auth/register.controller.ts | 72 ++-- 21 files changed, 565 insertions(+), 220 deletions(-) create mode 100644 src/gateway/auth/README.md create mode 100644 src/gateway/auth/auth.gateway.module.ts rename src/{business => gateway}/auth/current_user.decorator.ts (100%) rename src/{business/auth => gateway/auth/dto}/login.dto.ts (100%) rename src/{business/auth => gateway/auth/dto}/login_response.dto.ts (100%) rename src/{business => gateway}/auth/jwt_auth.guard.spec.ts (97%) rename src/{business => gateway}/auth/jwt_auth.guard.ts (100%) rename src/{business => gateway}/auth/jwt_usage_example.ts (86%) rename src/{business => gateway}/auth/login.controller.spec.ts (96%) rename src/{business => gateway}/auth/login.controller.ts (70%) rename src/{business => gateway}/auth/register.controller.spec.ts (97%) rename src/{business => gateway}/auth/register.controller.ts (84%) diff --git a/src/app.module.ts b/src/app.module.ts index 62a3cf3..3a5e5c8 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -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, diff --git a/src/business/auth/index.ts b/src/business/auth/index.ts index cf74d65..6499524 100644 --- a/src/business/auth/index.ts +++ b/src/business/auth/index.ts @@ -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'; \ No newline at end of file +export { RegisterService } from './register.service'; \ No newline at end of file diff --git a/src/business/location_broadcast/controllers/location_broadcast.controller.ts b/src/business/location_broadcast/controllers/location_broadcast.controller.ts index 75392fd..1f2c182 100644 --- a/src/business/location_broadcast/controllers/location_broadcast.controller.ts +++ b/src/business/location_broadcast/controllers/location_broadcast.controller.ts @@ -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'; // 导入业务服务 diff --git a/src/business/location_broadcast/location_broadcast.controller.ts b/src/business/location_broadcast/location_broadcast.controller.ts index 0835fce..30ecb8a 100644 --- a/src/business/location_broadcast/location_broadcast.controller.ts +++ b/src/business/location_broadcast/location_broadcast.controller.ts @@ -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'; // 导入业务服务 diff --git a/src/business/notice/notice.controller.ts b/src/business/notice/notice.controller.ts index 5b809c1..96e99de 100644 --- a/src/business/notice/notice.controller.ts +++ b/src/business/notice/notice.controller.ts @@ -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') diff --git a/src/business/zulip/chat.controller.spec.ts b/src/business/zulip/chat.controller.spec.ts index 4c19cec..87f0374 100644 --- a/src/business/zulip/chat.controller.spec.ts +++ b/src/business/zulip/chat.controller.spec.ts @@ -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 = { diff --git a/src/business/zulip/chat.controller.ts b/src/business/zulip/chat.controller.ts index d83f8f2..a352751 100644 --- a/src/business/zulip/chat.controller.ts +++ b/src/business/zulip/chat.controller.ts @@ -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 { diff --git a/src/business/zulip/zulip_accounts.controller.spec.ts b/src/business/zulip/zulip_accounts.controller.spec.ts index 36bbceb..8b04671 100644 --- a/src/business/zulip/zulip_accounts.controller.spec.ts +++ b/src/business/zulip/zulip_accounts.controller.spec.ts @@ -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'; diff --git a/src/business/zulip/zulip_accounts.controller.ts b/src/business/zulip/zulip_accounts.controller.ts index 9cc6c13..021065c 100644 --- a/src/business/zulip/zulip_accounts.controller.ts +++ b/src/business/zulip/zulip_accounts.controller.ts @@ -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'; diff --git a/src/gateway/auth/README.md b/src/gateway/auth/README.md new file mode 100644 index 0000000..fd655d6 --- /dev/null +++ b/src/gateway/auth/README.md @@ -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 { + 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 { + // 验证用户 + 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 +处理用户登录请求,支持用户名、邮箱或手机号多种方式登录。 + +#### githubOAuth(githubDto: GitHubOAuthDto, res: Response): Promise +处理GitHub OAuth登录请求,支持使用GitHub账户登录或注册。 + +#### refreshToken(refreshTokenDto: RefreshTokenDto, res: Response): Promise +刷新访问令牌,使用有效的刷新令牌生成新的访问令牌。 + +#### forgotPassword(forgotPasswordDto: ForgotPasswordDto, res: Response): Promise +发送密码重置验证码到用户邮箱或手机。 + +#### resetPassword(resetPasswordDto: ResetPasswordDto, res: Response): Promise +使用验证码重置用户密码。 + +#### changePassword(changePasswordDto: ChangePasswordDto, res: Response): Promise +修改用户密码,需要提供旧密码验证。 + +#### verificationCodeLogin(verificationCodeLoginDto: VerificationCodeLoginDto, res: Response): Promise +使用邮箱或手机号和验证码进行登录,无需密码。 + +#### sendLoginVerificationCode(sendLoginVerificationCodeDto: SendLoginVerificationCodeDto, res: Response): Promise +向用户邮箱或手机发送登录验证码。 + +#### debugVerificationCode(sendEmailVerificationDto: SendEmailVerificationDto, res: Response): Promise +获取验证码的详细调试信息,仅用于开发环境。 + +### RegisterController + +#### register(registerDto: RegisterDto, res: Response): Promise +处理用户注册请求,创建新用户账户。 + +#### sendEmailVerification(sendEmailVerificationDto: SendEmailVerificationDto, res: Response): Promise +向指定邮箱发送验证码。 + +#### verifyEmail(emailVerificationDto: EmailVerificationDto, res: Response): Promise +使用验证码验证邮箱。 + +#### resendEmailVerification(sendEmailVerificationDto: SendEmailVerificationDto, res: Response): Promise +重新向指定邮箱发送验证码。 + +### JwtAuthGuard + +#### canActivate(context: ExecutionContext): Promise +验证请求中的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 { + 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层实现 diff --git a/src/gateway/auth/auth.gateway.module.ts b/src/gateway/auth/auth.gateway.module.ts new file mode 100644 index 0000000..c3b08b1 --- /dev/null +++ b/src/gateway/auth/auth.gateway.module.ts @@ -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 {} diff --git a/src/business/auth/current_user.decorator.ts b/src/gateway/auth/current_user.decorator.ts similarity index 100% rename from src/business/auth/current_user.decorator.ts rename to src/gateway/auth/current_user.decorator.ts diff --git a/src/business/auth/login.dto.ts b/src/gateway/auth/dto/login.dto.ts similarity index 100% rename from src/business/auth/login.dto.ts rename to src/gateway/auth/dto/login.dto.ts diff --git a/src/business/auth/login_response.dto.ts b/src/gateway/auth/dto/login_response.dto.ts similarity index 100% rename from src/business/auth/login_response.dto.ts rename to src/gateway/auth/dto/login_response.dto.ts diff --git a/src/business/auth/jwt_auth.guard.spec.ts b/src/gateway/auth/jwt_auth.guard.spec.ts similarity index 97% rename from src/business/auth/jwt_auth.guard.spec.ts rename to src/gateway/auth/jwt_auth.guard.spec.ts index bd49168..abb26f7 100644 --- a/src/business/auth/jwt_auth.guard.spec.ts +++ b/src/gateway/auth/jwt_auth.guard.spec.ts @@ -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'; @@ -160,4 +161,4 @@ describe('JwtAuthGuard', () => { expect(loginCoreService.verifyToken).not.toHaveBeenCalled(); }); }); -}); \ No newline at end of file +}); diff --git a/src/business/auth/jwt_auth.guard.ts b/src/gateway/auth/jwt_auth.guard.ts similarity index 100% rename from src/business/auth/jwt_auth.guard.ts rename to src/gateway/auth/jwt_auth.guard.ts diff --git a/src/business/auth/jwt_usage_example.ts b/src/gateway/auth/jwt_usage_example.ts similarity index 86% rename from src/business/auth/jwt_usage_example.ts rename to src/gateway/auth/jwt_usage_example.ts index f1b34ee..4be4509 100644 --- a/src/business/auth/jwt_usage_example.ts +++ b/src/gateway/auth/jwt_usage_example.ts @@ -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'; diff --git a/src/business/auth/login.controller.spec.ts b/src/gateway/auth/login.controller.spec.ts similarity index 96% rename from src/business/auth/login.controller.spec.ts rename to src/gateway/auth/login.controller.spec.ts index 8de3f8a..6396f51 100644 --- a/src/business/auth/login.controller.spec.ts +++ b/src/gateway/auth/login.controller.spec.ts @@ -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; @@ -205,4 +206,4 @@ describe('LoginController', () => { expect(mockResponse.json).toHaveBeenCalledWith(mockResult); }); }); -}); \ No newline at end of file +}); diff --git a/src/business/auth/login.controller.ts b/src/gateway/auth/login.controller.ts similarity index 70% rename from src/business/auth/login.controller.ts rename to src/gateway/auth/login.controller.ts index 8aeb9e0..c53f016 100644 --- a/src/business/auth/login.controller.ts +++ b/src/gateway/auth/login.controller.ts @@ -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 { - // 实际应用中应从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> { - return await this.loginService.verificationCodeLogin({ + async verificationCodeLogin( + @Body() verificationCodeLoginDto: VerificationCodeLoginDto, + @Res() res: Response + ): Promise { + 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 { - 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 { - // 注入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 { - 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(), - }); + @ApiOperation({ + summary: '调试验证码信息', + description: '获取验证码的详细调试信息(仅开发环境)' + }) + @ApiBody({ type: SendEmailVerificationDto }) + @Post('debug-verification-code') + @UsePipes(new ValidationPipe({ transform: true })) + async debugVerificationCode( + @Body() sendEmailVerificationDto: SendEmailVerificationDto, + @Res() res: Response + ): Promise { + const result = await this.loginService.debugVerificationCode(sendEmailVerificationDto.email); + res.status(HttpStatus.OK).json(result); } - - /** - * 处理令牌刷新响应 - * @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' - }); - } -} \ No newline at end of file +} diff --git a/src/business/auth/register.controller.spec.ts b/src/gateway/auth/register.controller.spec.ts similarity index 97% rename from src/business/auth/register.controller.spec.ts rename to src/gateway/auth/register.controller.spec.ts index 6702daf..c8be301 100644 --- a/src/business/auth/register.controller.spec.ts +++ b/src/gateway/auth/register.controller.spec.ts @@ -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; @@ -227,4 +228,4 @@ describe('RegisterController', () => { expect(mockResponse.json).toHaveBeenCalledWith(mockResult); }); }); -}); \ No newline at end of file +}); diff --git a/src/business/auth/register.controller.ts b/src/gateway/auth/register.controller.ts similarity index 84% rename from src/business/auth/register.controller.ts rename to src/gateway/auth/register.controller.ts index 60759a1..c70f69c 100644 --- a/src/business/auth/register.controller.ts +++ b/src/gateway/auth/register.controller.ts @@ -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: '重新发送邮箱验证码', @@ -266,4 +282,4 @@ export class RegisterController { const result = await this.registerService.resendEmailVerification(sendEmailVerificationDto.email); this.handleResponse(result, res); } -} \ No newline at end of file +} -- 2.25.1 From f9a79461a06a9b02cd044c39d64228fb28056688 Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Wed, 14 Jan 2026 13:16:44 +0800 Subject: [PATCH 3/9] =?UTF-8?q?config=EF=BC=9A=E6=9B=B4=E6=96=B0=20.gitign?= =?UTF-8?q?ore=20=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 docs/ai-reading/me.config.json 到忽略列表 - 优化配置文件结构 --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c8a8147..4fb50ce 100644 --- a/.gitignore +++ b/.gitignore @@ -48,4 +48,5 @@ redis-data/ .kiro/ config/ -docs/merge-requests \ No newline at end of file +docs/merge-requests +docs/ai-reading/me.config.json \ No newline at end of file -- 2.25.1 From f1dd8cd14a46cca163673d86326df8c833404ac4 Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Wed, 14 Jan 2026 13:16:53 +0800 Subject: [PATCH 4/9] =?UTF-8?q?style=EF=BC=9A=E4=BC=98=E5=8C=96=E8=B4=A1?= =?UTF-8?q?=E7=8C=AE=E8=80=85=E6=96=87=E6=A1=A3=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 调整贡献者顺序展示 - 优化贡献统计表格排列 - 改善文档可读性 --- docs/CONTRIBUTORS.md | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/docs/CONTRIBUTORS.md b/docs/CONTRIBUTORS.md index 9b35a49..9e4f6a4 100644 --- a/docs/CONTRIBUTORS.md +++ b/docs/CONTRIBUTORS.md @@ -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% | ## 🌟 最新重要贡献 @@ -145,4 +145,4 @@ **再次感谢所有贡献者的辛勤付出!** 🙏 -*如果你的名字没有出现在列表中,请联系我们或提交PR更新此文件。* \ No newline at end of file +*如果你的名字没有出现在列表中,请联系我们或提交PR更新此文件。* -- 2.25.1 From 43874892b77fe87af8abd9b43279a07aa58138f8 Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Wed, 14 Jan 2026 13:17:02 +0800 Subject: [PATCH 5/9] =?UTF-8?q?feat=EF=BC=9A=E6=B7=BB=E5=8A=A0=20AI=20?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5=E7=94=A8=E6=88=B7=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E9=85=8D=E7=BD=AE=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 setup-user-info.js 脚本 - 自动获取当前日期并提示输入用户名 - 生成 me.config.json 配置文件供 AI 检查步骤使用 - 简化 AI 代码检查流程的用户信息收集 --- docs/ai-reading/tools/setup-user-info.js | 115 +++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 docs/ai-reading/tools/setup-user-info.js diff --git a/docs/ai-reading/tools/setup-user-info.js b/docs/ai-reading/tools/setup-user-info.js new file mode 100644 index 0000000..4953346 --- /dev/null +++ b/docs/ai-reading/tools/setup-user-info.js @@ -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 }; \ No newline at end of file -- 2.25.1 From 8bcd22ea50b6ffdf9cee4b3c677a23bbd6610605 Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Wed, 14 Jan 2026 13:17:12 +0800 Subject: [PATCH 6/9] =?UTF-8?q?docs=EF=BC=9A=E5=B0=86=20AI=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=A3=80=E6=9F=A5=E6=8C=87=E5=8D=97=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=E4=B8=BA=E8=8B=B1=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将主要内容从中文翻译为英文 - 添加用户信息配置脚本使用说明 - 优化文档结构和可读性 - 保持原有检查流程和规范不变 --- docs/ai-reading/README.md | 590 ++++++++++++++++++++------------------ 1 file changed, 313 insertions(+), 277 deletions(-) diff --git a/docs/ai-reading/README.md b/docs/ai-reading/README.md index aaf42e1..a2ff2b1 100644 --- a/docs/ai-reading/README.md +++ b/docs/ai-reading/README.md @@ -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 + +#### 🎯 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 +``` + +**⚠️ 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. **特定模块测试指令** - - **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性能测试 +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. **测试执行验证流程** +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 --- -**开始执行前,请确认已收集用户日期和名称信息!** \ No newline at end of file +**Before starting execution, please first run `node tools/setup-user-info.js` to set user information!** \ No newline at end of file -- 2.25.1 From 41c33d6159d282221bdb7d4bd011052cbfd40027 Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Wed, 14 Jan 2026 13:17:23 +0800 Subject: [PATCH 7/9] =?UTF-8?q?docs=EF=BC=9A=E5=AE=8C=E5=96=84=20NestJS=20?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E6=96=87=E4=BB=B6=E5=91=BD=E5=90=8D=E8=A7=84?= =?UTF-8?q?=E8=8C=83=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 详细说明 NestJS 文件命名规则(snake_case + 点分隔类型标识符) - 添加正确和错误的命名示例对比 - 补充所有 NestJS 文件类型标识符列表 - 增加常见错误判断方法说明 --- docs/ai-reading/step1-naming-convention.md | 64 +++++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/docs/ai-reading/step1-naming-convention.md b/docs/ai-reading/step1-naming-convention.md index 2555f98..ef99137 100644 --- a/docs/ai-reading/step1-naming-convention.md +++ b/docs/ai-reading/step1-naming-convention.md @@ -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` ## 🔍 检查执行步骤 -- 2.25.1 From cf431c210a6e5f160640e86c84455e4a8d173e7b Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Wed, 14 Jan 2026 13:17:44 +0800 Subject: [PATCH 8/9] =?UTF-8?q?docs=EF=BC=9A=E8=A1=A5=E5=85=85=20Gateway?= =?UTF-8?q?=20=E5=B1=82=E6=9E=B6=E6=9E=84=E8=A7=84=E8=8C=83=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 Gateway 层职责定义和检查规范 - 添加 Gateway 层协议处理示例代码 - 补充 Gateway 层依赖关系和文件类型检查 - 完善 4 层架构说明(Gateway、Business、Core、Common) - 增加 Gateway 层常见违规示例 --- docs/ai-reading/step4-architecture-layer.md | 202 ++++++++++++++++++-- 1 file changed, 189 insertions(+), 13 deletions(-) diff --git a/docs/ai-reading/step4-architecture-layer.md b/docs/ai-reading/step4-architecture-layer.md index eb0d148..2417eda 100644 --- a/docs/ai-reading/step4-architecture-layer.md +++ b/docs/ai-reading/step4-architecture-layer.md @@ -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 { + // 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 { + // 错误:在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 { + // 违规:在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 { + // 违规:直接调用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的分层正确性 - 双模式服务的架构设计 - 实时通信组件的职责分离 -- 2.25.1 From a147883e0504ac717f448c28ebd7ec557beea24b Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Wed, 14 Jan 2026 13:17:53 +0800 Subject: [PATCH 9/9] =?UTF-8?q?docs=EF=BC=9A=E6=B7=BB=E5=8A=A0=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E9=87=8D=E6=9E=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 ARCHITECTURE_REFACTORING.md 文档 - 记录项目架构重构计划和进度 --- docs/ARCHITECTURE_REFACTORING.md | 295 +++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 docs/ARCHITECTURE_REFACTORING.md diff --git a/docs/ARCHITECTURE_REFACTORING.md b/docs/ARCHITECTURE_REFACTORING.md new file mode 100644 index 0000000..bffc77c --- /dev/null +++ b/docs/ARCHITECTURE_REFACTORING.md @@ -0,0 +1,295 @@ +# 架构重构文档 + +## 重构目标 + +将现有的混合架构重构为清晰的4层架构,实现更好的关注点分离和代码组织。 + +## 架构对比 + +### 重构前 + +``` +src/ +├── business/auth/ # 混合了Gateway和Business职责 +│ ├── login.controller.ts # HTTP协议处理 +│ ├── login.service.ts # 业务逻辑 +│ ├── jwt_auth.guard.ts # 认证守卫 +│ └── dto/ # 数据传输对象 +└── core/login_core/ # 核心层 + └── login_core.service.ts # 数据访问和基础设施 +``` + +### 重构后 + +``` +src/ +├── gateway/auth/ # 网关层(新增) +│ ├── login.controller.ts # HTTP协议处理 +│ ├── register.controller.ts # HTTP协议处理 +│ ├── jwt_auth.guard.ts # 认证守卫 +│ ├── dto/ # 数据传输对象 +│ └── auth.gateway.module.ts # 网关模块 +├── business/auth/ # 业务层(精简) +│ ├── login.service.ts # 登录业务逻辑 +│ ├── register.service.ts # 注册业务逻辑 +│ └── auth.module.ts # 业务模块 +└── core/login_core/ # 核心层(不变) + └── login_core.service.ts # 数据访问和基础设施 +``` + +## 4层架构说明 + +### 1. Transport Layer(传输层)- 可选 + +**位置**:`src/transport/` + +**职责**: +- 底层网络通信和连接管理 +- WebSocket服务器、TCP/UDP服务器 +- 原生Socket连接池管理 + +**说明**:对于HTTP应用,NestJS已经提供了传输层,无需额外实现。对于WebSocket等特殊协议,可以在此层实现。 + +### 2. Gateway Layer(网关层) + +**位置**:`src/gateway/` + +**职责**: +- HTTP协议处理和请求响应 +- 数据验证(DTO) +- 路由管理 +- 认证守卫 +- 错误转换(业务错误 → HTTP状态码) +- API文档 + +**原则**: +- ✅ 只做协议转换,不做业务逻辑 +- ✅ 使用DTO进行数据验证 +- ✅ 统一的错误处理 +- ❌ 不直接访问数据库 +- ❌ 不包含业务规则 + +**示例**: +```typescript +@Controller('auth') +export class LoginController { + constructor(private readonly loginService: LoginService) {} + + @Post('login') + async login(@Body() loginDto: LoginDto, @Res() res: Response): Promise { + // 只做协议转换 + const result = await this.loginService.login({ + identifier: loginDto.identifier, + password: loginDto.password + }); + + // 转换为HTTP响应 + this.handleResponse(result, res); + } +} +``` + +### 3. Business Layer(业务层) + +**位置**:`src/business/` + +**职责**: +- 业务逻辑实现 +- 业务流程控制 +- 服务协调 +- 业务规则验证 +- 事务管理 + +**原则**: +- ✅ 实现所有业务逻辑 +- ✅ 协调多个Core层服务 +- ✅ 返回统一的业务响应 +- ❌ 不处理HTTP协议 +- ❌ 不直接访问数据库 + +**示例**: +```typescript +@Injectable() +export class LoginService { + async login(loginRequest: LoginRequest): Promise> { + try { + // 1. 调用核心服务进行认证 + const authResult = await this.loginCoreService.login(loginRequest); + + // 2. 业务逻辑:验证Zulip账号 + await this.validateAndUpdateZulipApiKey(authResult.user); + + // 3. 生成JWT令牌 + const tokenPair = await this.loginCoreService.generateTokenPair(authResult.user); + + // 4. 返回业务响应 + return { + success: true, + data: { user: this.formatUserInfo(authResult.user), ...tokenPair }, + message: '登录成功' + }; + } catch (error) { + return { + success: false, + message: error.message, + error_code: 'LOGIN_FAILED' + }; + } + } +} +``` + +### 4. Core Layer(核心层) + +**位置**:`src/core/` + +**职责**: +- 数据访问(数据库、缓存) +- 基础设施(Redis、消息队列) +- 外部系统集成 +- 技术实现细节 + +**原则**: +- ✅ 提供技术基础设施 +- ✅ 数据持久化和缓存 +- ✅ 外部API集成 +- ❌ 不包含业务逻辑 +- ❌ 不处理HTTP协议 + +## 数据流向 + +``` +客户端请求 + ↓ +Gateway Layer (Controller) + ↓ 调用 +Business Layer (Service) + ↓ 调用 +Core Layer (Data Access) + ↓ +数据库/缓存/外部API +``` + +## 依赖关系 + +``` +Gateway → Business → Core +``` + +- Gateway层依赖Business层 +- Business层依赖Core层 +- Core层不依赖任何业务层 +- 依赖方向单向,不允许反向依赖 + +## 重构步骤 + +### 第一阶段:登录注册模块(已完成) + +1. ✅ 创建`src/gateway/auth/`目录 +2. ✅ 移动Controller到Gateway层 +3. ✅ 移动DTO到Gateway层 +4. ✅ 移动Guard到Gateway层 +5. ✅ 创建`AuthGatewayModule` +6. ✅ 更新Business层模块,移除Controller +7. ✅ 更新`app.module.ts`使用新的Gateway模块 +8. ✅ 创建架构文档 + +### 第二阶段:其他业务模块(待进行) + +- [ ] 重构`location_broadcast`模块 +- [ ] 重构`user_mgmt`模块 +- [ ] 重构`admin`模块 +- [ ] 重构`zulip`模块 +- [ ] 重构`notice`模块 + +### 第三阶段:WebSocket模块(待进行) + +- [ ] 创建`src/transport/websocket/` +- [ ] 实现原生WebSocket服务器 +- [ ] 创建`src/gateway/location-broadcast/` +- [ ] 移动WebSocket Gateway到Gateway层 + +## 迁移指南 + +### 如何判断代码应该放在哪一层? + +**Gateway层**: +- 包含`@Controller()`装饰器 +- 包含`@Get()`, `@Post()`等HTTP方法装饰器 +- 包含`@Body()`, `@Param()`, `@Query()`等参数装饰器 +- 包含DTO类(`class LoginDto`) +- 包含Guard类(`class JwtAuthGuard`) + +**Business层**: +- 包含`@Injectable()`装饰器 +- 包含业务逻辑方法 +- 协调多个服务 +- 返回`ApiResponse`格式的响应 + +**Core层**: +- 包含数据库访问代码 +- 包含Redis操作代码 +- 包含外部API调用 +- 包含技术实现细节 + +### 重构Checklist + +对于每个模块: + +1. [ ] 识别Controller文件 +2. [ ] 创建对应的Gateway目录 +3. [ ] 移动Controller到Gateway层 +4. [ ] 移动DTO到Gateway层的`dto/`目录 +5. [ ] 移动Guard到Gateway层 +6. [ ] 创建Gateway Module +7. [ ] 更新Business Module,移除Controller +8. [ ] 更新imports,修正路径 +9. [ ] 更新app.module.ts +10. [ ] 运行测试确保功能正常 + +## 最佳实践 + +### 1. 保持层级职责清晰 + +每一层只做自己职责范围内的事情,不要越界。 + +### 2. 使用统一的响应格式 + +Business层返回统一的`ApiResponse`格式: + +```typescript +interface ApiResponse { + success: boolean; + data?: T; + message: string; + error_code?: string; +} +``` + +### 3. 错误处理分层 + +- Gateway层:将业务错误转换为HTTP状态码 +- Business层:捕获异常并转换为业务错误 +- Core层:抛出技术异常 + +### 4. 依赖注入 + +使用NestJS的依赖注入系统,通过Module配置依赖关系。 + +### 5. 文档完善 + +每个层级都应该有README文档说明职责和使用方法。 + +## 注意事项 + +1. **渐进式重构**:不要一次性重构所有模块,逐个模块进行 +2. **保持测试**:重构后运行测试确保功能正常 +3. **向后兼容**:重构过程中保持API接口不变 +4. **代码审查**:重构代码需要经过代码审查 +5. **文档更新**:及时更新相关文档 + +## 参考资料 + +- [NestJS官方文档](https://docs.nestjs.com/) +- [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) +- [Hexagonal Architecture](https://alistair.cockburn.us/hexagonal-architecture/) -- 2.25.1