fix: SDK-Module Frontend-Backend-Mismatches beheben + fehlende Proxy-Routes

- P0: enableBackendSync=true in SDKProvider aktiviert (PostgreSQL State-Persistenz)
- P0: Source Policy 4 Tabs an Backend-Schema angepasst (is_active→active,
  data.logs→data.entries, is_allowed→allowed, rule_type→category, severity→action)
- P0: OperationsMatrixTab holt jetzt Sources+Operations separat und joint client-side
- P0: PIIRulesTab PII-Test auf client-side Regex umgestellt (kein Backend-Endpoint noetig)
- P1: GET Proxy-Routes fuer Import, Screening und UCCA [id] (GET+DELETE) erstellt
- P1: Compliance Scope ScopeOverviewTab/ScopeExportTab Prop-Interfaces erweitert
- P2: Company Profile speichert jetzt auch zum dedizierten Backend-Endpoint
- P2: UCCA Wizard von 5 auf 8 Steps erweitert (Rechtsgrundlage, Datentransfer, Vertraege)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-02 11:40:44 +01:00
parent e6d666b89b
commit 80a988dc58
12 changed files with 563 additions and 181 deletions

View File

@@ -7,9 +7,9 @@ interface AuditLogEntry {
action: string
entity_type: string
entity_id?: string
old_value?: any
new_value?: any
user_email?: string
old_values?: any
new_values?: any
user_id?: string
created_at: string
}
@@ -91,7 +91,7 @@ export function AuditTab({ apiBase }: AuditTabProps) {
if (!res.ok) throw new Error('Fehler beim Laden')
const data = await res.json()
setAuditLogs(data.logs || [])
setAuditLogs(data.entries || [])
setAuditTotal(data.total || 0)
} catch (err) {
setError(err instanceof Error ? err.message : 'Unbekannter Fehler')
@@ -109,13 +109,20 @@ export function AuditTab({ apiBase }: AuditTabProps) {
params.append('limit', '100')
const res = await fetch(`${apiBase}/v1/admin/blocked-content?${params}`)
if (!res.ok) throw new Error('Fehler beim Laden')
if (!res.ok) {
// Endpoint may not exist yet — show empty state
setBlockedContent([])
setBlockedTotal(0)
return
}
const data = await res.json()
setBlockedContent(data.blocked || [])
setBlockedTotal(data.total || 0)
} catch (err) {
setError(err instanceof Error ? err.message : 'Unbekannter Fehler')
} catch {
// Endpoint not available — show empty state gracefully
setBlockedContent([])
setBlockedTotal(0)
} finally {
setBlockedLoading(false)
}
@@ -284,26 +291,26 @@ export function AuditTab({ apiBase }: AuditTabProps) {
{formatDate(log.created_at)}
</div>
</div>
{log.user_email && (
{log.user_id && (
<div className="mt-2 text-xs text-slate-500">
Benutzer: {log.user_email}
Benutzer: {log.user_id}
</div>
)}
{(log.old_value || log.new_value) && (
{(log.old_values || log.new_values) && (
<div className="mt-2 flex gap-4 text-xs">
{log.old_value && (
{log.old_values && (
<div className="flex-1 p-2 bg-red-50 rounded">
<div className="text-red-600 font-medium mb-1">Vorher:</div>
<pre className="text-red-700 overflow-x-auto">
{typeof log.old_value === 'string' ? log.old_value : JSON.stringify(log.old_value, null, 2)}
{typeof log.old_values === 'string' ? log.old_values : JSON.stringify(log.old_values, null, 2)}
</pre>
</div>
)}
{log.new_value && (
{log.new_values && (
<div className="flex-1 p-2 bg-green-50 rounded">
<div className="text-green-600 font-medium mb-1">Nachher:</div>
<pre className="text-green-700 overflow-x-auto">
{typeof log.new_value === 'string' ? log.new_value : JSON.stringify(log.new_value, null, 2)}
{typeof log.new_values === 'string' ? log.new_values : JSON.stringify(log.new_values, null, 2)}
</pre>
</div>
)}