diff --git a/admin-lehrer/app/(admin)/developers/sdk/configuration/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/configuration/page.tsx deleted file mode 100644 index 6cdb597..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/configuration/page.tsx +++ /dev/null @@ -1,256 +0,0 @@ -import { DevPortalLayout, CodeBlock, InfoBox, ParameterTable } from '@/components/developers/DevPortalLayout' - -export default function SDKConfigurationPage() { - return ( - -

SDKProvider Props

-

- Der SDKProvider akzeptiert folgende Konfigurationsoptionen: -

- void', - required: false, - description: 'Callback fuer Fehlerbehandlung', - }, - { - name: 'onStateChange', - type: '(state: SDKState) => void', - required: false, - description: 'Callback bei State-Aenderungen', - }, - ]} - /> - -

Vollstaendiges Beispiel

- -{`'use client' - -import { SDKProvider } from '@breakpilot/compliance-sdk' -import { useRouter } from 'next/navigation' - -export default function SDKLayout({ children }: { children: React.ReactNode }) { - const router = useRouter() - - return ( - { - console.error('SDK Error:', error) - // Optional: Sentry oder anderes Error-Tracking - }} - onStateChange={(state) => { - console.log('State changed:', state.currentStep) - // Optional: Analytics-Events - }} - > - {children} - - ) -}`} - - -

Synchronisations-Strategien

- -

1. Nur localStorage (Offline-Only)

- -{` - {children} -`} - -

- Ideal fuer: Lokale Entwicklung, Demos, Privacy-fokussierte Installationen. - Daten werden nur im Browser gespeichert. -

- -

2. Backend-Sync mit Fallback

- -{` - {children} -`} - -

- Empfohlen fuer: Produktionsumgebungen. Daten werden mit dem Backend - synchronisiert, localStorage dient als Fallback bei Netzwerkproblemen. -

- -

3. Nur Backend (kein lokaler Cache)

- -{` - {children} -`} - -

- Ideal fuer: Strenge Compliance-Anforderungen, Multi-User-Szenarien. - Daten werden nur im Backend gespeichert. -

- - - Im Backend-Only Modus ist eine aktive Internetverbindung erforderlich. - Bei Netzwerkproblemen koennen Daten verloren gehen. - - -

API URL Konfiguration

- -

Cloud-Version (Standard)

-

Keine zusaetzliche Konfiguration erforderlich:

- -{` - {/* Nutzt automatisch https://api.breakpilot.io/sdk/v1 */} -`} - - -

Self-Hosted

- -{` - {children} -`} - - -

Lokale Entwicklung

- -{` - {children} -`} - - -

Feature Flags

-

- Das SDK unterstuetzt Feature Flags ueber Subscription-Levels: -

- -{`import { useSDK } from '@breakpilot/compliance-sdk' - -function MyComponent() { - const { state } = useSDK() - - // Subscription-basierte Features - const isEnterprise = state.subscription === 'ENTERPRISE' - const isProfessional = ['PROFESSIONAL', 'ENTERPRISE'].includes(state.subscription) - - // Feature-Gates - const canExportPDF = isProfessional - const canUseRAG = isProfessional - const canCustomizeDSFA = isEnterprise - const canUseAPI = isProfessional - - return ( -
- {canExportPDF && } - {canUseRAG && } -
- ) -}`} -
- -

Logging & Debugging

-

- Aktivieren Sie detailliertes Logging fuer die Entwicklung: -

- -{`// In Ihrer .env.local -NEXT_PUBLIC_SDK_DEBUG=true - -// Oder programmatisch - { - if (process.env.NODE_ENV === 'development') { - console.log('[SDK] State Update:', { - phase: state.currentPhase, - step: state.currentStep, - useCases: state.useCases.length, - risks: state.risks.length, - }) - } - }} -> - {children} -`} - - - - Der SDK-State ist im React DevTools unter dem SDKProvider-Context sichtbar. - Installieren Sie die React Developer Tools Browser-Extension fuer einfaches Debugging. - -
- ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/consent/api-reference/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/consent/api-reference/page.tsx deleted file mode 100644 index f3cef52..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/consent/api-reference/page.tsx +++ /dev/null @@ -1,482 +0,0 @@ -'use client' - -import React, { useState } from 'react' -import { SDKDocsSidebar } from '@/components/developers/SDKDocsSidebar' -import { Copy, Check } from 'lucide-react' - -function CopyButton({ text }: { text: string }) { - const [copied, setCopied] = useState(false) - - const handleCopy = async () => { - await navigator.clipboard.writeText(text) - setCopied(true) - setTimeout(() => setCopied(false), 2000) - } - - return ( - - ) -} - -function CodeBlock({ code }: { code: string }) { - return ( -
-
- -
-
-        {code}
-      
-
- ) -} - -function MethodCard({ - name, - signature, - description, - params, - returns, - example, -}: { - name: string - signature: string - description: string - params?: { name: string; type: string; description: string }[] - returns?: string - example?: string -}) { - return ( -
-
- {name} -
-
-
- {signature} -
-

{description}

- - {params && params.length > 0 && ( -
-

Parameter

- - - {params.map((param) => ( - - - - - - ))} - -
- {param.name} - - {param.type} - {param.description}
-
- )} - - {returns && ( -
-

Rueckgabe

- {returns} -
- )} - - {example && ( -
-

Beispiel

- -
- )} -
-
- ) -} - -export default function APIReferencePage() { - return ( -
- - -
-
-

API Referenz

-

- Vollstaendige Dokumentation aller Methoden und Konfigurationsoptionen des Consent SDK. -

- - {/* ConsentManager */} -
-

ConsentManager

-

- Die zentrale Klasse fuer das Consent Management. Verwaltet Einwilligungen, Script-Blocking und Events. -

- - {/* Constructor */} -
- - - - - - - - - { - await consent.acceptAll(); -});`} - /> - - { - await consent.rejectAll(); -});`} - /> - - { - await consent.revokeAll(); - location.reload(); -});`} - /> - - { - console.log('Consent geaendert:', state); -}); - -// Spaeter: Listener entfernen -unsubscribe();`} - /> - - - - -
-
- - {/* Configuration */} -
-

Konfiguration

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Option - - Typ - - Default - - Beschreibung -
- apiEndpoint - - string - erforderlichURL des Consent-Backends
- siteId - - string - erforderlichEindeutige Site-ID
- debug - - boolean - falseAktiviert Debug-Logging
- language - - string - 'de'Sprache fuer UI-Texte
- consent.rememberDays - - number - 365Gueltigkeitsdauer in Tagen
- consent.recheckAfterDays - - number - 180Erneute Abfrage nach X Tagen
-
-
- - {/* Events */} -
-

Events

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Event - - Daten - - Beschreibung -
- init - - ConsentState | null - SDK initialisiert
- change - - ConsentState - Consent geaendert
- accept_all - - ConsentState - Alle akzeptiert
- reject_all - - ConsentState - Alle abgelehnt
- banner_show - - undefined - Banner angezeigt
- banner_hide - - undefined - Banner versteckt
- error - - Error - Fehler aufgetreten
-
-
- - {/* Types */} -
-

TypeScript Types

- ; - vendors: Record; - timestamp: string; - version: string; - consentId?: string; - expiresAt?: string; -} - -// Konfiguration -interface ConsentConfig { - apiEndpoint: string; - siteId: string; - debug?: boolean; - language?: string; - fallbackLanguage?: string; - ui?: ConsentUIConfig; - consent?: ConsentBehaviorConfig; - onConsentChange?: (state: ConsentState) => void; - onBannerShow?: () => void; - onBannerHide?: () => void; - onError?: (error: Error) => void; -}`} - /> -
-
-
-
- ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/consent/frameworks/angular/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/consent/frameworks/angular/page.tsx deleted file mode 100644 index 3c01a89..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/consent/frameworks/angular/page.tsx +++ /dev/null @@ -1,281 +0,0 @@ -'use client' - -import React, { useState } from 'react' -import { SDKDocsSidebar } from '@/components/developers/SDKDocsSidebar' -import { Copy, Check } from 'lucide-react' - -function CopyButton({ text }: { text: string }) { - const [copied, setCopied] = useState(false) - const handleCopy = async () => { - await navigator.clipboard.writeText(text) - setCopied(true) - setTimeout(() => setCopied(false), 2000) - } - return ( - - ) -} - -function CodeBlock({ code, filename }: { code: string; filename?: string }) { - return ( -
- {filename && ( -
- {filename} -
- )} -
-
- -
-
-          {code}
-        
-
-
- ) -} - -export default function AngularIntegrationPage() { - return ( -
- - -
-
-
-
- A -
-

Angular Integration

-
-

- Service und Module fuer Angular 14+ Projekte. -

- - {/* Installation */} -
-

Installation

- -
- - {/* Module Setup */} -
-

Module Setup

- -
- - {/* Standalone Setup */} -
-

Standalone Setup (Angular 15+)

- -
- - {/* Service Usage */} -
-

Service Usage

- - -
- \`, -}) -export class AnalyticsComponent implements OnInit { - hasAnalyticsConsent$ = this.consentService.hasConsent$('analytics'); - - constructor(private consentService: ConsentService) {} - - async loadAnalytics() { - if (await this.consentService.hasConsent('analytics')) { - // Load analytics - } - } -}`} - /> - - - {/* Cookie Banner */} -
-

Cookie Banner Component

- -
-

- Wir verwenden Cookies um Ihr Erlebnis zu verbessern. -

-
- - - -
-
-
- \`, -}) -export class CookieBannerComponent { - isBannerVisible$ = this.consentService.isBannerVisible$; - - constructor(private consentService: ConsentService) {} - - async acceptAll() { - await this.consentService.acceptAll(); - } - - async rejectAll() { - await this.consentService.rejectAll(); - } - - showSettings() { - this.consentService.showSettings(); - } -}`} - /> - - - {/* Directive */} -
-

