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

1650 lines
54 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 开发者代码检查规范 - Whale Town 游戏服务器
## 📖 概述
本文档为Whale Town游戏服务器开发者提供全面的代码检查规范确保代码质量、可维护性和团队协作效率。规范针对NestJS游戏服务器的双模式架构、实时通信、属性测试等特点进行了专门优化。
## 🎯 检查流程
代码检查分为6个步骤建议按顺序执行
1. **命名规范检查** - 文件、变量、函数、类的命名规范
2. **注释规范检查** - 文件头、类、方法注释的完整性
3. **代码质量检查** - 代码清洁度、性能优化
4. **架构分层检查** - 分层架构的合规性
5. **测试覆盖检查** - 测试文件的完整性和覆盖率
6. **功能文档生成** - README文档的生成和维护
---
## 1⃣ 命名规范检查
### 📁 文件和文件夹命名
**核心规则使用下划线分隔snake_case保持项目一致性**
```typescript
- 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/ #
```
**⚠️ 特别注意:保持项目现有的下划线命名风格,确保代码库一致性!**
**游戏服务器特殊文件类型:**
```typescript
- 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文档控制器
```
### 🏗️ 文件夹结构优化
**避免过度嵌套,减少单文件文件夹**
```typescript
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**
```typescript
const userName = 'Alice';
function getUserInfo() { }
async function validateUser() { }
const isGameStarted = false;
const UserName = 'Alice';
function GetUserInfo() { }
const is_game_started = false;
```
### 🏷️ 类和接口命名
**规则大驼峰命名PascalCase**
```typescript
class UserService { }
interface GameConfig { }
class CreateUserDto { }
enum UserStatus { }
class userService { }
interface gameConfig { }
class createUserDto { }
```
### 📊 常量命名
**规则:全大写 + 下划线分隔SCREAMING_SNAKE_CASE**
```typescript
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**
```typescript
@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⃣ 注释规范检查
### 📄 文件头注释
**必须包含的信息:**
```typescript
/**
* 文件功能描述
*
* 功能描述:
* - 主要功能点1
* - 主要功能点2
* - 主要功能点3
*
* 职责分离:
* - 职责描述1
* - 职责描述2
*
* 最近修改:
* - 2024-01-07: 代码规范优化 - 修复命名规范问题 (修改者: 张三)
* - 2024-01-06: 功能新增 - 添加用户验证功能 (修改者: 李四)
*
* @author 原始作者名称
* @version 1.0.1
* @since 2024-01-01
* @lastModified 2024-01-07
*/
```
### 🏛️ 类注释
**必须包含的信息:**
```typescript
/**
* 类功能描述
*
* 职责:
* - 主要职责1
* - 主要职责2
*
* 主要方法:
* - method1() - 方法1功能
* - method2() - 方法2功能
*
* 使用场景:
* - 场景描述
*/
@Injectable()
export class ExampleService {
// 类实现
}
```
### 🔧 方法注释(三级标准)
**必须包含的信息:**
```typescript
/**
* 用户登录验证
*
* 业务逻辑:
* 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修复` - 修复代码缺陷
- `性能优化` - 提升代码性能
- `重构` - 代码结构调整但功能不变
**格式要求:**
```typescript
/**
* 最近修改:
* - 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⃣ 代码质量检查
### 🧹 导入清理
**清理未使用的导入:**
```typescript
// ✅ 正确:只导入使用的模块
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'; // 未使用
```
**游戏服务器特殊导入检查:**
```typescript
// 检查双模式服务导入
import { UsersService } from './users.service';
import { UsersMemoryService } from './users-memory.service'; // 确保两个都被使用
// 检查WebSocket相关导入
import { Server, Socket } from 'socket.io'; // 确保Socket类型被使用
import { WsException } from '@nestjs/websockets'; // 确保异常处理被使用
```
### 📊 常量定义检查
```typescript
// ✅ 正确:使用全大写+下划线
const SALT_ROUNDS = 10;
const MAX_LOGIN_ATTEMPTS = 5;
const DEFAULT_PAGE_SIZE = 20;
// ❌ 错误:使用小驼峰
const saltRounds = 10;
const maxLoginAttempts = 5;
```
### 🗑️ 未使用代码清理
```typescript
// ❌ 需要删除:未使用的私有方法
private generateVerificationCode(): string {
// 如果这个方法没有被调用,应该删除
}
// ❌ 需要删除:未使用的变量
const unusedVariable = 'test';
```
### 🚫 TODO项处理
**强制要求最终文件不能包含TODO项**
```typescript
// ❌ 错误包含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中说明原因和计划
### 📏 方法长度检查
```typescript
// ✅ 正确方法长度合理建议不超过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_core``admin_core`
- **通用工具模块**:提供可复用的数据访问或基础技术服务,不使用`_core`后缀(如`user_profiles``redis``logger`
**游戏服务器Core层特殊模块**
```typescript
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后缀 ✓
```
```typescript
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
```
#### 技术实现示例
```typescript
// ✅ 正确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层规范
**职责:专注业务逻辑实现,不关心底层技术细节**
#### 业务逻辑完备性
```typescript
// ✅ 正确:完整的业务逻辑
@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客户端等
- ❌ 禁止:包含技术实现细节
#### 正确的分层实现
```typescript
// ✅ 正确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层违规示例
```typescript
// ❌ 错误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层违规示例
```typescript
// ❌ 错误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后缀外
```typescript
// ✅ 正确:严格一对一映射
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隔离外部依赖专注测试当前文件
```typescript
// ✅ 正确只测试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
```
**游戏服务器特殊测试要求:**
```typescript
// ✅ 必须有测试的文件类型
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__/等文件夹中
```typescript
// ✅ 正确:测试文件与源文件同目录
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中的所有公共方法**
```typescript
// 示例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', () => { });
});
// ... 其他方法的测试
});
```
### 🧪 测试场景真实性
**要求:每个方法必须测试正常情况、异常情况和边界情况**
```typescript
// ✅ 正确:游戏服务器完整测试场景
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);
});
});
```
### 🏗️ 测试代码质量
**要求:测试代码必须清晰、可维护、真实有效**
```typescript
// ✅ 正确:游戏服务器高质量测试代码
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目录**
```typescript
// ❌ 错误:集成测试放在源文件目录(旧做法)
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
- **配置集成**:测试配置文件和环境变量的集成
**游戏服务器集成测试重点:**
```typescript
// 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的消息同步集成
});
});
```
### ⚡ 测试执行
**游戏服务器推荐的测试命令:**
```bash
# 单元测试(严格限制:只执行.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配置建议**
```javascript
// 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. 模块概述
```markdown
# [模块名称] [中文描述]
[模块名称] 是 [一段话总结文件夹的整体功能和作用,说明其在项目中的定位和价值]。
```
#### 2. 对外提供的接口
```markdown
## 用户数据操作
### create()
创建新用户记录,支持数据验证和唯一性检查。
### findByEmail()
根据邮箱地址查询用户,用于登录验证和账户找回。
### updateUserStatus()
更新用户状态,支持激活、禁用、待验证等状态切换。
```
#### 2.1 API接口列表如适用
**如果business模块开放了可访问的API必须在此处列出**
```markdown
## 对外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. 使用的项目内部依赖
```markdown
## 使用的项目内部依赖
### UserStatus (来自 business/user-mgmt/enums/user-status.enum)
用户状态枚举,定义用户的激活、禁用、待验证等状态值。
### CreateUserDto (本模块)
用户创建数据传输对象,提供完整的数据验证规则和类型定义。
### LoggerService (来自 core/utils/logger)
日志服务,用于记录用户操作和系统事件。
```
#### 4. 核心特性
```markdown
## 核心特性
### 双存储模式支持
- 数据库模式使用TypeORM连接MySQL适用于生产环境
- 内存模式使用Map存储适用于开发测试和故障降级
- 动态模块配置通过UsersModule.forDatabase()和forMemory()灵活切换
- 自动检测:根据环境变量自动选择存储模式
### 实时通信能力
- WebSocket支持基于Socket.IO的实时双向通信
- 房间管理:支持用户加入/离开游戏房间
- 位置广播:实时广播用户位置更新给房间成员
- 连接管理:自动处理连接断开和重连机制
### 数据完整性保障
- 唯一性约束检查用户名、邮箱、手机号、GitHub ID
- 数据验证使用class-validator进行输入验证
- 事务支持:批量操作支持回滚机制
- 双模式一致性:确保内存模式和数据库模式行为一致
### 性能优化与监控
- 查询优化:使用索引和查询缓存
- 批量操作:支持批量创建和更新
- 内存缓存:热点数据缓存机制
- 性能监控WebSocket连接数、消息处理延迟等指标
- 属性测试使用fast-check进行随机化测试
### 第三方集成
- Zulip集成支持与Zulip聊天系统的消息同步
- 邮件服务:用户注册验证和通知
- Redis缓存支持Redis和文件存储双模式
- JWT认证完整的用户认证和授权体系
```
#### 5. 潜在风险
```markdown
## 潜在风险
### 内存模式数据丢失风险
- 内存存储在应用重启后数据会丢失
- 不适用于生产环境的持久化需求
- 建议仅在开发测试环境使用
- 缓解措施:提供数据导出/导入功能
### 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接口及功能说明
- [ ] 文档内容与代码实现一致
- [ ] 语言表达简洁明了
### 🔧 常用命令
#### 测试相关命令
```bash
# 游戏服务器测试命令(更新后的结构)
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测试
```
#### 代码检查命令
```bash
# 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. **告警策略**
- 连接数超过阈值
- 消息处理延迟过高
- 服务降级和故障转移
- 数据一致性检查失败