Files
whale-town-end/开发者代码检查规范.md
moyin d04ab7f75f CRITICAL ISSUES: Database management service with major problems
WARNING: This commit contains code with significant issues that need immediate attention:

1. Type Safety Issues:
   - Unused import ZulipAccountsService causing compilation warnings
   - Implicit 'any' type in formatZulipAccount method parameter
   - Type inconsistencies in service injections

2. Service Integration Problems:
   - Inconsistent service interface usage
   - Missing proper type definitions for injected services
   - Potential runtime errors due to type mismatches

3. Code Quality Issues:
   - Violation of TypeScript strict mode requirements
   - Inconsistent error handling patterns
   - Missing proper interface implementations

 Files affected:
   - src/business/admin/database_management.service.ts (main issue)
   - Multiple test files and service implementations
   - Configuration and documentation updates

 Next steps required:
   1. Fix TypeScript compilation errors
   2. Implement proper type safety
   3. Resolve service injection inconsistencies
   4. Add comprehensive error handling
   5. Update tests to match new implementations

 Impact: High - affects admin functionality and system stability
 Priority: Urgent - requires immediate review and fixes

Author: moyin
Date: 2026-01-10
2026-01-10 19:27:28 +08:00

54 KiB
Raw Blame History

开发者代码检查规范 - Whale Town 游戏服务器

📖 概述

本文档为Whale Town游戏服务器开发者提供全面的代码检查规范确保代码质量、可维护性和团队协作效率。规范针对NestJS游戏服务器的双模式架构、实时通信、属性测试等特点进行了专门优化。

🎯 检查流程

代码检查分为6个步骤建议按顺序执行

  1. 命名规范检查 - 文件、变量、函数、类的命名规范
  2. 注释规范检查 - 文件头、类、方法注释的完整性
  3. 代码质量检查 - 代码清洁度、性能优化
  4. 架构分层检查 - 分层架构的合规性
  5. 测试覆盖检查 - 测试文件的完整性和覆盖率
  6. 功能文档生成 - README文档的生成和维护

1 命名规范检查

📁 文件和文件夹命名

核心规则使用下划线分隔snake_case保持项目一致性

 正确示例:
- user_controller.ts
- admin_operation_log_service.ts  
- location_broadcast_gateway.ts
- websocket_auth_guard.ts
- src/business/user_mgmt/
- src/core/location_broadcast_core/

 错误示例:
- UserController.ts          # 大驼峰命名
- user-service.ts           # 短横线分隔
- adminOperationLog.service.ts      # 小驼峰命名
- src/Business/Auth/         # 大驼峰命名

⚠️ 特别注意:保持项目现有的下划线命名风格,确保代码库一致性!

游戏服务器特殊文件类型:

 游戏服务器专用文件类型:
- location_broadcast.gateway.ts     # WebSocket网关
- users_memory.service.ts          # 内存模式服务
- file_redis.service.ts            # 文件模式Redis
- admin.property.spec.ts           # 属性测试
- zulip_integration.e2e.spec.ts    # E2E测试
- performance_monitor.middleware.ts # 性能监控中间件
- websocket_docs.controller.ts     # WebSocket文档控制器

🏗️ 文件夹结构优化

避免过度嵌套,减少单文件文件夹

 错误:过度嵌套
src/
  guards/
    auth.guard.ts           # 只有一个文件,不需要单独文件夹
  interceptors/
    logging.interceptor.ts  # 只有一个文件,不需要单独文件夹

 正确:扁平化结构
src/
  auth.guard.ts
  logging.interceptor.ts

文件夹创建判断标准:

  • 不超过3个文件移到上级目录扁平化
  • 4个以上文件可以保持独立文件夹
  • 完整功能模块:即使文件较少也可以保持独立(需特殊说明)
  • 游戏服务器特殊考虑
    • WebSocket相关文件可以独立成文件夹实时通信复杂性
    • 双模式服务文件建议放在同一文件夹(便于对比)
    • 属性测试文件较多的模块可以保持独立结构

检查方法(重要):

  1. 必须使用工具详细检查:不能凭印象判断文件夹内容
  2. 逐个统计文件数量:使用listDirectory(path, depth=2)获取准确数据
  3. 识别单文件文件夹只有1个文件的文件夹必须扁平化
  4. 更新引用路径移动文件后必须更新所有import语句
  5. 考虑游戏服务器特殊性:实时通信、双模式、测试复杂度

常见检查错误:

  • 只看到文件夹存在就认为结构合理
  • 没有统计每个文件夹的文件数量
  • 凭印象判断而不使用工具验证
  • 遗漏单文件文件夹的识别

正确检查流程:

  1. 使用listDirectory工具查看详细结构
  2. 逐个文件夹统计文件数量
  3. 识别需要扁平化的文件夹≤3个文件
  4. 考虑游戏服务器特殊性WebSocket、双模式、测试复杂度
  5. 执行文件移动和路径更新操作

🔤 变量和函数命名

规则小驼峰命名camelCase

 正确示例:
const userName = 'Alice';
function getUserInfo() { }
async function validateUser() { }
const isGameStarted = false;

 错误示例:
const UserName = 'Alice';
function GetUserInfo() { }
const is_game_started = false;

🏷️ 类和接口命名

规则大驼峰命名PascalCase

 正确示例:
class UserService { }
interface GameConfig { }
class CreateUserDto { }
enum UserStatus { }

 错误示例:
class userService { }
interface gameConfig { }
class createUserDto { }

📊 常量命名

规则:全大写 + 下划线分隔SCREAMING_SNAKE_CASE

 正确示例:
const PORT = 3000;
const MAX_PLAYERS = 10;
const SALT_ROUNDS = 10;
const DEFAULT_TIMEOUT = 5000;

 错误示例:
const port = 3000;
const maxPlayers = 10;
const saltRounds = 10;

🛣️ 路由命名

规则:全小写 + 短横线分隔kebab-case

 正确示例:
@Get('user/get-info')
@Post('room/join-room')
@Put('player/update-position')
@WebSocketGateway({ path: '/location-broadcast' })  # WebSocket路径
@MessagePattern('user-position-update')             # 消息模式

 错误示例:
@Get('user/getInfo')
@Post('room/joinRoom')
@Put('player/update_position')

2 注释规范检查

📄 文件头注释

必须包含的信息:

/**
 * 文件功能描述
 * 
 * 功能描述:
 * - 主要功能点1
 * - 主要功能点2
 * - 主要功能点3
 * 
 * 职责分离:
 * - 职责描述1
 * - 职责描述2
 * 
 * 最近修改:
 * - 2024-01-07: 代码规范优化 - 修复命名规范问题 (修改者: 张三)
 * - 2024-01-06: 功能新增 - 添加用户验证功能 (修改者: 李四)
 * 
 * @author 原始作者名称
 * @version 1.0.1
 * @since 2024-01-01
 * @lastModified 2024-01-07
 */

