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:
2026-03-19 01:39:34 +08:00
parent cd55097dbf
commit 0dac26d781
176 changed files with 47075 additions and 8404 deletions

View 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;
};
}
}