ConsentGate Directive

- - - - -
- -
- -
-

Bitte stimmen Sie Statistik-Cookies zu.

- -
-
`} - /> -
- - {/* Service API */} -
-

Service API

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Property/Method - - Typ - - Beschreibung -
consent$Observable<ConsentState>Observable des aktuellen Consent
hasConsent$()Observable<boolean>Reaktive Consent-Pruefung
hasConsent()Promise<boolean>Async Consent-Pruefung
isBannerVisible$Observable<boolean>Banner-Sichtbarkeit
acceptAll()Promise<void>Akzeptiert alle
rejectAll()Promise<void>Lehnt alle ab
setConsent()Promise<void>Setzt spezifische Kategorien
-
-
- - - - ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/consent/frameworks/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/consent/frameworks/page.tsx deleted file mode 100644 index d8b1f88..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/consent/frameworks/page.tsx +++ /dev/null @@ -1,98 +0,0 @@ -'use client' - -import React from 'react' -import Link from 'next/link' -import { SDKDocsSidebar } from '@/components/developers/SDKDocsSidebar' -import { ChevronRight } from 'lucide-react' - -const frameworks = [ - { - name: 'React', - href: '/developers/sdk/consent/frameworks/react', - logo: '/logos/react.svg', - description: 'Hooks und Provider fuer React 17+ und Next.js', - features: ['ConsentProvider', 'useConsent Hook', 'ConsentGate Component'], - color: 'bg-cyan-500', - }, - { - name: 'Vue 3', - href: '/developers/sdk/consent/frameworks/vue', - logo: '/logos/vue.svg', - description: 'Composables und Plugin fuer Vue 3 und Nuxt', - features: ['Vue Plugin', 'useConsent Composable', 'ConsentGate Component'], - color: 'bg-emerald-500', - }, - { - name: 'Angular', - href: '/developers/sdk/consent/frameworks/angular', - logo: '/logos/angular.svg', - description: 'Service und Module fuer Angular 14+', - features: ['ConsentService', 'ConsentModule', 'Dependency Injection'], - color: 'bg-red-500', - }, -] - -export default function FrameworksPage() { - return ( -
- - -
-
-

Framework Integration

-

- Das Consent SDK bietet native Integrationen fuer alle gaengigen Frontend-Frameworks. -

- -
- {frameworks.map((framework) => ( - -
-
- {framework.name[0]} -
-
-
-

- {framework.name} -

- -
-

{framework.description}

-
- {framework.features.map((feature) => ( - - {feature} - - ))} -
-
-
- - ))} -
- - {/* Vanilla JS Note */} -
-

Vanilla JavaScript

-

- Sie koennen das SDK auch ohne Framework verwenden. Importieren Sie einfach den ConsentManager direkt - aus dem Hauptpaket. Siehe{' '} - - Installation - {' '} - fuer Details. -

-
-
-
-
- ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/consent/frameworks/react/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/consent/frameworks/react/page.tsx deleted file mode 100644 index d11c1c3..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/consent/frameworks/react/page.tsx +++ /dev/null @@ -1,277 +0,0 @@ -'use client' - -import React, { useState } from 'react' -import { SDKDocsSidebar } from '@/components/developers/SDKDocsSidebar' -import { Copy, Check } from 'lucide-react' - -function CopyButton({ text }: { text: string }) { - const [copied, setCopied] = useState(false) - const handleCopy = async () => { - await navigator.clipboard.writeText(text) - setCopied(true) - setTimeout(() => setCopied(false), 2000) - } - return ( - - ) -} - -function CodeBlock({ code, filename }: { code: string; filename?: string }) { - return ( -
- {filename && ( -
- {filename} -
- )} -
-
- -
-
-          {code}
-        
-
-
- ) -} - -export default function ReactIntegrationPage() { - return ( -
- - -
-
-
-
- R -
-

React Integration

-
-

- Hooks und Provider fuer React 17+ und Next.js Projekte. -

- - {/* Installation */} -
-

Installation

- -
- - {/* Provider Setup */} -
-

Provider Setup

-

- Umschliessen Sie Ihre App mit dem ConsentProvider: -

- - - - {children} - - - - ); -}`} - /> -
- - {/* useConsent Hook */} -
-

useConsent Hook

-

- Verwenden Sie den Hook in jeder Komponente: -

- - ); -}`} - /> -
- - {/* ConsentGate */} -
-

ConsentGate Component

-

- Zeigt Inhalte nur wenn Consent vorhanden ist: -

- -

Video erfordert Ihre Zustimmung.

- -
- } - > - `} - /> - - - {/* Requirements */} -
-

Systemvoraussetzungen

-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- Anforderung - - Minimum -
Node.js>= 18.0.0
React (optional)>= 17.0.0
Vue (optional)>= 3.0.0
TypeScript (optional)>= 4.7.0
-
-
- - {/* Browser Support */} -
-

Browser-Unterstuetzung

- - Das SDK unterstuetzt alle modernen Browser mit ES2017+ Unterstuetzung. - Fuer aeltere Browser wird ein automatischer Fallback fuer Crypto-Funktionen bereitgestellt. - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
- Browser - - Minimum Version -
Chrome>= 60
Firefox>= 55
Safari>= 11
Edge>= 79 (Chromium)
-
-
- - {/* Next Steps */} -
-

Naechste Schritte

-
- -

API Referenz

-

- Vollstaendige Dokumentation aller Methoden und Konfigurationsoptionen. -

-
- -

Framework Integration

-

- Detaillierte Anleitungen fuer React, Vue und Angular. -

-
-
-
-
- - - ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/android/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/android/page.tsx deleted file mode 100644 index 4ca46ce..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/android/page.tsx +++ /dev/null @@ -1,269 +0,0 @@ -'use client' - -import React, { useState } from 'react' -import { SDKDocsSidebar } from '@/components/developers/SDKDocsSidebar' -import { Copy, Check, Smartphone } from 'lucide-react' - -function CopyButton({ text }: { text: string }) { - const [copied, setCopied] = useState(false) - const handleCopy = async () => { - await navigator.clipboard.writeText(text) - setCopied(true) - setTimeout(() => setCopied(false), 2000) - } - return ( - - ) -} - -function CodeBlock({ code, filename }: { code: string; filename?: string }) { - return ( -
- {filename && ( -
- {filename} -
- )} -
-
- -
-
-          {code}
-        
-
-
- ) -} - -export default function AndroidSDKPage() { - return ( -
- - -
-
-
-
- -
-

Android SDK (Kotlin)

-
-

- Native Kotlin SDK fuer Android API 26+ mit Jetpack Compose Unterstuetzung. -

- - {/* Requirements */} -
-

Systemvoraussetzungen

-
- - - - - - - - - - - - - - - -
Kotlin Version1.9+
Min SDKAPI 26 (Android 8.0)
Compile SDK34+
-
-
- - {/* Installation */} -
-

Installation

- -
- - {/* Basic Setup */} -
-

Grundlegende Einrichtung

- -
- - {/* Jetpack Compose */} -
-

Jetpack Compose Integration

- -
- - {/* Traditional Android */} -
-

View-basierte Integration

- - updateUI(state) - } - } - - // Banner anzeigen wenn noetig - if (ConsentManager.needsConsent()) { - ConsentManager.showBanner(this) - } - } - - private fun updateUI(state: ConsentState?) { - if (state?.hasConsent(ConsentCategory.ANALYTICS) == true) { - loadAnalytics() - } - } - - fun onAcceptAllClick(view: View) { - lifecycleScope.launch { - ConsentManager.acceptAll() - } - } -}`} - /> -
- - {/* API Reference */} -
-

