feat: 添加货币和汇率管理功能

refactor: 重构前端路由和登录逻辑

docs: 更新业务闭环、任务和架构文档

style: 调整代码格式和文件结构

chore: 更新依赖项和配置文件
This commit is contained in:
2026-03-19 19:08:15 +08:00
parent 8de9ea0aaa
commit eafa1bbe94
203 changed files with 20240 additions and 39580 deletions

View File

@@ -0,0 +1,457 @@
import { DomainEventBus } from '../runtime/DomainEventBus';
// 数据分类
export interface DataClassification {
id: string;
name: string;
description: string;
sensitivity: 'public' | 'internal' | 'confidential' | 'restricted';
retentionPeriod: number; // 天数
createdAt: Date;
lastUpdated: Date;
}
// 数据访问策略
export interface DataAccessPolicy {
id: string;
name: string;
description: string;
classificationId: string;
roles: string[];
permissions: 'read' | 'write' | 'delete' | 'admin';
conditions?: string; // 访问条件
createdAt: Date;
lastUpdated: Date;
}
// 数据审计日志
export interface DataAuditLog {
id: string;
userId: string;
action: 'read' | 'write' | 'delete' | 'access' | 'export';
dataClassification: string;
dataEntity: string;
recordId?: string;
ipAddress: string;
timestamp: Date;
status: 'success' | 'failed';
errorMessage?: string;
}
// 数据隐私设置
export interface DataPrivacySetting {
id: string;
name: string;
description: string;
type: 'anonymization' | 'masking' | 'encryption' | 'retention';
configuration: Record<string, any>;
enabled: boolean;
createdAt: Date;
lastUpdated: Date;
}
// 数据治理
export class DataGovernance {
private static instance: DataGovernance;
private dataClassifications: Map<string, DataClassification> = new Map();
private accessPolicies: Map<string, DataAccessPolicy> = new Map();
private auditLogs: Map<string, DataAuditLog> = new Map();
private privacySettings: Map<string, DataPrivacySetting> = new Map();
private eventBus: DomainEventBus;
private constructor() {
this.eventBus = DomainEventBus.getInstance();
}
static getInstance(): DataGovernance {
if (!DataGovernance.instance) {
DataGovernance.instance = new DataGovernance();
}
return DataGovernance.instance;
}
// 创建数据分类
async createDataClassification(classification: Omit<DataClassification, 'id' | 'createdAt' | 'lastUpdated'>): Promise<DataClassification> {
const id = `class_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newClassification: DataClassification = {
...classification,
id,
createdAt: new Date(),
lastUpdated: new Date()
};
this.dataClassifications.set(id, newClassification);
this.eventBus.publish('data.classification.created', newClassification);
return newClassification;
}
// 获取数据分类
getDataClassification(classificationId: string): DataClassification | undefined {
return this.dataClassifications.get(classificationId);
}
// 获取所有数据分类
getAllDataClassifications(): DataClassification[] {
return Array.from(this.dataClassifications.values());
}
// 更新数据分类
async updateDataClassification(classificationId: string, updates: Partial<DataClassification>): Promise<DataClassification | null> {
const classification = this.dataClassifications.get(classificationId);
if (!classification) {
return null;
}
const updatedClassification = {
...classification,
...updates,
lastUpdated: new Date()
};
this.dataClassifications.set(classificationId, updatedClassification);
this.eventBus.publish('data.classification.updated', updatedClassification);
return updatedClassification;
}
// 创建数据访问策略
async createAccessPolicy(policy: Omit<DataAccessPolicy, 'id' | 'createdAt' | 'lastUpdated'>): Promise<DataAccessPolicy> {
const id = `policy_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newPolicy: DataAccessPolicy = {
...policy,
id,
createdAt: new Date(),
lastUpdated: new Date()
};
this.accessPolicies.set(id, newPolicy);
this.eventBus.publish('data.access.policy.created', newPolicy);
return newPolicy;
}
// 获取数据访问策略
getAccessPolicy(policyId: string): DataAccessPolicy | undefined {
return this.accessPolicies.get(policyId);
}
// 获取所有数据访问策略
getAllAccessPolicies(filters?: {
classificationId?: string;
role?: string;
permissions?: string;
}): DataAccessPolicy[] {
let result = Array.from(this.accessPolicies.values());
if (filters) {
if (filters.classificationId) {
result = result.filter(p => p.classificationId === filters.classificationId);
}
if (filters.role) {
result = result.filter(p => p.roles.includes(filters.role!));
}
if (filters.permissions) {
result = result.filter(p => p.permissions === filters.permissions);
}
}
return result;
}
// 更新数据访问策略
async updateAccessPolicy(policyId: string, updates: Partial<DataAccessPolicy>): Promise<DataAccessPolicy | null> {
const policy = this.accessPolicies.get(policyId);
if (!policy) {
return null;
}
const updatedPolicy = {
...policy,
...updates,
lastUpdated: new Date()
};
this.accessPolicies.set(policyId, updatedPolicy);
this.eventBus.publish('data.access.policy.updated', updatedPolicy);
return updatedPolicy;
}
// 检查数据访问权限
async checkAccessPermission(userId: string, role: string, dataClassification: string, action: 'read' | 'write' | 'delete' | 'admin'): Promise<{
allowed: boolean;
policyId?: string;
reason?: string;
}> {
// 这里应该有实际的权限检查逻辑
// 暂时模拟检查
await new Promise(resolve => setTimeout(resolve, 100));
const policies = Array.from(this.accessPolicies.values()).filter(
p => p.classificationId === dataClassification && p.roles.includes(role)
);
if (policies.length === 0) {
return { allowed: false, reason: 'No policy found for this role and classification' };
}
const policy = policies.find(p => {
switch (action) {
case 'admin':
return p.permissions === 'admin';
case 'delete':
return p.permissions === 'admin' || p.permissions === 'delete';
case 'write':
return p.permissions === 'admin' || p.permissions === 'delete' || p.permissions === 'write';
case 'read':
return true;
default:
return false;
}
});
if (policy) {
return { allowed: true, policyId: policy.id };
} else {
return { allowed: false, reason: 'Insufficient permissions' };
}
}
// 记录数据审计日志
async logAuditEvent(log: Omit<DataAuditLog, 'id' | 'timestamp'>): Promise<DataAuditLog> {
const id = `log_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newLog: DataAuditLog = {
...log,
id,
timestamp: new Date()
};
this.auditLogs.set(id, newLog);
this.eventBus.publish('data.audit.log.created', newLog);
return newLog;
}
// 获取审计日志
getAuditLog(logId: string): DataAuditLog | undefined {
return this.auditLogs.get(logId);
}
// 获取审计日志
getAuditLogs(filters?: {
userId?: string;
action?: string;
dataClassification?: string;
startDate?: Date;
endDate?: Date;
}): DataAuditLog[] {
let result = Array.from(this.auditLogs.values());
if (filters) {
if (filters.userId) {
result = result.filter(l => l.userId === filters.userId);
}
if (filters.action) {
result = result.filter(l => l.action === filters.action);
}
if (filters.dataClassification) {
result = result.filter(l => l.dataClassification === filters.dataClassification);
}
if (filters.startDate) {
result = result.filter(l => l.timestamp >= filters.startDate!);
}
if (filters.endDate) {
result = result.filter(l => l.timestamp <= filters.endDate!);
}
}
return result.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
}
// 创建数据隐私设置
async createPrivacySetting(setting: Omit<DataPrivacySetting, 'id' | 'createdAt' | 'lastUpdated'>): Promise<DataPrivacySetting> {
const id = `privacy_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newSetting: DataPrivacySetting = {
...setting,
id,
createdAt: new Date(),
lastUpdated: new Date()
};
this.privacySettings.set(id, newSetting);
this.eventBus.publish('data.privacy.setting.created', newSetting);
return newSetting;
}
// 获取数据隐私设置
getPrivacySetting(settingId: string): DataPrivacySetting | undefined {
return this.privacySettings.get(settingId);
}
// 获取所有数据隐私设置
getAllPrivacySettings(filters?: {
type?: string;
enabled?: boolean;
}): DataPrivacySetting[] {
let result = Array.from(this.privacySettings.values());
if (filters) {
if (filters.type) {
result = result.filter(s => s.type === filters.type);
}
if (filters.enabled !== undefined) {
result = result.filter(s => s.enabled === filters.enabled);
}
}
return result;
}
// 更新数据隐私设置
async updatePrivacySetting(settingId: string, updates: Partial<DataPrivacySetting>): Promise<DataPrivacySetting | null> {
const setting = this.privacySettings.get(settingId);
if (!setting) {
return null;
}
const updatedSetting = {
...setting,
...updates,
lastUpdated: new Date()
};
this.privacySettings.set(settingId, updatedSetting);
this.eventBus.publish('data.privacy.setting.updated', updatedSetting);
return updatedSetting;
}
// 启用/禁用数据隐私设置
async togglePrivacySetting(settingId: string, enabled: boolean): Promise<boolean> {
const setting = this.privacySettings.get(settingId);
if (!setting) {
return false;
}
setting.enabled = enabled;
setting.lastUpdated = new Date();
this.privacySettings.set(settingId, setting);
this.eventBus.publish('data.privacy.setting.toggled', setting);
return true;
}
// 应用数据隐私处理
async applyPrivacyTreatment(data: any, classificationId: string): Promise<any> {
// 这里应该有实际的隐私处理逻辑
// 暂时模拟处理
await new Promise(resolve => setTimeout(resolve, 500));
const classification = this.dataClassifications.get(classificationId);
if (!classification) {
return data;
}
// 根据数据分类应用不同的隐私处理
switch (classification.sensitivity) {
case 'restricted':
// 应用最严格的隐私处理
return this.maskSensitiveData(data);
case 'confidential':
// 应用中等隐私处理
return this.anonymizeData(data);
case 'internal':
// 应用轻度隐私处理
return this.removePII(data);
case 'public':
default:
// 无需处理
return data;
}
}
// 掩码敏感数据
private maskSensitiveData(data: any): any {
// 这里应该有实际的掩码逻辑
return { ...data, masked: true };
}
// 匿名化数据
private anonymizeData(data: any): any {
// 这里应该有实际的匿名化逻辑
return { ...data, anonymized: true };
}
// 移除个人身份信息
private removePII(data: any): any {
// 这里应该有实际的PII移除逻辑
return { ...data, piiRemoved: true };
}
// 生成数据治理报告
async generateGovernanceReport(): Promise<{
summary: {
totalClassifications: number;
totalPolicies: number;
totalAuditLogs: number;
totalPrivacySettings: number;
};
classifications: DataClassification[];
policies: DataAccessPolicy[];
recentAuditLogs: DataAuditLog[];
privacySettings: DataPrivacySetting[];
}> {
const classifications = Array.from(this.dataClassifications.values());
const policies = Array.from(this.accessPolicies.values());
const auditLogs = Array.from(this.auditLogs.values()).sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime()).slice(0, 100);
const privacySettings = Array.from(this.privacySettings.values());
return {
summary: {
totalClassifications: classifications.length,
totalPolicies: policies.length,
totalAuditLogs: this.auditLogs.size,
totalPrivacySettings: privacySettings.length
},
classifications,
policies,
recentAuditLogs: auditLogs,
privacySettings
};
}
// 获取数据治理统计信息
getGovernanceStats(): {
totalClassifications: number;
totalPolicies: number;
totalAuditLogs: number;
totalPrivacySettings: number;
enabledPrivacySettings: number;
auditLogsToday: number;
} {
const today = new Date();
today.setHours(0, 0, 0, 0);
const auditLogsToday = Array.from(this.auditLogs.values())
.filter(log => log.timestamp >= today)
.length;
const enabledPrivacySettings = Array.from(this.privacySettings.values())
.filter(setting => setting.enabled)
.length;
return {
totalClassifications: this.dataClassifications.size,
totalPolicies: this.accessPolicies.size,
totalAuditLogs: this.auditLogs.size,
totalPrivacySettings: this.privacySettings.size,
enabledPrivacySettings,
auditLogsToday
};
}
}

View File

