# 步骤4：架构分层检查

## 🎯 检查目标
检查架构分层的合规性，确保Core层和Business层职责清晰、依赖关系正确。

## 🏗️ 架构层级识别

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

### 检查范围
- **限制范围**：仅检查当前执行检查的文件夹
- **不跨模块**：不考虑其他同层功能模块
- **专注职责**：确保当前模块职责清晰

## 🔧 Core层规范检查

### 职责定义
**Core层专注技术实现，不包含业务逻辑**

### 命名规范检查

#### 业务支撑模块（使用_core后缀）
专门为特定业务功能提供技术支撑：
```typescript
✅ 正确示例：
src/core/location_broadcast_core/     # 为位置广播业务提供技术支撑
src/core/admin_core/                  # 为管理员业务提供技术支撑
src/core/user_auth_core/              # 为用户认证业务提供技术支撑
src/core/zulip_core/                  # 为Zulip集成提供技术支撑

❌ 错误示例：
src/core/location_broadcast/          # 应该是location_broadcast_core
src/core/admin/                       # 应该是admin_core
```

#### 通用工具模块（不使用后缀）
提供可复用的数据访问或技术服务：
```typescript
✅ 正确示例：
src/core/db/user_profiles/            # 通用的用户档案数据访问
src/core/redis/                       # 通用的Redis技术封装
src/core/utils/logger/                # 通用的日志工具服务
src/core/db/zulip_accounts/           # 通用的Zulip账户数据访问

❌ 错误示例：
src/core/db/user_profiles_core/       # 应该是user_profiles（通用工具）
src/core/redis_core/                  # 应该是redis（通用工具）
```

### 命名判断流程
```
1. 模块是否专门为某个特定业务功能服务？
   ├─ 是 → 检查模块名称是否体现业务领域
   │   ├─ 是 → 使用 _core 后缀
   │   └─ 否 → 重新设计模块职责
   └─ 否 → 模块是否提供通用的技术服务？
       ├─ 是 → 不使用 _core 后缀
       └─ 否 → 重新评估模块定位

2. 实际案例判断：
   - user_profiles: 通用的用户档案数据访问 → 不使用后缀 ✓
   - location_broadcast_core: 专门为位置广播业务服务 → 使用_core后缀 ✓
   - redis: 通用的缓存技术服务 → 不使用后缀 ✓
   - zulip_core: 专门为Zulip集成业务服务 → 使用_core后缀 ✓
```

### Core层技术实现示例
```typescript
// ✅ 正确：Core层专注技术实现
@Injectable()
export class LocationBroadcastCoreService {
  /**
   * 广播位置更新到指定房间
   * 
   * 技术实现：
   * 1. 验证WebSocket连接状态
   * 2. 序列化位置数据
   * 3. 通过Socket.IO广播消息
   * 4. 记录广播性能指标
   * 5. 处理广播异常和重试
   */
  async broadcastToRoom(roomId: string, data: PositionData): Promise<void> {
    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层依赖关系检查
```typescript
// ✅ 允许的导入
import { Injectable } from '@nestjs/common';           # NestJS框架
import { Server } from 'socket.io';                   # 第三方技术库
import { RedisService } from '../redis/redis.service'; # 其他Core层模块
import * as crypto from 'crypto';                     # Node.js内置模块

// ❌ 禁止的导入
import { UserBusinessService } from '../../business/users/user.service'; # Business层模块
import { AdminController } from '../../business/admin/admin.controller'; # Business层模块
```

## 💼 Business层规范检查

### 职责定义
**Business层专注业务逻辑实现，不关心底层技术细节**

### 业务逻辑完备性检查
```typescript
// ✅ 正确：完整的业务逻辑
@Injectable()
export class UserBusinessService {
  /**
   * 用户注册业务流程
   * 
   * 业务逻辑：
   * 1. 验证用户信息完整性
   * 2. 检查用户名/邮箱是否已存在
   * 3. 验证邮箱格式和域名白名单
   * 4. 生成用户唯一标识
   * 5. 设置默认用户权限
   * 6. 发送欢迎邮件
   * 7. 记录注册日志
   * 8. 返回注册结果
   */
  async registerUser(registerData: RegisterUserDto): Promise<UserResult> {
    await this.validateUserBusinessRules(registerData);
    const user = await this.userCoreService.create(registerData);
    await this.emailService.sendWelcomeEmail(user.email);
    await this.logService.recordUserRegistration(user.id);
    return this.buildUserResult(user);
  }
}

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