API Referenz

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodeBeschreibung
configure()SDK konfigurieren
initialize()SDK initialisieren (suspend)
hasConsent()Consent fuer Kategorie pruefen
consentFlowFlow fuer reaktive Updates
acceptAll()Alle akzeptieren (suspend)
rejectAll()Alle ablehnen (suspend)
setConsent()Kategorien setzen (suspend)
showBanner()Banner als DialogFragment
-
-
-
-
-
- ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/flutter/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/flutter/page.tsx deleted file mode 100644 index 196a98f..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/flutter/page.tsx +++ /dev/null @@ -1,313 +0,0 @@ -'use client' - -import React, { useState } from 'react' -import { SDKDocsSidebar } from '@/components/developers/SDKDocsSidebar' -import { Copy, Check, Smartphone } from 'lucide-react' - -function CopyButton({ text }: { text: string }) { - const [copied, setCopied] = useState(false) - const handleCopy = async () => { - await navigator.clipboard.writeText(text) - setCopied(true) - setTimeout(() => setCopied(false), 2000) - } - return ( - - ) -} - -function CodeBlock({ code, filename }: { code: string; filename?: string }) { - return ( -
- {filename && ( -
- {filename} -
- )} -
-
- -
-
-          {code}
-        
-
-
- ) -} - -export default function FlutterSDKPage() { - return ( -
- - -
-
-
-
- -
-

Flutter SDK

-
-

- Cross-Platform SDK fuer Flutter 3.16+ mit iOS, Android und Web Support. -

- - {/* Requirements */} -
-

Systemvoraussetzungen

-
- - - - - - - - - - - - - - - -
Dart Version3.0+
Flutter Version3.16+
PlattformeniOS, Android, Web
-
-
- - {/* Installation */} -
-

Installation

- -
- -
-
- - {/* Basic Setup */} -
-

Grundlegende Einrichtung

- -
- - {/* Widget Usage */} -
-

Widget Integration

- ( - stream: ConsentManager.instance.consentStream, - builder: (context, snapshot) { - final consent = snapshot.data; - - if (consent?.hasConsent(ConsentCategory.analytics) ?? false) { - return const AnalyticsWidget(); - } - - return const SizedBox.shrink(); - }, - ), - - // ConsentGate Widget - ConsentGate( - category: ConsentCategory.marketing, - fallback: const Center( - child: Text('Marketing-Zustimmung erforderlich'), - ), - child: const MarketingWidget(), - ), - - // Buttons - ElevatedButton( - onPressed: () => ConsentManager.instance.acceptAll(), - child: const Text('Alle akzeptieren'), - ), - - ElevatedButton( - onPressed: () => ConsentManager.instance.rejectAll(), - child: const Text('Alle ablehnen'), - ), - - TextButton( - onPressed: () => ConsentManager.instance.showSettings(context), - child: const Text('Einstellungen'), - ), - ], - ), - ); - } -}`} - /> -
- - {/* Custom Banner */} -
-

Custom Cookie Banner

- ( - stream: ConsentManager.instance.isBannerVisibleStream, - builder: (context, snapshot) { - if (!(snapshot.data ?? false)) { - return const SizedBox.shrink(); - } - - return Container( - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.1), - blurRadius: 10, - ), - ], - ), - child: SafeArea( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Text( - 'Wir verwenden Cookies um Ihr Erlebnis zu verbessern.', - style: TextStyle(fontSize: 14), - ), - const SizedBox(height: 16), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton( - onPressed: () => ConsentManager.instance.rejectAll(), - child: const Text('Ablehnen'), - ), - TextButton( - onPressed: () => ConsentManager.instance.showSettings(context), - child: const Text('Einstellungen'), - ), - ElevatedButton( - onPressed: () => ConsentManager.instance.acceptAll(), - child: const Text('Alle akzeptieren'), - ), - ], - ), - ], - ), - ), - ); - }, - ); - } -}`} - /> -
- - {/* API Reference */} -
-

API Referenz

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Methode/PropertyBeschreibung
initialize()SDK initialisieren (Future)
hasConsent()Consent pruefen
consentStreamStream fuer Consent-Updates
isBannerVisibleStreamStream fuer Banner-Sichtbarkeit
acceptAll()Alle akzeptieren (Future)
rejectAll()Alle ablehnen (Future)
setConsent()Kategorien setzen (Future)
showSettings()Einstellungs-Dialog oeffnen
-
-
-
-
-
- ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/ios/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/ios/page.tsx deleted file mode 100644 index 4ca4259..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/ios/page.tsx +++ /dev/null @@ -1,283 +0,0 @@ -'use client' - -import React, { useState } from 'react' -import { SDKDocsSidebar } from '@/components/developers/SDKDocsSidebar' -import { Copy, Check, Apple } from 'lucide-react' - -function CopyButton({ text }: { text: string }) { - const [copied, setCopied] = useState(false) - const handleCopy = async () => { - await navigator.clipboard.writeText(text) - setCopied(true) - setTimeout(() => setCopied(false), 2000) - } - return ( - - ) -} - -function CodeBlock({ code, filename }: { code: string; filename?: string }) { - return ( -
- {filename && ( -
- {filename} -
- )} -
-
- -
-
-          {code}
-        
-
-
- ) -} - -export default function iOSSDKPage() { - return ( -
- - -
-
-
-
- -
-

iOS SDK (Swift)

-
-

- Native Swift SDK fuer iOS 15+ und iPadOS mit SwiftUI-Unterstuetzung. -

- - {/* Requirements */} -
-

Systemvoraussetzungen

-
- - - - - - - - - - - - - - - -
Swift Version5.9+
iOS Deployment TargetiOS 15.0+
Xcode Version15.0+
-
-
- - {/* Installation */} -
-

Installation

-

Swift Package Manager

- -

- Oder in Xcode: File → Add Package Dependencies → URL eingeben -

-
- - {/* Basic Usage */} -
-

Grundlegende Verwendung

- Bool { - - // Consent Manager konfigurieren - ConsentManager.shared.configure( - apiEndpoint: "https://api.example.com/consent", - siteId: "my-ios-app" - ) - - // Initialisieren - Task { - await ConsentManager.shared.initialize() - } - - return true - } -}`} - /> -
- - {/* SwiftUI Integration */} -
-

SwiftUI Integration

- -
- - {/* UIKit Integration */} -
-

UIKit Integration

