const API_BASE = '/api/v1'; function getAuthHeaders(): Record { const token = localStorage.getItem('fraudshield_token'); const headers: Record = { 'Content-Type': 'application/json' }; if (token) headers['Authorization'] = `Bearer ${token}`; return headers; } async function apiFetch(path: string, options: RequestInit = {}): Promise { const res = await fetch(`${API_BASE}${path}`, { ...options, headers: { ...getAuthHeaders(), ...((options.headers as Record) || {}) }, }); if (!res.ok) { const err = await res.json().catch(() => ({ detail: res.statusText })); throw new Error(err.detail || `HTTP ${res.status}`); } return res.json(); } export interface AlertFilters { status?: string; min_score?: number; from_date?: string; to_date?: string; triggered_rule?: string; limit?: number; offset?: number; } export interface TriggeredRule { rule_id: string; rule_name: string; score: number; explanation: string; } export interface AlertSummary { id: string; score: number; status: string; amount: number; merchant_name: string; top_rule: string; created_at: string; } export interface AlertDetail { id: string; transaction_id: string; score: number; triggered_rules: TriggeredRule[]; explanation: string; status: string; assigned_to?: string | null; decision?: string | null; decided_by?: string | null; decided_at?: string | null; justification?: string | null; created_at: string; amount: number; merchant_name: string; merchant_category: string; channel: string; } export interface AlertListResponse { items: AlertSummary[]; total: number; limit: number; offset: number; } export interface AlertDecisionRequest { decision: string; justification?: string; notes?: string; } export interface TransactionAccepted { transaction_id: string; status: string; trace_id: string; } export interface DashboardMetrics { period: string; total_transactions: number; total_alerts: number; fraud_rate_pct: number; false_positive_rate_pct: number; alerts_by_status: { pending: number; confirmed: number; false_positive: number; escalated: number }; alerts_by_hour: { hour: number; count: number }[]; top_triggering_rules: { rule_name: string; alert_count: number }[]; score_distribution: { low: number; medium: number; high: number; critical: number }; } export interface DetectionRule { id: string; name: string; description: string; condition: string; weight: number; threshold: number; is_active: boolean; version: number; created_by: string; created_at: string; updated_at: string; } export function listAlerts(params: AlertFilters = {}): Promise { const qs = new URLSearchParams(); Object.entries(params).forEach(([k, v]) => { if (v !== undefined) qs.set(k, String(v)); }); return apiFetch(`/alerts?${qs.toString()}`); } export function getAlert(id: string): Promise { return apiFetch(`/alerts/${id}`); } export function decideAlert(id: string, data: AlertDecisionRequest): Promise { return apiFetch(`/alerts/${id}/decide`, { method: 'POST', body: JSON.stringify(data) }); } export function getDashboardMetrics(period = '24h'): Promise { return apiFetch(`/dashboard/metrics?period=${period}`); } export { getAuthHeaders };