Add autonomous compliance agent that fetches web documents (cookie banners, privacy policies), classifies them via Qwen/Ollama, assesses DSGVO compliance, assigns to the responsible role, and sends notification emails. Components: - ZeroClaw SOP (6-step workflow: fetch, classify, assess, summarize, assign, notify) - Backend: /api/compliance/agent/analyze (combined endpoint) - Backend: /api/compliance/agent/notify (standalone email) - Frontend: /sdk/agent page (Manager UI with URL input + results) - Helper scripts + E2E test Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
|
|
export interface AnalysisResult {
|
|
url: string
|
|
classification: string
|
|
risk_level: string
|
|
risk_score: number
|
|
escalation_level: string
|
|
responsible_role: string
|
|
findings: string[]
|
|
required_controls: string[]
|
|
summary: string
|
|
email_status: string
|
|
analyzed_at: string
|
|
}
|
|
|
|
const ESCALATION_ROLES: Record<string, string> = {
|
|
E0: 'Kein Handlungsbedarf',
|
|
E1: 'Teamleitung Datenschutz',
|
|
E2: 'Datenschutzbeauftragter (DSB)',
|
|
E3: 'DSB + Rechtsabteilung',
|
|
}
|
|
|
|
const SDK_HEADERS = {
|
|
'Content-Type': 'application/json',
|
|
'X-Tenant-ID': '9282a473-5c95-4b3a-bf78-0ecc0ec71d3e',
|
|
'X-User-ID': '00000000-0000-0000-0000-000000000001',
|
|
}
|
|
|
|
export function useAgentAnalysis() {
|
|
const [loading, setLoading] = useState(false)
|
|
const [error, setError] = useState<string | null>(null)
|
|
const [result, setResult] = useState<AnalysisResult | null>(null)
|
|
const [history, setHistory] = useState<AnalysisResult[]>([])
|
|
|
|
async function analyze(url: string) {
|
|
setLoading(true)
|
|
setError(null)
|
|
setResult(null)
|
|
|
|
try {
|
|
// Step 1: Fetch and classify
|
|
const fetchRes = await fetch('/api/sdk/v1/agent/analyze', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ url }),
|
|
})
|
|
|
|
if (!fetchRes.ok) {
|
|
throw new Error(`Analyse fehlgeschlagen: ${fetchRes.status}`)
|
|
}
|
|
|
|
const data = await fetchRes.json()
|
|
const analysisResult: AnalysisResult = {
|
|
url,
|
|
classification: data.classification || 'unknown',
|
|
risk_level: data.risk_level || 'unknown',
|
|
risk_score: data.risk_score || 0,
|
|
escalation_level: data.escalation_level || 'E0',
|
|
responsible_role: ESCALATION_ROLES[data.escalation_level] || ESCALATION_ROLES.E0,
|
|
findings: data.findings || [],
|
|
required_controls: data.required_controls || [],
|
|
summary: data.summary || '',
|
|
email_status: data.email_status || 'pending',
|
|
analyzed_at: new Date().toISOString(),
|
|
}
|
|
|
|
setResult(analysisResult)
|
|
setHistory(prev => [analysisResult, ...prev].slice(0, 20))
|
|
} catch (e) {
|
|
setError(e instanceof Error ? e.message : 'Unbekannter Fehler')
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
return { analyze, loading, error, result, history }
|
|
}
|