- () - - override func viewDidLoad() { - super.viewDidLoad() - - // Reaktiv auf Consent-Aenderungen reagieren - ConsentManager.shared.$consent - .receive(on: DispatchQueue.main) - .sink { [weak self] state in - self?.updateUI(consent: state) - } - .store(in: &cancellables) - } - - private func updateUI(consent: ConsentState?) { - if consent?.hasConsent(.analytics) == true { - loadAnalytics() - } - } - - @IBAction func acceptAllTapped(_ sender: UIButton) { - Task { - await ConsentManager.shared.acceptAll() - } - } -}`} - /> -
- - {/* Consent Categories */} -
-

Consent-Kategorien

- -
- - {/* API Reference */} -
-

API Referenz

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodeBeschreibung
configure()SDK konfigurieren
initialize()SDK initialisieren (async)
hasConsent(_:)Consent fuer Kategorie pruefen
acceptAll()Alle Kategorien akzeptieren (async)
rejectAll()Alle ablehnen (async)
setConsent(_:)Spezifische Kategorien setzen (async)
showBanner()Banner anzeigen
exportConsent()Consent-Daten exportieren (DSGVO)
-
-
-
-
-
- ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/page.tsx deleted file mode 100644 index 1dec219..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/consent/mobile/page.tsx +++ /dev/null @@ -1,95 +0,0 @@ -'use client' - -import React from 'react' -import Link from 'next/link' -import { SDKDocsSidebar } from '@/components/developers/SDKDocsSidebar' -import { ChevronRight, Apple, Smartphone } from 'lucide-react' - -const platforms = [ - { - name: 'iOS (Swift)', - href: '/developers/sdk/consent/mobile/ios', - description: 'Native Swift SDK fuer iOS 15+ und iPadOS', - features: ['Swift 5.9+', 'iOS 15.0+', 'SwiftUI Support', 'Combine Integration'], - color: 'bg-gray-900', - icon: Apple, - }, - { - name: 'Android (Kotlin)', - href: '/developers/sdk/consent/mobile/android', - description: 'Native Kotlin SDK fuer Android API 26+', - features: ['Kotlin 1.9+', 'API 26+', 'Jetpack Compose', 'Coroutines'], - color: 'bg-green-600', - icon: Smartphone, - }, - { - name: 'Flutter', - href: '/developers/sdk/consent/mobile/flutter', - description: 'Cross-Platform SDK fuer Flutter 3.16+', - features: ['Dart 3.0+', 'Flutter 3.16+', 'iOS & Android', 'Web Support'], - color: 'bg-blue-500', - icon: Smartphone, - }, -] - -export default function MobileSDKsPage() { - return ( -
- - -
-
-

Mobile SDKs

-

- Native SDKs fuer iOS, Android und Flutter mit vollstaendiger DSGVO-Konformitaet. -

- -
- {platforms.map((platform) => ( - -
-
- -
-
-
-

- {platform.name} -

- -
-

{platform.description}

-
- {platform.features.map((feature) => ( - - {feature} - - ))} -
-
-
- - ))} -
- - {/* Cross-Platform Note */} -
-

Cross-Platform Konsistenz

-

- Alle Mobile SDKs bieten dieselbe API-Oberflaeche wie das Web SDK. - Consent-Daten werden ueber die API synchronisiert, sodass Benutzer auf allen Geraeten - denselben Consent-Status haben. -

-
-
-
-
- ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/consent/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/consent/page.tsx deleted file mode 100644 index 9140be4..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/consent/page.tsx +++ /dev/null @@ -1,262 +0,0 @@ -'use client' - -import React, { useState } from 'react' -import Link from 'next/link' -import { - Shield, Code, Download, Smartphone, FileCode, Lock, - ChevronRight, Copy, Check, Zap, Globe, Layers, - BookOpen, Terminal -} from 'lucide-react' -import { SDKDocsSidebar } from '@/components/developers/SDKDocsSidebar' - -type Framework = 'npm' | 'yarn' | 'pnpm' - -const installCommands: Record = { - npm: 'npm install @breakpilot/consent-sdk', - yarn: 'yarn add @breakpilot/consent-sdk', - pnpm: 'pnpm add @breakpilot/consent-sdk', -} - -function CopyButton({ text }: { text: string }) { - const [copied, setCopied] = useState(false) - - const handleCopy = async () => { - await navigator.clipboard.writeText(text) - setCopied(true) - setTimeout(() => setCopied(false), 2000) - } - - return ( - - ) -} - -export default function ConsentSDKHubPage() { - const [selectedPM, setSelectedPM] = useState('npm') - - const quickLinks = [ - { - title: 'Installation', - description: 'SDK in wenigen Minuten einrichten', - href: '/developers/sdk/consent/installation', - icon: Download, - color: 'bg-blue-500', - }, - { - title: 'API Referenz', - description: 'Vollstaendige API-Dokumentation', - href: '/developers/sdk/consent/api-reference', - icon: FileCode, - color: 'bg-purple-500', - }, - { - title: 'Frameworks', - description: 'React, Vue, Angular Integration', - href: '/developers/sdk/consent/frameworks', - icon: Layers, - color: 'bg-green-500', - }, - { - title: 'Mobile SDKs', - description: 'iOS, Android, Flutter', - href: '/developers/sdk/consent/mobile', - icon: Smartphone, - color: 'bg-orange-500', - }, - { - title: 'Sicherheit', - description: 'Best Practices & Compliance', - href: '/developers/sdk/consent/security', - icon: Lock, - color: 'bg-red-500', - }, - ] - - const features = [ - { - title: 'DSGVO & TTDSG Konform', - description: 'Vollstaendige Unterstuetzung fuer EU-Datenschutzverordnungen mit revisionssicherer Consent-Speicherung.', - icon: Shield, - }, - { - title: 'Google Consent Mode v2', - description: 'Native Integration mit automatischer Synchronisation zu Google Analytics und Ads.', - icon: Globe, - }, - { - title: 'Script Blocking', - description: 'Automatisches Blockieren von Third-Party Scripts bis zur Einwilligung.', - icon: Code, - }, - { - title: 'Multi-Platform', - description: 'Unterstuetzung fuer Web, PWA, iOS, Android und Flutter aus einer Codebasis.', - icon: Smartphone, - }, - ] - - return ( -
- - -
-
- {/* Header */} -
-
-
- -
-
-

Consent SDK

-
- - v1.0.0 - - DSGVO/TTDSG Compliant -
-
-
-

- Das Consent SDK ermoeglicht DSGVO-konforme Einwilligungsverwaltung fuer Web, PWA und Mobile Apps. - Mit nativer Unterstuetzung fuer React, Vue, Angular und Mobile Platforms. -

-
- - {/* Quick Install */} -
-
-

Schnellinstallation

-
- {(['npm', 'yarn', 'pnpm'] as const).map((pm) => ( - - ))} -
-
-
- - $ {installCommands[selectedPM]} - - -
-
- - {/* Quick Links */} -
-

Dokumentation

-
- {quickLinks.map((link) => ( - -
-
- -
-
-

- {link.title} - -

-

{link.description}

-
-
- - ))} -
-
- - {/* Quick Start Code */} -
-
-

Schnellstart

-
-
-
-{`import { ConsentManager } from '@breakpilot/consent-sdk';
-
-// Manager initialisieren
-const consent = new ConsentManager({
-  apiEndpoint: 'https://api.example.com/consent',
-  siteId: 'your-site-id',
-});
-
-// SDK starten
-await consent.init();
-
-// Consent pruefen
-if (consent.hasConsent('analytics')) {
-  // Analytics laden
-}
-
-// Events abonnieren
-consent.on('change', (state) => {
-  console.log('Consent geaendert:', state);
-});`}
-              
-
-
- - {/* Features */} -
-

Features

-
- {features.map((feature) => ( -
-
-
- -
-
-

{feature.title}

-

{feature.description}

-
-
-
- ))} -
-
- - {/* Compliance Notice */} -
-
- -
-

DSGVO & TTDSG Compliance

-

- Das Consent SDK erfuellt alle Anforderungen der DSGVO (Art. 6, 7, 13, 14, 17, 20) und des TTDSG (§ 25). - Alle Einwilligungen werden revisionssicher gespeichert und koennen jederzeit exportiert werden. -

-
-
-
-
-
-
- ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/consent/security/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/consent/security/page.tsx deleted file mode 100644 index f3d0594..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/consent/security/page.tsx +++ /dev/null @@ -1,290 +0,0 @@ -'use client' - -import React from 'react' -import { SDKDocsSidebar } from '@/components/developers/SDKDocsSidebar' -import { Shield, Lock, Eye, Database, Key, AlertTriangle, CheckCircle } from 'lucide-react' - -function SecurityCard({ - title, - description, - icon: Icon, - items, -}: { - title: string - description: string - icon: React.ComponentType<{ className?: string }> - items: string[] -}) { - return ( -
-
-
- -
-
-

{title}

-

{description}

-
    - {items.map((item, i) => ( -
  • - - {item} -
  • - ))} -
-
-
-
- ) -} - -export default function SecurityPage() { - return ( -
- - -
-
-

Sicherheit & Compliance

-

- Best Practices fuer sichere Implementierung und DSGVO-konforme Nutzung des Consent SDK. -

- - {/* Security Features */} -
-

Sicherheits-Features

-
- - - - - - - -
-
- - {/* DSGVO Compliance */} -
-

DSGVO Compliance

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- DSGVO Artikel - - Anforderung - - SDK-Unterstuetzung -
Art. 6Rechtmaessigkeit der Verarbeitung - - Vollstaendig - -
Art. 7Bedingungen fuer Einwilligung - - Vollstaendig - -
Art. 13/14Informationspflichten - - Vollstaendig - -
Art. 17Recht auf Loeschung - - Vollstaendig - -
Art. 20Datenportabilitaet - - Vollstaendig - -
-
-
- - {/* TTDSG Compliance */} -
-

TTDSG Compliance

-
-
-
- -
-
-

§ 25 TTDSG - Schutz der Privatsphaere

-

- Das SDK erfuellt alle Anforderungen des § 25 TTDSG (Telemediengesetz): -

-
    -
  • - - - Einwilligung vor Speicherung: Cookies und localStorage werden erst nach - Einwilligung gesetzt (ausser technisch notwendige). - -
  • -
  • - - - Informierte Einwilligung: Klare Kategorisierung und Beschreibung - aller Cookies und Tracker. - -
  • -
  • - - - Widerrufsrecht: Jederzeit widerrufbare Einwilligung mit einem Klick. - -
  • -
-
-
-
-
- - {/* Best Practices */} -
-

Best Practices

- -
-
-

- - Empfohlen -

-
    -
  • • HTTPS fuer alle API-Aufrufe verwenden
  • -
  • • Consent-Banner vor dem Laden von Third-Party Scripts anzeigen
  • -
  • • Alle Kategorien klar und verstaendlich beschreiben
  • -
  • • Ablehnen-Button gleichwertig zum Akzeptieren-Button darstellen
  • -
  • • Consent-Aenderungen serverseitig protokollieren
  • -
  • • Regelmaessige Ueberpruefung der Consent-Gultigkeit (recheckAfterDays)
  • -
-
- -
-

- - Vermeiden -

-
    -
  • • Dark Patterns (versteckte Ablehnen-Buttons)
  • -
  • • Pre-checked Consent-Optionen
  • -
  • • Tracking vor Einwilligung
  • -
  • • Cookie-Walls ohne echte Alternative
  • -
  • • Unklare oder irrefuehrende Kategoriebezeichnungen
  • -
-
-
-
- - {/* Audit Trail */} -
-

Audit Trail

-
-

- Das SDK speichert fuer jeden Consent-Vorgang revisionssichere Daten: -

-
-
-{`{
-  "consentId": "consent_abc123...",
-  "timestamp": "2024-01-15T10:30:00.000Z",
-  "categories": {
-    "essential": true,
-    "analytics": true,
-    "marketing": false
-  },
-  "metadata": {
-    "userAgent": "Mozilla/5.0...",
-    "language": "de-DE",
-    "platform": "web",
-    "screenResolution": "1920x1080"
-  },
-  "signature": "sha256=...",
-  "version": "1.0.0"
-}`}
-                
-
-

- Diese Daten werden sowohl lokal als auch auf dem Server gespeichert und koennen - jederzeit fuer Audits exportiert werden. -

-
-
-
-
-
- ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/installation/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/installation/page.tsx deleted file mode 100644 index 6d6bd6d..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/installation/page.tsx +++ /dev/null @@ -1,186 +0,0 @@ -import { DevPortalLayout, CodeBlock, InfoBox, ParameterTable } from '@/components/developers/DevPortalLayout' - -export default function SDKInstallationPage() { - return ( - -

Voraussetzungen

-
    -
  • Node.js 18 oder hoeher
  • -
  • React 18+ / Next.js 14+
  • -
  • TypeScript 5.0+ (empfohlen)
  • -
- -

Installation

-

- Installieren Sie das SDK ueber Ihren bevorzugten Paketmanager: -

- -{`npm install @breakpilot/compliance-sdk`} - - -{`yarn add @breakpilot/compliance-sdk`} - - -{`pnpm add @breakpilot/compliance-sdk`} - - -

Peer Dependencies

-

- Das SDK hat folgende Peer Dependencies, die automatisch installiert werden sollten: -

- -{`{ - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } -}`} - - -

Zusaetzliche Pakete (optional)

-

- Fuer erweiterte Funktionen koennen Sie folgende Pakete installieren: -

- - -

TypeScript Konfiguration

-

- Das SDK ist vollstaendig in TypeScript geschrieben. Stellen Sie sicher, - dass Ihre tsconfig.json folgende Optionen enthaelt: -

- -{`{ - "compilerOptions": { - "target": "ES2020", - "lib": ["dom", "dom.iterable", "esnext"], - "module": "esnext", - "moduleResolution": "bundler", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true - } -}`} - - -

Next.js Integration

-

- Fuer Next.js 14+ mit App Router, fuegen Sie den Provider in Ihr Root-Layout ein: -

- -{`import { SDKProvider } from '@breakpilot/compliance-sdk' - -export default function RootLayout({ - children, -}: { - children: React.ReactNode -}) { - return ( - - - - {children} - - - - ) -}`} - - - - Der SDKProvider ist ein Client-Component. Wenn Sie Server Components - verwenden, wrappen Sie nur die Teile der App, die das SDK benoetigen. - - -

Umgebungsvariablen

-

- Erstellen Sie eine .env.local Datei mit folgenden Variablen: -

- -{`# Pflicht -NEXT_PUBLIC_TENANT_ID=your-tenant-id - -# Optional (fuer Backend-Sync) -BREAKPILOT_API_KEY=sk_live_... - -# Optional (fuer Self-Hosted) -NEXT_PUBLIC_SDK_API_URL=https://your-server.com/sdk/v1`} - - - - Der API Key sollte niemals im Frontend-Code oder in NEXT_PUBLIC_ Variablen - erscheinen. Verwenden Sie Server-Side API Routes fuer authentifizierte Anfragen. - - -

Verifizierung

-

- Testen Sie die Installation mit einer einfachen Komponente: -

- -{`'use client' - -import { useSDK } from '@breakpilot/compliance-sdk' - -export default function TestPage() { - const { state, completionPercentage } = useSDK() - - return ( -
-

SDK Test

-

Fortschritt: {completionPercentage}%

-

Aktuelle Phase: {state.currentPhase}

-

Use Cases: {state.useCases.length}

-
- ) -}`} -
- -

Fehlerbehebung

- -

Error: useSDK must be used within SDKProvider

-

- Stellen Sie sicher, dass der SDKProvider das gesamte Layout umschliesst - und dass Sie {'\'use client\''} in Client-Komponenten verwenden. -

- -

Error: Module not found

-

- Loeschen Sie node_modules und package-lock.json, dann reinstallieren: -

- -{`rm -rf node_modules package-lock.json -npm install`} - - -

TypeScript Errors

-

- Stellen Sie sicher, dass TypeScript 5.0+ installiert ist: -

- -{`npm install typescript@latest`} - -
- ) -} diff --git a/admin-lehrer/app/(admin)/developers/sdk/page.tsx b/admin-lehrer/app/(admin)/developers/sdk/page.tsx deleted file mode 100644 index 6578c42..0000000 --- a/admin-lehrer/app/(admin)/developers/sdk/page.tsx +++ /dev/null @@ -1,281 +0,0 @@ -import Link from 'next/link' -import { DevPortalLayout, CodeBlock, InfoBox } from '@/components/developers/DevPortalLayout' - -export default function SDKOverviewPage() { - return ( - -

Übersicht

-

- Das AI Compliance SDK ist ein TypeScript-Paket für die Integration des - Compliance-Workflows in React und Next.js Anwendungen. Es bietet: -

-
    -
  • React Context Provider für State Management
  • -
  • Hooks für einfachen Zugriff auf Compliance-Daten
  • -
  • Automatische Synchronisation mit dem Backend
  • -
  • Offline-Support mit localStorage Fallback
  • -
  • Export-Funktionen (PDF, JSON, ZIP)
  • -
- -

Kernkomponenten

- -

SDKProvider

-

- Der Provider wrappet Ihre App und stellt den SDK-Kontext bereit: -

- -{`import { SDKProvider } from '@breakpilot/compliance-sdk' - -export default function Layout({ children }) { - return ( - - {children} - - ) -}`} - - -

useSDK Hook

-

- Der Haupt-Hook für den Zugriff auf alle SDK-Funktionen: -

- -{`import { useSDK } from '@breakpilot/compliance-sdk' - -function MyComponent() { - const { - // State - state, - dispatch, - - // Navigation - currentStep, - goToStep, - goToNextStep, - goToPreviousStep, - canGoNext, - canGoPrevious, - - // Progress - completionPercentage, - phase1Completion, - phase2Completion, - - // Checkpoints - validateCheckpoint, - overrideCheckpoint, - getCheckpointStatus, - - // Data Updates - updateUseCase, - addRisk, - updateControl, - - // Persistence - saveState, - loadState, - - // Demo Data - seedDemoData, - clearDemoData, - isDemoDataLoaded, - - // Sync - syncState, - forceSyncToServer, - isOnline, - - // Export - exportState, - - // Command Bar - isCommandBarOpen, - setCommandBarOpen, - } = useSDK() - - return ( -
-

Progress: {completionPercentage}%

- -
- ) -}`} -
- -

Types

-

- Das SDK exportiert alle TypeScript-Types für volle Typsicherheit: -

- -{`import type { - // Core Types - SDKState, - SDKAction, - SDKStep, - SDKPhase, - - // Use Cases - UseCaseAssessment, - AssessmentResult, - - // Risk Management - Risk, - RiskSeverity, - RiskMitigation, - - // Controls & Evidence - Control, - Evidence, - Requirement, - - // Checkpoints - Checkpoint, - CheckpointStatus, - ValidationError, - - // DSFA - DSFA, - DSFASection, - DSFAApproval, - - // TOMs & VVT - TOM, - ProcessingActivity, - RetentionPolicy, - - // AI Act - AIActResult, - AIActRiskCategory, -} from '@breakpilot/compliance-sdk'`} - - -

Utility Functions

-

- Hilfreiche Funktionen für die Arbeit mit dem SDK: -

- -{`import { - // Step Navigation - getStepById, - getStepByUrl, - getNextStep, - getPreviousStep, - getStepsForPhase, - - // Risk Calculation - calculateRiskScore, - getRiskSeverityFromScore, - calculateResidualRisk, - - // Progress - getCompletionPercentage, - getPhaseCompletionPercentage, -} from '@breakpilot/compliance-sdk' - -// Beispiel: Risk Score berechnen -const inherentRisk = calculateRiskScore(4, 5) // likelihood * impact = 20 -const severity = getRiskSeverityFromScore(20) // 'CRITICAL'`} - - -

API Client

-

- Für direkten API-Zugriff ohne React Context: -

- -{`import { - getSDKApiClient, - SDKApiClient, -} from '@breakpilot/compliance-sdk' - -const client = getSDKApiClient('your-tenant-id') - -// State laden -const state = await client.getState() - -// State speichern -await client.saveState(updatedState) - -// Checkpoint validieren -const result = await client.validateCheckpoint('CP-UC', state) - -// Export -const blob = await client.exportState('pdf')`} - - -

RAG & LLM Client

-

- Zugriff auf die RAG-Suche und Dokumentengenerierung: -

- -{`import { - getSDKBackendClient, - isLegalQuery, -} from '@breakpilot/compliance-sdk' - -const client = getSDKBackendClient() - -// RAG-Suche -const results = await client.search('DSGVO Art. 5', 5) -console.log(results) // SearchResult[] - -// Dokumentengenerierung -const dsfa = await client.generateDSFA(context) -const toms = await client.generateTOM(context) -const vvt = await client.generateVVT(context) - -// Prüfen ob eine Query rechtliche Inhalte betrifft -if (isLegalQuery('Einwilligung DSGVO')) { - // RAG-Suche durchführen -}`} - - -

Export

-

- Exportieren Sie Compliance-Daten in verschiedenen Formaten: -

- -{`import { exportToPDF, exportToZIP, downloadExport } from '@breakpilot/compliance-sdk' - -// PDF Export -const pdfBlob = await exportToPDF(state) -downloadExport(pdfBlob, 'compliance-report.pdf') - -// ZIP Export (alle Dokumente) -const zipBlob = await exportToZIP(state) -downloadExport(zipBlob, 'compliance-export.zip') - -// Über den Hook -const { exportState } = useSDK() -const blob = await exportState('pdf') // 'json' | 'pdf' | 'zip'`} - - - -
    -
  • - - Installation Guide - -
  • -
  • - - Konfigurationsoptionen - -
  • -
  • - - Phase 1 Workflow Guide - -
  • -
-
-
- ) -} diff --git a/admin-lehrer/app/(sdk)/sdk/document-crawler/page.tsx b/admin-lehrer/app/(sdk)/sdk/document-crawler/page.tsx deleted file mode 100644 index 265edc4..0000000 --- a/admin-lehrer/app/(sdk)/sdk/document-crawler/page.tsx +++ /dev/null @@ -1,839 +0,0 @@ -'use client' - -import { useState, useEffect, useCallback } from 'react' - -// ============================================================================= -// TYPES -// ============================================================================= - -interface CrawlSource { - id: string - name: string - source_type: string - path: string - file_extensions: string[] - max_depth: number - exclude_patterns: string[] - enabled: boolean - created_at: string -} - -interface CrawlJob { - id: string - source_id: string - source_name?: string - status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled' - job_type: 'full' | 'delta' - files_found: number - files_processed: number - files_new: number - files_changed: number - files_skipped: number - files_error: number - error_message?: string - started_at?: string - completed_at?: string - created_at: string -} - -interface CrawlDocument { - id: string - file_name: string - file_extension: string - file_size_bytes: number - classification: string | null - classification_confidence: number | null - classification_corrected: boolean - extraction_status: string - archived: boolean - ipfs_cid: string | null - first_seen_at: string - last_seen_at: string - version_count: number - source_name?: string -} - -interface OnboardingReport { - id: string - total_documents_found: number - classification_breakdown: Record - gaps: GapItem[] - compliance_score: number - gap_summary?: { critical: number; high: number; medium: number } - created_at: string -} - -interface GapItem { - id: string - category: string - description: string - severity: 'CRITICAL' | 'HIGH' | 'MEDIUM' - regulation: string - requiredAction: string -} - -// ============================================================================= -// API HELPERS -// ============================================================================= - -const TENANT_ID = '00000000-0000-0000-0000-000000000001' // Default tenant - -async function api(path: string, options: RequestInit = {}) { - const res = await fetch(`/api/sdk/v1/crawler/${path}`, { - ...options, - headers: { - 'Content-Type': 'application/json', - 'X-Tenant-ID': TENANT_ID, - ...options.headers, - }, - }) - if (res.status === 204) return null - return res.json() -} - -// ============================================================================= -// CLASSIFICATION LABELS -// ============================================================================= - -const CLASSIFICATION_LABELS: Record = { - VVT: { label: 'VVT', color: 'bg-blue-100 text-blue-700' }, - TOM: { label: 'TOM', color: 'bg-green-100 text-green-700' }, - DSE: { label: 'DSE', color: 'bg-purple-100 text-purple-700' }, - AVV: { label: 'AVV', color: 'bg-orange-100 text-orange-700' }, - DSFA: { label: 'DSFA', color: 'bg-red-100 text-red-700' }, - Loeschkonzept: { label: 'Loeschkonzept', color: 'bg-yellow-100 text-yellow-700' }, - Einwilligung: { label: 'Einwilligung', color: 'bg-pink-100 text-pink-700' }, - Vertrag: { label: 'Vertrag', color: 'bg-indigo-100 text-indigo-700' }, - Richtlinie: { label: 'Richtlinie', color: 'bg-teal-100 text-teal-700' }, - Schulungsnachweis: { label: 'Schulung', color: 'bg-cyan-100 text-cyan-700' }, - Sonstiges: { label: 'Sonstiges', color: 'bg-gray-100 text-gray-700' }, -} - -const ALL_CLASSIFICATIONS = Object.keys(CLASSIFICATION_LABELS) - -// ============================================================================= -// TAB: QUELLEN (Sources) -// ============================================================================= - -function SourcesTab() { - const [sources, setSources] = useState([]) - const [loading, setLoading] = useState(true) - const [showForm, setShowForm] = useState(false) - const [formName, setFormName] = useState('') - const [formPath, setFormPath] = useState('') - const [testResult, setTestResult] = useState>({}) - - const loadSources = useCallback(async () => { - setLoading(true) - try { - const data = await api('sources') - setSources(data || []) - } catch { /* ignore */ } - setLoading(false) - }, []) - - useEffect(() => { loadSources() }, [loadSources]) - - const handleCreate = async () => { - if (!formName || !formPath) return - await api('sources', { - method: 'POST', - body: JSON.stringify({ name: formName, path: formPath }), - }) - setFormName('') - setFormPath('') - setShowForm(false) - loadSources() - } - - const handleDelete = async (id: string) => { - await api(`sources/${id}`, { method: 'DELETE' }) - loadSources() - } - - const handleToggle = async (source: CrawlSource) => { - await api(`sources/${source.id}`, { - method: 'PUT', - body: JSON.stringify({ enabled: !source.enabled }), - }) - loadSources() - } - - const handleTest = async (id: string) => { - setTestResult(prev => ({ ...prev, [id]: 'testing...' })) - const result = await api(`sources/${id}/test`, { method: 'POST' }) - setTestResult(prev => ({ ...prev, [id]: result?.message || 'Fehler' })) - } - - return ( -
-
-

Crawl-Quellen

- -
- - {showForm && ( -
-
- - setFormName(e.target.value)} - placeholder="z.B. Compliance-Ordner" - className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500" - /> -
-
- - setFormPath(e.target.value)} - placeholder="z.B. compliance-docs" - className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500" - /> -
-
- - -
-
- )} - - {loading ? ( -
Laden...
- ) : sources.length === 0 ? ( -
-

Keine Quellen konfiguriert

-

Erstellen Sie eine Crawl-Quelle um Dokumente zu scannen.

-
- ) : ( -
- {sources.map(s => ( -
-
-
-
{s.name}
-
{s.path}
-
- Tiefe: {s.max_depth} | Formate: {(typeof s.file_extensions === 'string' ? JSON.parse(s.file_extensions) : s.file_extensions).join(', ')} -
-
- {testResult[s.id] && ( - {testResult[s.id]} - )} - - - -
- ))} -
- )} -
- ) -} - -// ============================================================================= -// TAB: CRAWL-JOBS -// ============================================================================= - -function JobsTab() { - const [jobs, setJobs] = useState([]) - const [sources, setSources] = useState([]) - const [selectedSource, setSelectedSource] = useState('') - const [jobType, setJobType] = useState<'full' | 'delta'>('full') - const [loading, setLoading] = useState(true) - - const loadData = useCallback(async () => { - setLoading(true) - try { - const [j, s] = await Promise.all([api('jobs'), api('sources')]) - setJobs(j || []) - setSources(s || []) - if (!selectedSource && s?.length > 0) setSelectedSource(s[0].id) - } catch { /* ignore */ } - setLoading(false) - }, [selectedSource]) - - useEffect(() => { loadData() }, [loadData]) - - // Auto-refresh running jobs - useEffect(() => { - const hasRunning = jobs.some(j => j.status === 'running' || j.status === 'pending') - if (!hasRunning) return - const interval = setInterval(loadData, 3000) - return () => clearInterval(interval) - }, [jobs, loadData]) - - const handleTrigger = async () => { - if (!selectedSource) return - await api('jobs', { - method: 'POST', - body: JSON.stringify({ source_id: selectedSource, job_type: jobType }), - }) - loadData() - } - - const handleCancel = async (id: string) => { - await api(`jobs/${id}/cancel`, { method: 'POST' }) - loadData() - } - - const statusColor = (s: string) => { - switch (s) { - case 'completed': return 'bg-green-100 text-green-700' - case 'running': return 'bg-blue-100 text-blue-700' - case 'pending': return 'bg-yellow-100 text-yellow-700' - case 'failed': return 'bg-red-100 text-red-700' - case 'cancelled': return 'bg-gray-100 text-gray-600' - default: return 'bg-gray-100 text-gray-700' - } - } - - return ( -
- {/* Trigger form */} -
-

Neuen Crawl starten

-
-
- - -
-
- - -
- -
-
- - {/* Job list */} - {loading ? ( -
Laden...
- ) : jobs.length === 0 ? ( -
- Noch keine Crawl-Jobs ausgefuehrt. -
- ) : ( -
- {jobs.map(job => ( -
-
-
- - {job.status} - - {job.source_name || 'Quelle'} - {job.job_type === 'delta' ? 'Delta' : 'Voll'} -
-
- {(job.status === 'running' || job.status === 'pending') && ( - - )} - - {new Date(job.created_at).toLocaleString('de-DE')} - -
-
- - {/* Progress */} - {job.status === 'running' && job.files_found > 0 && ( -
-
-
-
-
- {job.files_processed} / {job.files_found} Dateien verarbeitet -
-
- )} - - {/* Stats */} -
-
-
{job.files_found}
-
Gefunden
-
-
-
{job.files_processed}
-
Verarbeitet
-
-
-
{job.files_new}
-
Neu
-
-
-
{job.files_changed}
-
Geaendert
-
-
-
{job.files_skipped}
-
Uebersprungen
-
-
-
{job.files_error}
-
Fehler
-
-
-
- ))} -
- )} -
- ) -} - -// ============================================================================= -// TAB: DOKUMENTE -// ============================================================================= - -function DocumentsTab() { - const [docs, setDocs] = useState([]) - const [total, setTotal] = useState(0) - const [loading, setLoading] = useState(true) - const [filterClass, setFilterClass] = useState('') - const [archiving, setArchiving] = useState>({}) - - const loadDocs = useCallback(async () => { - setLoading(true) - try { - const params = filterClass ? `?classification=${filterClass}` : '' - const data = await api(`documents${params}`) - setDocs(data?.documents || []) - setTotal(data?.total || 0) - } catch { /* ignore */ } - setLoading(false) - }, [filterClass]) - - useEffect(() => { loadDocs() }, [loadDocs]) - - const handleReclassify = async (docId: string, newClass: string) => { - await api(`documents/${docId}/classify`, { - method: 'PUT', - body: JSON.stringify({ classification: newClass }), - }) - loadDocs() - } - - const handleArchive = async (docId: string) => { - setArchiving(prev => ({ ...prev, [docId]: true })) - try { - await api(`documents/${docId}/archive`, { method: 'POST' }) - loadDocs() - } catch { /* ignore */ } - setArchiving(prev => ({ ...prev, [docId]: false })) - } - - const formatSize = (bytes: number) => { - if (bytes < 1024) return `${bytes} B` - if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB` - return `${(bytes / 1024 / 1024).toFixed(1)} MB` - } - - return ( -
-
-

{total} Dokumente

- -
- - {loading ? ( -
Laden...
- ) : docs.length === 0 ? ( -
- Keine Dokumente gefunden. Starten Sie zuerst einen Crawl-Job. -
- ) : ( -
- - - - - - - - - - - - - {docs.map(doc => { - const cls = CLASSIFICATION_LABELS[doc.classification || ''] || CLASSIFICATION_LABELS['Sonstiges'] - return ( - - - - - - - - - ) - })} - -
DateiKategorieKonfidenzGroesseArchivAktionen
-
{doc.file_name}
-
{doc.source_name}
-
- - {doc.classification_corrected && ( - * - )} - - {doc.classification_confidence != null && ( -
-
-
-
- - {(doc.classification_confidence * 100).toFixed(0)}% - -
- )} -
{formatSize(doc.file_size_bytes)} - {doc.archived ? ( - IPFS - ) : ( - - - )} - - {!doc.archived && ( - - )} -
-
- )} -
- ) -} - -// ============================================================================= -// TAB: ONBOARDING-REPORT -// ============================================================================= - -function ReportTab() { - const [reports, setReports] = useState([]) - const [activeReport, setActiveReport] = useState(null) - const [loading, setLoading] = useState(true) - const [generating, setGenerating] = useState(false) - - const loadReports = useCallback(async () => { - setLoading(true) - try { - const data = await api('reports') - setReports(data || []) - if (data?.length > 0 && !activeReport) { - const detail = await api(`reports/${data[0].id}`) - setActiveReport(detail) - } - } catch { /* ignore */ } - setLoading(false) - }, [activeReport]) - - useEffect(() => { loadReports() }, [loadReports]) - - const handleGenerate = async () => { - setGenerating(true) - try { - const result = await api('reports/generate', { - method: 'POST', - body: JSON.stringify({}), - }) - setActiveReport(result) - loadReports() - } catch { /* ignore */ } - setGenerating(false) - } - - const handleSelectReport = async (id: string) => { - const detail = await api(`reports/${id}`) - setActiveReport(detail) - } - - // Compliance score ring - const ComplianceRing = ({ score }: { score: number }) => { - const radius = 50 - const circumference = 2 * Math.PI * radius - const offset = circumference - (score / 100) * circumference - const color = score >= 75 ? '#16a34a' : score >= 50 ? '#f59e0b' : '#dc2626' - - return ( -
- - - - -
- {score.toFixed(0)}% - Compliance -
-
- ) - } - - return ( -
-
-

Onboarding-Report

- -
- - {/* Report selector */} - {reports.length > 1 && ( -
- {reports.map(r => ( - - ))} -
- )} - - {loading ? ( -
Laden...
- ) : !activeReport ? ( -
-

Kein Report vorhanden

-

Fuehren Sie zuerst einen Crawl durch und generieren Sie dann einen Report.

-
- ) : ( -
- {/* Score + Stats */} -
-
- -
-
-
{activeReport.total_documents_found}
-
Dokumente gefunden
-
-
-
- {Object.keys(activeReport.classification_breakdown || {}).length} -
-
Kategorien abgedeckt
-
-
-
- {(activeReport.gaps || []).length} -
-
Luecken identifiziert
-
-
-
-
- - {/* Classification breakdown */} -
-

Dokumenten-Verteilung

-
- {Object.entries(activeReport.classification_breakdown || {}).map(([cat, count]) => { - const cls = CLASSIFICATION_LABELS[cat] || CLASSIFICATION_LABELS['Sonstiges'] - return ( - - {cls.label}: {count as number} - - ) - })} - {Object.keys(activeReport.classification_breakdown || {}).length === 0 && ( - Keine Dokumente klassifiziert - )} -
-
- - {/* Gap summary */} - {activeReport.gap_summary && ( -
-
-
{activeReport.gap_summary.critical}
-
Kritisch
-
-
-
{activeReport.gap_summary.high}
-
Hoch
-
-
-
{activeReport.gap_summary.medium}
-
Mittel
-
-
- )} - - {/* Gap details */} - {(activeReport.gaps || []).length > 0 && ( -
-

Compliance-Luecken

-
- {activeReport.gaps.map((gap) => ( -
-
-
-
{gap.category}
-

{gap.description}

-
- - {gap.severity} - -
-
- Regulierung: {gap.regulation} | Aktion: {gap.requiredAction} -
-
- ))} -
-
- )} -
- )} -
- ) -} - -// ============================================================================= -// MAIN PAGE -// ============================================================================= - -type Tab = 'sources' | 'jobs' | 'documents' | 'report' - -export default function DocumentCrawlerPage() { - const [activeTab, setActiveTab] = useState('sources') - - const tabs: { id: Tab; label: string }[] = [ - { id: 'sources', label: 'Quellen' }, - { id: 'jobs', label: 'Crawl-Jobs' }, - { id: 'documents', label: 'Dokumente' }, - { id: 'report', label: 'Onboarding-Report' }, - ] - - return ( -
- {/* Header */} -
-