@@ -0,0 +1,392 @@
import { DomainEventBus } from '../runtime/DomainEventBus';
// 数据源配置
export interface DataSourceConfig {
id: string;
name: string;
type: 'database' | 'api' | 'file' | 'stream';
connectionString: string;
credentials?: Record<string, string>;
options?: Record<string, any>;
status: 'active' | 'inactive' | 'error';
createdAt: Date;
lastUpdated: Date;
}
// 数据转换规则
export interface DataTransformationRule {
id: string;
name: string;
sourceField: string;
targetField: string;
transformation: string; // 转换表达式
conditions?: string; // 条件表达式
createdAt: Date;
lastUpdated: Date;
}
// 数据集成任务
export interface IntegrationTask {
id: string;
name: string;
sourceDataSourceId: string;
targetDataSourceId: string;
transformationRules: string[]; // 规则ID列表
schedule: string; // cron表达式
status: 'pending' | 'running' | 'success' | 'failed';
lastRun: Date | null;
nextRun: Date | null;
createdAt: Date;
lastUpdated: Date;
}
// 集成任务执行日志
export interface IntegrationLog {
id: string;
taskId: string;
status: 'success' | 'failed';
startTime: Date;
endTime: Date;
recordsProcessed: number;
recordsFailed: number;
errorMessage?: string;
metadata?: Record<string, any>;
}
// 数据集成平台
export class DataIntegrationPlatform {
private static instance: DataIntegrationPlatform;
private dataSources: Map<string, DataSourceConfig> = new Map();
private transformationRules: Map<string, DataTransformationRule> = new Map();
private integrationTasks: Map<string, IntegrationTask> = new Map();
private integrationLogs: Map<string, IntegrationLog> = new Map();
private eventBus: DomainEventBus;
private constructor() {
this.eventBus = DomainEventBus.getInstance();
}
static getInstance(): DataIntegrationPlatform {
if (!DataIntegrationPlatform.instance) {
DataIntegrationPlatform.instance = new DataIntegrationPlatform();
}
return DataIntegrationPlatform.instance;
}
// 注册数据源
async registerDataSource(dataSource: Omit<DataSourceConfig, 'id' | 'status' | 'createdAt' | 'lastUpdated'>): Promise<DataSourceConfig> {
const id = `ds_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newDataSource: DataSourceConfig = {
...dataSource,
id,
status: 'inactive',
createdAt: new Date(),
lastUpdated: new Date()
};
this.dataSources.set(id, newDataSource);
this.eventBus.publish('datasource.registered', newDataSource);
return newDataSource;
}
// 获取数据源信息
getDataSource(dataSourceId: string): DataSourceConfig | undefined {
return this.dataSources.get(dataSourceId);
}
// 获取所有数据源
getAllDataSources(filters?: {
type?: string;
status?: string;
}): DataSourceConfig[] {
let result = Array.from(this.dataSources.values());
if (filters) {
if (filters.type) {
result = result.filter(ds => ds.type === filters.type);
}
if (filters.status) {
result = result.filter(ds => ds.status === filters.status);
}
}
return result;
}
// 更新数据源
async updateDataSource(dataSourceId: string, updates: Partial<DataSourceConfig>): Promise<DataSourceConfig | null> {
const dataSource = this.dataSources.get(dataSourceId);
if (!dataSource) {
return null;
}
const updatedDataSource = {
...dataSource,
...updates,
lastUpdated: new Date()
};
this.dataSources.set(dataSourceId, updatedDataSource);
this.eventBus.publish('datasource.updated', updatedDataSource);
return updatedDataSource;
}
// 测试数据源连接
async testDataSourceConnection(dataSourceId: string): Promise<{ success: boolean; message: string }> {
const dataSource = this.dataSources.get(dataSourceId);
if (!dataSource) {
return { success: false, message: 'DataSource not found' };
}
try {
// 这里应该有实际的连接测试逻辑
// 暂时模拟测试
await new Promise(resolve => setTimeout(resolve, 1000));
const success = Math.random() > 0.1; // 90% 成功率
if (success) {
dataSource.status = 'active';
this.dataSources.set(dataSourceId, dataSource);
return { success: true, message: 'Connection successful' };
} else {
dataSource.status = 'error';
this.dataSources.set(dataSourceId, dataSource);
return { success: false, message: 'Connection failed' };
}
} catch (error) {
dataSource.status = 'error';
this.dataSources.set(dataSourceId, dataSource);
return { success: false, message: error instanceof Error ? error.message : 'Unknown error' };
}
}
// 创建数据转换规则
async createTransformationRule(rule: Omit<DataTransformationRule, 'id' | 'createdAt' | 'lastUpdated'>): Promise<DataTransformationRule> {
const id = `rule_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newRule: DataTransformationRule = {
...rule,
id,
createdAt: new Date(),
lastUpdated: new Date()
};
this.transformationRules.set(id, newRule);
this.eventBus.publish('transformation.rule.created', newRule);
return newRule;
}
// 获取转换规则
getTransformationRule(ruleId: string): DataTransformationRule | undefined {
return this.transformationRules.get(ruleId);
}
// 获取所有转换规则
getAllTransformationRules(): DataTransformationRule[] {
return Array.from(this.transformationRules.values());
}
// 更新转换规则
async updateTransformationRule(ruleId: string, updates: Partial<DataTransformationRule>): Promise<DataTransformationRule | null> {
const rule = this.transformationRules.get(ruleId);
if (!rule) {
return null;
}
const updatedRule = {
...rule,
...updates,
lastUpdated: new Date()
};
this.transformationRules.set(ruleId, updatedRule);
this.eventBus.publish('transformation.rule.updated', updatedRule);
return updatedRule;
}
// 创建集成任务
async createIntegrationTask(task: Omit<IntegrationTask, 'id' | 'status' | 'lastRun' | 'nextRun' | 'createdAt' | 'lastUpdated'>): Promise<IntegrationTask> {
const id = `task_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newTask: IntegrationTask = {
...task,
id,
status: 'pending',
lastRun: null,
nextRun: this.calculateNextRun(task.schedule),
createdAt: new Date(),
lastUpdated: new Date()
};
this.integrationTasks.set(id, newTask);
this.eventBus.publish('integration.task.created', newTask);
return newTask;
}
// 获取集成任务
getIntegrationTask(taskId: string): IntegrationTask | undefined {
return this.integrationTasks.get(taskId);
}
// 获取所有集成任务
getAllIntegrationTasks(filters?: {
status?: string;
sourceDataSourceId?: string;
targetDataSourceId?: string;
}): IntegrationTask[] {
let result = Array.from(this.integrationTasks.values());
if (filters) {
if (filters.status) {
result = result.filter(t => t.status === filters.status);
}
if (filters.sourceDataSourceId) {
result = result.filter(t => t.sourceDataSourceId === filters.sourceDataSourceId);
}
if (filters.targetDataSourceId) {
result = result.filter(t => t.targetDataSourceId === filters.targetDataSourceId);
}
}
return result;
}
// 更新集成任务
async updateIntegrationTask(taskId: string, updates: Partial<IntegrationTask>): Promise<IntegrationTask | null> {
const task = this.integrationTasks.get(taskId);
if (!task) {
return null;
}
const updatedTask = {
...task,
...updates,
lastUpdated: new Date()
};
if (updates.schedule) {
updatedTask.nextRun = this.calculateNextRun(updates.schedule);
}
this.integrationTasks.set(taskId, updatedTask);
this.eventBus.publish('integration.task.updated', updatedTask);
return updatedTask;
}
// 执行集成任务
async executeIntegrationTask(taskId: string): Promise<IntegrationLog> {
const task = this.integrationTasks.get(taskId);
if (!task) {
throw new Error('Task not found');
}
task.status = 'running';
this.integrationTasks.set(taskId, task);
this.eventBus.publish('integration.task.started', task);
const startTime = new Date();
let recordsProcessed = 0;
let recordsFailed = 0;
let errorMessage: string | undefined;
try {
// 这里应该有实际的任务执行逻辑
// 暂时模拟执行
await new Promise(resolve => setTimeout(resolve, 3000));
recordsProcessed = Math.floor(Math.random() * 1000) + 100;
recordsFailed = Math.floor(Math.random() * 10);
if (recordsFailed > 5) {
throw new Error('Integration failed');
}
task.status = 'success';
task.lastRun = new Date();
task.nextRun = this.calculateNextRun(task.schedule);
} catch (error) {
task.status = 'failed';
errorMessage = error instanceof Error ? error.message : 'Unknown error';
}
this.integrationTasks.set(taskId, task);
const endTime = new Date();
const log: IntegrationLog = {
id: `log_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
taskId,
status: task.status === 'success' ? 'success' : 'failed',
startTime,
endTime,
recordsProcessed,
recordsFailed,
errorMessage
};
this.integrationLogs.set(log.id, log);
this.eventBus.publish('integration.task.completed', { task, log });
return log;
}
// 获取任务执行日志
getIntegrationLog(logId: string): IntegrationLog | undefined {
return this.integrationLogs.get(logId);
}
// 获取任务的执行日志
getTaskLogs(taskId: string): IntegrationLog[] {
return Array.from(this.integrationLogs.values()).filter(log => log.taskId === taskId);
}
// 计算下次执行时间
private calculateNextRun(cronExpression: string): Date {
// 这里应该有实际的cron表达式解析逻辑
// 暂时返回当前时间后1小时
const nextRun = new Date();
nextRun.setHours(nextRun.getHours() + 1);
return nextRun;
}
// 启动所有定时任务
async startScheduledTasks(): Promise<void> {
// 这里应该有实际的定时任务启动逻辑
// 暂时模拟启动
this.eventBus.publish('integration.tasks.started', { timestamp: new Date() });
}
// 停止所有定时任务
async stopScheduledTasks(): Promise<void> {
// 这里应该有实际的定时任务停止逻辑
// 暂时模拟停止
this.eventBus.publish('integration.tasks.stopped', { timestamp: new Date() });
}
// 获取平台状态
getPlatformStatus(): {
totalDataSources: number;
activeDataSources: number;
totalTasks: number;
runningTasks: number;
successTasks: number;
failedTasks: number;
totalLogs: number;
} {
const dataSources = Array.from(this.dataSources.values());
const tasks = Array.from(this.integrationTasks.values());
const logs = Array.from(this.integrationLogs.values());
return {
totalDataSources: dataSources.length,
activeDataSources: dataSources.filter(ds => ds.status === 'active').length,
totalTasks: tasks.length,
runningTasks: tasks.filter(t => t.status === 'running').length,
successTasks: tasks.filter(t => t.status === 'success').length,
failedTasks: tasks.filter(t => t.status === 'failed').length,
totalLogs: logs.length
};
}
}

View File

@@ -0,0 +1,399 @@
import { DomainEventBus } from '../runtime/DomainEventBus';
// 数据质量规则
export interface DataQualityRule {
id: string;
name: string;
description: string;
type: 'validation' | 'completeness' | 'accuracy' | 'consistency' | 'timeliness';
expression: string; // 规则表达式
severity: 'low' | 'medium' | 'high';
threshold: number;
enabled: boolean;
createdAt: Date;
lastUpdated: Date;
}
// 数据质量检查结果
export interface QualityCheckResult {
id: string;
ruleId: string;
dataSourceId: string;
entity: string; // 表名或实体名
recordsChecked: number;
recordsFailed: number;
failureRate: number;
status: 'pass' | 'warning' | 'fail';
timestamp: Date;
details?: Record<string, any>;
}
// 数据质量指标
export interface DataQualityMetrics {
dataSourceId: string;
entity: string;
completeness: number; // 完整性百分比
accuracy: number; // 准确性百分比
consistency: number; // 一致性百分比
timeliness: number; // 及时性百分比
overallScore: number; // 总体得分
lastUpdated: Date;
}
// 数据质量服务
export class DataQualityService {
private static instance: DataQualityService;
private qualityRules: Map<string, DataQualityRule> = new Map();
private checkResults: Map<string, QualityCheckResult> = new Map();
private qualityMetrics: Map<string, DataQualityMetrics> = new Map();
private eventBus: DomainEventBus;
private constructor() {
this.eventBus = DomainEventBus.getInstance();
}
static getInstance(): DataQualityService {
if (!DataQualityService.instance) {
DataQualityService.instance = new DataQualityService();
}
return DataQualityService.instance;
}
// 创建数据质量规则
async createQualityRule(rule: Omit<DataQualityRule, 'id' | 'createdAt' | 'lastUpdated'>): Promise<DataQualityRule> {
const id = `rule_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newRule: DataQualityRule = {
...rule,
id,
createdAt: new Date(),
lastUpdated: new Date()
};
this.qualityRules.set(id, newRule);
this.eventBus.publish('quality.rule.created', newRule);
return newRule;
}
// 获取质量规则
getQualityRule(ruleId: string): DataQualityRule | undefined {
return this.qualityRules.get(ruleId);
}
// 获取所有质量规则
getAllQualityRules(filters?: {
type?: string;
severity?: string;
enabled?: boolean;
}): DataQualityRule[] {
let result = Array.from(this.qualityRules.values());
if (filters) {
if (filters.type) {
result = result.filter(r => r.type === filters.type);
}
if (filters.severity) {
result = result.filter(r => r.severity === filters.severity);
}
if (filters.enabled !== undefined) {
result = result.filter(r => r.enabled === filters.enabled);
}
}
return result;
}
// 更新质量规则
async updateQualityRule(ruleId: string, updates: Partial<DataQualityRule>): Promise<DataQualityRule | null> {
const rule = this.qualityRules.get(ruleId);
if (!rule) {
return null;
}
const updatedRule = {
...rule,
...updates,
lastUpdated: new Date()
};
this.qualityRules.set(ruleId, updatedRule);
this.eventBus.publish('quality.rule.updated', updatedRule);
return updatedRule;
}
// 启用/禁用质量规则
async toggleQualityRule(ruleId: string, enabled: boolean): Promise<boolean> {
const rule = this.qualityRules.get(ruleId);
if (!rule) {
return false;
}
rule.enabled = enabled;
rule.lastUpdated = new Date();
this.qualityRules.set(ruleId, rule);
this.eventBus.publish('quality.rule.toggled', rule);
return true;
}
// 执行数据质量检查
async runQualityCheck(dataSourceId: string, entity: string): Promise<QualityCheckResult[]> {
const enabledRules = this.getAllQualityRules({ enabled: true });
const results: QualityCheckResult[] = [];
for (const rule of enabledRules) {
const result = await this.checkRule(dataSourceId, entity, rule);
results.push(result);
}
// 更新数据质量指标
await this.updateQualityMetrics(dataSourceId, entity, results);
this.eventBus.publish('quality.check.completed', { dataSourceId, entity, results, timestamp: new Date() });
return results;
}
// 检查单个规则
private async checkRule(dataSourceId: string, entity: string, rule: DataQualityRule): Promise<QualityCheckResult> {
// 这里应该有实际的规则检查逻辑
// 暂时模拟检查
await new Promise(resolve => setTimeout(resolve, 500));
const recordsChecked = Math.floor(Math.random() * 1000) + 100;
const recordsFailed = Math.floor(Math.random() * 50);
const failureRate = recordsFailed / recordsChecked;
let status: 'pass' | 'warning' | 'fail';
if (failureRate === 0) {
status = 'pass';
} else if (failureRate < rule.threshold) {
status = 'warning';
} else {
status = 'fail';
}
const result: QualityCheckResult = {
id: `result_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
ruleId: rule.id,
dataSourceId,
entity,
recordsChecked,
recordsFailed,
failureRate,
status,
timestamp: new Date()
};
this.checkResults.set(result.id, result);
return result;
}
// 更新数据质量指标
private async updateQualityMetrics(dataSourceId: string, entity: string, results: QualityCheckResult[]): Promise<void> {
const key = `${dataSourceId}:${entity}`;
// 计算各项指标
let completeness = 100;
let accuracy = 100;
let consistency = 100;
let timeliness = 100;
for (const result of results) {
const rule = this.qualityRules.get(result.ruleId);
if (rule) {
const score = (1 - result.failureRate) * 100;
switch (rule.type) {
case 'completeness':
completeness = score;
break;
case 'accuracy':
accuracy = score;
break;
case 'consistency':
consistency = score;
break;
case 'timeliness':
timeliness = score;
break;
}
}
}
const overallScore = (completeness + accuracy + consistency + timeliness) / 4;
const metrics: DataQualityMetrics = {
dataSourceId,
entity,
completeness,
accuracy,
consistency,
timeliness,
overallScore,
lastUpdated: new Date()
};
this.qualityMetrics.set(key, metrics);
this.eventBus.publish('quality.metrics.updated', metrics);
}
// 获取数据质量指标
getQualityMetrics(dataSourceId: string, entity: string): DataQualityMetrics | undefined {
const key = `${dataSourceId}:${entity}`;
return this.qualityMetrics.get(key);
}
// 获取所有数据质量指标
getAllQualityMetrics(filters?: {
dataSourceId?: string;
minScore?: number;
}): DataQualityMetrics[] {
let result = Array.from(this.qualityMetrics.values());
if (filters) {
if (filters.dataSourceId) {
result = result.filter(m => m.dataSourceId === filters.dataSourceId);
}
if (filters.minScore !== undefined) {
result = result.filter(m => m.overallScore >= filters.minScore!);
}
}
return result;
}
// 获取质量检查结果
getQualityCheckResult(resultId: string): QualityCheckResult | undefined {
return this.checkResults.get(resultId);
}
// 获取数据源的质量检查结果
getDataSourceCheckResults(dataSourceId: string): QualityCheckResult[] {
return Array.from(this.checkResults.values()).filter(r => r.dataSourceId === dataSourceId);
}
// 获取规则的质量检查结果
getRuleCheckResults(ruleId: string): QualityCheckResult[] {
return Array.from(this.checkResults.values()).filter(r => r.ruleId === ruleId);
}
// 生成数据质量报告
async generateQualityReport(dataSourceId?: string): Promise<{
summary: {
totalChecks: number;
passedChecks: number;
warningChecks: number;
failedChecks: number;
averageScore: number;
};
details: QualityCheckResult[];
metrics: DataQualityMetrics[];
}> {
let results = Array.from(this.checkResults.values());
let metrics = Array.from(this.qualityMetrics.values());
if (dataSourceId) {
results = results.filter(r => r.dataSourceId === dataSourceId);
metrics = metrics.filter(m => m.dataSourceId === dataSourceId);
}
const passedChecks = results.filter(r => r.status === 'pass').length;
const warningChecks = results.filter(r => r.status === 'warning').length;
const failedChecks = results.filter(r => r.status === 'fail').length;
const averageScore = metrics.length > 0
? metrics.reduce((sum, m) => sum + m.overallScore, 0) / metrics.length
: 0;
return {
summary: {
totalChecks: results.length,
passedChecks,
warningChecks,
failedChecks,
averageScore
},
details: results,
metrics
};
}
// 自动修复数据质量问题
async autoFixQualityIssues(dataSourceId: string, entity: string, ruleId: string): Promise<{
success: boolean;
fixedRecords: number;
message: string;
}> {
// 这里应该有实际的自动修复逻辑
// 暂时模拟修复
await new Promise(resolve => setTimeout(resolve, 2000));
const fixedRecords = Math.floor(Math.random() * 50);
const success = Math.random() > 0.2; // 80% 成功率
return {
success,
fixedRecords,
message: success
? `Fixed ${fixedRecords} records`
: 'Auto-fix failed'
};
}
// 获取数据质量趋势
getQualityTrend(dataSourceId: string, entity: string, days: number = 30): {
dates: string[];
scores: number[];
} {
// 这里应该有实际的趋势分析逻辑
// 暂时返回模拟数据
const dates: string[] = [];
const scores: number[] = [];
for (let i = days - 1; i >= 0; i--) {
const date = new Date();
date.setDate(date.getDate() - i);
dates.push(date.toISOString().split('T')[0]);
scores.push(Math.random() * 20 + 80); // 80-100 之间的随机数
}
return {
dates,
scores
};
}
// 获取数据质量统计信息
getQualityStats(): {
totalRules: number;
enabledRules: number;
totalChecks: number;
passedChecks: number;
warningChecks: number;
failedChecks: number;
averageScore: number;
} {
const rules = Array.from(this.qualityRules.values());
const results = Array.from(this.checkResults.values());
const metrics = Array.from(this.qualityMetrics.values());
const passedChecks = results.filter(r => r.status === 'pass').length;
const warningChecks = results.filter(r => r.status === 'warning').length;
const failedChecks = results.filter(r => r.status === 'fail').length;
const averageScore = metrics.length > 0
? metrics.reduce((sum, m) => sum + m.overallScore, 0) / metrics.length
: 0;
return {
totalRules: rules.length,
enabledRules: rules.filter(r => r.enabled).length,
totalChecks: results.length,
passedChecks,
warningChecks,
failedChecks,
averageScore
};
}
}

