- 新增 Gateway 层职责定义和检查规范 - 添加 Gateway 层协议处理示例代码 - 补充 Gateway 层依赖关系和文件类型检查 - 完善 4 层架构说明(Gateway、Business、Core、Common) - 增加 Gateway 层常见违规示例
17 KiB
17 KiB
步骤4:架构分层检查
⚠️ 执行前必读规范
🔥 重要:在执行本步骤之前,AI必须先完整阅读同级目录下的 README.md 文件!
该README文件包含:
- 🎯 执行前准备和用户信息收集要求
- 🔄 强制执行原则和分步执行流程
- 🔥 修改后立即重新执行当前步骤的强制规则
- 📝 文件修改记录规范和版本号递增规则
- 🧪 测试文件调试规范和测试指令使用规范
- 🚨 全局约束和游戏服务器特殊要求
不阅读README直接执行步骤将导致执行不规范,违反项目要求!
🎯 检查目标
检查架构分层的合规性,确保Core层和Business层职责清晰、依赖关系正确。
🏗️ 架构层级识别
项目分层结构
src/
├── 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层协议处理示例
// ✅ 正确:Gateway层只做协议转换
@Controller('auth')
export class LoginController {
constructor(private readonly loginService: LoginService) {}
@Post('login')
async login(@Body() loginDto: LoginDto, @Res() res: Response): Promise<void> {
// 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<any> {
// 错误:在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层依赖关系检查
// ✅ 允许的导入
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层文件类型检查
// ✅ 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层规范检查
职责定义
Core层专注技术实现,不包含业务逻辑
命名规范检查
业务支撑模块(使用_core后缀)
专门为特定业务功能提供技术支撑:
✅ 正确示例:
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
通用工具模块(不使用后缀)
提供可复用的数据访问或技术服务:
✅ 正确示例:
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层技术实现示例
// ✅ 正确: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层依赖关系检查
// ✅ 允许的导入
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层专注业务逻辑实现,不关心底层技术细节
业务逻辑完备性检查
// ✅ 正确:完整的业务逻辑
@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层依赖关系检查
// ✅ 允许的导入
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'; # 底层技术细节
🚨 常见架构违规
Gateway层违规示例
// ❌ 错误:Gateway层包含业务逻辑
@Controller('users')
export class UserController {
@Post('register')
async register(@Body() registerDto: RegisterDto): Promise<User> {
// 违规:在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<any> {
// 违规:直接调用Core层服务
return this.loginCoreService.login(loginDto);
}
}
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('不允许竞争对手注册');
}
}
}
🎮 游戏服务器架构特殊检查
WebSocket Gateway分层
// ✅ 正确: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);
}
}
双模式服务分层
// ✅ 正确: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;
}
}
🔍 检查执行步骤
-
识别当前模块的层级
- 确定是Gateway层、Business层还是Core层
- 检查文件夹路径和命名
- 根据层级应用对应的检查规则
-
Gateway层检查(如果是Gateway层)
- 检查是否只包含协议处理代码
- 检查是否使用DTO进行数据验证
- 检查是否只调用Business层服务
- 检查是否有统一的错误处理
- 检查文件类型是否符合Gateway层规范
-
Business层检查(如果是Business层)
- 检查是否只包含业务逻辑
- 检查是否协调多个Core层服务
- 检查是否返回统一的业务响应
- 检查是否不包含HTTP协议处理
-
Core层检查(如果是Core层)
- 检查Core层命名规范
- 业务支撑模块是否使用_core后缀
- 通用工具模块是否不使用后缀
- 根据模块职责判断命名正确性
- 检查是否只包含技术实现
-
检查职责分离
- Gateway层是否只做协议转换
- Business层是否只包含业务逻辑
- Core层是否只包含技术实现
- 是否有跨层职责混乱
-
检查依赖关系
- Gateway层是否只依赖Business层
- Business层是否只依赖Core层
- Core层是否不依赖业务层
- 依赖注入是否正确使用
-
检查架构违规
- 识别常见的分层违规模式
- 检查技术实现和业务逻辑的边界
- 检查协议处理和业务逻辑的边界
- 确保架构清晰度
-
游戏服务器特殊检查
- WebSocket Gateway的分层正确性
- 双模式服务的架构设计
- 实时通信组件的职责分离
🔥 重要提醒
如果在本步骤中执行了任何修改操作(调整分层结构、修正依赖关系、重构代码等),必须立即重新执行步骤4的完整检查!
- ✅ 执行修改 → 🔥 立即重新执行步骤4 → 提供验证报告 → 等待用户确认
- ❌ 执行修改 → 直接进入步骤5(错误做法)
🚨 重要强调:纯检查步骤不更新修改记录 如果检查发现架构分层已经符合规范,无需任何修改,则:
- ❌ 禁止添加检查记录:不要添加"AI代码检查步骤4:架构分层检查和优化"
- ❌ 禁止更新时间戳:不要修改@lastModified字段
- ❌ 禁止递增版本号:不要修改@version字段
- ✅ 仅提供检查报告:说明检查结果,确认符合规范
不能跳过重新检查环节!