From 80a988dc58c355851a9faa6312496938db2a1221 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Mon, 2 Mar 2026 11:40:44 +0100 Subject: [PATCH] fix: SDK-Module Frontend-Backend-Mismatches beheben + fehlende Proxy-Routes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- admin-compliance/app/(sdk)/layout.tsx | 2 +- .../app/(sdk)/sdk/company-profile/page.tsx | 37 +++- .../app/(sdk)/sdk/use-cases/new/page.tsx | 159 ++++++++++++++-- .../app/api/sdk/v1/import/route.ts | 42 +++++ .../app/api/sdk/v1/screening/route.ts | 42 +++++ .../api/sdk/v1/ucca/assessments/[id]/route.ts | 81 ++++++++ .../sdk/compliance-scope/ScopeExportTab.tsx | 11 +- .../sdk/compliance-scope/ScopeOverviewTab.tsx | 31 ++- .../components/sdk/source-policy/AuditTab.tsx | 35 ++-- .../sdk/source-policy/OperationsMatrixTab.tsx | 83 ++++---- .../sdk/source-policy/PIIRulesTab.tsx | 177 ++++++++++-------- .../sdk/source-policy/SourcesTab.tsx | 44 ++--- 12 files changed, 563 insertions(+), 181 deletions(-) create mode 100644 admin-compliance/app/api/sdk/v1/import/route.ts create mode 100644 admin-compliance/app/api/sdk/v1/screening/route.ts create mode 100644 admin-compliance/app/api/sdk/v1/ucca/assessments/[id]/route.ts diff --git a/admin-compliance/app/(sdk)/layout.tsx b/admin-compliance/app/(sdk)/layout.tsx index a2dfcea..a076fdb 100644 --- a/admin-compliance/app/(sdk)/layout.tsx +++ b/admin-compliance/app/(sdk)/layout.tsx @@ -166,7 +166,7 @@ export default function SDKRootLayout({ } return ( - + {children} ) diff --git a/admin-compliance/app/(sdk)/sdk/company-profile/page.tsx b/admin-compliance/app/(sdk)/sdk/company-profile/page.tsx index 07b1534..5be1a13 100644 --- a/admin-compliance/app/(sdk)/sdk/company-profile/page.tsx +++ b/admin-compliance/app/(sdk)/sdk/company-profile/page.tsx @@ -1161,7 +1161,7 @@ export default function CompanyProfilePage() { } } - const completeAndSaveProfile = () => { + const completeAndSaveProfile = async () => { const completeProfile: CompanyProfile = { ...formData, isComplete: true, @@ -1170,6 +1170,41 @@ export default function CompanyProfilePage() { setCompanyProfile(completeProfile) dispatch({ type: 'COMPLETE_STEP', payload: 'company-profile' }) + + // Also persist to dedicated backend endpoint + try { + await fetch('/api/sdk/v1/company-profile', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + company_name: formData.companyName || '', + legal_form: formData.legalForm || 'GmbH', + industry: formData.industry || '', + founded_year: formData.foundedYear || null, + business_model: formData.businessModel || 'B2B', + offerings: formData.offerings || [], + company_size: formData.companySize || 'small', + employee_count: formData.employeeCount || '', + annual_revenue: formData.annualRevenue || '', + headquarters_country: formData.headquartersCountry || 'DE', + headquarters_city: formData.headquartersCity || '', + has_international_locations: formData.hasInternationalLocations || false, + international_countries: formData.internationalCountries || [], + target_markets: formData.targetMarkets || [], + primary_jurisdiction: formData.primaryJurisdiction || 'DE', + is_data_controller: formData.isDataController ?? true, + is_data_processor: formData.isDataProcessor ?? false, + uses_ai: formData.usesAI ?? false, + ai_use_cases: formData.aiUseCases || [], + dpo_name: formData.dpoName || '', + dpo_email: formData.dpoEmail || '', + is_complete: true, + }), + }) + } catch (err) { + console.error('Failed to save company profile to backend:', err) + } + goToNextStep() } diff --git a/admin-compliance/app/(sdk)/sdk/use-cases/new/page.tsx b/admin-compliance/app/(sdk)/sdk/use-cases/new/page.tsx index 5b01760..3b83670 100644 --- a/admin-compliance/app/(sdk)/sdk/use-cases/new/page.tsx +++ b/admin-compliance/app/(sdk)/sdk/use-cases/new/page.tsx @@ -11,9 +11,12 @@ import { AssessmentResultCard } from '@/components/sdk/use-case-assessment/Asses const WIZARD_STEPS = [ { id: 1, title: 'Grundlegendes', description: 'Titel und Beschreibung' }, { id: 2, title: 'Datenkategorien', description: 'Welche Daten werden verarbeitet?' }, - { id: 3, title: 'Automatisierung', description: 'Grad der Automatisierung' }, - { id: 4, title: 'Hosting & Modell', description: 'Technische Details' }, - { id: 5, title: 'Datenhaltung', description: 'Aufbewahrung und Speicherung' }, + { id: 3, title: 'Verarbeitungszweck', description: 'Rechtsgrundlage und Zweck' }, + { id: 4, title: 'Automatisierung', description: 'Grad der Automatisierung' }, + { id: 5, title: 'Hosting & Modell', description: 'Technische Details' }, + { id: 6, title: 'Datentransfer', description: 'Internationaler Datentransfer' }, + { id: 7, title: 'Datenhaltung', description: 'Aufbewahrung und Speicherung' }, + { id: 8, title: 'Vertraege', description: 'Compliance und Vereinbarungen' }, ] const DOMAINS = [ @@ -70,9 +73,20 @@ export default function NewUseCasePage() { model_finetune: false, model_training: false, model_inference: true, - // Retention + // Legal Basis (Step 3) + legal_basis: 'consent' as 'consent' | 'contract' | 'legitimate_interest' | 'legal_obligation' | 'vital_interest' | 'public_interest', + // Data Transfer (Step 6) + international_transfer: false, + transfer_countries: [] as string[], + transfer_mechanism: 'none' as 'none' | 'scc' | 'bcr' | 'adequacy' | 'derogation', + // Retention (Step 7) retention_days: 90, retention_purpose: '', + // Contracts (Step 8) + has_dpa: false, + has_aia_documentation: false, + has_risk_assessment: false, + subprocessors: '', }) const updateForm = (updates: Partial) => { @@ -113,10 +127,22 @@ export default function NewUseCasePage() { training: form.model_training, inference: form.model_inference, }, + legal_basis: form.legal_basis, + international_transfer: { + enabled: form.international_transfer, + countries: form.transfer_countries, + mechanism: form.transfer_mechanism, + }, retention: { days: form.retention_days, purpose: form.retention_purpose, }, + contracts: { + has_dpa: form.has_dpa, + has_aia_documentation: form.has_aia_documentation, + has_risk_assessment: form.has_risk_assessment, + subprocessors: form.subprocessors, + }, store_raw_text: true, } @@ -276,6 +302,29 @@ export default function NewUseCasePage() { ))} + + )} + + {/* Step 3: Verarbeitungszweck & Rechtsgrundlage */} + {currentStep === 3 && ( +
+

Verarbeitungszweck & Rechtsgrundlage

+ +
+ + +

Zweck der Verarbeitung

{[ @@ -301,8 +350,8 @@ export default function NewUseCasePage() {
)} - {/* Step 3: Automatisierung */} - {currentStep === 3 && ( + {/* Step 4: Automatisierung */} + {currentStep === 4 && (

Grad der Automatisierung

{[ @@ -335,8 +384,8 @@ export default function NewUseCasePage() {
)} - {/* Step 4: Hosting & Modell */} - {currentStep === 4 && ( + {/* Step 5: Hosting & Modell */} + {currentStep === 5 && (

Technische Details

@@ -390,8 +439,59 @@ export default function NewUseCasePage() {
)} - {/* Step 5: Datenhaltung */} - {currentStep === 5 && ( + {/* Step 6: Internationaler Datentransfer */} + {currentStep === 6 && ( +
+

Internationaler Datentransfer

+ + + + {form.international_transfer && ( + <> +
+ + updateForm({ transfer_countries: e.target.value.split(',').map(s => s.trim()).filter(Boolean) })} + placeholder="z.B. USA, UK, CH" + className="w-full px-4 py-2 border border-gray-300 rounded-lg" + /> +

Kommagetrennte Laenderkuerzel

+
+ +
+ + +
+ + )} +
+ )} + + {/* Step 7: Datenhaltung */} + {currentStep === 7 && (

Datenhaltung & Aufbewahrung

@@ -420,6 +520,43 @@ export default function NewUseCasePage() {
)} + + {/* Step 8: Vertraege & Compliance */} + {currentStep === 8 && ( +
+

Vertraege & Compliance-Dokumentation

+ + {[ + { key: 'has_dpa', label: 'Auftragsverarbeitungsvertrag (AVV/DPA)', desc: 'Vertrag mit KI-Anbieter / Subprozessor nach Art. 28 DSGVO' }, + { key: 'has_aia_documentation', label: 'AI Act Dokumentation', desc: 'Risikoklassifizierung und technische Dokumentation nach EU AI Act' }, + { key: 'has_risk_assessment', label: 'Risikobewertung / DSFA', desc: 'Datenschutz-Folgenabschaetzung nach Art. 35 DSGVO' }, + ].map(item => ( + + ))} + +
+ +