/** * Audit Log Service - User action history tracking */ import api from '../core/api.js'; import logger from '../core/logger.js'; class AuditService { constructor() { this.cache = { categories: null, actions: null }; } /** * Get audit log with filters */ async getAuditLog(filters = {}) { const params = new URLSearchParams(); if (filters.project_id) params.append('project_id', filters.project_id); if (filters.user_id) params.append('user_id', filters.user_id); if (filters.action) params.append('action', filters.action); if (filters.category) params.append('category', filters.category); if (filters.entity_type) params.append('entity_type', filters.entity_type); if (filters.severity) params.append('severity', filters.severity); if (filters.start_date) params.append('start_date', filters.start_date); if (filters.end_date) params.append('end_date', filters.end_date); if (filters.limit) params.append('limit', filters.limit); if (filters.offset) params.append('offset', filters.offset); try { const response = await api.get(`/audit?${params.toString()}`); return response; } catch (error) { logger.error('AuditService', 'Failed to fetch audit log', error); throw error; } } /** * Get audit statistics */ async getStats() { try { return await api.get('/audit/stats'); } catch (error) { logger.error('AuditService', 'Failed to fetch audit stats', error); return { by_category: {}, by_user: {}, total_count: 0 }; } } /** * Get all categories */ async getCategories() { if (this.cache.categories) { return this.cache.categories; } try { this.cache.categories = await api.get('/audit/categories'); return this.cache.categories; } catch (error) { logger.error('AuditService', 'Failed to fetch categories', error); return []; } } /** * Get all actions */ async getActions() { if (this.cache.actions) { return this.cache.actions; } try { this.cache.actions = await api.get('/audit/actions'); return this.cache.actions; } catch (error) { logger.error('AuditService', 'Failed to fetch actions', error); return []; } } /** * Create audit entry */ async logAction(entry) { try { await api.post('/audit', entry); logger.info('AuditService', 'Action logged', { action: entry.action }); } catch (error) { logger.error('AuditService', 'Failed to log action', error); } } /** * Export audit log */ async export(filters = {}, format = 'json') { const params = new URLSearchParams({ format }); if (filters.project_id) params.append('project_id', filters.project_id); if (filters.category) params.append('category', filters.category); if (filters.start_date) params.append('start_date', filters.start_date); if (filters.end_date) params.append('end_date', filters.end_date); try { const url = `${api.baseUrl}/audit/export?${params.toString()}`; window.open(url, '_blank'); logger.info('AuditService', 'Export initiated', { format }); } catch (error) { logger.error('AuditService', 'Failed to export', error); throw error; } } /** * Get severity badge class */ getSeverityClass(severity) { const classes = { 'info': 'badge--primary', 'warning': 'badge--warning', 'critical': 'badge--destructive' }; return classes[severity] || 'badge--secondary'; } /** * Get category icon */ getCategoryIcon(category) { const icons = { 'design_system': '🎨', 'code': '⚛️', 'configuration': '⚙️', 'project': '📁', 'team': '👥', 'storybook': '📚', 'other': '📌' }; return icons[category] || '📌'; } /** * Format timestamp */ formatTimestamp(timestamp) { const date = new Date(timestamp); const now = new Date(); const diff = now - date; // Less than 1 minute if (diff < 60000) { return 'Just now'; } // Less than 1 hour if (diff < 3600000) { const minutes = Math.floor(diff / 60000); return `${minutes} minute${minutes > 1 ? 's' : ''} ago`; } // Less than 1 day if (diff < 86400000) { const hours = Math.floor(diff / 3600000); return `${hours} hour${hours > 1 ? 's' : ''} ago`; } // Less than 7 days if (diff < 604800000) { const days = Math.floor(diff / 86400000); return `${days} day${days > 1 ? 's' : ''} ago`; } // Show full date return date.toLocaleDateString() + ' ' + date.toLocaleTimeString(); } } // Singleton instance const auditService = new AuditService(); export default auditService; export { AuditService };