'use client' /** * Developer Documentation Page * * SDK-style documentation with architecture overview, API reference, * and interactive system architecture diagram */ import { useState } from 'react' import AdminLayout from '@/components/admin/AdminLayout' // Documentation paths for VS Code links const docPaths: Record = { 'postgres': 'docs/architecture/data-model.md', 'backend': 'docs/backend/README.md', 'consent-service': 'docs/consent-service/README.md', 'billing-service': 'docs/billing/billing-service-api.md', 'edu-search-service': 'docs/api/edu-search-seeds-api.md', 'dsms-gateway': 'docs/dsms/README.md', 'pca-platform': 'docs/api/pca-platform-api.md', 'matrix-synapse': 'docs/matrix/README.md', 'jitsi': 'docs/jitsi/README.md', 'mailpit': 'docs/guides/email-and-auth-testing.md', 'llm-gateway': 'docs/llm-platform/README.md', 'website': 'docs/website/README.md', 'opensearch': 'docs/llm-platform/guides/ollama-setup.md', 'klausur': 'klausur-service/docs/RAG-Admin-Spec.md', 'qdrant': 'klausur-service/docs/RAG-Admin-Spec.md', 'minio': 'klausur-service/docs/RAG-Admin-Spec.md', } // Base path for project (used for VS Code links) const PROJECT_BASE_PATH = '/Users/benjaminadmin/Projekte/breakpilot-pwa' // ================= ARCHITECTURE DIAGRAM DATA ================= interface ServiceNode { id: string name: string type: 'frontend' | 'backend' | 'database' | 'cache' | 'search' | 'storage' | 'security' | 'communication' | 'ai' | 'erp' port?: string technology: string description: string connections?: string[] } // All services in the architecture (30+ services) const ARCHITECTURE_SERVICES: ServiceNode[] = [ // Frontends { id: 'website', name: 'Admin Frontend', type: 'frontend', port: '3000', technology: 'Next.js 15', description: 'Admin Dashboard, Edu-Search, DSMS, Consent', connections: ['backend', 'consent-service'] }, { id: 'studio', name: 'Lehrer Studio', type: 'frontend', port: '8000', technology: 'FastAPI + JS', description: 'Klausur, School, Stundenplan Module', connections: ['backend'] }, { id: 'creator', name: 'Creator Studio', type: 'frontend', port: '-', technology: 'Vue 3', description: 'Content Creation Interface', connections: ['backend'] }, { id: 'policy-ui', name: 'Policy Vault UI', type: 'frontend', port: '4200', technology: 'Angular 17', description: 'Richtlinien-Verwaltung', connections: ['policy-api'] }, // Python Backend { id: 'backend', name: 'Main Backend', type: 'backend', port: '8000', technology: 'Python FastAPI', description: 'Haupt-API, DevSecOps, Studio UI', connections: ['postgres', 'vault', 'redis', 'qdrant', 'minio'] }, { id: 'klausur', name: 'Klausur Service', type: 'backend', port: '8086', technology: 'Python FastAPI', description: 'BYOEH Abitur-Klausurkorrektur, RAG Admin, NiBiS Ingestion', connections: ['postgres', 'minio', 'qdrant'] }, // Go Microservices { id: 'consent-service', name: 'Consent Service', type: 'backend', port: '8081', technology: 'Go Gin', description: 'DSGVO Consent Management', connections: ['postgres'] }, { id: 'school-service', name: 'School Service', type: 'backend', port: '8084', technology: 'Go Gin', description: 'Klausuren, Noten, Zeugnisse', connections: ['postgres'] }, { id: 'billing-service', name: 'Billing Service', type: 'backend', port: '8083', technology: 'Go Gin', description: 'Stripe Integration', connections: ['postgres'] }, { id: 'dsms-gateway', name: 'DSMS Gateway', type: 'backend', port: '8082', technology: 'Go', description: 'IPFS REST API', connections: ['ipfs'] }, // Node.js Services { id: 'h5p', name: 'H5P Service', type: 'backend', port: '8085', technology: 'Node.js', description: 'Interaktive Inhalte', connections: ['postgres', 'minio'] }, { id: 'policy-api', name: 'Policy Vault API', type: 'backend', port: '3001', technology: 'NestJS', description: 'Richtlinien-Verwaltung API', connections: ['postgres'] }, // Databases { id: 'postgres', name: 'PostgreSQL', type: 'database', port: '5432', technology: 'PostgreSQL 16', description: 'Hauptdatenbank', connections: [] }, { id: 'synapse-db', name: 'Synapse DB', type: 'database', port: '-', technology: 'PostgreSQL 16', description: 'Matrix Datenbank', connections: [] }, { id: 'mariadb', name: 'MariaDB', type: 'database', port: '-', technology: 'MariaDB 10.6', description: 'ERPNext Datenbank', connections: [] }, { id: 'mongodb', name: 'MongoDB', type: 'database', port: '27017', technology: 'MongoDB 7', description: 'LibreChat Datenbank', connections: [] }, // Cache & Queue { id: 'redis', name: 'Redis', type: 'cache', port: '6379', technology: 'Redis Alpine', description: 'Cache & Sessions', connections: [] }, // Search Engines { id: 'qdrant', name: 'Qdrant', type: 'search', port: '6333', technology: 'Qdrant 1.7', description: 'Vector DB - NiBiS EWH (7352 Chunks), BYOEH', connections: [] }, { id: 'opensearch', name: 'OpenSearch', type: 'search', port: '9200', technology: 'OpenSearch 2.x', description: 'Volltext-Suche', connections: [] }, { id: 'meilisearch', name: 'Meilisearch', type: 'search', port: '7700', technology: 'Meilisearch', description: 'Instant Search', connections: [] }, // Storage { id: 'minio', name: 'MinIO', type: 'storage', port: '9000/9001', technology: 'MinIO', description: 'S3-kompatibel - RAG Dokumente, Landes/Lehrer-Daten', connections: [] }, { id: 'ipfs', name: 'IPFS (Kubo)', type: 'storage', port: '5001', technology: 'IPFS 0.24', description: 'Dezentral', connections: [] }, // Security { id: 'vault', name: 'Vault', type: 'security', port: '8200', technology: 'HashiCorp Vault', description: 'Secrets Management', connections: [] }, { id: 'keycloak', name: 'Keycloak', type: 'security', port: '8180', technology: 'Keycloak 23', description: 'SSO/OIDC', connections: ['postgres'] }, // Communication { id: 'synapse', name: 'Matrix Synapse', type: 'communication', port: '8008', technology: 'Matrix', description: 'E2EE Messenger', connections: ['synapse-db'] }, { id: 'jitsi', name: 'Jitsi Meet', type: 'communication', port: '8443', technology: 'Jitsi', description: 'Videokonferenz', connections: [] }, // AI/LLM { id: 'librechat', name: 'LibreChat', type: 'ai', port: '3080', technology: 'LibreChat', description: 'Multi-LLM Chat', connections: ['mongodb', 'qdrant'] }, { id: 'ragflow', name: 'RAGFlow', type: 'ai', port: '9380', technology: 'RAGFlow', description: 'RAG Pipeline', connections: ['qdrant', 'opensearch'] }, // ERP { id: 'erpnext', name: 'ERPNext', type: 'erp', port: '8090', technology: 'ERPNext v15', description: 'Open Source ERP', connections: ['mariadb', 'redis'] }, ] // Architecture layers const LAYERS = [ { id: 'presentation', name: 'Presentation Layer', description: 'User Interfaces & Frontends', types: ['frontend'] }, { id: 'application', name: 'Application Layer', description: 'Business Logic & APIs', types: ['backend'] }, { id: 'data', name: 'Data Layer', description: 'Databases, Cache & Search', types: ['database', 'cache', 'search'] }, { id: 'infrastructure', name: 'Infrastructure Layer', description: 'Storage, Security & Communication', types: ['storage', 'security', 'communication', 'ai', 'erp'] }, ] const getArchTypeColor = (type: ServiceNode['type']) => { switch (type) { case 'frontend': return { bg: 'bg-blue-500', border: 'border-blue-600', text: 'text-blue-800', light: 'bg-blue-50' } case 'backend': return { bg: 'bg-green-500', border: 'border-green-600', text: 'text-green-800', light: 'bg-green-50' } case 'database': return { bg: 'bg-purple-500', border: 'border-purple-600', text: 'text-purple-800', light: 'bg-purple-50' } case 'cache': return { bg: 'bg-cyan-500', border: 'border-cyan-600', text: 'text-cyan-800', light: 'bg-cyan-50' } case 'search': return { bg: 'bg-pink-500', border: 'border-pink-600', text: 'text-pink-800', light: 'bg-pink-50' } case 'storage': return { bg: 'bg-orange-500', border: 'border-orange-600', text: 'text-orange-800', light: 'bg-orange-50' } case 'security': return { bg: 'bg-red-500', border: 'border-red-600', text: 'text-red-800', light: 'bg-red-50' } case 'communication': return { bg: 'bg-yellow-500', border: 'border-yellow-600', text: 'text-yellow-800', light: 'bg-yellow-50' } case 'ai': return { bg: 'bg-violet-500', border: 'border-violet-600', text: 'text-violet-800', light: 'bg-violet-50' } case 'erp': return { bg: 'bg-indigo-500', border: 'border-indigo-600', text: 'text-indigo-800', light: 'bg-indigo-50' } default: return { bg: 'bg-gray-500', border: 'border-gray-600', text: 'text-gray-800', light: 'bg-gray-50' } } } const getArchTypeLabel = (type: ServiceNode['type']) => { switch (type) { case 'frontend': return 'Frontend' case 'backend': return 'Backend' case 'database': return 'Datenbank' case 'cache': return 'Cache' case 'search': return 'Suche' case 'storage': return 'Speicher' case 'security': return 'Sicherheit' case 'communication': return 'Kommunikation' case 'ai': return 'KI/LLM' case 'erp': return 'ERP' default: return type } } // ================= API SERVICES DATA ================= // Service definitions with ports, technologies, and API info const services = [ { id: 'postgres', name: 'PostgreSQL', type: 'database', port: 5432, container: 'breakpilot-pwa-postgres', description: 'Zentrale Datenbank für alle Services', purpose: 'Persistente Datenspeicherung für Benutzer, Dokumente, Consents und alle Anwendungsdaten mit pgvector für Embedding-Suche.', tech: ['PostgreSQL 15', 'pgvector'], healthEndpoint: null, endpoints: [], envVars: ['POSTGRES_USER', 'POSTGRES_PASSWORD', 'POSTGRES_DB'], }, { id: 'backend', name: 'Python Backend', type: 'backend', port: 8000, container: 'breakpilot-pwa-backend', description: 'FastAPI Backend mit AI-Integration und GDPR-Export', purpose: 'Zentrale API-Schicht für das Studio-Frontend mit AI-gestützter Arbeitsblatt-Generierung, Multi-LLM-Integration und DSGVO-konformem Datenexport.', tech: ['Python 3.11', 'FastAPI', 'SQLAlchemy', 'Pydantic'], healthEndpoint: '/health', endpoints: [ { method: 'GET', path: '/api/v1/health', description: 'Health Check' }, { method: 'POST', path: '/api/v1/chat', description: 'AI Chat Endpoint' }, { method: 'GET', path: '/api/v1/gdpr/export', description: 'DSGVO Datenexport' }, { method: 'POST', path: '/api/v1/seeds', description: 'Edu Search Seeds' }, ], envVars: ['DATABASE_URL', 'JWT_SECRET', 'OPENAI_API_KEY', 'ANTHROPIC_API_KEY'], }, { id: 'consent-service', name: 'Consent Service', type: 'backend', port: 8081, container: 'breakpilot-pwa-consent-service', description: 'Go-basierter Consent-Management-Service', purpose: 'DSGVO-konforme Einwilligungsverwaltung mit Versionierung, Audit-Trail und rechtssicherer Dokumentenspeicherung für Schulen.', tech: ['Go 1.21', 'Gin', 'GORM', 'JWT'], healthEndpoint: '/health', endpoints: [ { method: 'GET', path: '/api/v1/health', description: 'Health Check' }, { method: 'GET', path: '/api/v1/consent/check', description: 'Consent Status pruefen' }, { method: 'POST', path: '/api/v1/consent/grant', description: 'Consent erteilen' }, { method: 'GET', path: '/api/v1/documents', description: 'Rechtsdokumente abrufen' }, { method: 'GET', path: '/api/v1/communication/status', description: 'Matrix/Jitsi Status' }, { method: 'POST', path: '/api/v1/communication/rooms', description: 'Matrix Raum erstellen' }, { method: 'POST', path: '/api/v1/communication/meetings', description: 'Jitsi Meeting erstellen' }, ], envVars: ['DATABASE_URL', 'JWT_SECRET', 'PORT', 'MATRIX_HOMESERVER_URL', 'JITSI_BASE_URL'], }, { id: 'billing-service', name: 'Billing Service', type: 'backend', port: 8083, container: 'breakpilot-pwa-billing-service', description: 'Stripe-basiertes Billing mit Trial & Subscription', purpose: 'Monetarisierung der Plattform mit 7-Tage-Trial, gestuften Abo-Modellen (Basic/Standard/Premium) und automatischer Nutzungslimitierung.', tech: ['Go 1.21', 'Gin', 'Stripe API', 'pgx'], healthEndpoint: '/health', endpoints: [ { method: 'GET', path: '/api/v1/billing/status', description: 'Subscription Status' }, { method: 'POST', path: '/api/v1/billing/trial/start', description: 'Trial starten' }, { method: 'POST', path: '/api/v1/billing/webhook', description: 'Stripe Webhooks' }, ], envVars: ['DATABASE_URL', 'STRIPE_SECRET_KEY', 'STRIPE_WEBHOOK_SECRET'], }, { id: 'edu-search-service', name: 'Edu Search Service', type: 'backend', port: 8086, container: 'breakpilot-edu-search', description: 'Bildungsquellen-Crawler mit OpenSearch-Integration', purpose: 'Automatisches Crawlen und Indexieren von Bildungsressourcen (OER, Lehrpläne, Schulbücher) für RAG-gestützte Arbeitsblatterstellung.', tech: ['Go 1.23', 'Gin', 'OpenSearch', 'Colly'], healthEndpoint: '/v1/health', endpoints: [ { method: 'GET', path: '/v1/health', description: 'Health Check' }, { method: 'GET', path: '/v1/search', description: 'Dokumentensuche' }, { method: 'POST', path: '/v1/crawl/start', description: 'Crawler starten' }, { method: 'GET', path: '/api/v1/staff/stats', description: 'Staff Statistiken' }, { method: 'POST', path: '/api/v1/admin/crawl/staff', description: 'Staff Crawl starten' }, ], envVars: ['OPENSEARCH_URL', 'DB_HOST', 'DB_USER', 'DB_PASSWORD'], }, { id: 'dsms-gateway', name: 'DSMS Gateway', type: 'backend', port: 8082, container: 'breakpilot-pwa-dsms-gateway', description: 'Datenschutz-Management Gateway', purpose: 'Dezentrale Dokumentenspeicherung mit IPFS-Integration für manipulationssichere Audit-Logs und Rechtsdokumente.', tech: ['Go 1.21', 'Gin', 'IPFS'], healthEndpoint: '/health', endpoints: [ { method: 'GET', path: '/health', description: 'Health Check' }, { method: 'POST', path: '/api/v1/documents', description: 'Dokument speichern' }, ], envVars: ['IPFS_URL', 'DATABASE_URL'], }, { id: 'pca-platform', name: 'PCA Platform', type: 'backend', port: 8084, container: 'breakpilot-pca-platform', description: 'Payment Card Adapter für Taschengeld-Management', purpose: 'Fintech-Integration für Schüler-Taschengeld mit virtuellen Karten, Spending-Limits und Echtzeit-Transaktionsverfolgung für Eltern.', tech: ['Go 1.21', 'Gin', 'Stripe Issuing', 'pgx'], healthEndpoint: '/health', endpoints: [ { method: 'GET', path: '/api/v1/health', description: 'Health Check' }, { method: 'POST', path: '/api/v1/cards/create', description: 'Virtuelle Karte erstellen' }, { method: 'GET', path: '/api/v1/transactions', description: 'Transaktionen abrufen' }, { method: 'POST', path: '/api/v1/wallet/topup', description: 'Wallet aufladen' }, ], envVars: ['DATABASE_URL', 'STRIPE_SECRET_KEY', 'STRIPE_WEBHOOK_SECRET'], }, { id: 'matrix-synapse', name: 'Matrix Synapse', type: 'communication', port: 8448, container: 'breakpilot-synapse', description: 'Ende-zu-Ende verschlüsselter Messenger', purpose: 'Sichere Kommunikation zwischen Lehrern und Eltern mit E2EE, Raum-Management und DSGVO-konformer Nachrichtenspeicherung.', tech: ['Matrix Protocol', 'Synapse', 'PostgreSQL'], healthEndpoint: '/_matrix/client/versions', endpoints: [ { method: 'GET', path: '/_matrix/client/versions', description: 'Client Versions' }, { method: 'POST', path: '/_matrix/client/v3/login', description: 'Matrix Login' }, { method: 'POST', path: '/_matrix/client/v3/createRoom', description: 'Raum erstellen' }, ], envVars: ['SYNAPSE_SERVER_NAME', 'POSTGRES_HOST', 'SYNAPSE_REGISTRATION_SHARED_SECRET'], }, { id: 'jitsi', name: 'Jitsi Meet', type: 'communication', port: 8443, container: 'breakpilot-jitsi', description: 'Videokonferenz-Plattform', purpose: 'Virtuelle Elterngespräche und Klassenkonferenzen mit optionaler JWT-Authentifizierung und Embedded-Integration ins Studio.', tech: ['Jitsi Meet', 'Prosody', 'JWT Auth'], healthEndpoint: '/http-bind', endpoints: [ { method: 'GET', path: '/http-bind', description: 'BOSH Endpoint' }, { method: 'GET', path: '/config.js', description: 'Jitsi Konfiguration' }, ], envVars: ['JITSI_APP_ID', 'JITSI_APP_SECRET', 'PUBLIC_URL'], }, { id: 'mailpit', name: 'Mailpit (SMTP)', type: 'infrastructure', port: 1025, container: 'breakpilot-pwa-mailpit', description: 'E-Mail-Testing und Vorschau', purpose: 'Lokaler SMTP-Server für E-Mail-Vorschau im Development mit Web-UI auf Port 8025 zur Überprüfung von Lifecycle-Emails.', tech: ['Mailpit', 'SMTP', 'Web UI'], healthEndpoint: null, endpoints: [ { method: 'GET', path: '/', description: 'Web UI (Port 8025)' }, ], envVars: ['MP_SMTP_AUTH', 'MP_SMTP_AUTH_ALLOW_INSECURE'], }, { id: 'llm-gateway', name: 'LLM Gateway', type: 'backend', port: 8085, container: 'breakpilot-llm-gateway', description: 'Multi-Provider LLM Router', purpose: 'Einheitliche API für verschiedene LLM-Anbieter (OpenAI, Anthropic, Ollama) mit Provider-Switching, Token-Tracking und Fallback-Logik.', tech: ['Python 3.11', 'FastAPI', 'LiteLLM'], healthEndpoint: '/health', endpoints: [ { method: 'GET', path: '/health', description: 'Health Check' }, { method: 'POST', path: '/v1/chat/completions', description: 'Chat Completion (OpenAI-kompatibel)' }, { method: 'GET', path: '/v1/models', description: 'Verfügbare Modelle' }, ], envVars: ['OPENAI_API_KEY', 'ANTHROPIC_API_KEY', 'OLLAMA_BASE_URL'], }, { id: 'website', name: 'Website (Next.js)', type: 'frontend', port: 3000, container: 'breakpilot-pwa-website', description: 'Next.js 14 Frontend mit App Router', purpose: 'Admin-Dashboard, Landing-Page und API-Routing für das Next.js Frontend mit Server Components und Edge Functions.', tech: ['Next.js 14', 'React 18', 'TypeScript', 'Tailwind CSS'], healthEndpoint: null, endpoints: [ { method: 'GET', path: '/', description: 'Landing Page' }, { method: 'GET', path: '/admin', description: 'Admin Dashboard' }, { method: 'GET', path: '/app', description: 'Benutzer-App (redirect to :8000)' }, ], envVars: ['NEXT_PUBLIC_API_URL', 'NEXTAUTH_SECRET'], }, { id: 'opensearch', name: 'OpenSearch', type: 'database', port: 9200, container: 'breakpilot-opensearch', description: 'Volltextsuche und Vektorsuche', purpose: 'Hochperformante Suche in Bildungsressourcen mit k-NN für semantische Ähnlichkeitssuche und BM25 für Keyword-Matching.', tech: ['OpenSearch 2.11', 'k-NN Plugin'], healthEndpoint: '/', endpoints: [ { method: 'GET', path: '/_cluster/health', description: 'Cluster Health' }, { method: 'POST', path: '/bp_documents_v1/_search', description: 'Dokumentensuche' }, ], envVars: ['OPENSEARCH_JAVA_OPTS'], }, ] // Architecture diagram as ASCII art (will be styled) const architectureAscii = ` BreakPilot Platform Architecture ┌─────────────────────────────────────────────────────────────────────────────────────────────┐ │ FRONTEND LAYER │ ├─────────────────────────────────────────────────────────────────────────────────────────────┤ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │ │ Website (3000) │ │ Studio App (8000) │ │ │ │ Next.js 14 │ │ FastAPI + Jinja │ │ │ │ Admin Dashboard │◄────────────────────────────►│ Arbeitsblatt UI │ │ │ └─────────────────────┘ └─────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────────────────────┘ │ │ ▼ ▼ ┌─────────────────────────────────────────────────────────────────────────────────────────────┐ │ BACKEND LAYER │ ├───────────────────┬───────────────────┬───────────────────┬─────────────────────────────────┤ │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐ │ │ │ Consent (8081)│ │ │ Billing (8083)│ │ │ PCA (8084) │ │ │ LLM GW (8085) │ │ │ │ Go/Gin │ │ │ Go/Stripe │ │ │ Go/Stripe │ │ │ Python/LiteLLM│ │ │ │ DSGVO-Consent │ │ │ Subscriptions │ │ │ Taschengeld │ │ │ Multi-Provider│ │ │ └───────┬───────┘ │ └───────┬───────┘ │ └───────┬───────┘ │ └───────────────┘ │ │ │ │ │ │ │ │ │ │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐ │ │ │ DSMS (8082) │ │ │ EduSearch │ │ │ StaffSearch │ │ │ Alerts Agent │ │ │ │ Go/IPFS │ │ │ (8086) Go │ │ │ Go/Colly │ │ │ Python/Tavily │ │ │ │ Audit Storage │ │ │ Bildungs-RAG │ │ │ Lehrersuche │ │ │ News-Alerts │ │ │ └───────────────┘ │ └───────┬───────┘ │ └───────────────┘ │ └───────────────┘ │ └───────────────────┴─────────┼─────────┴───────────────────┴─────────────────────────────────┘ │ ┌─────────────────────────────┼───────────────────────────────────────────────────────────────┐ │ DATA LAYER │ ├───────────────────┬─────────┼─────────┬─────────────────────────────────────────────────────┤ │ ┌───────────────┐ │ ┌───────┴───────┐ │ │ │ │ PostgreSQL │ │ │ OpenSearch │ │ │ │ │ (5432) │◄┼►│ (9200) │ │ │ │ │ + pgvector │ │ │ + k-NN Plugin │ │ │ │ └───────────────┘ │ └───────────────┘ │ │ └───────────────────┴───────────────────┴─────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────────────────────────┐ │ COMMUNICATION LAYER │ ├───────────────────┬───────────────────┬─────────────────────────────────────────────────────┤ │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐ │ │ │ Matrix (8448) │ │ │ Jitsi (8443) │ │ │ Mailpit (1025)│ │ │ │ E2EE Messenger│ │ │ Video Calls │ │ │ Email Testing │ │ │ │ Lehrer-Eltern │ │ │ Elterngespräch│ │ │ SMTP + Web UI │ │ │ └───────────────┘ │ └───────────────┘ │ └───────────────┘ │ └───────────────────┴───────────────────┴─────────────────────────────────────────────────────┘ ` type TabType = 'overview' | 'services' | 'api' | 'docker' | 'testing' export default function DeveloperDocsPage() { const [activeTab, setActiveTab] = useState('overview') const [selectedService, setSelectedService] = useState(null) const [copiedEndpoint, setCopiedEndpoint] = useState(null) // Architecture-specific state const [selectedArchService, setSelectedArchService] = useState(null) const [activeLayer, setActiveLayer] = useState('all') // Architecture helper functions const getServicesForLayer = (layer: typeof LAYERS[0]) => { return ARCHITECTURE_SERVICES.filter(s => layer.types.includes(s.type)) } const archStats = { total: ARCHITECTURE_SERVICES.length, frontends: ARCHITECTURE_SERVICES.filter(s => s.type === 'frontend').length, backends: ARCHITECTURE_SERVICES.filter(s => s.type === 'backend').length, databases: ARCHITECTURE_SERVICES.filter(s => s.type === 'database').length, infrastructure: ARCHITECTURE_SERVICES.filter(s => ['cache', 'search', 'storage', 'security', 'communication', 'ai', 'erp'].includes(s.type)).length, } const copyToClipboard = (text: string, id: string) => { navigator.clipboard.writeText(text) setCopiedEndpoint(id) setTimeout(() => setCopiedEndpoint(null), 2000) } const getServiceTypeColor = (type: string) => { switch (type) { case 'frontend': return 'bg-blue-100 text-blue-800' case 'backend': return 'bg-green-100 text-green-800' case 'database': return 'bg-purple-100 text-purple-800' case 'communication': return 'bg-orange-100 text-orange-800' case 'infrastructure': return 'bg-slate-200 text-slate-700' default: return 'bg-gray-100 text-gray-800' } } const getMethodColor = (method: string) => { switch (method) { case 'GET': return 'bg-emerald-100 text-emerald-700' case 'POST': return 'bg-blue-100 text-blue-700' case 'PUT': return 'bg-amber-100 text-amber-700' case 'DELETE': return 'bg-red-100 text-red-700' default: return 'bg-gray-100 text-gray-700' } } return ( {/* Tab Navigation */}
{/* Overview Tab - Interactive Architecture */} {activeTab === 'overview' && (
{/* Stats */}
{archStats.total}
Services Total
{archStats.frontends}
Frontends
{archStats.backends}
Backends
{archStats.databases}
Datenbanken
{archStats.infrastructure}
Infrastruktur
{/* ASCII Architecture Diagram with Arrows */}

Datenfluss-Diagramm

{`
                                    BreakPilot Platform - Datenfluss

    ┌─────────────────────────────────────────────────────────────────────────────────────────────┐
    │                                       FRONTEND LAYER                                         │
    ├─────────────────────────────────────────────────────────────────────────────────────────────┤
    │  ┌─────────────────────┐    ┌─────────────────────┐    ┌─────────────────────┐              │
    │  │   Admin Frontend    │    │    Lehrer Studio    │    │   Policy Vault UI   │              │
    │  │   Next.js :3000     │    │    FastAPI :8000    │    │    Angular :4200    │              │
    │  └──────────┬──────────┘    └──────────┬──────────┘    └──────────┬──────────┘              │
    └─────────────┼───────────────────────────┼───────────────────────────┼────────────────────────┘
                  │                           │                           │
                  ▼                           ▼                           ▼
    ┌─────────────────────────────────────────────────────────────────────────────────────────────┐
    │                                      BACKEND LAYER                                           │
    ├───────────────────┬───────────────────┬───────────────────┬─────────────────────────────────┤
    │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐               │
    │ │ Consent :8081 │ │ │ Billing :8083 │ │ │ School :8084  │ │ │ DSMS GW :8082 │               │
    │ │   Go/Gin      │ │ │   Go/Stripe   │ │ │   Go/Gin      │ │ │   Go/IPFS     │               │
    │ │ DSGVO Consent │ │ │ Subscriptions │ │ │ Noten/Zeugnis │ │ │ Audit Storage │               │
    │ └───────┬───────┘ │ └───────┬───────┘ │ └───────┬───────┘ │ └───────┬───────┘               │
    │         │         │         │         │         │         │         │                       │
    │         ▼         │         ▼         │         ▼         │         ▼                       │
    │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐               │
    │ │ Klausur :8086 │ │ │ H5P :8085     │ │ │ Policy API    │ │ │ LLM Services  │               │
    │ │ Python/BYOEH  │ │ │ Node.js       │ │ │ NestJS :3001  │ │ │ LibreChat/RAG │               │
    │ │ Abiturkorrek. │ │ │ Interaktiv    │ │ │ Richtlinien   │ │ │ KI-Assistenz  │               │
    │ └───────┬───────┘ │ └───────┬───────┘ │ └───────┬───────┘ │ └───────┬───────┘               │
    └─────────┼─────────┴─────────┼─────────┴─────────┼─────────┴─────────┼───────────────────────┘
              │                   │                   │                   │
              ▼                   ▼                   ▼                   ▼
    ┌─────────────────────────────────────────────────────────────────────────────────────────────┐
    │                                        DATA LAYER                                            │
    ├───────────────────┬───────────────────┬───────────────────┬─────────────────────────────────┤
    │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐               │
    │ │ PostgreSQL    │◄┼►│ Redis         │ │ │ Qdrant        │ │ │ OpenSearch    │               │
    │ │ :5432         │ │ │ :6379 Cache   │ │ │ :6333 Vector  │ │ │ :9200 Search  │               │
    │ │ Hauptdaten    │ │ │ Sessions      │ │ │ RAG Embeddings│ │ │ Volltext      │               │
    │ └───────────────┘ │ └───────────────┘ │ └───────────────┘ │ └───────────────┘               │
    └───────────────────┴───────────────────┴───────────────────┴─────────────────────────────────┘
                                                    │
                                                    ▼
    ┌─────────────────────────────────────────────────────────────────────────────────────────────┐
    │                                   INFRASTRUCTURE LAYER                                       │
    ├───────────────────┬───────────────────┬───────────────────┬─────────────────────────────────┤
    │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐               │
    │ │ Vault :8200   │ │ │ Keycloak :8180│ │ │ MinIO :9000   │ │ │ IPFS :5001    │               │
    │ │ Secrets Mgmt  │ │ │ SSO/OIDC Auth │ │ │ S3 Storage    │ │ │ Dezentral     │               │
    │ └───────────────┘ │ └───────────────┘ │ └───────────────┘ │ └───────────────┘               │
    │ ┌───────────────┐ │ ┌───────────────┐ │ ┌───────────────┐ │                                 │
    │ │ Matrix :8008  │ │ │ Jitsi :8443   │ │ │ ERPNext :8090 │ │                                 │
    │ │ E2EE Chat     │ │ │ Video Calls   │ │ │ Open ERP      │ │                                 │
    │ └───────────────┘ │ └───────────────┘ │ └───────────────┘ │                                 │
    └───────────────────┴───────────────────┴───────────────────┴─────────────────────────────────┘

    ═══════════════════════════════════════════════════════════════════════════════════════════════
    Legende:  ──► Datenfluss   ◄──► Bidirektional   │ Layer-Grenze   ┌─┐ Service-Box
    ═══════════════════════════════════════════════════════════════════════════════════════════════
`}
{/* Layer Filter */}
{LAYERS.map((layer) => ( ))}
{/* Architecture Diagram - Layered View */}

System-Architektur Diagramm

{LAYERS.map((layer) => { const layerServices = getServicesForLayer(layer) if (activeLayer !== 'all' && activeLayer !== layer.id) return null return (

{layer.name}

- {layer.description}
{layerServices.map((service) => { const colors = getArchTypeColor(service.type) const isSelected = selectedArchService?.id === service.id return (
setSelectedArchService(isSelected ? null : service)} className={`cursor-pointer rounded-lg border-2 p-3 transition-all ${ isSelected ? `${colors.border} ${colors.light} shadow-lg scale-105` : 'border-slate-200 bg-white hover:border-slate-300 hover:shadow' }`} >
{service.port && service.port !== '-' && ( :{service.port} )}

{service.name}

{service.technology}

{service.description}

{service.connections && service.connections.length > 0 && (
{service.connections.length} Verbindung{service.connections.length > 1 ? 'en' : ''}
)}
) })}
) })}
{/* Service Detail Panel */} {selectedArchService && (

{selectedArchService.name}

{selectedArchService.description}

Typ
{getArchTypeLabel(selectedArchService.type)}
Technologie
{selectedArchService.technology}
Port
{selectedArchService.port || '-'}
Verbindungen
{selectedArchService.connections?.length || 0} Services
{selectedArchService.connections && selectedArchService.connections.length > 0 && (

Verbunden mit:

{selectedArchService.connections.map((connId) => { const connService = ARCHITECTURE_SERVICES.find(s => s.id === connId) if (!connService) return null const colors = getArchTypeColor(connService.type) return ( ) })}
)}
)} {/* Legend */}

Legende

{(['frontend', 'backend', 'database', 'cache', 'search', 'storage', 'security', 'communication', 'ai', 'erp'] as const).map((type) => { const colors = getArchTypeColor(type) return (
{getArchTypeLabel(type)}
) })}
{/* Technical Details Section */}

Technische Details

{/* Data Flow */}

Datenfluss

1. Request: Browser → Next.js/FastAPI Frontend

2. API: Frontend → Python Backend / Go Microservices

3. Auth: Keycloak/Vault fuer SSO & Secrets

4. Data: PostgreSQL (ACID) / Redis (Cache)

5. Search: Qdrant (Vector) / Meilisearch (Fulltext)

6. Storage: MinIO (Files) / IPFS (Dezentral)

{/* Security */}

Sicherheit

Auth: JWT + Keycloak OIDC

Secrets: HashiCorp Vault (encrypted)

Communication: Matrix E2EE, TLS everywhere

DSGVO: Consent Service fuer Einwilligungen

DevSecOps: Trivy, Gitleaks, Semgrep, Bandit

SBOM: CycloneDX fuer alle Komponenten

{/* Languages */}

Programmiersprachen

Python 3.12 Go 1.21 TypeScript 5.x JavaScript ES2022
{/* Frameworks */}

Frameworks

Next.js 15 FastAPI Gin (Go) Vue 3 Angular 17 NestJS
)} {/* Services Tab */} {activeTab === 'services' && (
{services.map((service) => (
setSelectedService(selectedService === service.id ? null : service.id)} >

{service.name}

{service.type}
:{service.port}

{service.description}

{service.tech.map((t) => ( {t} ))}
{selectedService === service.id && (
{/* Purpose/Warum dieser Service */} {'purpose' in service && (
Warum dieser Service?
{(service as typeof service & {purpose: string}).purpose}
)}
Container: {service.container}
{service.healthEndpoint && (
Health: localhost:{service.port}{service.healthEndpoint}
)}
Endpoints: {service.endpoints.length}
{/* VS Code Link */} {docPaths[service.id] && ( e.stopPropagation()} className="mt-3 flex items-center gap-2 text-xs bg-blue-50 text-blue-700 px-3 py-2 rounded-lg hover:bg-blue-100 transition-colors" > In VS Code oeffnen )}
)}
))}
)} {/* API Reference Tab */} {activeTab === 'api' && (
{services.filter(s => s.endpoints.length > 0).map((service) => (

{service.name}

Base URL: http://localhost:{service.port}
{service.type}
{service.endpoints.map((endpoint, idx) => { const endpointId = `${service.id}-${idx}` const curlCommand = `curl -X ${endpoint.method} http://localhost:${service.port}${endpoint.path}` return (
{endpoint.method} {endpoint.path}
{endpoint.description}
) })}
))}
)} {/* Docker Tab */} {activeTab === 'docker' && (

Docker Compose Services

{services.map((service) => ( ))}
Container Port Type Health Check
{service.container} {service.port} {service.type} {service.healthEndpoint ? ( {service.healthEndpoint} ) : ( - )}
{/* Common Commands */}

Haeufige Befehle

{[ { label: 'Alle Services starten', cmd: 'docker compose up -d' }, { label: 'Logs anzeigen', cmd: 'docker compose logs -f [service]' }, { label: 'Service neu bauen', cmd: 'docker compose build [service] --no-cache' }, { label: 'Container Status', cmd: 'docker ps --format "table {{.Names}}\\t{{.Status}}\\t{{.Ports}}"' }, { label: 'In Container einloggen', cmd: 'docker exec -it [container] /bin/sh' }, ].map((item, idx) => (
{item.label}
{item.cmd}
))}
{/* Environment Variables */}

Wichtige Umgebungsvariablen

{services.filter(s => s.envVars.length > 0).map((service) => (

{service.name}

{service.envVars.map((env) => ( {env} ))}
))}
)} {/* Testing Tab */} {activeTab === 'testing' && (
{/* Quick Links to Docs */}
{[ { file: 'docs/testing/README.md', label: 'Test-Uebersicht', desc: 'Teststrategie & Coverage-Ziele' }, { file: 'docs/testing/QUICKSTART.md', label: 'Quickstart', desc: 'Schnellstart fuer Tests' }, { file: 'docs/testing/INTEGRATION_TESTS.md', label: 'Integrationstests', desc: 'API & DB Tests' }, ].map((doc) => (
{doc.label}
{doc.desc}
))}
{/* Test Pyramid */}

Test-Pyramide

{`                /\\
               /  \\  E2E (10%)
              /----\\
             /      \\  Integration (20%)
            /--------\\
           /          \\  Unit Tests (70%)
          /--------------\\`}
{/* Coverage Ziele */}

Coverage-Ziele

{[ { component: 'Go Consent Service', target: '80%', current: '~75%', color: 'green' }, { component: 'Python Backend', target: '70%', current: '~65%', color: 'yellow' }, { component: 'Critical Paths (Auth, OAuth)', target: '95%', current: '~90%', color: 'green' }, ].map((item) => (
{item.component}
{item.current}
Ziel: {item.target}
))}
{/* Test Commands */}

Test-Befehle

{[ { label: 'Go Tests (alle)', cmd: 'cd consent-service && go test -v ./...', lang: 'Go' }, { label: 'Go Tests mit Coverage', cmd: 'cd consent-service && go test -cover ./...', lang: 'Go' }, { label: 'Python Tests (alle)', cmd: 'cd backend && source venv/bin/activate && pytest -v', lang: 'Python' }, { label: 'Python Tests mit Coverage', cmd: 'cd backend && pytest --cov=. --cov-report=html', lang: 'Python' }, ].map((item, idx) => (
{item.lang}
{item.label}
{item.cmd}
))}
{/* Test-Struktur */}

Test-Struktur

{/* Go Tests */}

Go Consent Service

consent-service/
internal/
handlers/handlers_test.go
services/auth_service_test.go
services/oauth_service_test.go
services/totp_service_test.go
middleware/middleware_test.go
{/* Python Tests */}

Python Backend

backend/
tests/
test_consent_client.py
test_gdpr_api.py
test_dsms_webui.py
conftest.py
)} ) }