View File

@@ -0,0 +1,133 @@
import { StateMachine } from 'xstate';
// 数据状态定义
export type DataState = 'raw' | 'validating' | 'valid' | 'invalid' | 'processing' | 'processed' | 'error';
// 数据状态事件
export type DataEvent =
| { type: 'VALIDATE' }
| { type: 'VALID' }
| { type: 'INVALID' }
| { type: 'PROCESS' }
| { type: 'PROCESS_SUCCESS' }
| { type: 'PROCESS_ERROR' }
| { type: 'RETRY' };
// 数据状态上下文
export interface DataContext {
dataId: string;
tenantId: string;
shopId: string;
taskId: string;
traceId: string;
businessType: 'TOC' | 'TOB';
lastUpdated: string;
updatedBy: string;
dataType: string;
source: string;
}
// 数据状态机
export const dataStateMachine = StateMachine<DataContext, DataState, DataEvent>({
id: 'data',
initial: 'raw',
states: {
raw: {
on: {
VALIDATE: 'validating'
}
},
validating: {
on: {
VALID: 'valid',
INVALID: 'invalid'
}
},
valid: {
on: {
PROCESS: 'processing'
}
},
invalid: {
on: {
VALIDATE: 'validating'
}
},
processing: {
on: {
PROCESS_SUCCESS: 'processed',
PROCESS_ERROR: 'error'
}
},
processed: {
type: 'final'
},
error: {
on: {
RETRY: 'processing'
}
}
}
});
// 状态变更服务
export class DataStateMachineService {
private static instance: DataStateMachineService;
static getInstance(): DataStateMachineService {
if (!DataStateMachineService.instance) {
DataStateMachineService.instance = new DataStateMachineService();
}
return DataStateMachineService.instance;
}
async transition(
currentState: DataState,
event: DataEvent,
context: DataContext
): Promise<{
newState: DataState;
context: DataContext;
}> {
const state = dataStateMachine.transition(currentState, event);
// 更新上下文
const updatedContext = {
...context,
lastUpdated: new Date().toISOString(),
};
// 记录状态变更日志
this.logStateChange(updatedContext, currentState, state.value);
return {
newState: state.value,
context: updatedContext
};
}
private logStateChange(
context: DataContext,
fromState: DataState,
toState: DataState
): void {
console.log(`[DataStateMachine] Data ${context.dataId} transitioned from ${fromState} to ${toState}`, {
...context,
fromState,
toState,
timestamp: new Date().toISOString()
});
}
// 验证状态变更是否有效
isValidTransition(fromState: DataState, event: DataEvent): boolean {
const state = dataStateMachine.transition(fromState, event);
return state.value !== fromState || state.matches(fromState);
}
// 获取当前状态下可执行的事件
getAvailableEvents(state: DataState): DataEvent['type'][] {
const stateNode = dataStateMachine.getStateNode(state);
return Object.keys(stateNode.on || {});
}
}

View File

@@ -0,0 +1,141 @@
import { StateMachine } from 'xstate';
// 订单状态定义
export type OrderState = 'pending' | 'paid' | 'split' | 'processing' | 'shipped' | 'completed' | 'refunded' | 'cancelled';
// 订单状态事件
export type OrderEvent =
| { type: 'PAY' }
| { type: 'SPLIT' }
| { type: 'PROCESS' }
| { type: 'SHIP' }
| { type: 'COMPLETE' }
| { type: 'REFUND' }
| { type: 'CANCEL' };
// 订单状态上下文
export interface OrderContext {
orderId: string;
tenantId: string;
shopId: string;
taskId: string;
traceId: string;
businessType: 'TOC' | 'TOB';
lastUpdated: string;
updatedBy: string;
amount: number;
customerId: string;
}
// 订单状态机
export const orderStateMachine = StateMachine<OrderContext, OrderState, OrderEvent>({
id: 'order',
initial: 'pending',
states: {
pending: {
on: {
PAY: 'paid',
CANCEL: 'cancelled'
}
},
paid: {
on: {
SPLIT: 'split',
PROCESS: 'processing',
REFUND: 'refunded',
CANCEL: 'cancelled'
}
},
split: {
on: {
PROCESS: 'processing'
}
},
processing: {
on: {
SHIP: 'shipped',
REFUND: 'refunded',
CANCEL: 'cancelled'
}
},
shipped: {
on: {
COMPLETE: 'completed',
REFUND: 'refunded'
}
},
completed: {
on: {
REFUND: 'refunded'
}
},
refunded: {
type: 'final'
},
cancelled: {
type: 'final'
}
}
});
// 状态变更服务
export class OrderStateMachineService {
private static instance: OrderStateMachineService;
static getInstance(): OrderStateMachineService {
if (!OrderStateMachineService.instance) {
OrderStateMachineService.instance = new OrderStateMachineService();
}
return OrderStateMachineService.instance;
}
async transition(
currentState: OrderState,
event: OrderEvent,
context: OrderContext
): Promise<{
newState: OrderState;
context: OrderContext;
}> {
const state = orderStateMachine.transition(currentState, event);
// 更新上下文
const updatedContext = {
...context,
lastUpdated: new Date().toISOString(),
};
// 记录状态变更日志
this.logStateChange(updatedContext, currentState, state.value);
return {
newState: state.value,
context: updatedContext
};
}
private logStateChange(
context: OrderContext,
fromState: OrderState,
toState: OrderState
): void {
console.log(`[OrderStateMachine] Order ${context.orderId} transitioned from ${fromState} to ${toState}`, {
...context,
fromState,
toState,
timestamp: new Date().toISOString()
});
}
// 验证状态变更是否有效
isValidTransition(fromState: OrderState, event: OrderEvent): boolean {
const state = orderStateMachine.transition(fromState, event);
return state.value !== fromState || state.matches(fromState);
}
// 获取当前状态下可执行的事件
getAvailableEvents(state: OrderState): OrderEvent['type'][] {
const stateNode = orderStateMachine.getStateNode(state);
return Object.keys(stateNode.on || {});
}
}

View File

@@ -0,0 +1,124 @@
import { StateMachine } from 'xstate';
// 商品状态定义
export type ProductState = 'draft' | 'pending_approval' | 'active' | 'inactive' | 'discontinued';
// 商品状态事件
export type ProductEvent =
| { type: 'SUBMIT_FOR_APPROVAL' }
| { type: 'APPROVE' }
| { type: 'REJECT' }
| { type: 'ACTIVATE' }
| { type: 'DEACTIVATE' }
| { type: 'DISCONTINUE' }
| { type: 'REACTIVATE' };
// 商品状态上下文
export interface ProductContext {
productId: string;
tenantId: string;
shopId: string;
taskId: string;
traceId: string;
businessType: 'TOC' | 'TOB';
lastUpdated: string;
updatedBy: string;
}
// 商品状态机
export const productStateMachine = StateMachine<ProductContext, ProductState, ProductEvent>({
id: 'product',
initial: 'draft',
states: {
draft: {
on: {
SUBMIT_FOR_APPROVAL: 'pending_approval'
}
},
pending_approval: {
on: {
APPROVE: 'active',
REJECT: 'draft'
}
},
active: {
on: {
DEACTIVATE: 'inactive',
DISCONTINUE: 'discontinued'
}
},
inactive: {
on: {
ACTIVATE: 'active',
DISCONTINUE: 'discontinued'
}
},
discontinued: {
on: {
REACTIVATE: 'draft'
}
}
}
});
// 状态变更服务
export class ProductStateMachineService {
private static instance: ProductStateMachineService;
static getInstance(): ProductStateMachineService {
if (!ProductStateMachineService.instance) {
ProductStateMachineService.instance = new ProductStateMachineService();
}
return ProductStateMachineService.instance;
}
async transition(
currentState: ProductState,
event: ProductEvent,
context: ProductContext
): Promise<{
newState: ProductState;
context: ProductContext;
}> {
const state = productStateMachine.transition(currentState, event);
// 更新上下文
const updatedContext = {
...context,
lastUpdated: new Date().toISOString(),
};
// 记录状态变更日志
this.logStateChange(updatedContext, currentState, state.value);
return {
newState: state.value,
context: updatedContext
};
}
private logStateChange(
context: ProductContext,
fromState: ProductState,
toState: ProductState
): void {
console.log(`[ProductStateMachine] Product ${context.productId} transitioned from ${fromState} to ${toState}`, {
...context,
fromState,
toState,
timestamp: new Date().toISOString()
});
}
// 验证状态变更是否有效
isValidTransition(fromState: ProductState, event: ProductEvent): boolean {
const state = productStateMachine.transition(fromState, event);
return state.value !== fromState || state.matches(fromState);
}
// 获取当前状态下可执行的事件
getAvailableEvents(state: ProductState): ProductEvent['type'][] {
const stateNode = productStateMachine.getStateNode(state);
return Object.keys(stateNode.on || {});
}
}

View File

