/** * Alert Processor service API implementation * Note: Alert Processor is a background service that doesn't expose direct HTTP APIs * This service provides utilities and types for working with alert processing */ import { apiClient } from '../client/apiClient'; import type { AlertMessage, AlertResponse, AlertUpdateRequest, AlertFilters, AlertQueryParams, AlertDashboardData, NotificationSettings, ChannelRoutingConfig, WebhookConfig, WebhookPayload, AlertProcessingStatus, ProcessingMetrics, SSEAlertMessage, PaginatedResponse, } from '../types/alert_processor'; class AlertProcessorService { private readonly baseUrl = '/alerts'; private readonly notificationUrl = '/notifications'; private readonly webhookUrl = '/webhooks'; // Alert Management (these would be exposed via other services like inventory, production, etc.) async getAlerts( tenantId: string, queryParams?: AlertQueryParams ): Promise> { const params = new URLSearchParams(); if (queryParams?.severity?.length) { queryParams.severity.forEach(s => params.append('severity', s)); } if (queryParams?.type?.length) { queryParams.type.forEach(t => params.append('type', t)); } if (queryParams?.service?.length) { queryParams.service.forEach(s => params.append('service', s)); } if (queryParams?.item_type?.length) { queryParams.item_type.forEach(it => params.append('item_type', it)); } if (queryParams?.date_from) params.append('date_from', queryParams.date_from); if (queryParams?.date_to) params.append('date_to', queryParams.date_to); if (queryParams?.status) params.append('status', queryParams.status); if (queryParams?.search) params.append('search', queryParams.search); if (queryParams?.limit) params.append('limit', queryParams.limit.toString()); if (queryParams?.offset) params.append('offset', queryParams.offset.toString()); if (queryParams?.sort_by) params.append('sort_by', queryParams.sort_by); if (queryParams?.sort_order) params.append('sort_order', queryParams.sort_order); const queryString = params.toString() ? `?${params.toString()}` : ''; return apiClient.get>( `${this.baseUrl}/tenants/${tenantId}${queryString}` ); } async getAlert(tenantId: string, alertId: string): Promise { return apiClient.get( `${this.baseUrl}/tenants/${tenantId}/${alertId}` ); } async updateAlert( tenantId: string, alertId: string, updateData: AlertUpdateRequest ): Promise { return apiClient.put( `${this.baseUrl}/tenants/${tenantId}/${alertId}`, updateData ); } async dismissAlert(tenantId: string, alertId: string): Promise { return apiClient.put( `${this.baseUrl}/tenants/${tenantId}/${alertId}`, { status: 'dismissed' } ); } async acknowledgeAlert( tenantId: string, alertId: string, notes?: string ): Promise { return apiClient.put( `${this.baseUrl}/tenants/${tenantId}/${alertId}`, { status: 'acknowledged', notes } ); } async resolveAlert( tenantId: string, alertId: string, notes?: string ): Promise { return apiClient.put( `${this.baseUrl}/tenants/${tenantId}/${alertId}`, { status: 'resolved', notes } ); } // Dashboard Data async getDashboardData(tenantId: string): Promise { return apiClient.get( `${this.baseUrl}/tenants/${tenantId}/dashboard` ); } // Notification Settings async getNotificationSettings(tenantId: string): Promise { return apiClient.get( `${this.notificationUrl}/tenants/${tenantId}/settings` ); } async updateNotificationSettings( tenantId: string, settings: Partial ): Promise { return apiClient.put( `${this.notificationUrl}/tenants/${tenantId}/settings`, settings ); } async getChannelRoutingConfig(): Promise { return apiClient.get(`${this.notificationUrl}/routing-config`); } // Webhook Management async getWebhooks(tenantId: string): Promise { return apiClient.get(`${this.webhookUrl}/tenants/${tenantId}`); } async createWebhook( tenantId: string, webhook: Omit ): Promise { return apiClient.post( `${this.webhookUrl}/tenants/${tenantId}`, { ...webhook, tenant_id: tenantId } ); } async updateWebhook( tenantId: string, webhookId: string, webhook: Partial ): Promise { return apiClient.put( `${this.webhookUrl}/tenants/${tenantId}/${webhookId}`, webhook ); } async deleteWebhook(tenantId: string, webhookId: string): Promise<{ message: string }> { return apiClient.delete<{ message: string }>( `${this.webhookUrl}/tenants/${tenantId}/${webhookId}` ); } async testWebhook( tenantId: string, webhookId: string ): Promise<{ success: boolean; message: string }> { return apiClient.post<{ success: boolean; message: string }>( `${this.webhookUrl}/tenants/${tenantId}/${webhookId}/test` ); } // Processing Status and Metrics async getProcessingStatus( tenantId: string, alertId: string ): Promise { return apiClient.get( `${this.baseUrl}/tenants/${tenantId}/${alertId}/processing-status` ); } async getProcessingMetrics(tenantId: string): Promise { return apiClient.get( `${this.baseUrl}/tenants/${tenantId}/processing-metrics` ); } // SSE (Server-Sent Events) connection helpers getSSEUrl(tenantId: string): string { const baseUrl = apiClient.getAxiosInstance().defaults.baseURL; return `${baseUrl}/sse/tenants/${tenantId}/alerts`; } createSSEConnection(tenantId: string, token?: string): EventSource { const sseUrl = this.getSSEUrl(tenantId); const urlWithToken = token ? `${sseUrl}?token=${token}` : sseUrl; return new EventSource(urlWithToken); } // Utility methods for working with alerts static formatAlertMessage(alert: AlertMessage): string { return `[${alert.severity.toUpperCase()}] ${alert.title}: ${alert.message}`; } static getAlertIcon(alert: AlertMessage): string { const iconMap: Record = { inventory_low: '📦', quality_issue: '⚠️', delivery_delay: '🚚', production_delay: '🏭', equipment_failure: '🔧', food_safety: '🦠', temperature_alert: '🌡️', expiry_warning: '⏰', forecast_accuracy: '📊', demand_spike: '📈', supplier_issue: '🏢', cost_optimization: '💰', revenue_opportunity: '💡', }; return iconMap[alert.type] || '🔔'; } static getSeverityColor(severity: string): string { const colorMap: Record = { urgent: '#dc2626', // red-600 high: '#ea580c', // orange-600 medium: '#d97706', // amber-600 low: '#65a30d', // lime-600 }; return colorMap[severity] || '#6b7280'; // gray-500 } // Message queuing helpers (for RabbitMQ integration) static createAlertMessage( tenantId: string, alert: Omit ): AlertMessage { return { id: `alert_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, tenant_id: tenantId, timestamp: new Date().toISOString(), ...alert, }; } static validateWebhookSignature( payload: string, signature: string, secret: string ): boolean { // This would typically use crypto.createHmac for HMAC-SHA256 verification // Implementation depends on the specific signature algorithm used const crypto = window.crypto || (window as any).msCrypto; if (!crypto?.subtle) { console.warn('WebCrypto API not available for signature verification'); return false; } // Simplified example - actual implementation would use proper HMAC verification return signature.length > 0 && secret.length > 0; } } // Create and export singleton instance export const alertProcessorService = new AlertProcessorService(); export default alertProcessorService;