Document Crawler & Auto-Onboarding

-

- Automatisches Scannen von Dateisystemen, KI-Klassifizierung, IPFS-Archivierung und Compliance Gap-Analyse. -

-
- - {/* Tabs */} -
- -
- - {/* Tab content */} - {activeTab === 'sources' && } - {activeTab === 'jobs' && } - {activeTab === 'documents' && } - {activeTab === 'report' && } -
- ) -} diff --git a/admin-lehrer/app/(sdk)/sdk/dsb-portal/page.tsx b/admin-lehrer/app/(sdk)/sdk/dsb-portal/page.tsx deleted file mode 100644 index 4cf7bd4..0000000 --- a/admin-lehrer/app/(sdk)/sdk/dsb-portal/page.tsx +++ /dev/null @@ -1,2068 +0,0 @@ -'use client' - -import React, { useState, useEffect, useCallback, useRef } from 'react' - -// ============================================================================= -// TYPES -// ============================================================================= - -interface AssignmentOverview { - id: string - dsb_user_id: string - tenant_id: string - tenant_name: string - tenant_slug: string - status: string - contract_start: string - contract_end: string | null - monthly_hours_budget: number - notes: string - compliance_score: number - hours_this_month: number - hours_budget: number - open_task_count: number - urgent_task_count: number - next_deadline: string | null - created_at: string - updated_at: string -} - -interface DSBDashboard { - assignments: AssignmentOverview[] - total_assignments: number - active_assignments: number - total_hours_this_month: number - open_tasks: number - urgent_tasks: number - generated_at: string -} - -interface HourEntry { - id: string - assignment_id: string - date: string - hours: number - category: string - description: string - billable: boolean - created_at: string -} - -interface Task { - id: string - assignment_id: string - title: string - description: string - category: string - priority: string - status: string - due_date: string | null - completed_at: string | null - created_at: string - updated_at: string -} - -interface Communication { - id: string - assignment_id: string - direction: string - channel: string - subject: string - content: string - participants: string - created_at: string -} - -interface HoursSummary { - total_hours: number - billable_hours: number - by_category: Record - period: string -} - -// ============================================================================= -// CONSTANTS -// ============================================================================= - -const DSB_USER_ID = '00000000-0000-0000-0000-000000000001' - -const TASK_CATEGORIES = [ - 'DSFA-Pruefung', - 'Betroffenenanfrage', - 'Vorfall-Pruefung', - 'Audit-Vorbereitung', - 'Richtlinien-Pruefung', - 'Schulung', - 'Beratung', - 'Sonstiges', -] - -const HOUR_CATEGORIES = [ - 'DSFA-Pruefung', - 'Beratung', - 'Audit', - 'Schulung', - 'Vorfallreaktion', - 'Dokumentation', - 'Besprechung', - 'Sonstiges', -] - -const COMM_CHANNELS = ['E-Mail', 'Telefon', 'Besprechung', 'Portal', 'Brief'] - -const PRIORITY_LABELS: Record = { - urgent: 'Dringend', - high: 'Hoch', - medium: 'Mittel', - low: 'Niedrig', -} - -const PRIORITY_COLORS: Record = { - urgent: 'bg-red-100 text-red-700 border-red-200', - high: 'bg-orange-100 text-orange-700 border-orange-200', - medium: 'bg-blue-100 text-blue-700 border-blue-200', - low: 'bg-gray-100 text-gray-500 border-gray-200', -} - -const TASK_STATUS_LABELS: Record = { - open: 'Offen', - in_progress: 'In Bearbeitung', - waiting: 'Wartend', - completed: 'Erledigt', - cancelled: 'Abgebrochen', -} - -const TASK_STATUS_COLORS: Record = { - open: 'bg-blue-100 text-blue-700', - in_progress: 'bg-yellow-100 text-yellow-700', - waiting: 'bg-orange-100 text-orange-700', - completed: 'bg-green-100 text-green-700', - cancelled: 'bg-gray-100 text-gray-500', -} - -const ASSIGNMENT_STATUS_COLORS: Record = { - active: 'bg-green-100 text-green-700 border-green-300', - paused: 'bg-yellow-100 text-yellow-700 border-yellow-300', - terminated: 'bg-red-100 text-red-700 border-red-300', -} - -const ASSIGNMENT_STATUS_LABELS: Record = { - active: 'Aktiv', - paused: 'Pausiert', - terminated: 'Beendet', -} - -// ============================================================================= -// API HELPERS -// ============================================================================= - -async function apiFetch(url: string, options?: RequestInit): Promise { - const res = await fetch(url, { - ...options, - headers: { - 'Content-Type': 'application/json', - 'X-User-ID': DSB_USER_ID, - ...(options?.headers || {}), - }, - }) - if (!res.ok) { - const text = await res.text().catch(() => '') - throw new Error(`API Error ${res.status}: ${text || res.statusText}`) - } - return res.json() -} - -// ============================================================================= -// TOAST COMPONENT -// ============================================================================= - -interface ToastMessage { - id: number - message: string - type: 'success' | 'error' -} - -let toastIdCounter = 0 - -function useToast() { - const [toasts, setToasts] = useState([]) - - const addToast = useCallback((message: string, type: 'success' | 'error' = 'success') => { - const id = ++toastIdCounter - setToasts((prev) => [...prev, { id, message, type }]) - setTimeout(() => { - setToasts((prev) => prev.filter((t) => t.id !== id)) - }, 3500) - }, []) - - return { toasts, addToast } -} - -function ToastContainer({ toasts }: { toasts: ToastMessage[] }) { - if (toasts.length === 0) return null - return ( -
- {toasts.map((t) => ( -
- {t.message} -
- ))} -
- ) -} - -// ============================================================================= -// LOADING SKELETON -// ============================================================================= - -function Skeleton({ className = '' }: { className?: string }) { - return
-} - -function DashboardSkeleton() { - return ( -
-
- {Array.from({ length: 4 }).map((_, i) => ( - - ))} -
-
- {Array.from({ length: 3 }).map((_, i) => ( - - ))} -
-
- ) -} - -// ============================================================================= -// MODAL COMPONENT -// ============================================================================= - -function Modal({ - open, - onClose, - title, - children, - maxWidth = 'max-w-lg', -}: { - open: boolean - onClose: () => void - title: string - children: React.ReactNode - maxWidth?: string -}) { - const overlayRef = useRef(null) - - useEffect(() => { - if (!open) return - const handleEsc = (e: KeyboardEvent) => { - if (e.key === 'Escape') onClose() - } - document.addEventListener('keydown', handleEsc) - return () => document.removeEventListener('keydown', handleEsc) - }, [open, onClose]) - - if (!open) return null - - return ( -
{ - if (e.target === overlayRef.current) onClose() - }} - > -
-
-

