feat: 添加MSW模拟服务和数据源集成
refactor: 重构页面组件移除冗余Layout组件 feat: 实现WebSocket和事件总线系统 feat: 添加队列和调度系统 docs: 更新架构文档和服务映射 style: 清理重复接口定义使用数据源 chore: 更新依赖项配置 feat: 添加运行时系统和领域引导 ci: 配置ESLint边界检查规则 build: 添加Redis和WebSocket依赖 test: 添加MSW浏览器环境入口 perf: 优化数据获取逻辑使用统一数据源 fix: 修复类型定义和状态管理问题
This commit is contained in:
80
server/src/core/guards/service.guard.ts
Normal file
80
server/src/core/guards/service.guard.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { logger } from '../../utils/logger';
|
||||
|
||||
/**
|
||||
* Service Guard
|
||||
* 确保所有业务逻辑都通过 Service 层,禁止在 Controller 中直接操作数据库
|
||||
*/
|
||||
export class ServiceGuard {
|
||||
/**
|
||||
* 验证 Controller 是否只调用 Service 层
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param next 下一步中间件
|
||||
*/
|
||||
static async validateServiceLayerUsage(req: Request, res: Response, next: NextFunction) {
|
||||
try {
|
||||
// 这里可以添加更复杂的验证逻辑
|
||||
// 例如:检查 Controller 中是否直接导入了数据库连接或 ORM
|
||||
// 或者通过 AST 分析检查代码结构
|
||||
|
||||
// 记录请求信息
|
||||
logger.info(`[ServiceGuard] Validating service layer usage for ${req.method} ${req.path}`);
|
||||
|
||||
// 暂时通过,后续可以添加更严格的验证
|
||||
next();
|
||||
} catch (error) {
|
||||
logger.error(`[ServiceGuard] Validation failed: ${(error as any).message}`);
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
error: 'Controller must use Service layer for business logic'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 装饰器:确保方法只在 Service 层调用
|
||||
*/
|
||||
static OnlyService() {
|
||||
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||
const originalMethod = descriptor.value;
|
||||
|
||||
descriptor.value = function (...args: any[]) {
|
||||
// 检查调用栈,确保调用来自 Service 层
|
||||
const stack = new Error().stack || '';
|
||||
const isServiceLayer = stack.includes('/services/');
|
||||
|
||||
if (!isServiceLayer) {
|
||||
throw new Error(`Method ${propertyKey} can only be called from Service layer`);
|
||||
}
|
||||
|
||||
return originalMethod.apply(this, args);
|
||||
};
|
||||
|
||||
return descriptor;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 装饰器:禁止直接操作数据库
|
||||
*/
|
||||
static NoDirectDatabaseAccess() {
|
||||
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||
const originalMethod = descriptor.value;
|
||||
|
||||
descriptor.value = function (...args: any[]) {
|
||||
// 检查调用栈,确保不是直接操作数据库
|
||||
const stack = new Error().stack || '';
|
||||
const isRepositoryLayer = stack.includes('/repositories/');
|
||||
|
||||
if (!isRepositoryLayer) {
|
||||
throw new Error(`Direct database access is forbidden. Use Repository layer instead.`);
|
||||
}
|
||||
|
||||
return originalMethod.apply(this, args);
|
||||
};
|
||||
|
||||
return descriptor;
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user