🏛️ 类注释

必须包含的信息:

/**
 * 类功能描述
 * 
 * 职责:
 * - 主要职责1
 * - 主要职责2
 * 
 * 主要方法:
 * - method1() - 方法1功能
 * - method2() - 方法2功能
 * 
 * 使用场景:
 * - 场景描述
 */
@Injectable()
export class ExampleService {
  // 类实现
}

🔧 方法注释(三级标准)

必须包含的信息:

/**
 * 用户登录验证
 * 
 * 业务逻辑:
 * 1. 验证用户名或邮箱格式
 * 2. 查找用户记录
 * 3. 验证密码哈希值
 * 4. 检查用户状态是否允许登录
 * 5. 记录登录日志
 * 6. 返回认证结果
 * 
 * @param loginRequest 登录请求数据
 * @returns 认证结果,包含用户信息和认证状态
 * @throws UnauthorizedException 用户名或密码错误时
 * @throws ForbiddenException 用户状态不允许登录时
 * 
 * @example
 * ```typescript
 * const result = await loginService.validateUser({
 *   identifier: 'user@example.com',
 *   password: 'password123'
 * });
 * ```
 */
async validateUser(loginRequest: LoginRequest): Promise<AuthResult> {
  // 实现代码
}

📝 修改记录规范

修改类型定义:

  • 代码规范优化 - 命名规范、注释规范、代码清理等
  • 功能新增 - 添加新的功能或方法
  • 功能修改 - 修改现有功能的实现
  • Bug修复 - 修复代码缺陷
  • 性能优化 - 提升代码性能
  • 重构 - 代码结构调整但功能不变

格式要求:

/**
 * 最近修改:
 * - 2024-01-07: 代码规范优化 - 清理未使用的导入 (修改者: 张三)
 * - 2024-01-06: Bug修复 - 修复邮箱验证逻辑错误 (修改者: 李四)
 * - 2024-01-05: 功能新增 - 添加用户验证码登录功能 (修改者: 王五)
 * 
 * @version 1.0.1
 * @lastModified 2024-01-07
 */

作者字段处理规范:

  • 保留原则@author字段中的人名必须保留不得随意修改
  • AI标识替换:只有当@author字段包含AI标识如kiro、ChatGPT、Claude、AI等才可以替换为实际的修改者名称
  • 判断标准
    • 可以替换:@author kiro@author 张三
    • 可以替换:@author ChatGPT@author 李四
    • 不可替换:@author 王五 → 必须保留为 @author 王五
    • 不可替换:@author John Smith → 必须保留为 @author John Smith

修改记录更新要求:

  • 必须添加:每次修改文件后,必须在"最近修改"部分添加新的修改记录
  • 信息完整:包含修改日期、修改类型、修改内容、修改者姓名
  • 时间更新规则
    • 仅检查不修改:如果只是进行代码检查而没有实际修改文件内容,不更新@lastModified字段
    • 实际修改才更新:只有真正修改了文件内容(功能代码、注释内容、结构调整等)时才更新@lastModified字段
    • 检查规范强调:注释规范检查本身不是修改,除非发现需要修正的问题并进行了实际修改
    • Git变更检测通过git status和git diff检查文件是否有实际变更只有git显示文件被修改时才需要添加修改记录和更新时间戳
  • 版本递增:根据修改类型适当递增版本号

版本号递增规则:

  • 代码规范优化、Bug修复 → 修订版本 +1 (1.0.0 → 1.0.1)
  • 功能新增、功能修改 → 次版本 +1 (1.0.1 → 1.1.0)
  • 重构、架构变更 → 主版本 +1 (1.1.0 → 2.0.0)

3 代码质量检查

🧹 导入清理

清理未使用的导入:

// ✅ 正确:只导入使用的模块
import { Injectable, NotFoundException } from '@nestjs/common';
import { WebSocketGateway, WebSocketServer } from '@nestjs/websockets';
import { Server } from 'socket.io';

// ❌ 错误:导入未使用的模块
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { User, Admin } from './user.entity';
import * as crypto from 'crypto'; // 未使用
import { RedisService } from '../redis/redis.service'; // 未使用

游戏服务器特殊导入检查:

// 检查双模式服务导入
import { UsersService } from './users.service';
import { UsersMemoryService } from './users-memory.service'; // 确保两个都被使用

// 检查WebSocket相关导入
import { Server, Socket } from 'socket.io'; // 确保Socket类型被使用
import { WsException } from '@nestjs/websockets'; // 确保异常处理被使用

📊 常量定义检查

// ✅ 正确:使用全大写+下划线
const SALT_ROUNDS = 10;
const MAX_LOGIN_ATTEMPTS = 5;
const DEFAULT_PAGE_SIZE = 20;

// ❌ 错误:使用小驼峰
const saltRounds = 10;
const maxLoginAttempts = 5;

🗑️ 未使用代码清理

// ❌ 需要删除:未使用的私有方法
private generateVerificationCode(): string {
  // 如果这个方法没有被调用,应该删除
}

// ❌ 需要删除:未使用的变量
const unusedVariable = 'test';

🚫 TODO项处理

强制要求最终文件不能包含TODO项

// ❌ 错误包含TODO项的代码
async getUserProfile(id: string): Promise<UserProfile> {
  // TODO: 实现用户档案查询
  throw new Error('Not implemented');
}

// ❌ 游戏服务器常见TODO需要处理
async sendSmsVerification(phone: string): Promise<void> {
  // TODO: 集成短信服务提供商
  throw new Error('SMS service not implemented');
}

async cleanupOldPositions(): Promise<void> {
  // TODO: 实现位置历史数据清理
  console.log('Position cleanup not implemented');
}

// ✅ 正确:真正实现功能
async getUserProfile(id: string): Promise<UserProfile> {
  const profile = await this.userProfileRepository.findOne({ 
    where: { userId: id } 
  });
  
  if (!profile) {
    throw new NotFoundException('用户档案不存在');
  }
  
  return profile;
}

// ✅ 正确:游戏服务器实现示例
async broadcastPositionUpdate(userId: string, position: Position): Promise<void> {
  const room = await this.getRoomByUserId(userId);
  this.server.to(room.id).emit('position-update', {
    userId,
    position,
    timestamp: Date.now()
  });
  
  // 记录位置历史(如果需要)
  await this.savePositionHistory(userId, position);
}

游戏服务器TODO处理优先级

  • 高优先级:实时通信功能、用户认证、数据持久化
  • 中优先级:性能优化、监控告警、数据清理
  • 低优先级:辅助功能、统计分析、第三方集成

