Files
whale-town-end/docs/ai-reading/step3-code-quality.md
moyin ba8bd9cc7e docs:添加AI代码检查执行指南文档
- 添加完整的7步代码检查流程指导
- 包含命名规范、注释标准、代码质量等检查标准
- 提供游戏服务器特殊要求和最佳实践
- 支持NestJS双模式架构和WebSocket实时通信检查

涉及文件:
- docs/ai-reading/README.md - 总体执行指南
- docs/ai-reading/step1-naming-convention.md - 命名规范检查
- docs/ai-reading/step2-comment-standard.md - 注释规范检查
- docs/ai-reading/step3-code-quality.md - 代码质量检查
- docs/ai-reading/step4-architecture-layer.md - 架构分层检查
- docs/ai-reading/step5-test-coverage.md - 测试覆盖检查
- docs/ai-reading/step6-documentation.md - 功能文档生成
- docs/ai-reading/step7-code-commit.md - 代码提交规范
2026-01-12 16:19:01 +08:00

327 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
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.
# 步骤3代码质量检查
## 🎯 检查目标
清理和优化代码质量消除未使用代码、规范常量定义、处理TODO项。
## 🧹 未使用代码清理
### 清理未使用的导入
```typescript
// ❌ 错误:导入未使用的模块
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 { Injectable, NotFoundException } from '@nestjs/common';
import { User } from './user.entity';
```
### 清理未使用的变量
```typescript
// ❌ 错误:定义但未使用的变量
const unusedVariable = 'test';
let tempData = [];
// ✅ 正确:删除未使用的变量
// 只保留实际使用的变量
```
### 清理未使用的方法
```typescript
// ❌ 错误:定义但未调用的私有方法
private generateVerificationCode(): string {
// 如果这个方法没有被调用,应该删除
}
// ✅ 正确:删除未使用的私有方法
// 或者确保方法被正确调用
```
## 📊 常量定义规范
### 使用SCREAMING_SNAKE_CASE
```typescript
// ✅ 正确:使用全大写+下划线
const SALT_ROUNDS = 10;
const MAX_LOGIN_ATTEMPTS = 5;
const DEFAULT_PAGE_SIZE = 20;
const WEBSOCKET_TIMEOUT = 30000;
const MAX_ROOM_CAPACITY = 100;
// ❌ 错误:使用小驼峰
const saltRounds = 10;
const maxLoginAttempts = 5;
const defaultPageSize = 20;
```
### 提取魔法数字为常量
```typescript
// ❌ 错误:使用魔法数字
if (attempts > 5) {
throw new Error('Too many attempts');
}
setTimeout(callback, 30000);
// ✅ 正确:提取为常量
const MAX_LOGIN_ATTEMPTS = 5;
const WEBSOCKET_TIMEOUT = 30000;
if (attempts > MAX_LOGIN_ATTEMPTS) {
throw new Error('Too many attempts');
}
setTimeout(callback, WEBSOCKET_TIMEOUT);
```
## 📏 方法长度检查
### 长度限制
- **建议**方法不超过50行
- **原则**:一个方法只做一件事
- **拆分**:复杂方法拆分为多个小方法
### 方法拆分示例
```typescript
// ❌ 错误方法过长超过50行
async processUserRegistration(userData: CreateUserDto): Promise<User> {
// 验证用户数据
// 检查邮箱是否存在
// 生成密码哈希
// 创建用户记录
// 发送欢迎邮件
// 记录操作日志
// 返回用户信息
// ... 超过50行的复杂逻辑
}
// ✅ 正确:拆分为多个小方法
async processUserRegistration(userData: CreateUserDto): Promise<User> {
await this.validateUserData(userData);
await this.checkEmailExists(userData.email);
const hashedPassword = await this.generatePasswordHash(userData.password);
const user = await this.createUserRecord({ ...userData, password: hashedPassword });
await this.sendWelcomeEmail(user.email);
await this.logUserRegistration(user.id);
return user;
}
private async validateUserData(userData: CreateUserDto): Promise<void> {
// 验证逻辑
}
private async checkEmailExists(email: string): Promise<void> {
// 邮箱检查逻辑
}
```
## 🔄 代码重复消除
### 识别重复代码
```typescript
// ❌ 错误:重复的验证逻辑
async createUser(userData: CreateUserDto): Promise<User> {
if (!userData.email || !userData.name) {
throw new BadRequestException('Required fields missing');
}
if (!this.isValidEmail(userData.email)) {
throw new BadRequestException('Invalid email format');
}
// 创建用户逻辑
}
async updateUser(id: string, userData: UpdateUserDto): Promise<User> {
if (!userData.email || !userData.name) {
throw new BadRequestException('Required fields missing');
}
if (!this.isValidEmail(userData.email)) {
throw new BadRequestException('Invalid email format');
}
// 更新用户逻辑
}
// ✅ 正确:抽象为可复用方法
async createUser(userData: CreateUserDto): Promise<User> {
this.validateUserData(userData);
// 创建用户逻辑
}
async updateUser(id: string, userData: UpdateUserDto): Promise<User> {
this.validateUserData(userData);
// 更新用户逻辑
}
private validateUserData(userData: CreateUserDto | UpdateUserDto): void {
if (!userData.email || !userData.name) {
throw new BadRequestException('Required fields missing');
}
if (!this.isValidEmail(userData.email)) {
throw new BadRequestException('Invalid email format');
}
}
```
## 🚫 TODO项处理强制要求
### 处理原则
**最终文件不能包含TODO项**,必须:
1. **真正实现功能**
2. **删除未完成代码**
### 常见TODO处理
```typescript
// ❌ 错误包含TODO项的代码
async getUserProfile(id: string): Promise<UserProfile> {
// TODO: 实现用户档案查询
throw new Error('Not implemented');
}
async sendSmsVerification(phone: string): Promise<void> {
// TODO: 集成短信服务提供商
throw new Error('SMS service not implemented');
}
// ✅ 正确:真正实现功能
async getUserProfile(id: string): Promise<UserProfile> {
const profile = await this.userProfileRepository.findOne({
where: { userId: id }
});
if (!profile) {
throw new NotFoundException('用户档案不存在');
}
return profile;
}
// ✅ 正确:如果功能不需要,删除方法
// 删除sendSmsVerification方法及其调用
```
## 🎮 游戏服务器特殊质量要求
### WebSocket连接管理
```typescript
// ✅ 正确:完整的连接管理
const MAX_CONNECTIONS_PER_ROOM = 100;
const CONNECTION_TIMEOUT = 30000;
const HEARTBEAT_INTERVAL = 10000;
@WebSocketGateway()
export class LocationBroadcastGateway {
private readonly connections = new Map<string, Socket>();
handleConnection(client: Socket): void {
this.validateConnection(client);
this.setupHeartbeat(client);
this.trackConnection(client);
}
private validateConnection(client: Socket): void {
// 连接验证逻辑
}
private setupHeartbeat(client: Socket): void {
// 心跳检测逻辑
}
}
```
### 双模式服务质量
```typescript
// ✅ 正确:确保两种模式行为一致
const DEFAULT_USER_STATUS = UserStatus.PENDING;
const MAX_BATCH_SIZE = 1000;
@Injectable()
export class UsersMemoryService {
private readonly users = new Map<string, User>();
async create(userData: CreateUserDto): Promise<User> {
this.validateUserData(userData);
const user = this.buildUserEntity(userData);
this.users.set(user.id, user);
return user;
}
private validateUserData(userData: CreateUserDto): void {
// 与数据库模式相同的验证逻辑
}
private buildUserEntity(userData: CreateUserDto): User {
// 与数据库模式相同的实体构建逻辑
}
}
```
### 属性测试质量
```typescript
// ✅ 正确:完整的属性测试实现
import * as fc from 'fast-check';
const PROPERTY_TEST_RUNS = 1000;
const MAX_USER_ID = 1000000;
describe('AdminService Properties', () => {
it('should handle any valid user status update', () => {
fc.assert(fc.property(
fc.integer({ min: 1, max: MAX_USER_ID }),
fc.constantFrom(...Object.values(UserStatus)),
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);
}
}
), { numRuns: PROPERTY_TEST_RUNS });
});
});
```
## 🔍 检查执行步骤
1. **扫描未使用的导入**
- 检查每个import语句是否被使用
- 删除未使用的导入
2. **扫描未使用的变量和方法**
- 检查变量是否被引用
- 检查私有方法是否被调用
- 删除未使用的代码
3. **检查常量定义**
- 识别魔法数字和字符串
- 提取为SCREAMING_SNAKE_CASE常量
- 确保常量命名清晰
4. **检查方法长度**
- 统计每个方法的行数
- 识别超过50行的方法
- 建议拆分复杂方法
5. **识别重复代码**
- 查找相似的代码块
- 抽象为可复用的工具方法
- 消除代码重复
6. **处理所有TODO项**
- 搜索所有TODO注释
- 要求真正实现功能或删除代码
- 确保最终文件无TODO项
7. **游戏服务器特殊检查**
- WebSocket连接管理完整性
- 双模式服务行为一致性
- 属性测试实现质量
## 🔥 重要提醒
**如果在本步骤中执行了任何修改操作删除未使用代码、提取常量、实现TODO项等必须立即重新执行步骤3的完整检查**
- ✅ 执行修改 → 🔥 立即重新执行步骤3 → 提供验证报告 → 等待用户确认
- ❌ 执行修改 → 直接进入步骤4错误做法
**不能跳过重新检查环节!**