@@ -0,0 +1,357 @@
import { DomainEventBus } from '../runtime/DomainEventBus';
// 异常知识条目
export interface ExceptionKnowledgeItem {
id: string;
exceptionType: string;
messagePattern: string;
description: string;
cause: string;
solution: string;
prevention: string;
severity: 'low' | 'medium' | 'high' | 'critical';
frequency: number;
references?: string[];
createdAt: Date;
lastUpdated: Date;
lastSeen: Date;
}
// 异常知识查询结果
export interface ExceptionKnowledgeQueryResult {
items: ExceptionKnowledgeItem[];
total: number;
page: number;
pageSize: number;
query: string;
filters?: Record<string, string>;
}
// 异常知识统计
export interface ExceptionKnowledgeStats {
totalItems: number;
bySeverity: {
low: number;
medium: number;
high: number;
critical: number;
};
byType: Record<string, number>;
mostFrequent: ExceptionKnowledgeItem[];
recentlyUpdated: ExceptionKnowledgeItem[];
averageFrequency: number;
}
// 异常知识库
export class ExceptionKnowledgeBase {
private static instance: ExceptionKnowledgeBase;
private knowledgeItems: Map<string, ExceptionKnowledgeItem> = new Map();
private eventBus: DomainEventBus;
private constructor() {
this.eventBus = DomainEventBus.getInstance();
}
static getInstance(): ExceptionKnowledgeBase {
if (!ExceptionKnowledgeBase.instance) {
ExceptionKnowledgeBase.instance = new ExceptionKnowledgeBase();
}
return ExceptionKnowledgeBase.instance;
}
// 添加异常知识条目
async addKnowledgeItem(item: Omit<ExceptionKnowledgeItem, 'id' | 'frequency' | 'createdAt' | 'lastUpdated' | 'lastSeen'>): Promise<ExceptionKnowledgeItem> {
const id = `knowledge_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newItem: ExceptionKnowledgeItem = {
...item,
id,
frequency: 1,
createdAt: new Date(),
lastUpdated: new Date(),
lastSeen: new Date()
};
this.knowledgeItems.set(id, newItem);
this.eventBus.publish('exception.knowledge.added', newItem);
return newItem;
}
// 获取异常知识条目
getKnowledgeItem(itemId: string): ExceptionKnowledgeItem | undefined {
return this.knowledgeItems.get(itemId);
}
// 获取所有异常知识条目
getAllKnowledgeItems(filters?: {
severity?: string;
exceptionType?: string;
minFrequency?: number;
}): ExceptionKnowledgeItem[] {
let result = Array.from(this.knowledgeItems.values());
if (filters) {
if (filters.severity) {
result = result.filter(item => item.severity === filters.severity);
}
if (filters.exceptionType) {
result = result.filter(item => item.exceptionType === filters.exceptionType);
}
if (filters.minFrequency !== undefined) {
result = result.filter(item => item.frequency >= filters.minFrequency!);
}
}
return result.sort((a, b) => b.frequency - a.frequency);
}
// 更新异常知识条目
async updateKnowledgeItem(itemId: string, updates: Partial<ExceptionKnowledgeItem>): Promise<ExceptionKnowledgeItem | null> {
const item = this.knowledgeItems.get(itemId);
if (!item) {
return null;
}
const updatedItem = {
...item,
...updates,
lastUpdated: new Date()
};
this.knowledgeItems.set(itemId, updatedItem);
this.eventBus.publish('exception.knowledge.updated', updatedItem);
return updatedItem;
}
// 删除异常知识条目
async deleteKnowledgeItem(itemId: string): Promise<boolean> {
const item = this.knowledgeItems.get(itemId);
if (!item) {
return false;
}
this.knowledgeItems.delete(itemId);
this.eventBus.publish('exception.knowledge.deleted', item);
return true;
}
// 搜索异常知识
searchKnowledge(query: string, page: number = 1, pageSize: number = 10, filters?: Record<string, string>): ExceptionKnowledgeQueryResult {
let results = Array.from(this.knowledgeItems.values());
// 应用过滤器
if (filters) {
for (const [key, value] of Object.entries(filters)) {
if (key === 'severity') {
results = results.filter(item => item.severity === value);
} else if (key === 'exceptionType') {
results = results.filter(item => item.exceptionType === value);
}
}
}
// 搜索查询
if (query) {
const lowerQuery = query.toLowerCase();
results = results.filter(item =>
item.exceptionType.toLowerCase().includes(lowerQuery) ||
item.messagePattern.toLowerCase().includes(lowerQuery) ||
item.description.toLowerCase().includes(lowerQuery) ||
item.cause.toLowerCase().includes(lowerQuery) ||
item.solution.toLowerCase().includes(lowerQuery)
);
}
// 排序
results.sort((a, b) => b.frequency - a.frequency);
// 分页
const total = results.length;
const start = (page - 1) * pageSize;
const end = start + pageSize;
const paginatedResults = results.slice(start, end);
return {
items: paginatedResults,
total,
page,
pageSize,
query,
filters
};
}
// 匹配异常
matchException(exceptionType: string, message: string): ExceptionKnowledgeItem[] {
const results: ExceptionKnowledgeItem[] = [];
for (const item of this.knowledgeItems.values()) {
// 检查异常类型匹配
if (item.exceptionType === exceptionType) {
// 检查消息模式匹配
try {
const regex = new RegExp(item.messagePattern);
if (regex.test(message)) {
results.push(item);
}
} catch (error) {
// 正则表达式错误,使用简单字符串匹配
if (message.includes(item.messagePattern)) {
results.push(item);
}
}
}
}
// 按频率排序
return results.sort((a, b) => b.frequency - a.frequency);
}
// 增加异常频率
async incrementFrequency(itemId: string): Promise<ExceptionKnowledgeItem | null> {
const item = this.knowledgeItems.get(itemId);
if (!item) {
return null;
}
const updatedItem = {
...item,
frequency: item.frequency + 1,
lastSeen: new Date(),
lastUpdated: new Date()
};
this.knowledgeItems.set(itemId, updatedItem);
this.eventBus.publish('exception.knowledge.frequency.updated', updatedItem);
return updatedItem;
}
// 批量增加异常频率
async batchIncrementFrequency(itemIds: string[]): Promise<ExceptionKnowledgeItem[]> {
const updatedItems: ExceptionKnowledgeItem[] = [];
for (const itemId of itemIds) {
const updatedItem = await this.incrementFrequency(itemId);
if (updatedItem) {
updatedItems.push(updatedItem);
}
}
return updatedItems;
}
// 获取异常知识统计
getKnowledgeStats(): ExceptionKnowledgeStats {
const items = Array.from(this.knowledgeItems.values());
const totalItems = items.length;
const bySeverity = {
low: 0,
medium: 0,
high: 0,
critical: 0
};
const byType: Record<string, number> = {};
let totalFrequency = 0;
for (const item of items) {
bySeverity[item.severity]++;
byType[item.exceptionType] = (byType[item.exceptionType] || 0) + 1;
totalFrequency += item.frequency;
}
const mostFrequent = [...items].sort((a, b) => b.frequency - a.frequency).slice(0, 10);
const recentlyUpdated = [...items].sort((a, b) => b.lastUpdated.getTime() - a.lastUpdated.getTime()).slice(0, 10);
const averageFrequency = totalItems > 0 ? totalFrequency / totalItems : 0;
return {
totalItems,
bySeverity,
byType,
mostFrequent,
recentlyUpdated,
averageFrequency
};
}
// 导入异常知识
async importKnowledge(items: Omit<ExceptionKnowledgeItem, 'id' | 'frequency' | 'createdAt' | 'lastUpdated' | 'lastSeen'>[]): Promise<{
success: number;
failed: number;
}> {
let success = 0;
let failed = 0;
for (const item of items) {
try {
await this.addKnowledgeItem(item);
success++;
} catch (error) {
failed++;
}
}
return { success, failed };
}
// 导出异常知识
exportKnowledge(filters?: {
severity?: string;
exceptionType?: string;
minFrequency?: number;
}): ExceptionKnowledgeItem[] {
return this.getAllKnowledgeItems(filters);
}
// 生成异常知识报告
async generateKnowledgeReport(): Promise<{
stats: ExceptionKnowledgeStats;
mostCommonExceptions: ExceptionKnowledgeItem[];
leastCommonExceptions: ExceptionKnowledgeItem[];
recentlyAdded: ExceptionKnowledgeItem[];
}> {
const items = Array.from(this.knowledgeItems.values());
const stats = this.getKnowledgeStats();
const mostCommonExceptions = [...items].sort((a, b) => b.frequency - a.frequency).slice(0, 20);
const leastCommonExceptions = [...items].sort((a, b) => a.frequency - b.frequency).slice(0, 20);
const recentlyAdded = [...items].sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()).slice(0, 20);
return {
stats,
mostCommonExceptions,
leastCommonExceptions,
recentlyAdded
};
}
// 清理旧的异常知识
async cleanupOldKnowledge(days: number = 365): Promise<number> {
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - days);
let removedCount = 0;
for (const [id, item] of this.knowledgeItems.entries()) {
if (item.lastSeen < cutoffDate && item.frequency < 5) {
this.knowledgeItems.delete(id);
removedCount++;
}
}
if (removedCount > 0) {
this.eventBus.publish('exception.knowledge.cleanup', {
removedCount,
cutoffDate,
timestamp: new Date()
});
}
return removedCount;
}
}

View File

@@ -0,0 +1,412 @@
import { DomainEventBus } from '../runtime/DomainEventBus';
// 异常信息
export interface ExceptionInfo {
id: string;
type: string;
message: string;
stack?: string;
service: string;
context?: Record<string, any>;
severity: 'low' | 'medium' | 'high' | 'critical';
status: 'open' | 'processing' | 'resolved' | 'ignored';
createdAt: Date;
lastUpdated: Date;
resolvedAt?: Date;
resolvedBy?: string;
}
// 异常统计
export interface ExceptionStats {
total: number;
bySeverity: {
low: number;
medium: number;
high: number;
critical: number;
};
byStatus: {
open: number;
processing: number;
resolved: number;
ignored: number;
};
byService: Record<string, number>;
byType: Record<string, number>;
averageResolutionTime: number; // 平均解决时间(分钟)
last24Hours: number;
last7Days: number;
}
// 异常监控
export class ExceptionMonitor {
private static instance: ExceptionMonitor;
private exceptions: Map<string, ExceptionInfo> = new Map();
private eventBus: DomainEventBus;
private severityThresholds: Record<string, number> = {
low: 10,
medium: 5,
high: 2,
critical: 1
};
private constructor() {
this.eventBus = DomainEventBus.getInstance();
}
static getInstance(): ExceptionMonitor {
if (!ExceptionMonitor.instance) {
ExceptionMonitor.instance = new ExceptionMonitor();
}
return ExceptionMonitor.instance;
}
// 记录异常
async recordException(exception: Omit<ExceptionInfo, 'id' | 'status' | 'createdAt' | 'lastUpdated'>): Promise<ExceptionInfo> {
const id = `exception_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newException: ExceptionInfo = {
...exception,
id,
status: 'open',
createdAt: new Date(),
lastUpdated: new Date()
};
this.exceptions.set(id, newException);
this.eventBus.publish('exception.recorded', newException);
// 检查是否需要触发告警
await this.checkAlertThreshold(newException);
return newException;
}
// 获取异常信息
getException(exceptionId: string): ExceptionInfo | undefined {
return this.exceptions.get(exceptionId);
}
// 获取所有异常
getAllExceptions(filters?: {
severity?: string;
status?: string;
service?: string;
type?: string;
startDate?: Date;
endDate?: Date;
}): ExceptionInfo[] {
let result = Array.from(this.exceptions.values());
if (filters) {
if (filters.severity) {
result = result.filter(e => e.severity === filters.severity);
}
if (filters.status) {
result = result.filter(e => e.status === filters.status);
}
if (filters.service) {
result = result.filter(e => e.service === filters.service);
}
if (filters.type) {
result = result.filter(e => e.type === filters.type);
}
if (filters.startDate) {
result = result.filter(e => e.createdAt >= filters.startDate!);
}
if (filters.endDate) {
result = result.filter(e => e.createdAt <= filters.endDate!);
}
}
return result.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
}
// 更新异常状态
async updateExceptionStatus(exceptionId: string, status: 'open' | 'processing' | 'resolved' | 'ignored', resolvedBy?: string): Promise<ExceptionInfo | null> {
const exception = this.exceptions.get(exceptionId);
if (!exception) {
return null;
}
const updatedException = {
...exception,
status,
lastUpdated: new Date(),
resolvedAt: status === 'resolved' ? new Date() : exception.resolvedAt,
resolvedBy: status === 'resolved' ? resolvedBy : exception.resolvedBy
};
this.exceptions.set(exceptionId, updatedException);
this.eventBus.publish('exception.status.updated', updatedException);
return updatedException;
}
// 更新异常信息
async updateException(exceptionId: string, updates: Partial<ExceptionInfo>): Promise<ExceptionInfo | null> {
const exception = this.exceptions.get(exceptionId);
if (!exception) {
return null;
}
const updatedException = {
...exception,
...updates,
lastUpdated: new Date()
};
this.exceptions.set(exceptionId, updatedException);
this.eventBus.publish('exception.updated', updatedException);
return updatedException;
}
// 检查告警阈值
private async checkAlertThreshold(exception: ExceptionInfo): Promise<void> {
const threshold = this.severityThresholds[exception.severity];
if (!threshold) return;
// 检查过去24小时内相同类型的异常数量
const last24Hours = new Date();
last24Hours.setHours(last24Hours.getHours() - 24);
const similarExceptions = Array.from(this.exceptions.values()).filter(e =>
e.type === exception.type &&
e.service === exception.service &&
e.createdAt >= last24Hours
);
if (similarExceptions.length >= threshold) {
this.eventBus.publish('exception.alert', {
exception,
count: similarExceptions.length,
threshold,
timestamp: new Date()
});
}
}
// 获取异常统计
getExceptionStats(): ExceptionStats {
const exceptions = Array.from(this.exceptions.values());
const total = exceptions.length;
const bySeverity = {
low: 0,
medium: 0,
high: 0,
critical: 0
};
const byStatus = {
open: 0,
processing: 0,
resolved: 0,
ignored: 0
};
const byService: Record<string, number> = {};
const byType: Record<string, number> = {};
let totalResolutionTime = 0;
let resolvedExceptions = 0;
const last24Hours = new Date();
last24Hours.setHours(last24Hours.getHours() - 24);
const last7Days = new Date();
last7Days.setDate(last7Days.getDate() - 7);
let exceptionsLast24Hours = 0;
let exceptionsLast7Days = 0;
for (const exception of exceptions) {
bySeverity[exception.severity]++;
byStatus[exception.status]++;
byService[exception.service] = (byService[exception.service] || 0) + 1;
byType[exception.type] = (byType[exception.type] || 0) + 1;
if (exception.status === 'resolved' && exception.resolvedAt) {
const resolutionTime = (exception.resolvedAt.getTime() - exception.createdAt.getTime()) / (1000 * 60); // 转换为分钟
totalResolutionTime += resolutionTime;
resolvedExceptions++;
}
if (exception.createdAt >= last24Hours) {
exceptionsLast24Hours++;
}
if (exception.createdAt >= last7Days) {
exceptionsLast7Days++;
}
}
const averageResolutionTime = resolvedExceptions > 0
? totalResolutionTime / resolvedExceptions
: 0;
return {
total,
bySeverity,
byStatus,
byService,
byType,
averageResolutionTime,
last24Hours: exceptionsLast24Hours,
last7Days: exceptionsLast7Days
};
}
// 获取服务异常统计
getServiceExceptionStats(service: string): ExceptionStats {
const serviceExceptions = Array.from(this.exceptions.values()).filter(e => e.service === service);
const total = serviceExceptions.length;
const bySeverity = {
low: 0,
medium: 0,
high: 0,
critical: 0
};
const byStatus = {
open: 0,
processing: 0,
resolved: 0,
ignored: 0
};
const byType: Record<string, number> = {};
let totalResolutionTime = 0;
let resolvedExceptions = 0;
const last24Hours = new Date();
last24Hours.setHours(last24Hours.getHours() - 24);
const last7Days = new Date();
last7Days.setDate(last7Days.getDate() - 7);
let exceptionsLast24Hours = 0;
let exceptionsLast7Days = 0;
for (const exception of serviceExceptions) {
bySeverity[exception.severity]++;
byStatus[exception.status]++;
byType[exception.type] = (byType[exception.type] || 0) + 1;
if (exception.status === 'resolved' && exception.resolvedAt) {
const resolutionTime = (exception.resolvedAt.getTime() - exception.createdAt.getTime()) / (1000 * 60); // 转换为分钟
totalResolutionTime += resolutionTime;
resolvedExceptions++;
}
if (exception.createdAt >= last24Hours) {
exceptionsLast24Hours++;
}
if (exception.createdAt >= last7Days) {
exceptionsLast7Days++;
}
}
const averageResolutionTime = resolvedExceptions > 0
? totalResolutionTime / resolvedExceptions
: 0;
return {
total,
bySeverity,
byStatus,
byService: { [service]: total },
byType,
averageResolutionTime,
last24Hours: exceptionsLast24Hours,
last7Days: exceptionsLast7Days
};
}
// 清理旧异常
async cleanupOldExceptions(days: number = 30): Promise<number> {
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - days);
let removedCount = 0;
for (const [id, exception] of this.exceptions.entries()) {
if (exception.createdAt < cutoffDate && exception.status === 'resolved') {
this.exceptions.delete(id);
removedCount++;
}
}
if (removedCount > 0) {
this.eventBus.publish('exception.cleanup', {
removedCount,
cutoffDate,
timestamp: new Date()
});
}
return removedCount;
}
// 生成异常报告
async generateExceptionReport(startDate: Date, endDate: Date): Promise<{
summary: ExceptionStats;
topExceptions: ExceptionInfo[];
serviceStats: Record<string, ExceptionStats>;
}> {
const filteredExceptions = Array.from(this.exceptions.values()).filter(
e => e.createdAt >= startDate && e.createdAt <= endDate
);
// 按频率排序的异常类型
const typeFrequency: Record<string, number> = {};
for (const exception of filteredExceptions) {
typeFrequency[exception.type] = (typeFrequency[exception.type] || 0) + 1;
}
const sortedTypes = Object.entries(typeFrequency)
.sort(([, a], [, b]) => b - a)
.slice(0, 10)
.map(([type]) => type);
const topExceptions = filteredExceptions
.filter(e => sortedTypes.includes(e.type))
.slice(0, 20);
// 按服务分组的统计
const serviceStats: Record<string, ExceptionStats> = {};
const services = Array.from(new Set(filteredExceptions.map(e => e.service)));
for (const service of services) {
serviceStats[service] = this.getServiceExceptionStats(service);
}
return {
summary: this.getExceptionStats(),
topExceptions,
serviceStats
};
}
// 设置严重性阈值
setSeverityThresholds(thresholds: Record<string, number>): void {
this.severityThresholds = {
...this.severityThresholds,
...thresholds
};
}
// 获取严重性阈值
getSeverityThresholds(): Record<string, number> {
return { ...this.severityThresholds };
}
}