TODO处理原则

  • 真正实现:如果功能需要,必须提供完整的实现
  • 删除代码:如果功能不需要,删除相关方法和接口
  • 分阶段实现如果功能复杂可以分多个版本实现但每个版本都不能有TODO
  • 文档说明如果某些功能暂不实现在README中说明原因和计划

📏 方法长度检查

// ✅ 正确方法长度合理建议不超过50行
async createUser(userData: CreateUserDto): Promise<User> {
  // 简洁的实现
}

// ❌ 错误:方法过长,需要拆分
async complexMethod() {
  // 超过50行的复杂逻辑应该拆分成多个小方法
}

4 架构分层检查

🏗️ 架构层级识别

项目采用分层架构:

src/
├── core/           # Core层技术实现层
│   ├── db/         # 数据访问
│   ├── redis/      # 缓存服务
│   └── utils/      # 工具服务
├── business/       # Business层业务逻辑层
│   ├── auth/       # 认证业务
│   ├── users/      # 用户业务
│   └── admin/      # 管理业务
└── common/         # 公共层:通用组件

🔧 Core层规范

职责:专注技术实现,不包含业务逻辑

命名规范

  • 检查范围:仅检查当前执行检查的文件夹,不考虑其他同层功能模块
  • 业务支撑模块:专门为特定业务功能提供技术支撑,使用_core后缀(如location_broadcast_coreadmin_core
  • 通用工具模块:提供可复用的数据访问或基础技术服务,不使用_core后缀(如user_profilesredislogger

游戏服务器Core层特殊模块

 正确示例:
src/core/location_broadcast_core/     # 专门为位置广播业务提供技术支撑
src/core/admin_core/                  # 专门为管理员业务提供技术支撑
src/core/zulip_core/                  # 专门为Zulip集成提供技术支撑
src/core/login_core/                  # 专门为登录认证提供技术支撑
src/core/security_core/               # 专门为安全功能提供技术支撑
src/core/db/user_profiles/            # 通用的用户档案数据访问服务
src/core/redis/                       # 通用的Redis技术封装
src/core/utils/logger/                # 通用的日志工具服务

 错误示例:
src/core/location_broadcast/          # 应该是location_broadcast_core
src/core/db/user_profiles_core/       # 应该是user_profiles(通用工具)
src/core/redis_core/                  # 应该是redis(通用工具)

判断流程:

1. 模块是否专门为某个特定业务功能服务?
   ├─ 是 → 检查模块名称是否体现业务领域
   │   ├─ 是 → 使用 _core 后缀 (如: location_broadcast_core)
   │   └─ 否 → 重新设计模块职责
   └─ 否 → 模块是否提供通用的技术服务?
       ├─ 是 → 不使用 _core 后缀 (如: user_profiles, redis)
       └─ 否 → 重新评估模块定位

2. 实际案例判断:
   - user_profiles: 通用的用户档案数据访问 → 不使用后缀 ✓
   - location_broadcast_core: 专门为位置广播业务服务 → 使用_core后缀 ✓
   - redis: 通用的缓存技术服务 → 不使用后缀 ✓
   - user_auth_core: 专门为用户认证业务服务 → 使用_core后缀 ✓
 正确示例:
src/core/location_broadcast_core/     # 专门为位置广播业务提供技术支撑
src/core/user_auth_core/              # 专门为用户认证业务提供技术支撑
src/core/db/user_profiles/            # 通用的用户档案数据访问服务
src/core/redis/                       # 通用的Redis技术封装
src/core/utils/logger/                # 通用的日志工具服务

 错误示例:
src/core/location_broadcast/          # 应该是location_broadcast_core
src/core/db/user_profiles_core/       # 应该是user_profiles(通用工具)
src/core/redis_core/                  # 应该是redis(通用工具)

技术实现示例

// ✅ 正确Core层专注技术实现
@Injectable()
export class LocationBroadcastCoreService {
  /**
   * 广播位置更新到指定房间
   * 
   * 技术实现:
   * 1. 验证WebSocket连接状态
   * 2. 序列化位置数据
   * 3. 通过Socket.IO广播消息
   * 4. 记录广播性能指标
   * 5. 处理广播异常和重试
   */
  async broadcastToRoom(roomId: string, data: PositionData): Promise<void> {
    // 专注WebSocket技术实现细节
    const room = this.server.sockets.adapter.rooms.get(roomId);
    if (!room) {
      throw new NotFoundException(`Room ${roomId} not found`);
    }
    
    this.server.to(roomId).emit('position-update', data);
    this.metricsService.recordBroadcast(roomId, data.userId);
  }
}

// ❌ 错误Core层包含业务逻辑
@Injectable()
export class LocationBroadcastCoreService {
  async broadcastUserPosition(userId: string, position: Position): Promise<void> {
    // 错误:包含了用户权限检查的业务概念
    const user = await this.userService.findById(userId);
    if (user.status !== UserStatus.ACTIVE) {
      throw new ForbiddenException('用户状态不允许位置广播');
    }
  }
}

依赖关系

  • 允许导入其他Core层模块
  • 允许:导入第三方技术库
  • 允许导入Node.js内置模块
  • 禁止导入Business层模块
  • 禁止:包含具体业务概念的命名

💼 Business层规范

职责:专注业务逻辑实现,不关心底层技术细节

业务逻辑完备性

// ✅ 正确:完整的业务逻辑
@Injectable()
export class UserBusinessService {
  /**
   * 用户注册业务流程
   * 
   * 业务逻辑:
   * 1. 验证用户信息完整性
   * 2. 检查用户名/邮箱是否已存在
   * 3. 验证邮箱格式和域名白名单
   * 4. 生成用户唯一标识
   * 5. 设置默认用户权限
   * 6. 发送欢迎邮件
   * 7. 记录注册日志
   * 8. 返回注册结果
   */
  async registerUser(registerData: RegisterUserDto): Promise<UserResult> {
    // 完整的业务逻辑实现
  }
}

// ❌ 错误:业务逻辑不完整
@Injectable()
export class UserBusinessService {
  async registerUser(registerData: RegisterUserDto): Promise<User> {
    // 只是简单调用数据库保存,缺少业务验证和流程
    return this.userRepository.save(registerData);
  }
}

依赖关系

  • 允许导入对应的Core层业务支撑模块
  • 允许导入Core层通用工具模块
  • 允许导入其他Business层模块谨慎使用
  • 允许:导入第三方业务库
  • 禁止直接导入底层技术实现如数据库连接、Redis客户端等
  • 禁止:包含技术实现细节

正确的分层实现

// ✅ 正确Business层调用Core层服务
@Injectable()
export class UserBusinessService {
  constructor(
    private readonly userCoreService: UserCoreService,
    private readonly cacheService: CacheService,
    private readonly emailService: EmailService,
  ) {}

  async createUser(userData: CreateUserDto): Promise<User> {
    // 业务验证
    await this.validateUserBusinessRules(userData);
    
    // 调用Core层服务
    const user = await this.userCoreService.create(userData);
    await this.cacheService.set(`user:${user.id}`, user);
    await this.emailService.sendWelcomeEmail(user.email);
    
    return user;
  }
}

🔍 常见架构违规

Business层违规示例

// ❌ 错误Business层包含技术实现细节
@Injectable()
export class UserBusinessService {
  async createUser(userData: CreateUserDto): Promise<User> {
    // 违规直接操作Redis连接
    const redis = new Redis({ host: 'localhost', port: 6379 });
    await redis.set(`user:${userData.id}`, JSON.stringify(userData));
    
    // 违规直接写SQL语句
    const sql = 'INSERT INTO users (name, email) VALUES (?, ?)';
    await this.database.query(sql, [userData.name, userData.email]);
  }
}

Core层违规示例

// ❌ 错误Core层包含业务逻辑
@Injectable()
export class DatabaseService {
  async saveUser(userData: CreateUserDto): Promise<User> {
    // 违规:包含用户注册的业务验证
    if (userData.age < 18) {
      throw new BadRequestException('用户年龄必须大于18岁');
    }
    
    // 违规:包含业务规则
    if (userData.email.endsWith('@competitor.com')) {
      throw new ForbiddenException('不允许竞争对手注册');
    }
  }
}

5 测试覆盖检查

📋 测试文件存在性

规则每个Service、Controller、Gateway都必须有对应的测试文件

⚠️ 游戏服务器测试要求(重要): 以下类型需要测试文件:

  • Service类:文件名包含.service.ts的业务逻辑类
  • Controller类:文件名包含.controller.ts的控制器类
  • Gateway类:文件名包含.gateway.ts的WebSocket网关类
  • Guard类:文件名包含.guard.ts的守卫类(游戏服务器安全重要)
  • Interceptor类:文件名包含.interceptor.ts的拦截器类(日志监控重要)
  • Middleware类:文件名包含.middleware.ts的中间件类(性能监控重要)

以下类型不需要测试文件:

  • DTO类:数据传输对象(.dto.ts)不需要测试文件
  • Interface文件:接口定义(.interface.ts)不需要测试文件
  • 简单Utils工具类:简单工具函数(.utils.ts)不需要测试文件
  • Config文件:配置文件(.config.ts)不需要测试文件
  • Constants文件:常量定义(.constants.ts)不需要测试文件

🔥 测试代码检查严格要求(新增):

1. 严格一对一映射原则

  • 强制要求:每个测试文件必须严格对应一个源文件,属于严格一对一关系
  • 禁止多对一:不允许一个测试文件测试多个源文件的功能
  • 禁止一对多:不允许一个源文件的测试分散在多个测试文件中
  • 命名对应:测试文件名必须与源文件名完全对应(除.spec.ts后缀外
// ✅ 正确:严格一对一映射
src/business/auth/login.service.ts
src/business/auth/login.service.spec.ts

src/core/location_broadcast_core/location_broadcast_core.service.ts
src/core/location_broadcast_core/location_broadcast_core.service.spec.ts

// ❌ 错误:一个测试文件测试多个源文件
src/business/auth/auth_services.spec.ts  # 测试多个service,违反一对一原则

// ❌ 错误:一个源文件的测试分散在多个文件
src/business/auth/login.service.spec.ts
src/business/auth/login_validation.spec.ts  # 应该合并到login.service.spec.ts

2. 测试范围严格限制

  • 范围限制:测试内容必须严格限于对应源文件的功能测试
  • 禁止跨文件:不允许在单元测试中测试其他文件的功能
  • 依赖隔离使用Mock隔离外部依赖专注测试当前文件
// ✅ 正确只测试LoginService的功能
// 文件src/business/auth/login.service.spec.ts
describe('LoginService', () => {
  describe('validateUser', () => {
    it('should validate user credentials', () => {
      // 只测试LoginService.validateUser方法
      // 使用Mock隔离UserRepository等外部依赖
    });
  });
});

// ❌ 错误在LoginService测试中测试其他服务
describe('LoginService', () => {
  it('should integrate with UserRepository', () => {
    // 错误这是集成测试应该移到test/integration/
  });
  
  it('should work with EmailService', () => {
    // 错误测试了EmailService的功能违反范围限制
  });
});

3. 集成测试强制分离

  • 强制分离:所有集成测试必须从单元测试文件中移除
  • 统一位置:集成测试统一放在顶层test/integration/目录
  • 最后执行:集成测试在所有单元测试通过后统一执行

4. 顶层test目录结构强制要求

test/
├── integration/          # 集成测试 - 测试多个模块间的交互
│   ├── auth_integration.spec.ts
│   ├── location_broadcast_integration.spec.ts
│   └── zulip_integration.spec.ts
├── e2e/                 # 端到端测试 - 完整业务流程测试
│   ├── user_registration_e2e.spec.ts
│   ├── location_broadcast_e2e.spec.ts
│   └── admin_operations_e2e.spec.ts
├── performance/         # 性能测试 - WebSocket和高并发测试
│   ├── websocket_performance.spec.ts
│   ├── database_performance.spec.ts
│   └── memory_usage.spec.ts
├── property/           # 属性测试 - 基于属性的随机测试
│   ├── admin_property.spec.ts
│   ├── user_validation_property.spec.ts
│   └── position_update_property.spec.ts
└── fixtures/           # 测试数据和工具
    ├── test_data.ts
    └── test_helpers.ts

游戏服务器特殊测试要求:

// ✅ 必须有测试的文件类型
src/business/location-broadcast/location-broadcast.gateway.ts
src/business/location-broadcast/location-broadcast.gateway.spec.ts

src/core/security-core/websocket-auth.guard.ts  
src/core/security-core/websocket-auth.guard.spec.ts

src/business/admin/performance-monitor.middleware.ts
src/business/admin/performance-monitor.middleware.spec.ts

// ❌ 不需要测试的文件类型
src/business/location-broadcast/dto/position-update.dto.ts  # DTO不需要测试
src/core/location-broadcast-core/position.interface.ts      # 接口不需要测试
src/business/admin/admin.constants.ts                       # 常量不需要测试

测试文件位置规范(重要):

  • 正确位置:测试文件必须与对应源文件放在同一目录
  • 错误位置测试文件放在单独的tests/、test/、spec/、tests/等文件夹中
// ✅ 正确:测试文件与源文件同目录
src/core/db/users/users.service.ts
src/core/db/users/users.service.spec.ts

src/business/admin/admin.service.ts  
src/business/admin/admin.service.spec.ts

// ❌ 错误:测试文件在单独文件夹
src/business/admin/admin.service.ts
src/business/admin/tests/admin.service.spec.ts        # 错误位置
src/business/admin/__tests__/admin.service.spec.ts    # 错误位置

// ❌ 错误:缺少测试文件
src/core/login_core/login_core.service.ts
# 缺少:src/core/login_core/login_core.service.spec.ts

扁平化要求:

  • 强制扁平化所有tests/、test/、spec/、tests/等测试专用文件夹必须扁平化
  • 移动规则:将测试文件移动到对应源文件的同一目录
  • 更新引用移动后必须更新所有import路径引用
  • 删除空文件夹:移动完成后删除空的测试文件夹

🎯 测试用例覆盖完整性

要求测试文件必须覆盖Service中的所有公共方法

// 示例Service
@Injectable()
export class UserService {
  async createUser(userData: CreateUserDto): Promise<User> { }
  async findUserById(id: string): Promise<User> { }
  async updateUser(id: string, updateData: UpdateUserDto): Promise<User> { }
  async deleteUser(id: string): Promise<void> { }
  async findUsersByStatus(status: UserStatus): Promise<User[]> { }
}

// ✅ 正确:完整的测试覆盖
describe('UserService', () => {
  // 每个公共方法都有对应的测试
  describe('createUser', () => {
    it('should create user successfully', () => { });
    it('should throw error when email already exists', () => { });
    it('should throw error when required fields missing', () => { });
  });

  describe('findUserById', () => {
    it('should return user when found', () => { });
    it('should throw NotFoundException when user not found', () => { });
    it('should throw error when id is invalid', () => { });
  });

  // ... 其他方法的测试
});

🧪 测试场景真实性

要求:每个方法必须测试正常情况、异常情况和边界情况

// ✅ 正确:游戏服务器完整测试场景
describe('LocationBroadcastGateway', () => {
  describe('handleConnection', () => {
    // 正常情况
    it('should accept valid WebSocket connection with JWT token', async () => {
      const mockSocket = createMockSocket({ token: validJwtToken });
      const result = await gateway.handleConnection(mockSocket);
      expect(result).toBeTruthy();
      expect(mockSocket.join).toHaveBeenCalledWith(expectedRoomId);
    });

    // 异常情况
    it('should reject connection with invalid JWT token', async () => {
      const mockSocket = createMockSocket({ token: 'invalid-token' });
      expect(() => gateway.handleConnection(mockSocket)).toThrow(WsException);
    });

    // 边界情况
    it('should handle connection when room is at capacity limit', async () => {
      const mockSocket = createMockSocket({ token: validJwtToken });
      jest.spyOn(gateway, 'getRoomMemberCount').mockResolvedValue(MAX_ROOM_CAPACITY);
      
      expect(() => gateway.handleConnection(mockSocket))
        .toThrow(new WsException('房间已满'));
    });
  });

  describe('handlePositionUpdate', () => {
    // 实时通信测试
    it('should broadcast position to all room members', async () => {
      const positionData = { x: 100, y: 200, timestamp: Date.now() };
      await gateway.handlePositionUpdate(mockSocket, positionData);
      
      expect(mockServer.to).toHaveBeenCalledWith(roomId);
      expect(mockServer.emit).toHaveBeenCalledWith('position-update', {
        userId: mockSocket.userId,
        position: positionData
      });
    });

    // 数据验证测试
    it('should validate position data format', async () => {
      const invalidPosition = { x: 'invalid', y: 200 };
      
      expect(() => gateway.handlePositionUpdate(mockSocket, invalidPosition))
        .toThrow(WsException);
    });
  });
});

// ✅ 双模式服务测试
describe('UsersService vs UsersMemoryService', () => {
  it('should have identical behavior for user creation', async () => {
    const userData = { name: 'Test User', email: 'test@example.com' };
    
    const dbResult = await usersService.create(userData);
    const memoryResult = await usersMemoryService.create(userData);
    
    expect(dbResult).toMatchObject(memoryResult);
  });
});

🏗️ 测试代码质量

要求:测试代码必须清晰、可维护、真实有效

// ✅ 正确:游戏服务器高质量测试代码
describe('LocationBroadcastGateway', () => {
  let gateway: LocationBroadcastGateway;
  let mockServer: jest.Mocked<Server>;
  let mockLocationService: jest.Mocked<LocationBroadcastCoreService>;

  beforeEach(async () => {
    const mockServer = {
      to: jest.fn().mockReturnThis(),
      emit: jest.fn(),
      sockets: {
        adapter: {
          rooms: new Map()
        }
      }
    };

    const mockLocationService = {
      broadcastToRoom: jest.fn(),
      validatePosition: jest.fn(),
      getRoomMembers: jest.fn()
    };

    const module: TestingModule = await Test.createTestingModule({
      providers: [
        LocationBroadcastGateway,
        { provide: 'SERVER', useValue: mockServer },
        { provide: LocationBroadcastCoreService, useValue: mockLocationService },
      ],
    }).compile();

    gateway = module.get<LocationBroadcastGateway>(LocationBroadcastGateway);
    mockServer = module.get('SERVER');
    mockLocationService = module.get(LocationBroadcastCoreService);
  });

  afterEach(() => {
    jest.clearAllMocks();
  });

  describe('handlePositionUpdate', () => {
    it('should broadcast valid position update to room members', async () => {
      // Arrange
      const mockSocket = createMockSocket({ userId: 'user123', roomId: 'room456' });
      const positionData = { x: 100, y: 200, timestamp: Date.now() };
      mockLocationService.validatePosition.mockResolvedValue(true);
      mockLocationService.getRoomMembers.mockResolvedValue(['user123', 'user456']);

      // Act
      await gateway.handlePositionUpdate(mockSocket, positionData);

      // Assert
      expect(mockLocationService.validatePosition).toHaveBeenCalledWith(positionData);
      expect(mockServer.to).toHaveBeenCalledWith('room456');
      expect(mockServer.emit).toHaveBeenCalledWith('position-update', {
        userId: 'user123',
        position: positionData,
        timestamp: expect.any(Number)
      });
    });
  });
});

// ✅ 属性测试示例(管理员模块)
describe('AdminService Properties', () => {
  it('should handle any valid user status update', () => {
    fc.assert(fc.property(
      fc.integer({ min: 1, max: 1000000 }), // userId
      fc.constantFrom(...Object.values(UserStatus)), // status
      async (userId, status) => {
        // 属性:任何有效的用户状态更新都应该成功或抛出明确的异常
        try {
          const result = await adminService.updateUserStatus(userId, status);
          expect(result).toBeDefined();
          expect(result.status).toBe(status);
        } catch (error) {
          // 如果抛出异常,应该是已知的业务异常
          expect(error).toBeInstanceOf(NotFoundException || BadRequestException);
        }
      }
    ));
  });
});

🔗 集成测试

要求复杂Service需要集成测试文件(.integration.spec.ts)

⚠️ 重要变更集成测试必须移动到顶层test目录

// ❌ 错误:集成测试放在源文件目录(旧做法)
src/core/location_broadcast_core/location_broadcast_core.service.ts
src/core/location_broadcast_core/location_broadcast_core.service.spec.ts          # 单元测试
src/core/location_broadcast_core/location_broadcast_core.integration.spec.ts     # 错误位置

// ✅ 正确集成测试统一放在顶层test目录新要求
src/core/location_broadcast_core/location_broadcast_core.service.ts
src/core/location_broadcast_core/location_broadcast_core.service.spec.ts          # 单元测试
test/integration/location_broadcast_core_integration.spec.ts                      # 正确位置

// ✅ 正确:其他类型测试的位置
test/e2e/zulip_integration_e2e.spec.ts                    # E2E测试
test/performance/websocket_performance.spec.ts            # 性能测试
test/property/admin_property.spec.ts                      # 属性测试

集成测试内容要求:

  • 模块间交互:测试多个模块之间的协作
  • 数据流验证:验证数据在模块间的正确传递
  • 依赖关系测试真实的依赖关系而非Mock
  • 配置集成:测试配置文件和环境变量的集成

游戏服务器集成测试重点:

// test/integration/location_broadcast_integration.spec.ts
describe('LocationBroadcast Integration', () => {
  it('should integrate gateway with core service and database', async () => {
    // 测试Gateway -> CoreService -> Database的完整链路
  });
  
  it('should handle WebSocket connection with Redis session', async () => {
    // 测试WebSocket连接与Redis会话管理的集成
  });
});

// test/integration/zulip_integration.spec.ts  
describe('Zulip Integration', () => {
  it('should sync messages between game chat and Zulip', async () => {
    // 测试游戏聊天与Zulip的消息同步集成
  });
});

测试执行

游戏服务器推荐的测试命令:

# 单元测试(严格限制:只执行.spec.ts文件排除集成测试和E2E测试
npm run test:unit
# 等价于: jest --testPathPattern=spec.ts --testPathIgnorePatterns="integration|e2e|performance|property"

# 集成测试统一在test/integration/目录执行)
npm run test:integration
# 等价于: jest test/integration/

# E2E测试统一在test/e2e/目录执行,需要设置环境变量)
npm run test:e2e
# 等价于: cross-env RUN_E2E_TESTS=true jest test/e2e/

# 属性测试统一在test/property/目录执行)
npm run test:property
# 等价于: jest test/property/

# 性能测试统一在test/performance/目录执行)
npm run test:performance
# 等价于: jest test/performance/

# 分阶段执行(推荐顺序)
npm run test:unit          # 第一阶段:单元测试
npm run test:integration   # 第二阶段:集成测试
npm run test:e2e          # 第三阶段E2E测试
npm run test:performance  # 第四阶段:性能测试

# 全部测试(按顺序执行所有测试)
npm run test:all

# 带覆盖率的测试执行
npm run test:cov

测试执行顺序说明:

  1. 单元测试优先:确保每个模块的基础功能正确
  2. 集成测试其次:验证模块间的协作
  3. E2E测试再次:验证完整的业务流程
  4. 性能测试最后:在功能正确的基础上验证性能

Jest配置建议

// jest.config.js
module.exports = {
  // 单元测试配置
  testMatch: [
    '<rootDir>/src/**/*.spec.ts'  // 只匹配源文件目录中的.spec.ts文件
  ],
  testPathIgnorePatterns: [
    '<rootDir>/test/',            // 忽略顶层test目录
    'integration',                // 忽略集成测试
    'e2e',                       // 忽略E2E测试
    'performance',               // 忽略性能测试
    'property'                   // 忽略属性测试
  ],
  
  // 集成测试配置(单独配置文件)
  projects: [
    {
      displayName: 'unit',
      testMatch: ['<rootDir>/src/**/*.spec.ts'],
      testPathIgnorePatterns: ['<rootDir>/test/']
    },
    {
      displayName: 'integration',
      testMatch: ['<rootDir>/test/integration/**/*.spec.ts']
    },
    {
      displayName: 'e2e',
      testMatch: ['<rootDir>/test/e2e/**/*.spec.ts']
    }
  ]
};

6 功能文档生成

📚 README文档结构

要求每个功能模块文件夹都必须有README.md文档

1. 模块概述

# [模块名称] [中文描述]

[模块名称] 是 [一段话总结文件夹的整体功能和作用,说明其在项目中的定位和价值]。

2. 对外提供的接口

## 用户数据操作

### create()
创建新用户记录,支持数据验证和唯一性检查。

### findByEmail()
根据邮箱地址查询用户,用于登录验证和账户找回。

### updateUserStatus()
更新用户状态,支持激活、禁用、待验证等状态切换。

2.1 API接口列表如适用

如果business模块开放了可访问的API必须在此处列出

## 对外API接口

### POST /api/auth/login
用户登录接口,支持用户名/邮箱/手机号多种方式登录。

### GET /api/users/:id
根据用户ID获取用户详细信息。

### PUT /api/users/:id/status
更新指定用户的状态(激活/禁用/待验证)。

### DELETE /api/users/:id
删除指定用户账户及相关数据。

### GET /api/users/search
根据条件搜索用户,支持邮箱、用户名、状态等筛选。

## WebSocket事件接口

### 'connection'
客户端建立WebSocket连接需要提供JWT认证token。

### 'position_update'
接收客户端位置更新,广播给房间内其他用户。
- 输入: `{ x: number, y: number, timestamp: number }`
- 输出: 广播给房间成员

### 'join_room'
用户加入游戏房间,建立实时通信连接。
- 输入: `{ roomId: string }`
- 输出: `{ success: boolean, members: string[] }`

### 'chat_message'
处理聊天消息支持Zulip集成和消息过滤。
- 输入: `{ message: string, roomId: string }`
- 输出: 广播给房间成员或转发到Zulip

### 'disconnect'
客户端断开连接,清理相关资源和通知其他用户。

3. 使用的项目内部依赖

## 使用的项目内部依赖

### UserStatus (来自 business/user-mgmt/enums/user-status.enum)
用户状态枚举,定义用户的激活、禁用、待验证等状态值。

### CreateUserDto (本模块)
用户创建数据传输对象,提供完整的数据验证规则和类型定义。

### LoggerService (来自 core/utils/logger)
日志服务,用于记录用户操作和系统事件。

4. 核心特性

## 核心特性

### 双存储模式支持
- 数据库模式使用TypeORM连接MySQL适用于生产环境
- 内存模式使用Map存储适用于开发测试和故障降级
- 动态模块配置通过UsersModule.forDatabase()和forMemory()灵活切换
- 自动检测:根据环境变量自动选择存储模式

### 实时通信能力
- WebSocket支持基于Socket.IO的实时双向通信
- 房间管理:支持用户加入/离开游戏房间
- 位置广播:实时广播用户位置更新给房间成员
- 连接管理:自动处理连接断开和重连机制

### 数据完整性保障
- 唯一性约束检查用户名、邮箱、手机号、GitHub ID
- 数据验证使用class-validator进行输入验证
- 事务支持:批量操作支持回滚机制
- 双模式一致性:确保内存模式和数据库模式行为一致

### 性能优化与监控
- 查询优化:使用索引和查询缓存
- 批量操作:支持批量创建和更新
- 内存缓存:热点数据缓存机制
- 性能监控WebSocket连接数、消息处理延迟等指标
- 属性测试使用fast-check进行随机化测试

### 第三方集成
- Zulip集成支持与Zulip聊天系统的消息同步
- 邮件服务:用户注册验证和通知
- Redis缓存支持Redis和文件存储双模式
- JWT认证完整的用户认证和授权体系

5. 潜在风险

## 潜在风险

### 内存模式数据丢失风险
- 内存存储在应用重启后数据会丢失
- 不适用于生产环境的持久化需求
- 建议仅在开发测试环境使用
- 缓解措施:提供数据导出/导入功能

### WebSocket连接管理风险
- 大量并发连接可能导致内存泄漏
- 网络不稳定时连接频繁断开重连
- 房间成员过多时广播性能下降
- 缓解措施:连接数限制、心跳检测、分片广播

### 实时通信性能风险
- 高频位置更新可能导致服务器压力
- 消息广播延迟影响游戏体验
- WebSocket消息丢失或重复
- 缓解措施:消息限流、优先级队列、消息确认机制

### 双模式一致性风险
- 内存模式和数据库模式行为可能不一致
- 模式切换时数据同步问题
- 测试覆盖不完整导致隐藏差异
- 缓解措施:统一接口抽象、完整的对比测试

### 第三方集成风险
- Zulip服务不可用时影响聊天功能
- 邮件服务故障影响用户注册
- Redis连接失败时缓存降级
- 缓解措施:服务降级、重试机制、监控告警

### 并发操作风险
- 内存模式的ID生成锁机制相对简单
- 高并发场景可能存在性能瓶颈
- 位置更新冲突和数据竞争
- 建议在生产环境使用数据库模式和分布式锁

### 数据一致性风险
- 跨模块操作时可能存在数据不一致
- WebSocket连接状态与用户状态不同步
- 需要注意事务边界的设计
- 建议使用分布式事务或补偿机制

### 安全风险
- WebSocket连接缺少足够的认证验证
- 用户位置信息泄露风险
- 管理员权限过度集中
- 缓解措施JWT认证、数据脱敏、权限细分

📝 文档质量要求

内容质量标准

  • 准确性:所有信息必须与代码实现一致
  • 完整性:覆盖所有公共接口和重要功能
  • 简洁性:每个说明控制在一句话内,突出核心要点
  • 实用性:提供对开发者有价值的信息和建议

语言表达规范

  • 使用中文进行描述,专业术语可保留英文
  • 语言简洁明了,避免冗长的句子
  • 统一术语使用,保持前后一致
  • 避免主观评价,客观描述功能和特性

🛠️ 实用工具和技巧

📋 检查清单

命名规范检查清单

  • 文件名使用snake_case下划线分隔
  • 变量和函数使用camelCase小驼峰
  • 类和接口使用PascalCase大驼峰
  • 常量使用SCREAMING_SNAKE_CASE全大写+下划线)
  • 路由使用kebab-case短横线分隔
  • 避免过度嵌套的文件夹结构
  • Core层业务支撑模块使用_core后缀通用工具模块不使用后缀

注释规范检查清单

  • 文件头注释包含功能描述、职责分离、修改记录
  • 类注释包含职责、主要方法、使用场景
  • 方法注释包含业务逻辑、参数说明、返回值、异常、示例
  • 修改记录使用正确的日期和修改者信息
  • 版本号按规则递增
  • @author字段正确处理AI标识替换为实际作者

代码质量检查清单

  • 清理所有未使用的导入
  • 清理所有未使用的变量和方法
  • 常量使用正确的命名规范
  • 方法长度控制在合理范围内建议不超过50行
  • 避免代码重复
  • 处理所有TODO项实现功能或删除代码

架构分层检查清单

  • Core层专注技术实现不包含业务逻辑
  • Business层专注业务逻辑不包含技术实现细节
  • 依赖关系符合分层架构要求
  • 模块职责清晰,边界明确

测试覆盖检查清单

  • 每个Service都有对应的.spec.ts测试文件
  • 测试文件与源文件严格一对一映射
  • 测试内容严格限于对应源文件的功能范围
  • 所有集成测试已移动到test/integration/目录
  • 所有E2E测试已移动到test/e2e/目录
  • 所有性能测试已移动到test/performance/目录
  • 所有属性测试已移动到test/property/目录
  • 单元测试文件中不包含集成测试或跨文件测试代码
  • 所有公共方法都有测试覆盖
  • 测试覆盖正常情况、异常情况、边界情况
  • 测试代码质量高,真实有效
  • 复杂Service提供集成测试
  • 测试能够成功执行

功能文档检查清单

  • 每个功能模块都有README.md文档
  • 文档包含模块概述、对外接口、内部依赖、核心特性、潜在风险
  • 所有公共接口都有准确的功能描述
  • 如果是business模块且开放了API必须列出所有API接口及功能说明
  • 文档内容与代码实现一致
  • 语言表达简洁明了

🔧 常用命令

测试相关命令

# 游戏服务器测试命令(更新后的结构)
npm run test:unit                    # 单元测试只测试src/目录中的.spec.ts
npm run test:integration             # 集成测试test/integration/目录)
npm run test:e2e                     # E2E测试test/e2e/目录)
npm run test:property                # 属性测试test/property/目录)
npm run test:performance             # 性能测试test/performance/目录)
npm run test:cov                     # 测试覆盖率
npm run test:all                     # 全部测试(按顺序执行)

# 分阶段测试执行(推荐)
npm run test:unit && npm run test:integration && npm run test:e2e

# Jest特定目录测试
jest src/                            # 只测试源文件目录
jest test/integration/               # 只测试集成测试
jest test/e2e/                      # 只测试E2E测试
jest test/performance/              # 只测试性能测试

# WebSocket测试需要启动服务
npm run dev &                        # 后台启动开发服务器
npm run test:e2e                     # 运行E2E测试

代码检查命令

# TypeScript类型检查
npx tsc --noEmit

# ESLint代码检查
npx eslint src/**/*.ts

# Prettier代码格式化
npx prettier --write src/**/*.ts

🚨 常见错误和解决方案

命名规范常见错误

  1. 短横线命名错误(不符合项目规范)

    • 错误:admin-operation-log.service.ts
    • 正确:admin_operation_log.service.ts
    • 解决:统一使用下划线分隔,保持项目一致性
  2. 游戏服务器特殊文件命名错误

    • 错误:locationBroadcast.gateway.ts
    • 正确:location_broadcast.gateway.ts
    • 错误:websocketAuth.guard.ts
    • 正确:websocket_auth.guard.ts
  3. 常量命名错误

    • 错误:const saltRounds = 10;
    • 正确:const SALT_ROUNDS = 10;
    • 解决:常量使用全大写+下划线

架构分层常见错误

  1. Business层包含技术实现

    • 错误:直接操作数据库连接
    • 正确调用Core层服务
    • 解决通过依赖注入使用Core层服务
  2. Core层包含业务逻辑

    • 错误:在数据层进行业务验证
    • 正确:只处理技术实现
    • 解决将业务逻辑移到Business层

测试覆盖常见错误

  1. 测试文件位置错误

    • 错误测试文件放在单独的tests/文件夹中
    • 正确:测试文件必须与源文件放在同一目录
    • 解决:将测试文件移动到对应源文件的同一目录
  2. 测试范围混乱

    • 错误:单元测试中包含集成测试代码
    • 正确:严格区分单元测试和集成测试
    • 解决将集成测试移动到test/integration/目录
  3. 一对多测试文件

    • 错误:一个测试文件测试多个源文件
    • 正确:每个测试文件严格对应一个源文件
    • 解决:拆分测试文件,确保一对一映射
  4. WebSocket测试文件缺失

    • 错误Gateway没有对应的.spec.ts文件
    • 解决为每个Gateway创建完整的连接、消息处理测试
  5. 双模式测试不完整

    • 错误:只测试数据库模式,忽略内存模式
    • 正确:确保两种模式行为一致性测试
    • 解决:创建对比测试用例
  6. 属性测试缺失

    • 错误:管理员模块缺少随机化测试
    • 正确使用fast-check进行属性测试
    • 解决在test/property/目录补充基于属性的测试用例
  7. 实时通信测试场景不完整

    • 错误:只测试正常连接,忽略异常断开
    • 正确:测试连接、断开、重连、消息处理全流程
    • 解决补充WebSocket生命周期测试

📈 最佳实践建议

🎯 开发流程建议

  1. 编码前:明确模块职责和架构定位
  2. 编码中:遵循命名规范和注释规范
  3. 编码后:进行代码质量检查和测试覆盖
  4. 提交前:生成或更新功能文档

🔄 持续改进

  1. 定期检查:建议每周进行一次全面的代码规范检查
  2. 团队协作通过Code Review确保规范执行
  3. 工具辅助使用ESLint、Prettier等工具自动化检查
  4. 文档维护:及时更新文档,保持与代码同步

📊 质量指标

  1. 命名规范达标率目标100%
  2. 注释覆盖率文件头、类、公共方法100%覆盖
  3. 测试覆盖率:单元测试覆盖率>90%
  4. 文档完整性每个功能模块都有README文档

🤝 团队协作

👥 角色职责

  • 开发者:遵循规范进行开发,自检代码质量
  • Code Reviewer:检查代码是否符合规范要求
  • 架构师:制定和维护架构分层规范
  • 测试工程师:确保测试覆盖率和测试质量

📋 Review检查点

  1. 命名规范:文件、变量、函数、类的命名是否符合规范
  2. 注释完整性:文件头、类、方法注释是否完整准确
  3. 代码质量:是否有未使用的代码,常量定义是否规范
  4. 架构合规性:是否符合分层架构要求
  5. 测试覆盖:是否有对应的测试文件和完整的测试用例
  6. 文档同步README文档是否与代码实现一致

🛡️ 质量保障

  1. 自动化检查集成ESLint、Prettier、Jest等工具
  2. CI/CD集成:在构建流程中加入代码规范检查
  3. 定期审计:定期进行代码规范审计和改进
  4. 培训推广:定期组织团队培训,提高规范意识

📞 支持和反馈

如果在使用过程中遇到问题或有改进建议,请:

  1. 查阅本文档的相关章节
  2. 参考常见错误和解决方案
  3. 向团队架构师或技术负责人咨询
  4. 提交改进建议,持续优化规范

记住:代码规范不是束缚,而是提高代码质量和团队协作效率的有力工具! 🚀


🎮 游戏服务器特殊优化建议

🚀 实时通信优化

  1. WebSocket连接管理

    • 实现连接池和心跳检测
    • 设置合理的连接超时和重连机制
    • 监控连接数量和消息处理延迟
  2. 消息广播优化

    • 使用房间分片减少广播范围
    • 实现消息优先级队列
    • 添加消息确认和重试机制
  3. 位置更新优化

    • 实现位置更新频率限制
    • 使用差分更新减少数据传输
    • 添加位置验证防止作弊

🔄 双模式架构优化

  1. 模式切换优化

    • 提供平滑的模式切换机制
    • 实现数据迁移和同步工具
    • 添加模式状态监控
  2. 一致性保障

    • 统一接口抽象层
    • 完整的行为对比测试
    • 自动化一致性检查
  3. 性能对比

    • 定期进行性能基准测试
    • 监控两种模式的资源使用
    • 优化内存模式的并发处理

🧪 测试策略优化

  1. 严格一对一测试映射

    • 每个测试文件严格对应一个源文件
    • 测试内容严格限于对应源文件的功能
    • 禁止跨文件测试和混合测试
  2. 分层测试架构

    • 单元测试:放在源文件同目录,测试单个模块功能
    • 集成测试统一放在test/integration/,测试模块间协作
    • E2E测试统一放在test/e2e/,测试完整业务流程
    • 性能测试统一放在test/performance/,测试系统性能
    • 属性测试统一放在test/property/,进行随机化测试
  3. 属性测试应用

    • 管理员模块使用fast-check
    • 随机化用户状态变更测试
    • 边界条件自动发现
  4. 集成测试重点

    • WebSocket连接生命周期
    • 双模式服务一致性
    • 第三方服务集成
  5. E2E测试场景

    • 完整的用户游戏流程
    • 多用户实时交互
    • 异常恢复和降级
  6. 测试执行顺序

    • 第一阶段:单元测试(快速反馈)
    • 第二阶段:集成测试(模块协作)
    • 第三阶段E2E测试业务流程
    • 第四阶段:性能测试(系统性能)

📊 监控和告警

  1. 关键指标监控

    • WebSocket连接数和延迟
    • 位置更新频率和处理时间
    • 内存使用和GC频率
    • 第三方服务可用性
  2. 告警策略

    • 连接数超过阈值
    • 消息处理延迟过高
    • 服务降级和故障转移
    • 数据一致性检查失败