Re_Backend/_archive/services/activity.service.ts

115 lines
3.6 KiB
TypeScript

import logger from '@utils/logger';
// Special UUID for system events (login, etc.) - well-known UUID: 00000000-0000-0000-0000-000000000001
export const SYSTEM_EVENT_REQUEST_ID = '00000000-0000-0000-0000-000000000001';
export type ActivityEntry = {
requestId: string;
type: 'created' | 'submitted' | 'assignment' | 'approval' | 'rejection' | 'status_change' | 'comment' | 'reminder' | 'document_added' | 'sla_warning' | 'ai_conclusion_generated' | 'summary_generated' | 'closed' | 'login' | 'paused' | 'resumed' | 'pause_retriggered';
user?: { userId: string; name?: string; email?: string };
timestamp: string;
action: string;
details: string;
metadata?: any;
ipAddress?: string;
userAgent?: string;
category?: string;
severity?: string;
};
class ActivityService {
private byRequest: Map<string, ActivityEntry[]> = new Map();
private inferCategory(type: string): string {
const categoryMap: Record<string, string> = {
'created': 'WORKFLOW',
'submitted': 'WORKFLOW',
'approval': 'WORKFLOW',
'rejection': 'WORKFLOW',
'status_change': 'WORKFLOW',
'assignment': 'WORKFLOW',
'comment': 'COLLABORATION',
'document_added': 'DOCUMENT',
'sla_warning': 'SYSTEM',
'reminder': 'SYSTEM',
'ai_conclusion_generated': 'SYSTEM',
'closed': 'WORKFLOW',
'login': 'AUTHENTICATION',
'paused': 'WORKFLOW',
'resumed': 'WORKFLOW',
'pause_retriggered': 'WORKFLOW'
};
return categoryMap[type] || 'OTHER';
}
private inferSeverity(type: string): string {
const severityMap: Record<string, string> = {
'rejection': 'WARNING',
'sla_warning': 'WARNING',
'approval': 'INFO',
'closed': 'INFO',
'status_change': 'INFO',
'login': 'INFO',
'created': 'INFO',
'submitted': 'INFO',
'comment': 'INFO',
'document_added': 'INFO',
'assignment': 'INFO',
'reminder': 'INFO',
'ai_conclusion_generated': 'INFO',
'paused': 'WARNING',
'resumed': 'INFO',
'pause_retriggered': 'INFO'
};
return severityMap[type] || 'INFO';
}
async log(entry: ActivityEntry) {
const list = this.byRequest.get(entry.requestId) || [];
list.push(entry);
this.byRequest.set(entry.requestId, list);
// Persist to database
try {
const { Activity } = require('@models/Activity');
const userName = entry.user?.name || entry.user?.email || null;
const activityData = {
requestId: entry.requestId,
userId: entry.user?.userId || null,
userName: userName,
activityType: entry.type,
activityDescription: entry.details,
activityCategory: entry.category || this.inferCategory(entry.type),
severity: entry.severity || this.inferSeverity(entry.type),
metadata: entry.metadata || null,
isSystemEvent: !entry.user,
ipAddress: entry.ipAddress || null, // Database accepts null
userAgent: entry.userAgent || null, // Database accepts null
};
logger.info(`[Activity] Creating activity:`, {
requestId: entry.requestId,
userName,
userId: entry.user?.userId,
type: entry.type,
ipAddress: entry.ipAddress ? '***' : null
});
await Activity.create(activityData);
logger.info(`[Activity] Successfully logged activity for request ${entry.requestId} by user: ${userName}`);
} catch (error) {
logger.error('[Activity] Failed to persist activity:', error);
}
}
get(requestId: string): ActivityEntry[] {
return this.byRequest.get(requestId) || [];
}
}
export const activityService = new ActivityService();