View File

@@ -0,0 +1,398 @@
import { DomainEventBus } from '../runtime/DomainEventBus';
import { ExceptionInfo } from './ExceptionMonitor';
// 异常处理策略
export interface ExceptionHandlingStrategy {
id: string;
name: string;
description: string;
exceptionType: string;
severity: 'low' | 'medium' | 'high' | 'critical';
actions: ExceptionAction[];
enabled: boolean;
createdAt: Date;
lastUpdated: Date;
}
// 异常处理动作
export interface ExceptionAction {
type: 'retry' | 'fallback' | 'alert' | 'auto-fix' | 'escalate';
parameters?: Record<string, any>;
order: number;
}
// 异常处理结果
export interface ExceptionHandlingResult {
id: string;
exceptionId: string;
strategyId: string;
actions: {
type: string;
success: boolean;
message: string;
timestamp: Date;
}[];
overallStatus: 'success' | 'partial' | 'failure';
timestamp: Date;
}
// 智能异常处理
export class IntelligentExceptionHandler {
private static instance: IntelligentExceptionHandler;
private strategies: Map<string, ExceptionHandlingStrategy> = new Map();
private handlingResults: Map<string, ExceptionHandlingResult> = new Map();
private eventBus: DomainEventBus;
private constructor() {
this.eventBus = DomainEventBus.getInstance();
}
static getInstance(): IntelligentExceptionHandler {
if (!IntelligentExceptionHandler.instance) {
IntelligentExceptionHandler.instance = new IntelligentExceptionHandler();
}
return IntelligentExceptionHandler.instance;
}
// 创建异常处理策略
async createStrategy(strategy: Omit<ExceptionHandlingStrategy, 'id' | 'createdAt' | 'lastUpdated'>): Promise<ExceptionHandlingStrategy> {
const id = `strategy_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newStrategy: ExceptionHandlingStrategy = {
...strategy,
id,
createdAt: new Date(),
lastUpdated: new Date()
};
this.strategies.set(id, newStrategy);
this.eventBus.publish('exception.strategy.created', newStrategy);
return newStrategy;
}
// 获取异常处理策略
getStrategy(strategyId: string): ExceptionHandlingStrategy | undefined {
return this.strategies.get(strategyId);
}
// 获取所有异常处理策略
getAllStrategies(filters?: {
exceptionType?: string;
severity?: string;
enabled?: boolean;
}): ExceptionHandlingStrategy[] {
let result = Array.from(this.strategies.values());
if (filters) {
if (filters.exceptionType) {
result = result.filter(s => s.exceptionType === filters.exceptionType);
}
if (filters.severity) {
result = result.filter(s => s.severity === filters.severity);
}
if (filters.enabled !== undefined) {
result = result.filter(s => s.enabled === filters.enabled);
}
}
return result;
}
// 更新异常处理策略
async updateStrategy(strategyId: string, updates: Partial<ExceptionHandlingStrategy>): Promise<ExceptionHandlingStrategy | null> {
const strategy = this.strategies.get(strategyId);
if (!strategy) {
return null;
}
const updatedStrategy = {
...strategy,
...updates,
lastUpdated: new Date()
};
this.strategies.set(strategyId, updatedStrategy);
this.eventBus.publish('exception.strategy.updated', updatedStrategy);
return updatedStrategy;
}
// 启用/禁用异常处理策略
async toggleStrategy(strategyId: string, enabled: boolean): Promise<boolean> {
const strategy = this.strategies.get(strategyId);
if (!strategy) {
return false;
}
strategy.enabled = enabled;
strategy.lastUpdated = new Date();
this.strategies.set(strategyId, strategy);
this.eventBus.publish('exception.strategy.toggled', strategy);
return true;
}
// 处理异常
async handleException(exception: ExceptionInfo): Promise<ExceptionHandlingResult> {
// 查找匹配的策略
const strategies = this.getAllStrategies({
exceptionType: exception.type,
enabled: true
});
// 按严重性排序,选择最匹配的策略
strategies.sort((a, b) => {
const severityOrder = { critical: 4, high: 3, medium: 2, low: 1 };
return severityOrder[b.severity] - severityOrder[a.severity];
});
const strategy = strategies[0];
const actions: ExceptionHandlingResult['actions'] = [];
let overallStatus: 'success' | 'partial' | 'failure' = 'failure';
if (strategy) {
// 按顺序执行策略中的动作
const sortedActions = [...strategy.actions].sort((a, b) => a.order - b.order);
let successCount = 0;
for (const action of sortedActions) {
const result = await this.executeAction(action, exception);
actions.push(result);
if (result.success) {
successCount++;
}
}
if (successCount === sortedActions.length) {
overallStatus = 'success';
} else if (successCount > 0) {
overallStatus = 'partial';
}
} else {
// 默认动作:告警
const result = await this.executeAction({
type: 'alert',
order: 1
}, exception);
actions.push(result);
overallStatus = result.success ? 'success' : 'failure';
}
const handlingResult: ExceptionHandlingResult = {
id: `result_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
exceptionId: exception.id,
strategyId: strategy?.id || 'default',
actions,
overallStatus,
timestamp: new Date()
};
this.handlingResults.set(handlingResult.id, handlingResult);
this.eventBus.publish('exception.handled', handlingResult);
return handlingResult;
}
// 执行异常处理动作
private async executeAction(action: ExceptionAction, exception: ExceptionInfo): Promise<ExceptionHandlingResult['actions'][0]> {
try {
switch (action.type) {
case 'retry':
return await this.executeRetryAction(action, exception);
case 'fallback':
return await this.executeFallbackAction(action, exception);
case 'alert':
return await this.executeAlertAction(action, exception);
case 'auto-fix':
return await this.executeAutoFixAction(action, exception);
case 'escalate':
return await this.executeEscalateAction(action, exception);
default:
return {
type: action.type,
success: false,
message: `Unknown action type: ${action.type}`,
timestamp: new Date()
};
}
} catch (error) {
return {
type: action.type,
success: false,
message: error instanceof Error ? error.message : 'Unknown error',
timestamp: new Date()
};
}
}
// 执行重试动作
private async executeRetryAction(action: ExceptionAction, exception: ExceptionInfo): Promise<ExceptionHandlingResult['actions'][0]> {
const maxRetries = action.parameters?.maxRetries || 3;
const delayMs = action.parameters?.delayMs || 1000;
for (let i = 0; i < maxRetries; i++) {
try {
// 这里应该有实际的重试逻辑
// 暂时模拟重试
await new Promise(resolve => setTimeout(resolve, delayMs));
const success = Math.random() > 0.3; // 70% 成功率
if (success) {
return {
type: 'retry',
success: true,
message: `Successfully retried after ${i + 1} attempt(s)`,
timestamp: new Date()
};
}
} catch (error) {
// 重试失败,继续下一次
}
}
return {
type: 'retry',
success: false,
message: `Failed after ${maxRetries} attempts`,
timestamp: new Date()
};
}
// 执行回退动作
private async executeFallbackAction(action: ExceptionAction, exception: ExceptionInfo): Promise<ExceptionHandlingResult['actions'][0]> {
// 这里应该有实际的回退逻辑
// 暂时模拟回退
await new Promise(resolve => setTimeout(resolve, 500));
return {
type: 'fallback',
success: true,
message: 'Fallback executed successfully',
timestamp: new Date()
};
}
// 执行告警动作
private async executeAlertAction(action: ExceptionAction, exception: ExceptionInfo): Promise<ExceptionHandlingResult['actions'][0]> {
// 这里应该有实际的告警逻辑
// 暂时模拟告警
await new Promise(resolve => setTimeout(resolve, 200));
this.eventBus.publish('exception.alert', {
exception,
timestamp: new Date()
});
return {
type: 'alert',
success: true,
message: 'Alert sent successfully',
timestamp: new Date()
};
}
// 执行自动修复动作
private async executeAutoFixAction(action: ExceptionAction, exception: ExceptionInfo): Promise<ExceptionHandlingResult['actions'][0]> {
// 这里应该有实际的自动修复逻辑
// 暂时模拟自动修复
await new Promise(resolve => setTimeout(resolve, 1000));
const success = Math.random() > 0.2; // 80% 成功率
return {
type: 'auto-fix',
success,
message: success ? 'Auto-fix executed successfully' : 'Auto-fix failed',
timestamp: new Date()
};
}
// 执行升级动作
private async executeEscalateAction(action: ExceptionAction, exception: ExceptionInfo): Promise<ExceptionHandlingResult['actions'][0]> {
// 这里应该有实际的升级逻辑
// 暂时模拟升级
await new Promise(resolve => setTimeout(resolve, 300));
this.eventBus.publish('exception.escalated', {
exception,
timestamp: new Date()
});
return {
type: 'escalate',
success: true,
message: 'Exception escalated successfully',
timestamp: new Date()
};
}
// 获取异常处理结果
getHandlingResult(resultId: string): ExceptionHandlingResult | undefined {
return this.handlingResults.get(resultId);
}
// 获取异常的处理结果
getExceptionHandlingResults(exceptionId: string): ExceptionHandlingResult[] {
return Array.from(this.handlingResults.values()).filter(r => r.exceptionId === exceptionId);
}
// 获取策略的处理结果
getStrategyHandlingResults(strategyId: string): ExceptionHandlingResult[] {
return Array.from(this.handlingResults.values()).filter(r => r.strategyId === strategyId);
}
// 批量处理异常
async batchHandleExceptions(exceptionIds: string[], exceptionMonitor: any): Promise<ExceptionHandlingResult[]> {
const results: ExceptionHandlingResult[] = [];
for (const exceptionId of exceptionIds) {
const exception = exceptionMonitor.getException(exceptionId);
if (exception) {
const result = await this.handleException(exception);
results.push(result);
}
}
return results;
}
// 生成异常处理报告
async generateHandlingReport(startDate: Date, endDate: Date): Promise<{
summary: {
totalExceptions: number;
successfullyHandled: number;
partiallyHandled: number;
failedHandled: number;
mostUsedStrategies: string[];
};
details: ExceptionHandlingResult[];
}> {
const filteredResults = Array.from(this.handlingResults.values()).filter(
r => r.timestamp >= startDate && r.timestamp <= endDate
);
const successfullyHandled = filteredResults.filter(r => r.overallStatus === 'success').length;
const partiallyHandled = filteredResults.filter(r => r.overallStatus === 'partial').length;
const failedHandled = filteredResults.filter(r => r.overallStatus === 'failure').length;
// 统计最常用的策略
const strategyUsage: Record<string, number> = {};
for (const result of filteredResults) {
strategyUsage[result.strategyId] = (strategyUsage[result.strategyId] || 0) + 1;
}
const mostUsedStrategies = Object.entries(strategyUsage)
.sort(([, a], [, b]) => b - a)
.slice(0, 5)
.map(([strategyId]) => strategyId);
return {
summary: {
totalExceptions: filteredResults.length,
successfullyHandled,
partiallyHandled,
failedHandled,
mostUsedStrategies
},
details: filteredResults
};
}
}

