/** * Custom hook: resume-polling für eine laufende Compliance-Check-Pruefung. * * Beim Mount: wenn localStorage eine `STORAGE_KEY_CHECK_ID` enthaelt aber * noch kein Result da ist, pollt der Hook alle 3s den Status. Setzt * Result, Progress, Error oder cleared den active-check-id beim * Abschluss. */ import { useEffect } from 'react' import { STORAGE_KEY_CHECK_ID, STORAGE_KEY_RESULTS, } from './_compliance_storage' interface ResumePollingArgs { activeCheckId: string results: unknown | null setLoading: (b: boolean) => void setProgress: (s: string) => void setProgressPct: (n: number) => void setResults: (r: unknown) => void setActiveCheckId: (s: string) => void setError: (s: string | null) => void } export function useCompliancePollingResume({ activeCheckId, results, setLoading, setProgress, setProgressPct, setResults, setActiveCheckId, setError, }: ResumePollingArgs) { useEffect(() => { if (!activeCheckId || results) return let cancelled = false setLoading(true) setProgress('Pruefung laeuft noch...') const poll = async () => { while (!cancelled) { await new Promise(r => setTimeout(r, 3000)) try { const res = await fetch( `/api/sdk/v1/agent/compliance-check?check_id=${activeCheckId}`, ) if (!res.ok) continue const data = await res.json() if (data.progress) setProgress(data.progress) if (typeof data.progress_pct === 'number') { setProgressPct(data.progress_pct) } if (data.status === 'completed' && data.result) { setResults(data.result) setProgress('') setProgressPct(0) setLoading(false) localStorage.setItem( STORAGE_KEY_RESULTS, JSON.stringify(data.result), ) localStorage.removeItem(STORAGE_KEY_CHECK_ID) setActiveCheckId('') return } if (['failed', 'not_found', 'skipped_tdm'].includes(data.status)) { if (data.status !== 'not_found') { setError( data.error || (data.status === 'skipped_tdm' ? 'TDM-Vorbehalt erkannt — Crawl uebersprungen' : 'Pruefung fehlgeschlagen'), ) } setProgress('') setProgressPct(0) setLoading(false) localStorage.removeItem(STORAGE_KEY_CHECK_ID) setActiveCheckId('') return } } catch { /* retry */ } } } poll() return () => { cancelled = true } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) }