### Business层依赖关系检查
```typescript
// ✅ 允许的导入
import { UserCoreService } from '../../core/user_auth_core/user_core.service';     # 对应Core层业务支撑
import { CacheService } from '../../core/redis/cache.service';                     # Core层通用工具
import { EmailService } from '../../core/utils/email.service';                     # Core层通用工具
import { OtherBusinessService } from '../other/other.service';                     # 其他Business层（谨慎）

// ❌ 禁止的导入
import { createConnection } from 'typeorm';                                        # 直接技术实现
import * as Redis from 'ioredis';                                                 # 直接技术实现
import { DatabaseConnection } from '../../core/db/connection';                     # 底层技术细节
```

## 🚨 常见架构违规

### 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('不允许竞争对手注册');
    }
  }
}
```

## 🎮 游戏服务器架构特殊检查

### WebSocket Gateway分层
```typescript
// ✅ 正确：Gateway在Business层，调用Core层服务
@WebSocketGateway()
export class LocationBroadcastGateway {
  constructor(
    private readonly locationBroadcastCore: LocationBroadcastCoreService,
    private readonly userProfiles: UserProfilesService,
  ) {}
  
  @SubscribeMessage('position_update')
  async handlePositionUpdate(client: Socket, data: PositionData): Promise<void> {
    // 业务逻辑：验证、权限检查
    await this.validateUserPermission(client.userId);
    
    // 调用Core层技术实现
    await this.locationBroadcastCore.broadcastToRoom(client.roomId, data);
  }
}
```

### 双模式服务分层
```typescript
// ✅ 正确：Business层统一接口，Core层不同实现
@Injectable()
export class UsersBusinessService {
  constructor(
    @Inject('USERS_SERVICE') 
    private readonly usersCore: UsersMemoryService | UsersDatabaseService,
  ) {}
  
  async createUser(userData: CreateUserDto): Promise<User> {
    // 业务逻辑：验证、权限、流程
    await this.validateUserBusinessRules(userData);
    
    // 调用Core层（内存或数据库模式）
    const user = await this.usersCore.create(userData);
    
    // 业务逻辑：后续处理
    await this.sendWelcomeNotification(user);
    return user;
  }
}
```

## 🔍 检查执行步骤

1. **识别当前模块的层级**
   - 确定是Core层还是Business层
   - 检查文件夹路径和命名

2. **检查Core层命名规范**
   - 业务支撑模块是否使用_core后缀
   - 通用工具模块是否不使用后缀
   - 根据模块职责判断命名正确性

3. **检查职责分离**
   - Core层是否只包含技术实现
   - Business层是否只包含业务逻辑
   - 是否有跨层职责混乱

4. **检查依赖关系**
   - Core层是否导入了Business层模块
   - Business层是否直接使用底层技术实现
   - 依赖注入是否正确使用

5. **检查架构违规**
   - 识别常见的分层违规模式
   - 检查技术实现和业务逻辑的边界
   - 确保架构清晰度

6. **游戏服务器特殊检查**
   - WebSocket Gateway的分层正确性
   - 双模式服务的架构设计
   - 实时通信组件的职责分离

## 🔥 重要提醒

**如果在本步骤中执行了任何修改操作（调整分层结构、修正依赖关系、重构代码等），必须立即重新执行步骤4的完整检查！**

- ✅ 执行修改 → 🔥 立即重新执行步骤4 → 提供验证报告 → 等待用户确认
- ❌ 执行修改 → 直接进入步骤5（错误做法）

**不能跳过重新检查环节！**