View File

@@ -0,0 +1,272 @@
import { DomainEventBus } from '../runtime/DomainEventBus';
import { ServiceRegistry } from '../orchestrator/ServiceRegistry';
// 开发者信息
export interface Developer {
id: string;
name: string;
email: string;
apiKey: string;
createdAt: Date;
lastActive: Date;
status: 'active' | 'inactive' | 'suspended';
permissions: string[];
metadata?: Record<string, any>;
}
// 插件信息
export interface Plugin {
id: string;
name: string;
version: string;
description: string;
developerId: string;
type: 'adapter' | 'service' | 'UI' | 'integration';
status: 'pending' | 'approved' | 'rejected' | 'published';
dependencies: string[];
entryPoint: string;
createdAt: Date;
lastUpdated: Date;
metadata?: Record<string, any>;
}
// API密钥
export interface ApiKey {
id: string;
developerId: string;
key: string;
name: string;
permissions: string[];
createdAt: Date;
expiresAt: Date;
status: 'active' | 'revoked' | 'expired';
}
// 开发者平台
export class DeveloperPlatform {
private static instance: DeveloperPlatform;
private developers: Map<string, Developer> = new Map();
private plugins: Map<string, Plugin> = new Map();
private apiKeys: Map<string, ApiKey> = new Map();
private serviceRegistry: ServiceRegistry;
private eventBus: DomainEventBus;
private constructor() {
this.serviceRegistry = ServiceRegistry.getInstance();
this.eventBus = DomainEventBus.getInstance();
}
static getInstance(): DeveloperPlatform {
if (!DeveloperPlatform.instance) {
DeveloperPlatform.instance = new DeveloperPlatform();
}
return DeveloperPlatform.instance;
}
// 注册开发者
async registerDeveloper(developer: Omit<Developer, 'id' | 'createdAt' | 'lastActive' | 'apiKey'>): Promise<Developer> {
const id = `dev_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const apiKey = this.generateApiKey();
const newDeveloper: Developer = {
...developer,
id,
apiKey,
createdAt: new Date(),
lastActive: new Date()
};
this.developers.set(id, newDeveloper);
this.eventBus.publish('developer.registered', newDeveloper);
return newDeveloper;
}
// 获取开发者信息
getDeveloper(developerId: string): Developer | undefined {
return this.developers.get(developerId);
}
// 获取所有开发者
getAllDevelopers(): Developer[] {
return Array.from(this.developers.values());
}
// 更新开发者信息
async updateDeveloper(developerId: string, updates: Partial<Developer>): Promise<Developer | null> {
const developer = this.developers.get(developerId);
if (!developer) {
return null;
}
const updatedDeveloper = {
...developer,
...updates,
lastActive: new Date()
};
this.developers.set(developerId, updatedDeveloper);
this.eventBus.publish('developer.updated', updatedDeveloper);
return updatedDeveloper;
}
// 停用开发者
async deactivateDeveloper(developerId: string): Promise<boolean> {
const developer = this.developers.get(developerId);
if (!developer) {
return false;
}
developer.status = 'inactive';
developer.lastActive = new Date();
this.developers.set(developerId, developer);
this.eventBus.publish('developer.deactivated', developer);
return true;
}
// 注册插件
async registerPlugin(plugin: Omit<Plugin, 'id' | 'createdAt' | 'lastUpdated' | 'status'>): Promise<Plugin> {
const id = `plugin_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newPlugin: Plugin = {
...plugin,
id,
status: 'pending',
createdAt: new Date(),
lastUpdated: new Date()
};
this.plugins.set(id, newPlugin);
this.eventBus.publish('plugin.registered', newPlugin);
return newPlugin;
}
// 获取插件信息
getPlugin(pluginId: string): Plugin | undefined {
return this.plugins.get(pluginId);
}
// 获取所有插件
getAllPlugins(): Plugin[] {
return Array.from(this.plugins.values());
}
// 获取开发者的插件
getDeveloperPlugins(developerId: string): Plugin[] {
return Array.from(this.plugins.values()).filter(p => p.developerId === developerId);
}
// 审核插件
async reviewPlugin(pluginId: string, status: 'approved' | 'rejected', reason?: string): Promise<Plugin | null> {
const plugin = this.plugins.get(pluginId);
if (!plugin) {
return null;
}
plugin.status = status;
plugin.lastUpdated = new Date();
if (reason) {
plugin.metadata = {
...plugin.metadata,
reviewReason: reason
};
}
this.plugins.set(pluginId, plugin);
this.eventBus.publish('plugin.reviewed', plugin);
if (status === 'approved') {
// 发布插件
plugin.status = 'published';
this.eventBus.publish('plugin.published', plugin);
}
return plugin;
}
// 生成API密钥
async generateApiKey(developerId: string, name: string, permissions: string[], expiresInDays: number = 365): Promise<ApiKey> {
const developer = this.developers.get(developerId);
if (!developer) {
throw new Error('Developer not found');
}
const id = `apikey_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const key = this.generateApiKey();
const expiresAt = new Date();
expiresAt.setDate(expiresAt.getDate() + expiresInDays);
const apiKey: ApiKey = {
id,
developerId,
key,
name,
permissions,
createdAt: new Date(),
expiresAt,
status: 'active'
};
this.apiKeys.set(id, apiKey);
this.eventBus.publish('apiKey.created', apiKey);
return apiKey;
}
// 验证API密钥
validateApiKey(apiKey: string): ApiKey | null {
const key = Array.from(this.apiKeys.values()).find(k => k.key === apiKey && k.status === 'active' && k.expiresAt > new Date());
return key || null;
}
// 撤销API密钥
async revokeApiKey(apiKeyId: string): Promise<boolean> {
const apiKey = this.apiKeys.get(apiKeyId);
if (!apiKey) {
return false;
}
apiKey.status = 'revoked';
this.apiKeys.set(apiKeyId, apiKey);
this.eventBus.publish('apiKey.revoked', apiKey);
return true;
}
// 获取开发者的API密钥
getDeveloperApiKeys(developerId: string): ApiKey[] {
return Array.from(this.apiKeys.values()).filter(k => k.developerId === developerId);
}
// 生成API密钥
private generateApiKey(): string {
return `sk_${Math.random().toString(36).substr(2, 32)}`;
}
// 导入插件
async importPlugin(pluginData: any): Promise<Plugin> {
// 这里应该有插件导入逻辑
// 暂时返回一个模拟的插件
return this.registerPlugin({
name: pluginData.name,
version: pluginData.version,
description: pluginData.description,
developerId: pluginData.developerId,
type: pluginData.type || 'service',
dependencies: pluginData.dependencies || [],
entryPoint: pluginData.entryPoint
});
}
// 导出插件
async exportPlugin(pluginId: string): Promise<any> {
const plugin = this.plugins.get(pluginId);
if (!plugin) {
throw new Error('Plugin not found');
}
// 这里应该有插件导出逻辑
// 暂时返回插件信息
return {
...plugin,
developer: this.developers.get(plugin.developerId)
};
}
}

View File

@@ -0,0 +1,361 @@
import { DomainEventBus } from '../runtime/DomainEventBus';
import { ServiceRegistry } from '../orchestrator/ServiceRegistry';
import { ServiceOrchestrator } from '../orchestrator/ServiceOrchestrator';
// 服务治理规则
export interface GovernanceRule {
id: string;
name: string;
description: string;
type: 'performance' | 'security' | 'compliance' | 'availability';
severity: 'low' | 'medium' | 'high' | 'critical';
condition: string; // 规则条件
action: 'alert' | 'block' | 'auto-fix';
createdAt: Date;
lastUpdated: Date;
enabled: boolean;
}
// 服务治理事件
export interface GovernanceEvent {
id: string;
serviceId: string;
ruleId: string;
severity: 'low' | 'medium' | 'high' | 'critical';
message: string;
timestamp: Date;
status: 'open' | 'resolved' | 'ignored';
metadata?: Record<string, any>;
}
// 服务配额
export interface ServiceQuota {
serviceId: string;
maxRequestsPerSecond: number;
maxConcurrentRequests: number;
maxMemoryUsage: number; // MB
maxCpuUsage: number; // %
createdAt: Date;
lastUpdated: Date;
}
// 服务治理
export class ServiceGovernance {
private static instance: ServiceGovernance;
private rules: Map<string, GovernanceRule> = new Map();
private events: Map<string, GovernanceEvent> = new Map();
private quotas: Map<string, ServiceQuota> = new Map();
private serviceRegistry: ServiceRegistry;
private serviceOrchestrator: ServiceOrchestrator;
private eventBus: DomainEventBus;
private constructor() {
this.serviceRegistry = ServiceRegistry.getInstance();
this.serviceOrchestrator = ServiceOrchestrator.getInstance();
this.eventBus = DomainEventBus.getInstance();
}
static getInstance(): ServiceGovernance {
if (!ServiceGovernance.instance) {
ServiceGovernance.instance = new ServiceGovernance();
}
return ServiceGovernance.instance;
}
// 创建治理规则
async createRule(rule: Omit<GovernanceRule, 'id' | 'createdAt' | 'lastUpdated'>): Promise<GovernanceRule> {
const id = `rule_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newRule: GovernanceRule = {
...rule,
id,
createdAt: new Date(),
lastUpdated: new Date()
};
this.rules.set(id, newRule);
this.eventBus.publish('governance.rule.created', newRule);
return newRule;
}
// 获取规则信息
getRule(ruleId: string): GovernanceRule | undefined {
return this.rules.get(ruleId);
}
// 获取所有规则
getAllRules(filters?: {
type?: string;
severity?: string;
enabled?: boolean;
}): GovernanceRule[] {
let result = Array.from(this.rules.values());
if (filters) {
if (filters.type) {
result = result.filter(r => r.type === filters.type);
}
if (filters.severity) {
result = result.filter(r => r.severity === filters.severity);
}
if (filters.enabled !== undefined) {
result = result.filter(r => r.enabled === filters.enabled);
}
}
return result;
}
// 更新规则
async updateRule(ruleId: string, updates: Partial<GovernanceRule>): Promise<GovernanceRule | null> {
const rule = this.rules.get(ruleId);
if (!rule) {
return null;
}
const updatedRule = {
...rule,
...updates,
lastUpdated: new Date()
};
this.rules.set(ruleId, updatedRule);
this.eventBus.publish('governance.rule.updated', updatedRule);
return updatedRule;
}
// 启用/禁用规则
async toggleRule(ruleId: string, enabled: boolean): Promise<boolean> {
const rule = this.rules.get(ruleId);
if (!rule) {
return false;
}
rule.enabled = enabled;
rule.lastUpdated = new Date();
this.rules.set(ruleId, rule);
this.eventBus.publish('governance.rule.toggled', rule);
return true;
}
// 删除规则
async deleteRule(ruleId: string): Promise<boolean> {
const rule = this.rules.get(ruleId);
if (!rule) {
return false;
}
this.rules.delete(ruleId);
this.eventBus.publish('governance.rule.deleted', rule);
return true;
}
// 创建治理事件
async createEvent(event: Omit<GovernanceEvent, 'id' | 'timestamp' | 'status'>): Promise<GovernanceEvent> {
const id = `event_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newEvent: GovernanceEvent = {
...event,
id,
timestamp: new Date(),
status: 'open'
};
this.events.set(id, newEvent);
this.eventBus.publish('governance.event.created', newEvent);
return newEvent;
}
// 获取事件信息
getEvent(eventId: string): GovernanceEvent | undefined {
return this.events.get(eventId);
}
// 获取所有事件
getAllEvents(filters?: {
serviceId?: string;
ruleId?: string;
severity?: string;
status?: string;
startDate?: Date;
endDate?: Date;
}): GovernanceEvent[] {
let result = Array.from(this.events.values());
if (filters) {
if (filters.serviceId) {
result = result.filter(e => e.serviceId === filters.serviceId);
}
if (filters.ruleId) {
result = result.filter(e => e.ruleId === filters.ruleId);
}
if (filters.severity) {
result = result.filter(e => e.severity === filters.severity);
}
if (filters.status) {
result = result.filter(e => e.status === filters.status);
}
if (filters.startDate) {
result = result.filter(e => e.timestamp >= filters.startDate!);
}
if (filters.endDate) {
result = result.filter(e => e.timestamp <= filters.endDate!);
}
}
return result;
}
// 解决事件
async resolveEvent(eventId: string, resolution: string): Promise<boolean> {
const event = this.events.get(eventId);
if (!event) {
return false;
}
event.status = 'resolved';
event.metadata = {
...event.metadata,
resolution
};
this.events.set(eventId, event);
this.eventBus.publish('governance.event.resolved', event);
return true;
}
// 忽略事件
async ignoreEvent(eventId: string, reason: string): Promise<boolean> {
const event = this.events.get(eventId);
if (!event) {
return false;
}
event.status = 'ignored';
event.metadata = {
...event.metadata,
ignoreReason: reason
};
this.events.set(eventId, event);
this.eventBus.publish('governance.event.ignored', event);
return true;
}
// 设置服务配额
async setServiceQuota(quota: Omit<ServiceQuota, 'createdAt' | 'lastUpdated'>): Promise<ServiceQuota> {
const existingQuota = this.quotas.get(quota.serviceId);
const newQuota: ServiceQuota = {
...quota,
createdAt: existingQuota?.createdAt || new Date(),
lastUpdated: new Date()
};
this.quotas.set(quota.serviceId, newQuota);
this.eventBus.publish('governance.quota.set', newQuota);
return newQuota;
}
// 获取服务配额
getServiceQuota(serviceId: string): ServiceQuota | undefined {
return this.quotas.get(serviceId);
}
// 获取所有服务配额
getAllServiceQuotas(): ServiceQuota[] {
return Array.from(this.quotas.values());
}
// 检查服务是否符合治理规则
async checkServiceCompliance(serviceId: string): Promise<{
compliant: boolean;
violations: GovernanceEvent[];
}> {
const service = this.serviceRegistry.getService(serviceId);
if (!service) {
throw new Error('Service not found');
}
const violations: GovernanceEvent[] = [];
const enabledRules = this.getAllRules({ enabled: true });
for (const rule of enabledRules) {
// 这里应该有实际的规则检查逻辑
// 暂时模拟检查
const isViolation = Math.random() < 0.1; // 10% 概率违反规则
if (isViolation) {
const violation = await this.createEvent({
serviceId,
ruleId: rule.id,
severity: rule.severity,
message: `Service ${serviceId} violates rule ${rule.name}`
});
violations.push(violation);
}
}
return {
compliant: violations.length === 0,
violations
};
}
// 执行服务治理检查
async runGovernanceCheck(): Promise<{
totalServices: number;
compliantServices: number;
violations: GovernanceEvent[];
}> {
const services = this.serviceRegistry.getAllServices();
const violations: GovernanceEvent[] = [];
let compliantCount = 0;
for (const service of services) {
const result = await this.checkServiceCompliance(service.id);
if (result.compliant) {
compliantCount++;
} else {
violations.push(...result.violations);
}
}
return {
totalServices: services.length,
compliantServices: compliantCount,
violations
};
}
// 获取治理统计信息
getGovernanceStats(): {
totalRules: number;
enabledRules: number;
totalEvents: number;
openEvents: number;
resolvedEvents: number;
ignoredEvents: number;
compliantServices: number;
totalServices: number;
} {
const totalServices = this.serviceRegistry.getAllServices().length;
const compliantServices = 0; // 这里应该计算实际的合规服务数量
return {
totalRules: this.rules.size,
enabledRules: Array.from(this.rules.values()).filter(r => r.enabled).length,
totalEvents: this.events.size,
openEvents: Array.from(this.events.values()).filter(e => e.status === 'open').length,
resolvedEvents: Array.from(this.events.values()).filter(e => e.status === 'resolved').length,
ignoredEvents: Array.from(this.events.values()).filter(e => e.status === 'ignored').length,
compliantServices,
totalServices
};
}
}

View File

@@ -0,0 +1,323 @@
import { DomainEventBus } from '../runtime/DomainEventBus';
// 策略信息
export interface Strategy {
id: string;
name: string;
description: string;
type: 'pricing' | 'product_selection' | 'marketing' | 'logistics' | 'risk';
version: string;
developerId: string;
price: number;
rating: number;
usageCount: number;
status: 'draft' | 'published' | 'archived';
tags: string[];
createdAt: Date;
lastUpdated: Date;
metadata?: Record<string, any>;
}
// 策略订阅
export interface StrategySubscription {
id: string;
strategyId: string;
merchantId: string;
status: 'active' | 'expired' | 'cancelled';
startDate: Date;
endDate: Date;
price: number;
metadata?: Record<string, any>;
}
// 策略评价
export interface StrategyReview {
id: string;
strategyId: string;
merchantId: string;
rating: number; // 1-5
comment: string;
createdAt: Date;
metadata?: Record<string, any>;
}
// 策略市场
export class StrategyMarketplace {
private static instance: StrategyMarketplace;
private strategies: Map<string, Strategy> = new Map();
private subscriptions: Map<string, StrategySubscription> = new Map();
private reviews: Map<string, StrategyReview> = new Map();
private eventBus: DomainEventBus;
private constructor() {
this.eventBus = DomainEventBus.getInstance();
}
static getInstance(): StrategyMarketplace {
if (!StrategyMarketplace.instance) {
StrategyMarketplace.instance = new StrategyMarketplace();
}
return StrategyMarketplace.instance;
}
// 发布策略
async publishStrategy(strategy: Omit<Strategy, 'id' | 'rating' | 'usageCount' | 'status' | 'createdAt' | 'lastUpdated'>): Promise<Strategy> {
const id = `strategy_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newStrategy: Strategy = {
...strategy,
id,
rating: 0,
usageCount: 0,
status: 'published',
createdAt: new Date(),
lastUpdated: new Date()
};
this.strategies.set(id, newStrategy);
this.eventBus.publish('strategy.published', newStrategy);
return newStrategy;
}
// 获取策略信息
getStrategy(strategyId: string): Strategy | undefined {
return this.strategies.get(strategyId);
}
// 获取所有策略
getAllStrategies(filters?: {
type?: string;
tags?: string[];
minRating?: number;
maxPrice?: number;
}): Strategy[] {
let result = Array.from(this.strategies.values());
if (filters) {
if (filters.type) {
result = result.filter(s => s.type === filters.type);
}
if (filters.tags && filters.tags.length > 0) {
result = result.filter(s => filters.tags!.some(tag => s.tags.includes(tag)));
}
if (filters.minRating !== undefined) {
result = result.filter(s => s.rating >= filters.minRating!);
}
if (filters.maxPrice !== undefined) {
result = result.filter(s => s.price <= filters.maxPrice!);
}
}
return result;
}
// 获取开发者的策略
getDeveloperStrategies(developerId: string): Strategy[] {
return Array.from(this.strategies.values()).filter(s => s.developerId === developerId);
}
// 更新策略
async updateStrategy(strategyId: string, updates: Partial<Strategy>): Promise<Strategy | null> {
const strategy = this.strategies.get(strategyId);
if (!strategy) {
return null;
}
const updatedStrategy = {
...strategy,
...updates,
lastUpdated: new Date()
};
this.strategies.set(strategyId, updatedStrategy);
this.eventBus.publish('strategy.updated', updatedStrategy);
return updatedStrategy;
}
// 归档策略
async archiveStrategy(strategyId: string): Promise<boolean> {
const strategy = this.strategies.get(strategyId);
if (!strategy) {
return false;
}
strategy.status = 'archived';
strategy.lastUpdated = new Date();
this.strategies.set(strategyId, strategy);
this.eventBus.publish('strategy.archived', strategy);
return true;
}
// 订阅策略
async subscribeToStrategy(strategyId: string, merchantId: string, durationDays: number = 30): Promise<StrategySubscription> {
const strategy = this.strategies.get(strategyId);
if (!strategy || strategy.status !== 'published') {
throw new Error('Strategy not available');
}
const id = `sub_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const startDate = new Date();
const endDate = new Date();
endDate.setDate(endDate.getDate() + durationDays);
const subscription: StrategySubscription = {
id,
strategyId,
merchantId,
status: 'active',
startDate,
endDate,
price: strategy.price * (durationDays / 30)
};
this.subscriptions.set(id, subscription);
// 更新策略使用次数
strategy.usageCount++;
this.strategies.set(strategyId, strategy);
this.eventBus.publish('strategy.subscribed', subscription);
return subscription;
}
// 获取订阅信息
getSubscription(subscriptionId: string): StrategySubscription | undefined {
return this.subscriptions.get(subscriptionId);
}
// 获取商户的订阅
getMerchantSubscriptions(merchantId: string): StrategySubscription[] {
return Array.from(this.subscriptions.values()).filter(s => s.merchantId === merchantId);
}
// 获取策略的订阅
getStrategySubscriptions(strategyId: string): StrategySubscription[] {
return Array.from(this.subscriptions.values()).filter(s => s.strategyId === strategyId);
}
// 取消订阅
async cancelSubscription(subscriptionId: string): Promise<boolean> {
const subscription = this.subscriptions.get(subscriptionId);
if (!subscription) {
return false;
}
subscription.status = 'cancelled';
this.subscriptions.set(subscriptionId, subscription);
this.eventBus.publish('subscription.cancelled', subscription);
return true;
}
// 评价策略
async reviewStrategy(strategyId: string, merchantId: string, rating: number, comment: string): Promise<StrategyReview> {
const strategy = this.strategies.get(strategyId);
if (!strategy) {
throw new Error('Strategy not found');
}
// 检查商户是否订阅过该策略
const hasSubscription = Array.from(this.subscriptions.values()).some(
s => s.strategyId === strategyId && s.merchantId === merchantId
);
if (!hasSubscription) {
throw new Error('Merchant has not subscribed to this strategy');
}
const id = `review_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const review: StrategyReview = {
id,
strategyId,
merchantId,
rating,
comment,
createdAt: new Date()
};
this.reviews.set(id, review);
// 更新策略评分
this.updateStrategyRating(strategyId);
this.eventBus.publish('strategy.reviewed', review);
return review;
}
// 获取策略的评价
getStrategyReviews(strategyId: string): StrategyReview[] {
return Array.from(this.reviews.values()).filter(r => r.strategyId === strategyId);
}
// 更新策略评分
private updateStrategyRating(strategyId: string): void {
const reviews = this.getStrategyReviews(strategyId);
if (reviews.length === 0) {
return;
}
const totalRating = reviews.reduce((sum, review) => sum + review.rating, 0);
const averageRating = totalRating / reviews.length;
const strategy = this.strategies.get(strategyId);
if (strategy) {
strategy.rating = averageRating;
strategy.lastUpdated = new Date();
this.strategies.set(strategyId, strategy);
}
}
// 搜索策略
searchStrategies(query: string, filters?: {
type?: string;
minRating?: number;
maxPrice?: number;
}): Strategy[] {
let result = Array.from(this.strategies.values());
// 关键词搜索
if (query) {
const lowerQuery = query.toLowerCase();
result = result.filter(s =>
s.name.toLowerCase().includes(lowerQuery) ||
s.description.toLowerCase().includes(lowerQuery) ||
s.tags.some(tag => tag.toLowerCase().includes(lowerQuery))
);
}
// 应用过滤器
if (filters) {
if (filters.type) {
result = result.filter(s => s.type === filters.type);
}
if (filters.minRating !== undefined) {
result = result.filter(s => s.rating >= filters.minRating!);
}
if (filters.maxPrice !== undefined) {
result = result.filter(s => s.price <= filters.maxPrice!);
}
}
return result;
}
// 获取热门策略
getPopularStrategies(limit: number = 10): Strategy[] {
return Array.from(this.strategies.values())
.filter(s => s.status === 'published')
.sort((a, b) => b.usageCount - a.usageCount)
.slice(0, limit);
}
// 获取推荐策略
getRecommendedStrategies(merchantId: string, limit: number = 5): Strategy[] {
// 这里应该有推荐算法
// 暂时返回热门策略
return this.getPopularStrategies(limit);
}
}