{title}

- -
-
{children}
-
-
- ) -} - -// ============================================================================= -// STAT CARD -// ============================================================================= - -function StatCard({ - title, - value, - icon, - accent = false, -}: { - title: string - value: string | number - icon: React.ReactNode - accent?: boolean -}) { - return ( -
-
-
- {icon} -
-
-

{title}

-

- {value} -

-
-
-
- ) -} - -// ============================================================================= -// COMPLIANCE PROGRESS BAR -// ============================================================================= - -function ComplianceBar({ score }: { score: number }) { - const color = - score < 40 ? 'bg-red-500' : score < 70 ? 'bg-yellow-500' : 'bg-green-500' - const textColor = - score < 40 ? 'text-red-700' : score < 70 ? 'text-yellow-700' : 'text-green-700' - return ( -
-
-
-
- - {score}% - -
- ) -} - -// ============================================================================= -// HOURS PROGRESS BAR -// ============================================================================= - -function HoursBar({ used, budget }: { used: number; budget: number }) { - const pct = budget > 0 ? Math.min((used / budget) * 100, 100) : 0 - const over = used > budget - return ( -
-
-
-
- - {used}h / {budget}h - -
- ) -} - -// ============================================================================= -// BADGE -// ============================================================================= - -function Badge({ label, className = '' }: { label: string; className?: string }) { - return ( - - {label} - - ) -} - -// ============================================================================= -// FORM COMPONENTS -// ============================================================================= - -function FormLabel({ children, htmlFor }: { children: React.ReactNode; htmlFor?: string }) { - return ( - - ) -} - -function FormInput({ - id, - type = 'text', - value, - onChange, - placeholder, - required, - min, - max, - step, -}: { - id?: string - type?: string - value: string | number - onChange: (val: string) => void - placeholder?: string - required?: boolean - min?: string | number - max?: string | number - step?: string | number -}) { - return ( - onChange(e.target.value)} - placeholder={placeholder} - required={required} - min={min} - max={max} - step={step} - className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500" - /> - ) -} - -function FormTextarea({ - id, - value, - onChange, - placeholder, - rows = 3, -}: { - id?: string - value: string - onChange: (val: string) => void - placeholder?: string - rows?: number -}) { - return ( -