/** * useAuditLogs Hook * React Query hooks for Audit Logs management * @created Sprint 2 - TASK-2026-01-30-ANALISIS-INTEGRACION */ import { useQuery } from '@tanstack/react-query'; import { apiClient } from '../../../lib/apiClient'; // ============================================================================ // Types // ============================================================================ export type AuditEventType = | 'auth.login' | 'auth.logout' | 'auth.register' | 'auth.password_change' | 'auth.2fa_enabled' | 'auth.2fa_disabled' | 'user.profile_update' | 'user.settings_change' | 'trading.order_placed' | 'trading.order_cancelled' | 'investment.deposit' | 'investment.withdrawal' | 'payment.subscription' | 'payment.refund' | 'admin.user_suspend' | 'admin.user_activate' | 'system.config_change'; export type EventSeverity = 'info' | 'warning' | 'error' | 'critical'; export type EventStatus = 'success' | 'failure' | 'pending'; export interface AuditLog { id: string; eventType: AuditEventType; eventStatus: EventStatus; severity: EventSeverity; userId: string | null; sessionId: string | null; ipAddress: string | null; userAgent: string | null; resourceType: string; resourceId: string | null; resourceName: string | null; action: string; description: string | null; oldValues: Record | null; newValues: Record | null; metadata: Record; requestId: string | null; correlationId: string | null; serviceName: string | null; createdAt: Date; } export interface AuditLogFilters { userId?: string; eventType?: AuditEventType; resourceType?: string; resourceId?: string; severity?: EventSeverity; dateFrom?: string; dateTo?: string; limit?: number; offset?: number; } export interface AuditStats { totalLogs: number; byEventType: Partial>; bySeverity: Partial>; criticalEvents: number; } export interface SecurityEvent { id: string; category: string; severity: EventSeverity; eventStatus: EventStatus; userId: string | null; ipAddress: string; userAgent: string | null; eventCode: string; eventName: string; description: string | null; isBlocked: boolean; blockReason: string | null; requiresReview: boolean; createdAt: Date; } export interface SecurityEventFilters { userId?: string; category?: string; severity?: EventSeverity; isBlocked?: boolean; requiresReview?: boolean; dateFrom?: string; dateTo?: string; limit?: number; offset?: number; } // ============================================================================ // API Functions // ============================================================================ async function getAuditLogs(filters: AuditLogFilters = {}): Promise { const params = new URLSearchParams(); if (filters.userId) params.append('userId', filters.userId); if (filters.eventType) params.append('eventType', filters.eventType); if (filters.resourceType) params.append('resourceType', filters.resourceType); if (filters.resourceId) params.append('resourceId', filters.resourceId); if (filters.severity) params.append('severity', filters.severity); if (filters.dateFrom) params.append('dateFrom', filters.dateFrom); if (filters.dateTo) params.append('dateTo', filters.dateTo); if (filters.limit) params.append('limit', filters.limit.toString()); if (filters.offset) params.append('offset', filters.offset.toString()); const response = await apiClient.get(`/audit/logs?${params.toString()}`); return response.data.data || []; } async function getAuditStats(dateFrom?: string, dateTo?: string): Promise { const params = new URLSearchParams(); if (dateFrom) params.append('dateFrom', dateFrom); if (dateTo) params.append('dateTo', dateTo); const response = await apiClient.get(`/audit/stats?${params.toString()}`); return response.data.data; } async function getSecurityEvents(filters: SecurityEventFilters = {}): Promise { const params = new URLSearchParams(); if (filters.userId) params.append('userId', filters.userId); if (filters.category) params.append('category', filters.category); if (filters.severity) params.append('severity', filters.severity); if (filters.isBlocked !== undefined) params.append('isBlocked', filters.isBlocked.toString()); if (filters.requiresReview !== undefined) params.append('requiresReview', filters.requiresReview.toString()); if (filters.dateFrom) params.append('dateFrom', filters.dateFrom); if (filters.dateTo) params.append('dateTo', filters.dateTo); if (filters.limit) params.append('limit', filters.limit.toString()); if (filters.offset) params.append('offset', filters.offset.toString()); const response = await apiClient.get(`/audit/security-events?${params.toString()}`); return response.data.data || []; } async function getUserAuditLogs(userId: string, limit = 50): Promise { return getAuditLogs({ userId, limit }); } // ============================================================================ // React Query Hooks // ============================================================================ /** * Get audit logs with optional filters */ export function useAuditLogs(filters: AuditLogFilters = {}) { return useQuery({ queryKey: ['audit', 'logs', filters], queryFn: () => getAuditLogs(filters), staleTime: 30 * 1000, // 30 seconds }); } /** * Get audit stats for dashboard */ export function useAuditStats(dateFrom?: string, dateTo?: string) { return useQuery({ queryKey: ['audit', 'stats', dateFrom, dateTo], queryFn: () => getAuditStats(dateFrom, dateTo), staleTime: 60 * 1000, // 1 minute }); } /** * Get security events with optional filters */ export function useSecurityEvents(filters: SecurityEventFilters = {}) { return useQuery({ queryKey: ['audit', 'security-events', filters], queryFn: () => getSecurityEvents(filters), staleTime: 30 * 1000, // 30 seconds }); } /** * Get audit logs for a specific user */ export function useUserAuditLogs(userId: string, limit = 50) { return useQuery({ queryKey: ['audit', 'user', userId, limit], queryFn: () => getUserAuditLogs(userId, limit), enabled: !!userId, staleTime: 30 * 1000, }); } // ============================================================================ // Helper Functions // ============================================================================ /** * Get user-friendly label for event type */ export function getEventTypeLabel(eventType: AuditEventType): string { const labels: Record = { 'auth.login': 'Login', 'auth.logout': 'Logout', 'auth.register': 'Registration', 'auth.password_change': 'Password Change', 'auth.2fa_enabled': '2FA Enabled', 'auth.2fa_disabled': '2FA Disabled', 'user.profile_update': 'Profile Update', 'user.settings_change': 'Settings Change', 'trading.order_placed': 'Order Placed', 'trading.order_cancelled': 'Order Cancelled', 'investment.deposit': 'Deposit', 'investment.withdrawal': 'Withdrawal', 'payment.subscription': 'Subscription', 'payment.refund': 'Refund', 'admin.user_suspend': 'User Suspended', 'admin.user_activate': 'User Activated', 'system.config_change': 'System Config Change', }; return labels[eventType] || eventType; } /** * Get severity color for styling */ export function getSeverityColor(severity: EventSeverity): string { const colors: Record = { info: 'text-blue-500', warning: 'text-yellow-500', error: 'text-red-500', critical: 'text-red-700', }; return colors[severity] || 'text-gray-500'; } /** * Get severity badge styles */ export function getSeverityBadgeClass(severity: EventSeverity): string { const classes: Record = { info: 'bg-blue-100 text-blue-800', warning: 'bg-yellow-100 text-yellow-800', error: 'bg-red-100 text-red-800', critical: 'bg-red-200 text-red-900 font-bold', }; return classes[severity] || 'bg-gray-100 text-gray-800'; } /** * Get status badge styles */ export function getStatusBadgeClass(status: EventStatus): string { const classes: Record = { success: 'bg-green-100 text-green-800', failure: 'bg-red-100 text-red-800', pending: 'bg-yellow-100 text-yellow-800', }; return classes[status] || 'bg-gray-100 text-gray-800'; } /** * Format date for display */ export function formatAuditDate(date: Date | string): string { const d = typeof date === 'string' ? new Date(date) : date; return d.toLocaleString('es-MX', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', }); } // ============================================================================ // Export // ============================================================================ export const auditHooks = { useAuditLogs, useAuditStats, useSecurityEvents, useUserAuditLogs, getEventTypeLabel, getSeverityColor, getSeverityBadgeClass, getStatusBadgeClass, formatAuditDate, }; export default auditHooks;