View File

@@ -0,0 +1,266 @@
import { DomainEventBus } from '../runtime/DomainEventBus';
import { ServiceOrchestrator, ServiceStatus } from './ServiceOrchestrator';
import { ServiceRegistry } from './ServiceRegistry';
// 服务监控指标
export interface ServiceMetrics {
serviceId: string;
status: ServiceStatus;
responseTime: number; // 毫秒
errorRate: number; // 错误率
throughput: number; // 每秒请求数
lastHealthCheck: Date;
uptime: number; // 秒
memoryUsage?: number; // 内存使用量MB
cpuUsage?: number; // CPU使用率%
}
// 服务监控配置
export interface MonitorConfig {
healthCheckInterval: number; // 健康检查间隔(毫秒)
metricsCollectionInterval: number; // 指标收集间隔(毫秒)
alertThresholds: {
errorRate: number;
responseTime: number;
uptime: number;
};
}
// 服务监控器
export class ServiceMonitor {
private static instance: ServiceMonitor;
private serviceOrchestrator: ServiceOrchestrator;
private serviceRegistry: ServiceRegistry;
private eventBus: DomainEventBus;
private metrics: Map<string, ServiceMetrics> = new Map();
private config: MonitorConfig;
private healthCheckTimers: Map<string, NodeJS.Timeout> = new Map();
private metricsCollectionTimer: NodeJS.Timeout | null = null;
private constructor() {
this.serviceOrchestrator = ServiceOrchestrator.getInstance();
this.serviceRegistry = ServiceRegistry.getInstance();
this.eventBus = DomainEventBus.getInstance();
this.config = {
healthCheckInterval: 30000, // 30秒
metricsCollectionInterval: 60000, // 60秒
alertThresholds: {
errorRate: 0.1, // 10%
responseTime: 1000, // 1秒
uptime: 86400, // 24小时
}
};
}
static getInstance(): ServiceMonitor {
if (!ServiceMonitor.instance) {
ServiceMonitor.instance = new ServiceMonitor();
}
return ServiceMonitor.instance;
}
// 启动监控
startMonitoring(): void {
// 启动指标收集
this.startMetricsCollection();
// 为每个服务启动健康检查
for (const service of this.serviceRegistry.getAllServices()) {
this.startHealthCheck(service.id);
}
// 监听服务注册事件
this.eventBus.subscribe('service.registered', (data: { serviceId: string }) => {
this.startHealthCheck(data.serviceId);
});
// 监听服务状态变更事件
this.eventBus.subscribe('service.started', (data: { serviceId: string }) => {
this.updateMetrics(data.serviceId);
});
this.eventBus.subscribe('service.stopped', (data: { serviceId: string }) => {
this.updateMetrics(data.serviceId);
});
this.eventBus.subscribe('service.error', (data: { serviceId: string, error: string }) => {
this.updateMetrics(data.serviceId);
this.sendAlert(data.serviceId, `Service error: ${data.error}`);
});
this.eventBus.subscribe('service.recovered', (data: { serviceId: string }) => {
this.updateMetrics(data.serviceId);
this.sendAlert(data.serviceId, 'Service recovered', 'info');
});
}
// 停止监控
stopMonitoring(): void {
// 停止健康检查
for (const [serviceId, timer] of this.healthCheckTimers) {
clearInterval(timer);
}
this.healthCheckTimers.clear();
// 停止指标收集
if (this.metricsCollectionTimer) {
clearInterval(this.metricsCollectionTimer);
this.metricsCollectionTimer = null;
}
}
// 启动健康检查
private startHealthCheck(serviceId: string): void {
if (this.healthCheckTimers.has(serviceId)) {
return;
}
const timer = setInterval(async () => {
try {
const healthy = await this.serviceOrchestrator.healthCheck(serviceId);
if (!healthy) {
this.sendAlert(serviceId, 'Service health check failed');
}
} catch (error) {
console.error(`Error checking health for service ${serviceId}:`, error);
}
}, this.config.healthCheckInterval);
this.healthCheckTimers.set(serviceId, timer);
}
// 停止健康检查
private stopHealthCheck(serviceId: string): void {
const timer = this.healthCheckTimers.get(serviceId);
if (timer) {
clearInterval(timer);
this.healthCheckTimers.delete(serviceId);
}
}
// 启动指标收集
private startMetricsCollection(): void {
if (this.metricsCollectionTimer) {
return;
}
this.metricsCollectionTimer = setInterval(() => {
this.collectMetrics();
}, this.config.metricsCollectionInterval);
}
// 收集指标
private collectMetrics(): void {
for (const service of this.serviceRegistry.getAllServices()) {
this.updateMetrics(service.id);
}
}
// 更新指标
private updateMetrics(serviceId: string): void {
const status = this.serviceOrchestrator.getServiceStatus(serviceId);
if (!status) {
return;
}
const currentMetrics = this.metrics.get(serviceId) || {
serviceId,
status: 'stopped' as ServiceStatus,
responseTime: 0,
errorRate: 0,
throughput: 0,
lastHealthCheck: new Date(),
uptime: 0
};
const newMetrics: ServiceMetrics = {
...currentMetrics,
status,
lastHealthCheck: new Date(),
// 这里应该有实际的指标收集逻辑
// 暂时使用模拟数据
responseTime: Math.random() * 500,
errorRate: Math.random() * 0.05,
throughput: Math.random() * 100,
uptime: currentMetrics.uptime + (this.config.metricsCollectionInterval / 1000)
};
this.metrics.set(serviceId, newMetrics);
// 检查是否需要告警
this.checkAlertThresholds(newMetrics);
// 发布指标更新事件
this.eventBus.publish('service.metrics.updated', newMetrics);
}
// 检查告警阈值
private checkAlertThresholds(metrics: ServiceMetrics): void {
if (metrics.errorRate > this.config.alertThresholds.errorRate) {
this.sendAlert(metrics.serviceId, `High error rate: ${(metrics.errorRate * 100).toFixed(2)}%`);
}
if (metrics.responseTime > this.config.alertThresholds.responseTime) {
this.sendAlert(metrics.serviceId, `High response time: ${metrics.responseTime.toFixed(2)}ms`);
}
if (metrics.uptime < this.config.alertThresholds.uptime) {
this.sendAlert(metrics.serviceId, `Low uptime: ${(metrics.uptime / 3600).toFixed(2)} hours`);
}
}
// 发送告警
private sendAlert(serviceId: string, message: string, level: 'error' | 'warning' | 'info' = 'error'): void {
console.log(`[${level.toUpperCase()}] Service ${serviceId}: ${message}`);
this.eventBus.publish('service.alert', { serviceId, message, level, timestamp: new Date() });
}
// 获取服务指标
getServiceMetrics(serviceId: string): ServiceMetrics | undefined {
return this.metrics.get(serviceId);
}
// 获取所有服务指标
getAllServiceMetrics(): ServiceMetrics[] {
return Array.from(this.metrics.values());
}
// 获取服务健康状态
getServiceHealth(serviceId: string): 'healthy' | 'unhealthy' | 'unknown' {
const metrics = this.metrics.get(serviceId);
if (!metrics) {
return 'unknown';
}
if (metrics.status === 'running' && metrics.errorRate < 0.05 && metrics.responseTime < 500) {
return 'healthy';
}
return 'unhealthy';
}
// 获取所有服务健康状态
getAllServiceHealth(): Map<string, 'healthy' | 'unhealthy' | 'unknown'> {
const healthStatus = new Map<string, 'healthy' | 'unhealthy' | 'unknown'>();
for (const service of this.serviceRegistry.getAllServices()) {
healthStatus.set(service.id, this.getServiceHealth(service.id));
}
return healthStatus;
}
// 设置监控配置
setConfig(config: Partial<MonitorConfig>): void {
this.config = {
...this.config,
...config
};
}
// 获取监控配置
getConfig(): MonitorConfig {
return { ...this.config };
}
}

View File

@@ -0,0 +1,261 @@
import { DomainEventBus } from '../runtime/DomainEventBus';
import { ServiceRegistry } from './ServiceRegistry';
import { ServiceMonitor } from './ServiceMonitor';
// 服务类型定义
export interface ServiceDefinition {
id: string;
name: string;
version: string;
dependencies: string[];
healthCheck: () => Promise<boolean>;
start: () => Promise<void>;
stop: () => Promise<void>;
metadata?: Record<string, any>;
}
// 服务状态
export type ServiceStatus = 'stopped' | 'starting' | 'running' | 'stopping' | 'error';
// 服务实例
export interface ServiceInstance {
definition: ServiceDefinition;
status: ServiceStatus;
lastHealthCheck: Date;
error?: string;
}
// 服务编排器
export class ServiceOrchestrator {
private static instance: ServiceOrchestrator;
private serviceRegistry: ServiceRegistry;
private serviceMonitor: ServiceMonitor;
private serviceInstances: Map<string, ServiceInstance> = new Map();
private eventBus: DomainEventBus;
private constructor() {
this.serviceRegistry = ServiceRegistry.getInstance();
this.serviceMonitor = ServiceMonitor.getInstance();
this.eventBus = DomainEventBus.getInstance();
}
static getInstance(): ServiceOrchestrator {
if (!ServiceOrchestrator.instance) {
ServiceOrchestrator.instance = new ServiceOrchestrator();
}
return ServiceOrchestrator.instance;
}
// 注册服务
async registerService(service: ServiceDefinition): Promise<void> {
// 验证服务依赖
for (const dependency of service.dependencies) {
if (!this.serviceRegistry.getService(dependency)) {
throw new Error(`Dependency ${dependency} not found`);
}
}
// 注册到服务注册表
await this.serviceRegistry.registerService(service);
// 创建服务实例
const instance: ServiceInstance = {
definition: service,
status: 'stopped',
lastHealthCheck: new Date()
};
this.serviceInstances.set(service.id, instance);
this.eventBus.publish('service.registered', { serviceId: service.id });
}
// 启动服务
async startService(serviceId: string): Promise<void> {
const instance = this.serviceInstances.get(serviceId);
if (!instance) {
throw new Error(`Service ${serviceId} not found`);
}
if (instance.status === 'running') {
return;
}
// 启动依赖服务
for (const dependencyId of instance.definition.dependencies) {
await this.startService(dependencyId);
}
instance.status = 'starting';
this.eventBus.publish('service.starting', { serviceId });
try {
await instance.definition.start();
instance.status = 'running';
instance.lastHealthCheck = new Date();
this.eventBus.publish('service.started', { serviceId });
} catch (error) {
instance.status = 'error';
instance.error = error instanceof Error ? error.message : String(error);
this.eventBus.publish('service.error', { serviceId, error: instance.error });
throw error;
}
}
// 停止服务
async stopService(serviceId: string): Promise<void> {
const instance = this.serviceInstances.get(serviceId);
if (!instance) {
throw new Error(`Service ${serviceId} not found`);
}
if (instance.status === 'stopped') {
return;
}
// 检查是否有其他服务依赖此服务
const dependentServices = Array.from(this.serviceInstances.values())
.filter(s => s.definition.dependencies.includes(serviceId));
if (dependentServices.length > 0) {
throw new Error(`Service ${serviceId} is being used by other services: ${dependentServices.map(s => s.definition.id).join(', ')}`);
}
instance.status = 'stopping';
this.eventBus.publish('service.stopping', { serviceId });
try {
await instance.definition.stop();
instance.status = 'stopped';
this.eventBus.publish('service.stopped', { serviceId });
} catch (error) {
instance.status = 'error';
instance.error = error instanceof Error ? error.message : String(error);
this.eventBus.publish('service.error', { serviceId, error: instance.error });
throw error;
}
}
// 启动所有服务
async startAllServices(): Promise<void> {
const services = Array.from(this.serviceInstances.values());
// 按依赖顺序排序
const sortedServices = this.topologicalSort(services);
for (const service of sortedServices) {
await this.startService(service.definition.id);
}
}
// 停止所有服务
async stopAllServices(): Promise<void> {
const services = Array.from(this.serviceInstances.values());
// 按依赖顺序的逆序排序
const sortedServices = this.topologicalSort(services).reverse();
for (const service of sortedServices) {
try {
await this.stopService(service.definition.id);
} catch (error) {
console.error(`Error stopping service ${service.definition.id}:`, error);
}
}
}
// 拓扑排序服务依赖
private topologicalSort(services: ServiceInstance[]): ServiceInstance[] {
const visited = new Set<string>();
const temp = new Set<string>();
const result: ServiceInstance[] = [];
const visit = (serviceId: string) => {
if (temp.has(serviceId)) {
throw new Error('Circular dependency detected');
}
if (visited.has(serviceId)) {
return;
}
temp.add(serviceId);
const service = services.find(s => s.definition.id === serviceId);
if (service) {
for (const dependencyId of service.definition.dependencies) {
visit(dependencyId);
}
}
temp.delete(serviceId);
visited.add(serviceId);
const foundService = services.find(s => s.definition.id === serviceId);
if (foundService) {
result.push(foundService);
}
};
for (const service of services) {
if (!visited.has(service.definition.id)) {
visit(service.definition.id);
}
}
return result;
}
// 获取服务状态
getServiceStatus(serviceId: string): ServiceStatus | undefined {
const instance = this.serviceInstances.get(serviceId);
return instance?.status;
}
// 获取所有服务状态
getAllServiceStatuses(): Map<string, ServiceStatus> {
const statuses = new Map<string, ServiceStatus>();
for (const [id, instance] of this.serviceInstances) {
statuses.set(id, instance.status);
}
return statuses;
}
// 健康检查
async healthCheck(serviceId: string): Promise<boolean> {
const instance = this.serviceInstances.get(serviceId);
if (!instance) {
return false;
}
try {
const healthy = await instance.definition.healthCheck();
instance.lastHealthCheck = new Date();
if (instance.status === 'error' && healthy) {
instance.status = 'running';
instance.error = undefined;
this.eventBus.publish('service.recovered', { serviceId });
}
return healthy;
} catch (error) {
instance.status = 'error';
instance.error = error instanceof Error ? error.message : String(error);
instance.lastHealthCheck = new Date();
this.eventBus.publish('service.error', { serviceId, error: instance.error });
return false;
}
}
// 执行所有服务的健康检查
async healthCheckAll(): Promise<Map<string, boolean>> {
const results = new Map<string, boolean>();
for (const serviceId of this.serviceInstances.keys()) {
const healthy = await this.healthCheck(serviceId);
results.set(serviceId, healthy);
}
return results;
}
}

View File

@@ -0,0 +1,133 @@
import { ServiceDefinition } from './ServiceOrchestrator';
// 服务注册表
export class ServiceRegistry {
private static instance: ServiceRegistry;
private services: Map<string, ServiceDefinition> = new Map();
private serviceIndex: Map<string, string[]> = new Map(); // 按名称索引服务
private constructor() {}
static getInstance(): ServiceRegistry {
if (!ServiceRegistry.instance) {
ServiceRegistry.instance = new ServiceRegistry();
}
return ServiceRegistry.instance;
}
// 注册服务
async registerService(service: ServiceDefinition): Promise<void> {
if (this.services.has(service.id)) {
throw new Error(`Service with id ${service.id} already exists`);
}
this.services.set(service.id, service);
// 按名称索引
if (!this.serviceIndex.has(service.name)) {
this.serviceIndex.set(service.name, []);
}
this.serviceIndex.get(service.name)?.push(service.id);
}
// 注销服务
async unregisterService(serviceId: string): Promise<void> {
const service = this.services.get(serviceId);
if (!service) {
throw new Error(`Service ${serviceId} not found`);
}
this.services.delete(serviceId);
// 更新名称索引
const serviceIds = this.serviceIndex.get(service.name);
if (serviceIds) {
const index = serviceIds.indexOf(serviceId);
if (index !== -1) {
serviceIds.splice(index, 1);
if (serviceIds.length === 0) {
this.serviceIndex.delete(service.name);
}
}
}
}
// 获取服务
getService(serviceId: string): ServiceDefinition | undefined {
return this.services.get(serviceId);
}
// 根据名称获取服务
getServicesByName(name: string): ServiceDefinition[] {
const serviceIds = this.serviceIndex.get(name) || [];
return serviceIds.map(id => this.services.get(id)).filter((s): s is ServiceDefinition => s !== undefined);
}
// 获取所有服务
getAllServices(): ServiceDefinition[] {
return Array.from(this.services.values());
}
// 检查服务是否存在
hasService(serviceId: string): boolean {
return this.services.has(serviceId);
}
// 获取服务依赖图
getDependencyGraph(): Map<string, string[]> {
const graph = new Map<string, string[]>();
for (const [id, service] of this.services) {
graph.set(id, service.dependencies);
}
return graph;
}
// 验证服务依赖
validateDependencies(): { valid: boolean; errors: string[] } {
const errors: string[] = [];
for (const [id, service] of this.services) {
for (const dependencyId of service.dependencies) {
if (!this.services.has(dependencyId)) {
errors.push(`Service ${id} depends on non-existent service ${dependencyId}`);
}
}
}
return {
valid: errors.length === 0,
errors
};
}
// 导出服务注册表
exportRegistry(): Record<string, ServiceDefinition> {
const registry: Record<string, ServiceDefinition> = {};
for (const [id, service] of this.services) {
registry[id] = service;
}
return registry;
}
// 导入服务注册表
async importRegistry(registry: Record<string, ServiceDefinition>): Promise<void> {
for (const [id, service] of Object.entries(registry)) {
await this.registerService(service);
}
}
// 清空服务注册表
clear(): void {
this.services.clear();
this.serviceIndex.clear();
}
// 获取服务数量
size(): number {
return this.services.size;
}
}