fix: Restore all files lost during destructive rebase

A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.

This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).

Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-02-09 09:51:32 +01:00
parent f7487ee240
commit bfdaf63ba9
2009 changed files with 749983 additions and 1731 deletions

View File

@@ -0,0 +1,347 @@
'use client'
/**
* Admin Layout with Sidebar Navigation
*
* Shared layout for all admin pages with collapsible sidebar
*/
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import { useState } from 'react'
interface NavItem {
name: string
href: string
icon: React.ReactNode
description?: string
}
const navigation: NavItem[] = [
{
name: 'Dashboard',
href: '/admin',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
),
description: 'Übersicht & Statistiken',
},
{
name: 'GPU Infrastruktur',
href: '/admin/gpu',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" />
</svg>
),
description: 'vast.ai GPU Management',
},
{
name: 'Consent Verwaltung',
href: '/admin/consent',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
),
description: 'Rechtliche Dokumente & Versionen',
},
{
name: 'Datenschutzanfragen',
href: '/admin/dsr',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
</svg>
),
description: 'DSGVO Art. 15-21 Anfragen',
},
{
name: 'DSMS',
href: '/admin/dsms',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>
),
description: 'Datenschutz-Management-System',
},
{
name: 'Übersetzungen',
href: '/admin/content',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129" />
</svg>
),
description: 'Website Content & Sprachen',
},
{
name: 'Education Search',
href: '/admin/edu-search',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
</svg>
),
description: 'Bildungsquellen & Crawler',
},
{
name: 'Personensuche',
href: '/admin/staff-search',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
</svg>
),
description: 'Uni-Mitarbeiter & Publikationen',
},
{
name: 'Uni-Crawler',
href: '/admin/uni-crawler',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
),
description: 'Universitaets-Crawling Orchestrator',
},
{
name: 'LLM Vergleich',
href: '/admin/llm-compare',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" />
</svg>
),
description: 'KI-Provider Vergleich',
},
{
name: 'Daten & RAG',
href: '/admin/rag',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4" />
</svg>
),
description: 'Training Data & RAG Management',
},
{
name: 'PCA Platform',
href: '/admin/pca-platform',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
),
description: 'Bot-Erkennung & Monetarisierung',
},
{
name: 'Production Backlog',
href: '/admin/backlog',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" />
</svg>
),
description: 'Go-Live Checkliste',
},
{
name: 'Developer Docs',
href: '/admin/docs',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
</svg>
),
description: 'API & Architektur Dokumentation',
},
{
name: 'Kommunikation',
href: '/admin/communication',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg>
),
description: 'Matrix & Jitsi Monitoring',
},
{
name: 'Unified Inbox',
href: '/admin/mail',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
),
description: 'E-Mail-Konten & KI-Analyse',
},
{
name: 'Security',
href: '/admin/security',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
</svg>
),
description: 'DevSecOps Dashboard & Scans',
},
{
name: 'SBOM',
href: '/admin/sbom',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4" />
</svg>
),
description: 'Software Bill of Materials',
},
{
name: 'Brandbook',
href: '/admin/brandbook',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" />
</svg>
),
description: 'Corporate Design & Styleguide',
},
{
name: 'Unity Bridge',
href: '/admin/unity-bridge',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
),
description: 'Unity Editor Steuerung',
},
{
name: 'Qualitaet',
href: '/admin/quality',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
),
description: 'BQAS Quality Dashboard',
},
]
interface AdminLayoutProps {
children: React.ReactNode
title?: string
description?: string
}
export default function AdminLayout({ children, title, description }: AdminLayoutProps) {
const pathname = usePathname()
const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
const isActive = (href: string) => {
if (href === '/admin') {
return pathname === '/admin'
}
return pathname.startsWith(href)
}
return (
<div className="min-h-screen bg-slate-50 flex">
{/* Sidebar */}
<aside
className={`${
sidebarCollapsed ? 'w-16' : 'w-64'
} bg-slate-900 text-white flex flex-col transition-all duration-300 fixed h-full z-20`}
>
{/* Logo/Header */}
<div className="h-16 flex items-center justify-between px-4 border-b border-slate-700">
{!sidebarCollapsed && (
<Link href="/admin" className="font-bold text-lg">
BreakPilot Admin
</Link>
)}
<button
onClick={() => setSidebarCollapsed(!sidebarCollapsed)}
className="p-2 rounded-lg hover:bg-slate-800 transition-colors"
title={sidebarCollapsed ? 'Sidebar erweitern' : 'Sidebar einklappen'}
>
<svg
className={`w-5 h-5 transition-transform ${sidebarCollapsed ? 'rotate-180' : ''}`}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 19l-7-7 7-7m8 14l-7-7 7-7" />
</svg>
</button>
</div>
{/* Navigation */}
<nav className="flex-1 py-4 overflow-y-auto">
<ul className="space-y-1 px-2">
{navigation.map((item) => (
<li key={item.href}>
<Link
href={item.href}
className={`flex items-center gap-3 px-3 py-2.5 rounded-lg transition-colors ${
isActive(item.href)
? 'bg-primary-600 text-white'
: 'text-slate-300 hover:bg-slate-800 hover:text-white'
}`}
title={sidebarCollapsed ? item.name : undefined}
>
<span className="flex-shrink-0">{item.icon}</span>
{!sidebarCollapsed && (
<span className="truncate">{item.name}</span>
)}
</Link>
</li>
))}
</ul>
</nav>
{/* Footer */}
<div className="p-4 border-t border-slate-700">
<Link
href="/"
className={`flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-slate-800 transition-colors ${
sidebarCollapsed ? 'justify-center' : ''
}`}
title="Zur Website"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
{!sidebarCollapsed && <span>Zur Website</span>}
</Link>
</div>
</aside>
{/* Main Content */}
<div className={`flex-1 ${sidebarCollapsed ? 'ml-16' : 'ml-64'} transition-all duration-300`}>
{/* Top Header */}
<header className="h-16 bg-white border-b border-slate-200 flex items-center px-6 sticky top-0 z-10">
<div className="flex-1">
{title && <h1 className="text-xl font-semibold text-slate-900">{title}</h1>}
{description && <p className="text-sm text-slate-500">{description}</p>}
</div>
{/* User/Settings Area */}
<div className="flex items-center gap-4">
<span className="text-sm text-slate-500">Developer Admin</span>
<div className="w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center text-white text-sm font-medium">
A
</div>
</div>
</header>
{/* Page Content */}
<main className="p-6">
{children}
</main>
</div>
</div>
)
}

View File

@@ -0,0 +1,232 @@
'use client'
/**
* AI Prompt Component
*
* Eingabezeile für Fragen an den lokalen Ollama-Server.
* Unterstützt Streaming-Antworten und automatische Modell-Erkennung.
*/
import { useState, useEffect, useRef } from 'react'
interface OllamaModel {
name: string
size: number
digest: string
}
export default function AiPrompt() {
const [prompt, setPrompt] = useState('')
const [response, setResponse] = useState('')
const [isLoading, setIsLoading] = useState(false)
const [models, setModels] = useState<OllamaModel[]>([])
const [selectedModel, setSelectedModel] = useState('llama3.2:latest')
const [showResponse, setShowResponse] = useState(false)
const textareaRef = useRef<HTMLTextAreaElement>(null)
const abortControllerRef = useRef<AbortController | null>(null)
// Lade verfügbare Modelle von Ollama
useEffect(() => {
const loadModels = async () => {
try {
const ollamaUrl = getOllamaBaseUrl()
const res = await fetch(`${ollamaUrl}/api/tags`)
if (res.ok) {
const data = await res.json()
if (data.models && data.models.length > 0) {
setModels(data.models)
setSelectedModel(data.models[0].name)
}
}
} catch (error) {
console.log('Ollama nicht erreichbar:', error)
}
}
loadModels()
}, [])
const getOllamaBaseUrl = () => {
if (typeof window !== 'undefined') {
if (window.location.hostname === 'macmini') {
return 'http://macmini:11434'
}
}
return 'http://localhost:11434'
}
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault()
sendPrompt()
}
}
const autoResize = () => {
if (textareaRef.current) {
textareaRef.current.style.height = 'auto'
textareaRef.current.style.height = Math.min(textareaRef.current.scrollHeight, 120) + 'px'
}
}
const sendPrompt = async () => {
if (!prompt.trim() || isLoading) return
// Vorherige Anfrage abbrechen
if (abortControllerRef.current) {
abortControllerRef.current.abort()
}
abortControllerRef.current = new AbortController()
setIsLoading(true)
setResponse('')
setShowResponse(true)
try {
const ollamaUrl = getOllamaBaseUrl()
const res = await fetch(`${ollamaUrl}/api/generate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: selectedModel,
prompt: prompt.trim(),
stream: true,
}),
signal: abortControllerRef.current.signal,
})
if (!res.ok) {
throw new Error(`Ollama Fehler: ${res.status}`)
}
const reader = res.body?.getReader()
const decoder = new TextDecoder()
let fullResponse = ''
if (reader) {
while (true) {
const { done, value } = await reader.read()
if (done) break
const chunk = decoder.decode(value)
const lines = chunk.split('\n').filter(l => l.trim())
for (const line of lines) {
try {
const data = JSON.parse(line)
if (data.response) {
fullResponse += data.response
setResponse(fullResponse)
}
} catch {
// Ignore JSON parse errors for partial chunks
}
}
}
}
} catch (error) {
if ((error as Error).name === 'AbortError') {
setResponse('Anfrage abgebrochen.')
} else {
console.error('AI Prompt Fehler:', error)
setResponse(`❌ Fehler: ${(error as Error).message}\n\nBitte prüfen Sie, ob Ollama läuft.`)
}
} finally {
setIsLoading(false)
abortControllerRef.current = null
}
}
const formatResponse = (text: string) => {
// Einfache Markdown-Formatierung
return text
.replace(/```(\w+)?\n([\s\S]*?)```/g, '<pre class="bg-slate-800 text-slate-100 p-3 rounded-lg my-2 overflow-x-auto text-sm"><code>$2</code></pre>')
.replace(/`([^`]+)`/g, '<code class="bg-slate-200 px-1.5 py-0.5 rounded text-sm">$1</code>')
.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
.replace(/\*([^*]+)\*/g, '<em>$1</em>')
.replace(/\n/g, '<br>')
}
return (
<div className="bg-gradient-to-br from-slate-50 to-slate-100 rounded-2xl border border-slate-200 p-5 mb-8 shadow-sm">
{/* Header */}
<div className="flex items-center gap-3 mb-4">
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-600 to-primary-700 flex items-center justify-center text-white text-xl shadow-lg">
🤖
</div>
<div>
<h3 className="font-semibold text-slate-900">KI-Assistent</h3>
<p className="text-xs text-slate-500">Fragen Sie Ihren lokalen Ollama-Assistenten</p>
</div>
</div>
{/* Input */}
<div className="flex gap-3 items-end">
<textarea
ref={textareaRef}
value={prompt}
onChange={(e) => {
setPrompt(e.target.value)
autoResize()
}}
onKeyDown={handleKeyDown}
placeholder="Stellen Sie eine Frage... (z.B. 'Wie schreibe ich einen Elternbrief?' oder 'Erstelle mir einen Lückentext')"
rows={1}
className="flex-1 min-h-[44px] max-h-[120px] px-4 py-3 rounded-xl border border-slate-300 bg-white text-slate-900 text-sm resize-none focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent placeholder:text-slate-400 transition-all"
/>
<button
onClick={sendPrompt}
disabled={isLoading || !prompt.trim()}
className={`w-11 h-11 rounded-xl flex items-center justify-center text-white text-lg transition-all shadow-lg ${
isLoading
? 'bg-slate-400 cursor-wait animate-pulse'
: 'bg-gradient-to-br from-primary-600 to-primary-700 hover:from-primary-700 hover:to-primary-800 hover:scale-105 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100'
}`}
>
{isLoading ? '⏳' : '➤'}
</button>
</div>
{/* Response */}
{showResponse && (
<div className="mt-4 p-4 bg-white rounded-xl border border-slate-200 shadow-inner">
<div className="flex items-center gap-2 text-xs text-slate-500 mb-3">
<span>🤖</span>
<span className="font-medium">{selectedModel}</span>
{isLoading && <span className="animate-pulse"> Generiert...</span>}
</div>
<div
className="text-sm text-slate-700 leading-relaxed prose prose-sm max-w-none"
dangerouslySetInnerHTML={{ __html: formatResponse(response) || '<span class="text-slate-400 italic">Warte auf Antwort...</span>' }}
/>
</div>
)}
{/* Model Selector */}
<div className="flex items-center gap-2 mt-4 pt-4 border-t border-slate-200">
<span className="text-xs text-slate-500">Modell:</span>
<select
value={selectedModel}
onChange={(e) => setSelectedModel(e.target.value)}
className="text-xs px-2 py-1.5 rounded-lg border border-slate-300 bg-white text-slate-700 focus:outline-none focus:ring-2 focus:ring-primary-500 cursor-pointer"
>
{models.length > 0 ? (
models.map((model) => (
<option key={model.name} value={model.name}>
{model.name}
</option>
))
) : (
<>
<option value="llama3.2:latest">Llama 3.2</option>
<option value="mistral:latest">Mistral</option>
<option value="qwen2.5:7b">Qwen 2.5</option>
</>
)}
</select>
{models.length === 0 && (
<span className="text-xs text-amber-600"> Ollama nicht verbunden</span>
)}
</div>
</div>
)
}

View File

@@ -0,0 +1,311 @@
'use client'
import { useState, useEffect } from 'react'
import {
CheckCircle2,
XCircle,
Clock,
Loader2,
GitBranch,
RefreshCw,
ExternalLink,
Play
} from 'lucide-react'
interface PipelineStep {
name: string
state: 'pending' | 'running' | 'success' | 'failure' | 'skipped'
exit_code: number
}
interface Pipeline {
id: number
number: number
status: 'pending' | 'running' | 'success' | 'failure'
event: string
branch: string
commit: string
message: string
author: string
created: number
started: number
finished: number
steps: PipelineStep[]
}
interface CICDStatus {
status: 'online' | 'offline'
pipelines: Pipeline[]
lastUpdate: string
error?: string
}
const StatusIcon = ({ status }: { status: string }) => {
switch (status) {
case 'success':
return <CheckCircle2 className="w-4 h-4 text-green-500" />
case 'failure':
return <XCircle className="w-4 h-4 text-red-500" />
case 'running':
return <Loader2 className="w-4 h-4 text-blue-500 animate-spin" />
case 'pending':
return <Clock className="w-4 h-4 text-yellow-500" />
default:
return <Clock className="w-4 h-4 text-slate-400" />
}
}
const StatusBadge = ({ status }: { status: string }) => {
const colors: Record<string, string> = {
success: 'bg-green-100 text-green-800 border-green-200',
failure: 'bg-red-100 text-red-800 border-red-200',
running: 'bg-blue-100 text-blue-800 border-blue-200',
pending: 'bg-yellow-100 text-yellow-800 border-yellow-200',
}
const labels: Record<string, string> = {
success: 'Erfolgreich',
failure: 'Fehlgeschlagen',
running: 'Läuft',
pending: 'Wartend',
}
return (
<span className={`px-2 py-0.5 text-xs font-medium rounded-full border ${colors[status] || 'bg-slate-100 text-slate-800'}`}>
{labels[status] || status}
</span>
)
}
function formatDuration(started: number, finished: number): string {
if (!started) return '-'
const end = finished || Date.now() / 1000
const duration = Math.floor(end - started)
if (duration < 60) return `${duration}s`
if (duration < 3600) return `${Math.floor(duration / 60)}m ${duration % 60}s`
return `${Math.floor(duration / 3600)}h ${Math.floor((duration % 3600) / 60)}m`
}
function formatTimeAgo(timestamp: number): string {
if (!timestamp) return '-'
const seconds = Math.floor(Date.now() / 1000 - timestamp)
if (seconds < 60) return 'Gerade eben'
if (seconds < 3600) return `vor ${Math.floor(seconds / 60)} Min`
if (seconds < 86400) return `vor ${Math.floor(seconds / 3600)} Std`
return `vor ${Math.floor(seconds / 86400)} Tagen`
}
export default function CICDStatusWidget() {
const [data, setData] = useState<CICDStatus | null>(null)
const [loading, setLoading] = useState(true)
const [triggering, setTriggering] = useState(false)
const [expanded, setExpanded] = useState(false)
const fetchStatus = async () => {
try {
const response = await fetch('/api/admin/cicd?limit=5')
const result = await response.json()
setData(result)
} catch (error) {
console.error('Failed to fetch CI/CD status:', error)
setData({
status: 'offline',
pipelines: [],
lastUpdate: new Date().toISOString()
})
} finally {
setLoading(false)
}
}
const triggerPipeline = async () => {
setTriggering(true)
try {
const response = await fetch('/api/admin/cicd', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ branch: 'main' })
})
if (response.ok) {
// Refresh status after triggering
setTimeout(fetchStatus, 2000)
}
} catch (error) {
console.error('Failed to trigger pipeline:', error)
} finally {
setTriggering(false)
}
}
useEffect(() => {
fetchStatus()
// Auto-refresh every 30 seconds if a pipeline is running
const interval = setInterval(() => {
if (data?.pipelines.some(p => p.status === 'running')) {
fetchStatus()
}
}, 30000)
return () => clearInterval(interval)
}, [])
if (loading) {
return (
<div className="bg-white rounded-xl border border-slate-200 p-4">
<div className="flex items-center gap-2">
<Loader2 className="w-4 h-4 animate-spin text-slate-400" />
<span className="text-sm text-slate-500">Lade CI/CD Status...</span>
</div>
</div>
)
}
const latestPipeline = data?.pipelines[0]
return (
<div className="bg-white rounded-xl border border-slate-200 shadow-sm">
{/* Header */}
<div className="flex items-center justify-between p-4 border-b border-slate-100">
<div className="flex items-center gap-2">
<GitBranch className="w-4 h-4 text-slate-500" />
<h3 className="font-medium text-slate-900">CI/CD Pipeline</h3>
{data?.status === 'online' ? (
<span className="w-2 h-2 rounded-full bg-green-500"></span>
) : (
<span className="w-2 h-2 rounded-full bg-red-500"></span>
)}
</div>
<div className="flex items-center gap-2">
<button
onClick={fetchStatus}
className="p-1.5 text-slate-400 hover:text-slate-600 hover:bg-slate-100 rounded-lg transition-colors"
title="Aktualisieren"
>
<RefreshCw className="w-4 h-4" />
</button>
<a
href="http://macmini:8090"
target="_blank"
rel="noopener noreferrer"
className="p-1.5 text-slate-400 hover:text-slate-600 hover:bg-slate-100 rounded-lg transition-colors"
title="Woodpecker öffnen"
>
<ExternalLink className="w-4 h-4" />
</a>
</div>
</div>
{/* Content */}
<div className="p-4">
{data?.status === 'offline' ? (
<div className="text-sm text-slate-500">
Woodpecker CI nicht erreichbar
</div>
) : latestPipeline ? (
<div className="space-y-3">
{/* Latest Pipeline */}
<div className="flex items-start justify-between">
<div className="flex items-center gap-3">
<StatusIcon status={latestPipeline.status} />
<div>
<div className="flex items-center gap-2">
<span className="font-medium text-slate-900">
#{latestPipeline.number}
</span>
<StatusBadge status={latestPipeline.status} />
</div>
<div className="text-xs text-slate-500 mt-0.5">
{latestPipeline.branch} {latestPipeline.commit}
</div>
</div>
</div>
<div className="text-right text-xs text-slate-500">
<div>{formatTimeAgo(latestPipeline.created)}</div>
<div>{formatDuration(latestPipeline.started, latestPipeline.finished)}</div>
</div>
</div>
{/* Steps Progress */}
{latestPipeline.steps.length > 0 && (
<div className="flex gap-1">
{latestPipeline.steps.map((step, i) => (
<div
key={i}
className={`h-1.5 flex-1 rounded-full ${
step.state === 'success' ? 'bg-green-500' :
step.state === 'failure' ? 'bg-red-500' :
step.state === 'running' ? 'bg-blue-500 animate-pulse' :
step.state === 'skipped' ? 'bg-slate-200' :
'bg-slate-300'
}`}
title={`${step.name}: ${step.state}`}
/>
))}
</div>
)}
{/* Expandable Steps */}
{expanded && latestPipeline.steps.length > 0 && (
<div className="mt-2 space-y-1 text-xs">
{latestPipeline.steps.map((step, i) => (
<div key={i} className="flex items-center gap-2 text-slate-600">
<StatusIcon status={step.state} />
<span>{step.name}</span>
</div>
))}
</div>
)}
{/* Actions */}
<div className="flex items-center gap-2 pt-2">
<button
onClick={() => setExpanded(!expanded)}
className="text-xs text-slate-500 hover:text-slate-700"
>
{expanded ? 'Weniger anzeigen' : 'Details anzeigen'}
</button>
<button
onClick={triggerPipeline}
disabled={triggering}
className="ml-auto flex items-center gap-1 px-2 py-1 text-xs font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
>
{triggering ? (
<Loader2 className="w-3 h-3 animate-spin" />
) : (
<Play className="w-3 h-3" />
)}
Pipeline starten
</button>
</div>
{/* Recent Pipelines */}
{data.pipelines.length > 1 && (
<div className="pt-3 border-t border-slate-100">
<div className="text-xs font-medium text-slate-500 mb-2">
Letzte Pipelines
</div>
<div className="space-y-1">
{data.pipelines.slice(1, 4).map((p) => (
<div key={p.id} className="flex items-center gap-2 text-xs text-slate-600">
<StatusIcon status={p.status} />
<span>#{p.number}</span>
<span className="text-slate-400">{p.branch}</span>
<span className="ml-auto text-slate-400">
{formatTimeAgo(p.created)}
</span>
</div>
))}
</div>
</div>
)}
</div>
) : (
<div className="text-sm text-slate-500">
Keine Pipelines gefunden
</div>
)}
</div>
</div>
)
}

View File

@@ -0,0 +1,316 @@
'use client'
import { useState, useEffect, useCallback, useRef } from 'react'
interface StreamStatus {
is_streaming: boolean
frame_count: number
width: number
height: number
quality: number
uptime_seconds: string
}
interface StreamFrameResponse {
success: boolean
frame_count?: number
width?: number
height?: number
data?: string // Base64 encoded JPEG
message?: string
}
interface GameViewProps {
isUnityOnline: boolean
isPlaying?: boolean
}
export default function GameView({ isUnityOnline, isPlaying }: GameViewProps) {
const [isStreaming, setIsStreaming] = useState(false)
const [streamStatus, setStreamStatus] = useState<StreamStatus | null>(null)
const [frameData, setFrameData] = useState<string | null>(null)
const [frameCount, setFrameCount] = useState(0)
const [fps, setFps] = useState(0)
const [error, setError] = useState<string | null>(null)
const [isLoading, setIsLoading] = useState(false)
const lastFrameTimeRef = useRef<number>(Date.now())
const frameCountRef = useRef<number>(0)
const fpsIntervalRef = useRef<NodeJS.Timeout | null>(null)
const streamIntervalRef = useRef<NodeJS.Timeout | null>(null)
// Fetch stream status
const fetchStreamStatus = useCallback(async () => {
if (!isUnityOnline) return
try {
const res = await fetch('/api/admin/unity-bridge?action=stream-status')
if (res.ok) {
const data: StreamStatus = await res.json()
setStreamStatus(data)
setIsStreaming(data.is_streaming)
}
} catch {
// Ignore errors
}
}, [isUnityOnline])
// Capture single screenshot
const captureScreenshot = async () => {
if (!isUnityOnline) return
setIsLoading(true)
setError(null)
try {
const res = await fetch('/api/admin/unity-bridge?action=screenshot')
if (res.ok) {
const blob = await res.blob()
const url = URL.createObjectURL(blob)
setFrameData(url)
setFrameCount(prev => prev + 1)
} else {
const errorData = await res.json()
setError(errorData.error || 'Screenshot fehlgeschlagen')
}
} catch (err) {
setError('Verbindung fehlgeschlagen')
}
setIsLoading(false)
}
// Start streaming
const startStreaming = async () => {
if (!isUnityOnline) return
setIsLoading(true)
setError(null)
try {
const res = await fetch('/api/admin/unity-bridge?action=stream-start')
if (res.ok) {
const data = await res.json()
if (data.success) {
setIsStreaming(true)
frameCountRef.current = 0
} else {
setError(data.message || 'Streaming konnte nicht gestartet werden')
}
}
} catch {
setError('Verbindung fehlgeschlagen')
}
setIsLoading(false)
}
// Stop streaming
const stopStreaming = async () => {
setIsLoading(true)
try {
const res = await fetch('/api/admin/unity-bridge?action=stream-stop')
if (res.ok) {
setIsStreaming(false)
}
} catch {
// Ignore errors
}
setIsLoading(false)
}
// Fetch frame during streaming
const fetchFrame = useCallback(async () => {
if (!isStreaming || !isUnityOnline) return
try {
const res = await fetch('/api/admin/unity-bridge?action=stream-frame')
if (res.ok) {
const data: StreamFrameResponse = await res.json()
if (data.success && data.data) {
setFrameData(`data:image/jpeg;base64,${data.data}`)
setFrameCount(data.frame_count || 0)
frameCountRef.current++
}
}
} catch {
// Ignore single frame failures
}
}, [isStreaming, isUnityOnline])
// Calculate FPS every second
useEffect(() => {
if (isStreaming) {
fpsIntervalRef.current = setInterval(() => {
setFps(frameCountRef.current)
frameCountRef.current = 0
}, 1000)
} else {
if (fpsIntervalRef.current) {
clearInterval(fpsIntervalRef.current)
fpsIntervalRef.current = null
}
setFps(0)
}
return () => {
if (fpsIntervalRef.current) {
clearInterval(fpsIntervalRef.current)
}
}
}, [isStreaming])
// Streaming loop - fetch frames at ~10 FPS
useEffect(() => {
if (isStreaming) {
// Initial fetch
fetchFrame()
// Setup interval for continuous fetching
streamIntervalRef.current = setInterval(fetchFrame, 100) // 10 FPS
} else {
if (streamIntervalRef.current) {
clearInterval(streamIntervalRef.current)
streamIntervalRef.current = null
}
}
return () => {
if (streamIntervalRef.current) {
clearInterval(streamIntervalRef.current)
}
}
}, [isStreaming, fetchFrame])
// Initial status fetch
useEffect(() => {
fetchStreamStatus()
}, [fetchStreamStatus])
return (
<div className="bg-white rounded-lg border border-gray-200 shadow-sm overflow-hidden">
{/* Header */}
<div className="flex items-center justify-between px-4 py-3 border-b border-gray-200 bg-gray-50">
<div className="flex items-center gap-3">
<h3 className="font-semibold text-gray-900">Game View</h3>
{isStreaming && (
<span className="flex items-center gap-1.5 px-2 py-0.5 bg-red-100 text-red-700 rounded text-xs font-medium">
<span className="w-2 h-2 bg-red-500 rounded-full animate-pulse" />
LIVE
</span>
)}
</div>
<div className="flex items-center gap-2">
{/* Screenshot Button */}
<button
onClick={captureScreenshot}
disabled={!isUnityOnline || isLoading || isStreaming}
className="px-3 py-1.5 text-sm bg-gray-100 text-gray-700 rounded hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center gap-1.5"
title="Einzelner Screenshot"
>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" />
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
Screenshot
</button>
{/* Stream Toggle */}
{isStreaming ? (
<button
onClick={stopStreaming}
disabled={isLoading}
className="px-3 py-1.5 text-sm bg-red-600 text-white rounded hover:bg-red-700 disabled:opacity-50 transition-colors flex items-center gap-1.5"
>
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<rect x="6" y="6" width="12" height="12" />
</svg>
Stop
</button>
) : (
<button
onClick={startStreaming}
disabled={!isUnityOnline || isLoading}
className="px-3 py-1.5 text-sm bg-green-600 text-white rounded hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center gap-1.5"
>
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M8 5v14l11-7z" />
</svg>
Stream
</button>
)}
</div>
</div>
{/* Game View Area */}
<div className="relative bg-gray-900 aspect-video">
{error ? (
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-center text-white">
<svg className="w-12 h-12 mx-auto mb-3 text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
<p className="text-red-300">{error}</p>
</div>
</div>
) : !isUnityOnline ? (
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-center text-gray-400">
<svg className="w-16 h-16 mx-auto mb-3 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
<p>Unity Bridge offline</p>
<p className="text-sm mt-1">Starte den Server in Unity</p>
</div>
</div>
) : !frameData ? (
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-center text-gray-400">
<svg className="w-16 h-16 mx-auto mb-3 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" />
</svg>
<p>Kein Bild verfügbar</p>
<p className="text-sm mt-1">
{isPlaying
? 'Klicke "Stream" um die Spielansicht zu sehen'
: 'Starte Play Mode und dann den Stream'}
</p>
</div>
</div>
) : (
// eslint-disable-next-line @next/next/no-img-element
<img
src={frameData}
alt="Unity Game View"
className="w-full h-full object-contain"
/>
)}
{/* Loading Overlay */}
{isLoading && (
<div className="absolute inset-0 bg-black/50 flex items-center justify-center">
<div className="w-8 h-8 border-2 border-white border-t-transparent rounded-full animate-spin" />
</div>
)}
</div>
{/* Status Bar */}
<div className="px-4 py-2 bg-gray-50 border-t border-gray-200 flex items-center justify-between text-xs text-gray-600">
<div className="flex items-center gap-4">
<span>
<span className="font-medium">Resolution:</span>{' '}
{streamStatus ? `${streamStatus.width}x${streamStatus.height}` : '1280x720'}
</span>
<span>
<span className="font-medium">Quality:</span>{' '}
{streamStatus ? `${streamStatus.quality}%` : '75%'}
</span>
</div>
<div className="flex items-center gap-4">
{isStreaming && (
<>
<span>
<span className="font-medium">FPS:</span> {fps}
</span>
<span>
<span className="font-medium">Frames:</span> {frameCount}
</span>
</>
)}
<span className={isUnityOnline ? 'text-green-600' : 'text-red-600'}>
{isUnityOnline ? 'Connected' : 'Disconnected'}
</span>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,244 @@
'use client'
/**
* Germany School Map Component
*
* Displays a choropleth map of Germany showing school density by state.
* Uses react-simple-maps for SVG rendering.
*/
import { useState, useEffect, useCallback, memo } from 'react'
import {
ComposableMap,
Geographies,
Geography,
ZoomableGroup,
} from 'react-simple-maps'
// Germany GeoJSON - local file (simplified boundaries)
const GERMANY_GEO_URL = '/germany-states.json'
const STATE_NAMES: Record<string, string> = {
'BW': 'Baden-Wuerttemberg',
'BY': 'Bayern',
'BE': 'Berlin',
'BB': 'Brandenburg',
'HB': 'Bremen',
'HH': 'Hamburg',
'HE': 'Hessen',
'MV': 'Mecklenburg-Vorpommern',
'NI': 'Niedersachsen',
'NW': 'Nordrhein-Westfalen',
'RP': 'Rheinland-Pfalz',
'SL': 'Saarland',
'SN': 'Sachsen',
'ST': 'Sachsen-Anhalt',
'SH': 'Schleswig-Holstein',
'TH': 'Thueringen',
}
interface SchoolStats {
total_schools: number
by_state?: Record<string, number>
}
interface GermanySchoolMapProps {
stats: SchoolStats | null
onStateClick?: (stateCode: string) => void
selectedState?: string
}
// Color scale for school density
const getStateColor = (count: number, maxCount: number): string => {
if (count === 0) return '#f1f5f9' // slate-100
const intensity = count / maxCount
if (intensity < 0.2) return '#dbeafe' // blue-100
if (intensity < 0.4) return '#93c5fd' // blue-300
if (intensity < 0.6) return '#3b82f6' // blue-500
if (intensity < 0.8) return '#1d4ed8' // blue-700
return '#1e3a8a' // blue-900
}
function GermanySchoolMap({ stats, onStateClick, selectedState }: GermanySchoolMapProps) {
const [tooltipContent, setTooltipContent] = useState('')
const [tooltipPosition, setTooltipPosition] = useState({ x: 0, y: 0 })
const [showTooltip, setShowTooltip] = useState(false)
const [zoom, setZoom] = useState(1)
const [center, setCenter] = useState<[number, number]>([10.5, 51.2])
const maxSchools = stats?.by_state
? Math.max(...Object.values(stats.by_state))
: 0
const handleStateHover = useCallback((geo: { properties: { code?: string; name?: string } }, evt: React.MouseEvent) => {
const stateCode = geo.properties.code || ''
const stateName = geo.properties.name || STATE_NAMES[stateCode] || stateCode
const schoolCount = stats?.by_state?.[stateCode] || 0
setTooltipContent(`${stateName}: ${schoolCount.toLocaleString()} Schulen`)
setTooltipPosition({ x: evt.clientX, y: evt.clientY })
setShowTooltip(true)
}, [stats])
const handleStateLeave = useCallback(() => {
setShowTooltip(false)
}, [])
const handleZoomIn = () => {
if (zoom < 4) setZoom(zoom * 1.5)
}
const handleZoomOut = () => {
if (zoom > 1) setZoom(zoom / 1.5)
}
const handleReset = () => {
setZoom(1)
setCenter([10.5, 51.2])
}
return (
<div className="relative bg-white rounded-lg border p-4">
{/* Map Controls */}
<div className="absolute top-6 right-6 z-10 flex flex-col gap-2">
<button
onClick={handleZoomIn}
className="w-8 h-8 bg-white border rounded shadow hover:bg-gray-50 flex items-center justify-center text-lg font-bold"
title="Vergroessern"
>
+
</button>
<button
onClick={handleZoomOut}
className="w-8 h-8 bg-white border rounded shadow hover:bg-gray-50 flex items-center justify-center text-lg font-bold"
title="Verkleinern"
>
-
</button>
<button
onClick={handleReset}
className="w-8 h-8 bg-white border rounded shadow hover:bg-gray-50 flex items-center justify-center text-xs"
title="Zuruecksetzen"
>
Reset
</button>
</div>
{/* Legend */}
<div className="absolute bottom-6 left-6 z-10 bg-white/90 p-3 rounded border shadow-sm">
<h4 className="text-xs font-medium text-slate-700 mb-2">Schulen pro Bundesland</h4>
<div className="flex items-center gap-1">
<div className="w-4 h-4 bg-blue-100 rounded-sm" />
<div className="w-4 h-4 bg-blue-300 rounded-sm" />
<div className="w-4 h-4 bg-blue-500 rounded-sm" />
<div className="w-4 h-4 bg-blue-700 rounded-sm" />
<div className="w-4 h-4 bg-blue-900 rounded-sm" />
</div>
<div className="flex justify-between text-xs text-slate-500 mt-1">
<span>0</span>
<span>{maxSchools.toLocaleString()}</span>
</div>
</div>
{/* Tooltip */}
{showTooltip && (
<div
className="fixed z-50 px-3 py-2 bg-slate-900 text-white text-sm rounded shadow-lg pointer-events-none"
style={{
left: tooltipPosition.x + 10,
top: tooltipPosition.y - 30,
}}
>
{tooltipContent}
</div>
)}
{/* Map */}
<ComposableMap
projection="geoMercator"
projectionConfig={{
scale: 2800,
center: [10.5, 51.2],
}}
className="w-full h-[500px]"
>
<ZoomableGroup
zoom={zoom}
center={center}
onMoveEnd={({ coordinates, zoom: newZoom }: { coordinates: [number, number]; zoom: number }) => {
setCenter(coordinates)
setZoom(newZoom)
}}
>
<Geographies geography={GERMANY_GEO_URL}>
{({ geographies }: { geographies: any[] }) =>
geographies.map((geo: any) => {
const stateCode = geo.properties.code || ''
const schoolCount = stats?.by_state?.[stateCode] || 0
const isSelected = selectedState === stateCode
return (
<Geography
key={geo.rsmKey}
geography={geo}
onMouseEnter={(evt: React.MouseEvent) => handleStateHover(geo, evt)}
onMouseLeave={handleStateLeave}
onClick={() => onStateClick?.(stateCode)}
style={{
default: {
fill: isSelected
? '#f59e0b' // amber-500 for selected
: getStateColor(schoolCount, maxSchools),
stroke: '#ffffff',
strokeWidth: 0.5,
outline: 'none',
},
hover: {
fill: isSelected ? '#d97706' : '#60a5fa', // blue-400
stroke: '#ffffff',
strokeWidth: 1,
outline: 'none',
cursor: 'pointer',
},
pressed: {
fill: '#f59e0b',
stroke: '#ffffff',
strokeWidth: 1,
outline: 'none',
},
}}
/>
)
})
}
</Geographies>
</ZoomableGroup>
</ComposableMap>
{/* State List */}
{stats?.by_state && (
<div className="mt-4 pt-4 border-t">
<h4 className="text-sm font-medium text-slate-700 mb-2">Schulen nach Bundesland</h4>
<div className="grid grid-cols-2 md:grid-cols-4 gap-2 text-xs">
{Object.entries(stats.by_state)
.sort(([,a], [,b]) => b - a)
.map(([code, count]) => (
<button
key={code}
onClick={() => onStateClick?.(code)}
className={`flex justify-between items-center p-2 rounded hover:bg-slate-100 transition-colors ${
selectedState === code ? 'bg-amber-100 text-amber-800' : ''
}`}
>
<span>{STATE_NAMES[code] || code}</span>
<span className="font-medium">{count.toLocaleString()}</span>
</button>
))}
</div>
</div>
)}
</div>
)
}
export default memo(GermanySchoolMap)

View File

@@ -0,0 +1,243 @@
'use client'
/**
* LLM Mode Switcher Component
*
* UI-Komponente zum Umschalten zwischen LLM-Modi:
* - Hybrid: Lokal zuerst, Cloud als Fallback
* - Nur Lokal: Maximaler Datenschutz (nur Ollama)
* - Nur Cloud: Beste Qualitaet (Claude/OpenAI)
* - Auto: Automatische Auswahl nach Komplexitaet
*
* Kann als standalone oder in andere Komponenten integriert verwendet werden.
*/
import { useLLMMode, LLMMode, LLM_MODE_CONFIGS } from '@/lib/llm-mode-context'
interface LLMModeSwitcherProps {
// Kompakte Ansicht (nur Icons) oder volle Ansicht (mit Beschreibungen)
compact?: boolean
// Callback wenn Modus geaendert wird
onModeChange?: (mode: LLMMode) => void
// Zeigt Provider-Details an
showProviderDetails?: boolean
// Custom className fuer den Container
className?: string
}
// Icons als SVG (Tailwind-freundlich)
const ModeIcon = ({ mode, className = 'w-5 h-5' }: { mode: LLMMode; className?: string }) => {
switch (mode) {
case 'hybrid':
return (
<svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
)
case 'local-only':
return (
<svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
</svg>
)
case 'cloud-only':
return (
<svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z" />
</svg>
)
case 'auto':
return (
<svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
)
default:
return null
}
}
// Mode colors for styling
const modeColors: Record<LLMMode, { bg: string; border: string; text: string; activeBg: string }> = {
hybrid: {
bg: 'bg-blue-50',
border: 'border-blue-300',
text: 'text-blue-700',
activeBg: 'bg-blue-100',
},
'local-only': {
bg: 'bg-green-50',
border: 'border-green-300',
text: 'text-green-700',
activeBg: 'bg-green-100',
},
'cloud-only': {
bg: 'bg-purple-50',
border: 'border-purple-300',
text: 'text-purple-700',
activeBg: 'bg-purple-100',
},
auto: {
bg: 'bg-amber-50',
border: 'border-amber-300',
text: 'text-amber-700',
activeBg: 'bg-amber-100',
},
}
export default function LLMModeSwitcher({
compact = false,
onModeChange,
showProviderDetails = false,
className = '',
}: LLMModeSwitcherProps) {
const { mode, setMode, config, enableOllama, enableClaude, enableOpenAI } = useLLMMode()
const handleModeChange = (newMode: LLMMode) => {
setMode(newMode)
onModeChange?.(newMode)
}
const modes = Object.keys(LLM_MODE_CONFIGS) as LLMMode[]
if (compact) {
// Compact view: horizontal button group
return (
<div className={`flex items-center gap-1 ${className}`}>
{modes.map((m) => {
const isActive = m === mode
const colors = modeColors[m]
return (
<button
key={m}
onClick={() => handleModeChange(m)}
className={`p-2 rounded-lg border transition-all ${
isActive
? `${colors.activeBg} ${colors.border} ${colors.text} border-2`
: 'bg-white border-slate-200 text-slate-500 hover:bg-slate-50'
}`}
title={`${LLM_MODE_CONFIGS[m].label}: ${LLM_MODE_CONFIGS[m].description}`}
>
<ModeIcon mode={m} className="w-5 h-5" />
</button>
)
})}
</div>
)
}
// Full view: cards with descriptions
return (
<div className={className}>
<div className="mb-3 flex items-center justify-between">
<h3 className="text-sm font-semibold text-slate-700">LLM-Modus</h3>
<span className={`text-xs px-2 py-1 rounded-full ${modeColors[mode].bg} ${modeColors[mode].text}`}>
{config.label}
</span>
</div>
<div className="grid grid-cols-2 gap-2">
{modes.map((m) => {
const modeConfig = LLM_MODE_CONFIGS[m]
const isActive = m === mode
const colors = modeColors[m]
return (
<button
key={m}
onClick={() => handleModeChange(m)}
className={`p-3 rounded-lg border-2 transition-all text-left ${
isActive
? `${colors.activeBg} ${colors.border} ${colors.text}`
: 'bg-white border-slate-200 text-slate-600 hover:border-slate-300 hover:bg-slate-50'
}`}
>
<div className="flex items-center gap-2 mb-1">
<ModeIcon mode={m} className={`w-4 h-4 ${isActive ? colors.text : 'text-slate-400'}`} />
<span className={`text-sm font-medium ${isActive ? colors.text : 'text-slate-700'}`}>
{modeConfig.label}
</span>
</div>
<p className={`text-xs ${isActive ? colors.text : 'text-slate-500'}`}>
{modeConfig.description}
</p>
</button>
)
})}
</div>
{/* Provider Details */}
{showProviderDetails && (
<div className="mt-4 p-3 bg-slate-50 rounded-lg">
<p className="text-xs font-medium text-slate-600 mb-2">Aktive Provider:</p>
<div className="flex flex-wrap gap-2">
{enableOllama && (
<span className="text-xs px-2 py-1 rounded bg-green-100 text-green-700">
Ollama (Lokal)
</span>
)}
{enableClaude && (
<span className="text-xs px-2 py-1 rounded bg-orange-100 text-orange-700">
Claude
</span>
)}
{enableOpenAI && (
<span className="text-xs px-2 py-1 rounded bg-emerald-100 text-emerald-700">
OpenAI
</span>
)}
{!enableOllama && !enableClaude && !enableOpenAI && (
<span className="text-xs px-2 py-1 rounded bg-red-100 text-red-700">
Keine Provider aktiv
</span>
)}
</div>
</div>
)}
</div>
)
}
// Export compact variant for use in headers/toolbars
export function LLMModeSwitcherCompact(props: Omit<LLMModeSwitcherProps, 'compact'>) {
return <LLMModeSwitcher {...props} compact />
}
// Export a dropdown variant for tight spaces
export function LLMModeSwitcherDropdown({
className = '',
onModeChange,
}: Pick<LLMModeSwitcherProps, 'className' | 'onModeChange'>) {
const { mode, setMode, config } = useLLMMode()
const colors = modeColors[mode]
const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
const newMode = e.target.value as LLMMode
setMode(newMode)
onModeChange?.(newMode)
}
return (
<div className={`relative ${className}`}>
<select
value={mode}
onChange={handleChange}
className={`appearance-none pl-8 pr-8 py-2 rounded-lg border text-sm font-medium cursor-pointer ${colors.bg} ${colors.border} ${colors.text}`}
>
{(Object.keys(LLM_MODE_CONFIGS) as LLMMode[]).map((m) => (
<option key={m} value={m}>
{LLM_MODE_CONFIGS[m].label}
</option>
))}
</select>
<div className="absolute left-2 top-1/2 -translate-y-1/2 pointer-events-none">
<ModeIcon mode={mode} className={`w-4 h-4 ${colors.text}`} />
</div>
<div className="absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none">
<svg className={`w-4 h-4 ${colors.text}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</div>
</div>
)
}

View File

@@ -0,0 +1,362 @@
'use client'
/**
* SystemInfoSection Component
*
* Reusable component for displaying system documentation, architecture,
* features, and optimization roadmap in admin pages.
*
* Configurations are now in ./system-info-configs/
*/
import { useState } from 'react'
// Types are now exported from configs
export type {
Feature,
RoadmapPhase,
TechDetail,
AuditInfo,
SystemInfoConfig,
} from './system-info-configs/types'
// Import types for local use
import type { Feature, RoadmapPhase, SystemInfoConfig } from './system-info-configs/types'
// Re-export configs for backwards compatibility
export { SYSTEM_INFO_CONFIGS } from './system-info-configs'
interface SystemInfoSectionProps {
config: SystemInfoConfig
}
export default function SystemInfoSection({ config }: SystemInfoSectionProps) {
const [activeTab, setActiveTab] = useState<'overview' | 'architecture' | 'roadmap' | 'technical' | 'audit' | 'documentation'>('overview')
const [showFullDocs, setShowFullDocs] = useState(false)
const tabs = [
{ id: 'overview' as const, label: 'Uebersicht' },
{ id: 'architecture' as const, label: 'Architektur' },
{ id: 'roadmap' as const, label: 'Roadmap' },
{ id: 'technical' as const, label: 'Technisch' },
...(config.auditInfo ? [{ id: 'audit' as const, label: 'Audit' }] : []),
...(config.fullDocumentation ? [{ id: 'documentation' as const, label: 'Dokumentation' }] : []),
]
const getStatusBadge = (status: Feature['status']) => {
const styles = {
active: 'bg-green-100 text-green-800',
planned: 'bg-amber-100 text-amber-800',
disabled: 'bg-slate-100 text-slate-600',
}
const labels = {
active: 'Aktiv',
planned: 'Geplant',
disabled: 'Deaktiviert',
}
return (
<span className={`px-2 py-0.5 rounded-full text-xs font-medium ${styles[status]}`}>
{labels[status]}
</span>
)
}
const getPriorityBadge = (priority: RoadmapPhase['priority']) => {
const styles = {
high: 'bg-red-100 text-red-800',
medium: 'bg-amber-100 text-amber-800',
low: 'bg-blue-100 text-blue-800',
}
return (
<span className={`px-2 py-0.5 rounded text-xs font-semibold uppercase ${styles[priority]}`}>
{priority}
</span>
)
}
return (
<div className="space-y-6">
{/* Header */}
<div className="flex justify-between items-start">
<div>
<h2 className="text-lg font-semibold text-slate-900">{config.title}</h2>
<p className="text-sm text-slate-500">{config.description}</p>
</div>
{config.version && (
<span className="px-3 py-1 bg-green-100 text-green-800 text-xs font-medium rounded-full">
Version {config.version}
</span>
)}
</div>
{/* Privacy Notes */}
{config.privacyNotes && config.privacyNotes.length > 0 && (
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
<h3 className="text-sm font-semibold text-blue-800 mb-2">Datenschutz-Hinweise</h3>
<ul className="space-y-1">
{config.privacyNotes.map((note, i) => (
<li key={i} className="text-sm text-blue-700 flex items-start gap-2">
<svg className="w-4 h-4 mt-0.5 text-blue-500 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
{note}
</li>
))}
</ul>
</div>
)}
{/* Tab Navigation */}
<div className="border-b border-slate-200">
<nav className="flex gap-4">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`pb-3 px-1 text-sm font-medium border-b-2 transition-colors ${
activeTab === tab.id
? 'border-primary-600 text-primary-600'
: 'border-transparent text-slate-500 hover:text-slate-700'
}`}
>
{tab.label}
</button>
))}
</nav>
</div>
{/* Tab Content */}
<div className="min-h-[400px]">
{/* Overview Tab */}
{activeTab === 'overview' && (
<div className="space-y-6">
<h3 className="text-sm font-semibold text-slate-700 uppercase tracking-wide">Features</h3>
<div className="grid gap-3">
{config.features.map((feature, i) => (
<div key={i} className="bg-white rounded-lg border border-slate-200 p-4">
<div className="flex items-center justify-between mb-2">
<span className="font-medium text-slate-900">{feature.name}</span>
{getStatusBadge(feature.status)}
</div>
<p className="text-sm text-slate-500">{feature.description}</p>
</div>
))}
</div>
</div>
)}
{/* Architecture Tab */}
{activeTab === 'architecture' && (
<div className="space-y-6">
<h3 className="text-sm font-semibold text-slate-700 uppercase tracking-wide">System-Architektur</h3>
<div className="bg-white rounded-lg border border-slate-200 p-6">
<div className="flex flex-col items-center gap-3">
{config.architecture.layers.map((layer, i) => (
<div key={i} className="w-full">
<div
className="w-full p-4 rounded-lg border-2 text-center"
style={{
borderColor: layer.color || '#3b82f6',
backgroundColor: `${layer.color || '#3b82f6'}10`,
}}
>
<div
className="font-semibold text-sm mb-2"
style={{ color: layer.color || '#3b82f6' }}
>
{layer.title}
</div>
<div className="flex flex-wrap gap-2 justify-center">
{layer.components.map((comp, j) => (
<span
key={j}
className="px-3 py-1 rounded text-xs font-medium"
style={{
backgroundColor: `${layer.color || '#3b82f6'}20`,
color: layer.color || '#1e40af',
}}
>
{comp}
</span>
))}
</div>
</div>
{i < config.architecture.layers.length - 1 && (
<div className="flex justify-center py-2">
<svg className="w-6 h-6 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 14l-7 7m0 0l-7-7m7 7V3" />
</svg>
</div>
)}
</div>
))}
</div>
</div>
</div>
)}
{/* Roadmap Tab */}
{activeTab === 'roadmap' && (
<div className="space-y-6">
<h3 className="text-sm font-semibold text-slate-700 uppercase tracking-wide">Optimierungs-Roadmap</h3>
<div className="space-y-4">
{config.roadmap.map((phase, i) => (
<div key={i} className="bg-white rounded-lg border border-slate-200 p-4">
<div className="flex items-center justify-between mb-3">
<span className="font-semibold text-slate-900">{phase.phase}</span>
{getPriorityBadge(phase.priority)}
</div>
<ul className="space-y-2">
{phase.items.map((item, j) => (
<li key={j} className="flex items-start gap-2 text-sm text-slate-600">
<span className="text-slate-400 mt-1"></span>
{item}
</li>
))}
</ul>
</div>
))}
</div>
</div>
)}
{/* Technical Tab */}
{activeTab === 'technical' && (
<div className="space-y-6">
<h3 className="text-sm font-semibold text-slate-700 uppercase tracking-wide">Technische Details</h3>
<div className="bg-white rounded-lg border border-slate-200 overflow-hidden">
<table className="min-w-full divide-y divide-slate-200">
<thead className="bg-slate-50">
<tr>
<th className="px-4 py-3 text-left text-xs font-medium text-slate-500 uppercase">Komponente</th>
<th className="px-4 py-3 text-left text-xs font-medium text-slate-500 uppercase">Technologie</th>
<th className="px-4 py-3 text-left text-xs font-medium text-slate-500 uppercase">Version</th>
<th className="px-4 py-3 text-left text-xs font-medium text-slate-500 uppercase">Beschreibung</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-100">
{config.technicalDetails.map((detail, i) => (
<tr key={i}>
<td className="px-4 py-3 text-sm font-medium text-slate-900">{detail.component}</td>
<td className="px-4 py-3 text-sm text-slate-600 font-mono">{detail.technology}</td>
<td className="px-4 py-3 text-sm text-slate-500">{detail.version || '-'}</td>
<td className="px-4 py-3 text-sm text-slate-500">{detail.description || '-'}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)}
{/* Audit Tab */}
{activeTab === 'audit' && config.auditInfo && (
<div className="space-y-6">
<h3 className="text-sm font-semibold text-slate-700 uppercase tracking-wide">Audit-relevante Informationen</h3>
<div className="space-y-4">
{config.auditInfo.map((section, i) => (
<div key={i} className="bg-white rounded-lg border border-slate-200 p-4">
<h4 className="font-semibold text-slate-900 mb-3 flex items-center gap-2">
<svg className="w-5 h-5 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
{section.category}
</h4>
<div className="space-y-2">
{section.items.map((item, j) => (
<div key={j} className="flex items-center justify-between py-2 border-b border-slate-100 last:border-0">
<span className="text-sm text-slate-600">{item.label}</span>
<span className={`text-sm font-medium px-2 py-0.5 rounded ${
item.status === 'ok' ? 'bg-green-100 text-green-800' :
item.status === 'warning' ? 'bg-amber-100 text-amber-800' :
item.status === 'critical' ? 'bg-red-100 text-red-800' :
'text-slate-900'
}`}>
{item.value}
</span>
</div>
))}
</div>
</div>
))}
</div>
</div>
)}
{/* Documentation Tab */}
{activeTab === 'documentation' && config.fullDocumentation && (
<div className="space-y-6">
<div className="flex justify-between items-center">
<h3 className="text-sm font-semibold text-slate-700 uppercase tracking-wide">Vollstaendige Dokumentation</h3>
<button
onClick={() => setShowFullDocs(!showFullDocs)}
className="px-3 py-1 text-sm font-medium text-primary-700 bg-primary-50 rounded-lg hover:bg-primary-100"
>
{showFullDocs ? 'Kompakt' : 'Erweitert'}
</button>
</div>
<div
className={`prose prose-sm max-w-none bg-slate-900 text-slate-100 p-6 rounded-lg overflow-auto ${
showFullDocs ? 'max-h-none' : 'max-h-[600px]'
}`}
style={{
// Custom styles for dark background
}}
dangerouslySetInnerHTML={{ __html: config.fullDocumentation }}
/>
{/* Export Button */}
<div className="flex justify-end gap-3">
<button
onClick={() => {
const blob = new Blob([JSON.stringify(config, null, 2)], { type: 'application/json' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = `${config.title.toLowerCase().replace(/\s+/g, '-')}-system-info.json`
a.click()
}}
className="px-4 py-2 text-sm font-medium text-slate-700 bg-white border border-slate-300 rounded-lg hover:bg-slate-50"
>
JSON Export
</button>
<button
onClick={() => {
const printWindow = window.open('', '_blank')
if (printWindow) {
printWindow.document.write(`
<html>
<head>
<title>${config.title} - Dokumentation</title>
<style>
body { font-family: system-ui, sans-serif; padding: 40px; max-width: 800px; margin: 0 auto; }
h1, h2, h3 { color: #1e293b; }
pre { background: #f1f5f9; padding: 12px; border-radius: 6px; overflow-x: auto; }
code { background: #f1f5f9; padding: 2px 6px; border-radius: 4px; }
table { border-collapse: collapse; width: 100%; margin: 16px 0; }
th, td { border: 1px solid #e2e8f0; padding: 8px 12px; text-align: left; }
th { background: #f8fafc; }
</style>
</head>
<body>
<h1>${config.title}</h1>
<p><em>${config.description}</em></p>
<hr>
${config.fullDocumentation}
</body>
</html>
`)
printWindow.document.close()
printWindow.print()
}
}}
className="px-4 py-2 text-sm font-medium text-white bg-primary-600 rounded-lg hover:bg-primary-700"
>
Drucken / PDF
</button>
</div>
</div>
)}
</div>
</div>
)
}

View File

@@ -0,0 +1,183 @@
import type { SystemInfoConfig } from './types'
export const backlogConfig: SystemInfoConfig = {
title: 'Backlog System-Info',
description: 'Produkt-Backlog und Feature-Tracking.',
version: '1.0',
architecture: {
layers: [
{ title: 'Backlog UI', components: ['Board View', 'List View', 'Roadmap'], color: '#3b82f6' },
{ title: 'Planning', components: ['Sprint Planning', 'Estimation', 'Prioritization'], color: '#8b5cf6' },
{ title: 'Tracking', components: ['Progress', 'Velocity', 'Burndown'], color: '#10b981' },
{ title: 'Integration', components: ['GitHub', 'Jira', 'Notion'], color: '#f59e0b' },
],
},
features: [
{ name: 'Feature Tracking', status: 'active', description: 'Anforderungsverwaltung' },
{ name: 'Prioritization', status: 'active', description: 'MoSCoW/RICE Methoden' },
{ name: 'Sprint Planning', status: 'active', description: 'Agile Planung' },
{ name: 'Dependency Tracking', status: 'planned', description: 'Feature-Abhaengigkeiten' },
],
roadmap: [
{ phase: 'Phase 1: Core (Q1)', priority: 'high', items: ['Kanban Board', 'Story Points', 'Labels/Tags', 'Assignees'] },
{ phase: 'Phase 2: Planning (Q2)', priority: 'medium', items: ['Sprint Backlog', 'Velocity Charts', 'Capacity Planning', 'Release Planning'] },
{ phase: 'Phase 3: Intelligence (Q3)', priority: 'low', items: ['Auto-Prioritization', 'Effort Prediction', 'Risk Identification', 'Stakeholder Reports'] },
],
technicalDetails: [
{ component: 'UI', technology: 'React DnD', description: 'Drag & Drop' },
{ component: 'Storage', technology: 'PostgreSQL', description: 'Relational Data' },
{ component: 'Sync', technology: 'GitHub API', description: 'Issue Sync' },
{ component: 'Export', technology: 'CSV/JSON', description: 'Data Export' },
],
auditInfo: [
{
category: 'Backlog Status',
items: [
{ label: 'Offene Items', value: 'Tracking', status: 'ok' },
{ label: 'In Progress', value: 'Tracking', status: 'ok' },
{ label: 'Completed (Sprint)', value: 'Tracking', status: 'ok' },
{ label: 'Backlog Grooming', value: 'Woechentlich', status: 'ok' },
],
},
{
category: 'Priorisierung',
items: [
{ label: 'Must Have', value: 'Tracking', status: 'ok' },
{ label: 'Should Have', value: 'Tracking', status: 'ok' },
{ label: 'Could Have', value: 'Tracking', status: 'ok' },
{ label: 'Wont Have', value: 'Tracking', status: 'ok' },
],
},
{
category: 'Integration',
items: [
{ label: 'GitHub Sync', value: 'Aktiv', status: 'ok' },
{ label: 'Jira Sync', value: 'Optional', status: 'ok' },
{ label: 'Slack Notifications', value: 'Konfigurierbar', status: 'ok' },
{ label: 'Webhooks', value: 'Aktiv', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>Backlog Management System</h2>
<h3>1. Uebersicht</h3>
<p>Das Backlog-Modul verwaltet alle Feature-Anfragen, Bugs und Verbesserungen. Es unterstuetzt agile Methoden wie Scrum und Kanban.</p>
<h3>2. Item-Typen</h3>
<table>
<tr><th>Typ</th><th>Icon</th><th>Beschreibung</th></tr>
<tr><td>Epic</td><td>⚡</td><td>Grosses Feature, mehrere Stories</td></tr>
<tr><td>Story</td><td>📖</td><td>User Story mit Akzeptanzkriterien</td></tr>
<tr><td>Task</td><td>✓</td><td>Technische Aufgabe</td></tr>
<tr><td>Bug</td><td>🐛</td><td>Fehlerbericht</td></tr>
<tr><td>Improvement</td><td>💡</td><td>Verbesserungsvorschlag</td></tr>
</table>
<h3>3. Workflow</h3>
<pre>
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Backlog │ → │ Selected │ → │ In Dev │ → │ Review │ → │ Done │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
│ │ │ │ │
│ │ │ │ │
Priorisiert Sprint Entwicklung Code Review Abgeschlossen
Planning & Testing & QA
</pre>
<h3>4. Item-Struktur</h3>
<pre>
{
"id": "BP-123",
"type": "story",
"title": "Als Nutzer moechte ich...",
"description": "...",
"acceptance_criteria": [
"Gegeben..., Wenn..., Dann..."
],
"priority": "must_have",
"story_points": 5,
"labels": ["frontend", "ux"],
"assignee": "user_id",
"sprint": "Sprint 12",
"epic": "BP-100",
"created_at": "2025-01-14T10:00:00Z",
"updated_at": "2025-01-14T12:00:00Z"
}
</pre>
<h3>5. Priorisierung (MoSCoW)</h3>
<table>
<tr><th>Prioritaet</th><th>Beschreibung</th><th>Behandlung</th></tr>
<tr><td>Must Have</td><td>Unverzichtbar</td><td>Im naechsten Sprint</td></tr>
<tr><td>Should Have</td><td>Wichtig</td><td>Baldmoeglichst</td></tr>
<tr><td>Could Have</td><td>Wuenschenswert</td><td>Wenn Zeit</td></tr>
<tr><td>Wont Have</td><td>Nicht jetzt</td><td>Spaeter evaluieren</td></tr>
</table>
<h3>6. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/backlog/items</td><td>GET</td><td>Items listen</td></tr>
<tr><td>/api/backlog/items</td><td>POST</td><td>Neues Item</td></tr>
<tr><td>/api/backlog/items/{id}</td><td>PATCH</td><td>Item aktualisieren</td></tr>
<tr><td>/api/backlog/sprints</td><td>GET</td><td>Sprints listen</td></tr>
<tr><td>/api/backlog/kanban</td><td>GET</td><td>Board-Ansicht</td></tr>
</table>
<h3>7. Sprint Planning</h3>
<pre>
Sprint Planning Flow:
1. Velocity berechnen
└── Durchschnitt der letzten 3 Sprints
2. Kapazitaet ermitteln
└── Teamgroesse × Verfuegbarkeit
3. Items auswaehlen
├── Priorisierte Items
├── Story Points summieren
└── Kapazitaet nicht ueberschreiten
4. Sprint Goal definieren
└── Uebergreifendes Ziel
5. Sprint starten
└── 2 Wochen Timeebox
</pre>
<h3>8. Metriken</h3>
<table>
<tr><th>Metrik</th><th>Beschreibung</th><th>Ziel</th></tr>
<tr><td>Velocity</td><td>Story Points/Sprint</td><td>Stabil</td></tr>
<tr><td>Cycle Time</td><td>Zeit bis Done</td><td>Sinkend</td></tr>
<tr><td>Lead Time</td><td>Backlog bis Done</td><td>Sinkend</td></tr>
<tr><td>Burndown</td><td>Remaining Work</td><td>Linear</td></tr>
</table>
<h3>9. GitHub Integration</h3>
<pre>
Sync-Konfiguration:
GitHub Issues → Backlog Items
├── Labels → Typ-Mapping
├── Milestones → Sprints
├── Assignees → Team-Members
└── Comments → Bidirektional
Automatisierung:
├── PR merged → Item nach Done
├── Branch erstellt → Item nach In Dev
└── Review requested → Item nach Review
</pre>
<h3>10. Reporting</h3>
<ul>
<li><strong>Burndown Chart:</strong> Sprint-Fortschritt</li>
<li><strong>Velocity Chart:</strong> Trend ueber Sprints</li>
<li><strong>Cumulative Flow:</strong> WIP-Analyse</li>
<li><strong>Sprint Report:</strong> Completed vs Planned</li>
</ul>
`,
}

View File

@@ -0,0 +1,170 @@
import type { SystemInfoConfig } from './types'
export const brandbookConfig: SystemInfoConfig = {
title: 'Brandbook System-Info',
description: 'Corporate Design Guidelines und Style Guide.',
version: '1.0',
architecture: {
layers: [
{ title: 'Style Guide UI', components: ['Colors', 'Typography', 'Components'], color: '#3b82f6' },
{ title: 'Design Tokens', components: ['CSS Variables', 'Tailwind Config', 'Figma Tokens'], color: '#8b5cf6' },
{ title: 'Assets', components: ['Logo', 'Icons', 'Illustrations'], color: '#10b981' },
{ title: 'Documentation', components: ['Usage Guidelines', 'Examples', 'Do/Donts'], color: '#f59e0b' },
],
},
features: [
{ name: 'Farb-Palette', status: 'active', description: 'Primaer- und Sekundaerfarben' },
{ name: 'Typografie', status: 'active', description: 'Schriftarten und -groessen' },
{ name: 'Komponenten-Bibliothek', status: 'active', description: 'UI-Komponenten-Dokumentation' },
{ name: 'Figma Sync', status: 'planned', description: 'Design Token Synchronisation' },
],
roadmap: [
{ phase: 'Phase 1: Foundation (Q1)', priority: 'high', items: ['Design Tokens', 'Color System', 'Typography Scale', 'Spacing System'] },
{ phase: 'Phase 2: Components (Q2)', priority: 'medium', items: ['Button Variants', 'Form Elements', 'Cards', 'Navigation'] },
{ phase: 'Phase 3: Templates (Q3)', priority: 'low', items: ['Page Templates', 'E-Mail Templates', 'Print Templates', 'Social Media'] },
],
technicalDetails: [
{ component: 'CSS', technology: 'Tailwind CSS', version: '3.x', description: 'Utility Classes' },
{ component: 'Icons', technology: 'Heroicons', version: '2.x', description: 'SVG Icons' },
{ component: 'Fonts', technology: 'Inter/System', description: 'Web Fonts' },
{ component: 'Design', technology: 'Figma', description: 'Design Source' },
],
auditInfo: [
{
category: 'Design System Status',
items: [
{ label: 'Farbpalette', value: 'Definiert', status: 'ok' },
{ label: 'Typografie', value: 'Definiert', status: 'ok' },
{ label: 'Komponenten', value: '15+ Komponenten', status: 'ok' },
{ label: 'Figma Sync', value: 'Geplant', status: 'warning' },
],
},
{
category: 'Dokumentation',
items: [
{ label: 'Usage Guidelines', value: 'Vorhanden', status: 'ok' },
{ label: 'Code Examples', value: 'Vorhanden', status: 'ok' },
{ label: 'Do/Donts', value: 'Vorhanden', status: 'ok' },
{ label: 'Accessibility', value: 'WCAG 2.1 AA', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>Brandbook & Design System</h2>
<h3>1. Uebersicht</h3>
<p>Das Brandbook definiert alle visuellen Elemente der BreakPilot-Marke. Es dient als zentrale Referenz fuer konsistentes Design ueber alle Produkte und Plattformen.</p>
<h3>2. Farbpalette</h3>
<table>
<tr><th>Name</th><th>Hex</th><th>Verwendung</th></tr>
<tr><td>Primary</td><td>#3B82F6</td><td>Buttons, Links, Akzente</td></tr>
<tr><td>Primary Dark</td><td>#1E40AF</td><td>Hover States</td></tr>
<tr><td>Secondary</td><td>#8B5CF6</td><td>Sekundaere Aktionen</td></tr>
<tr><td>Success</td><td>#10B981</td><td>Erfolg, Bestaetigung</td></tr>
<tr><td>Warning</td><td>#F59E0B</td><td>Warnungen</td></tr>
<tr><td>Error</td><td>#EF4444</td><td>Fehler, Loeschung</td></tr>
<tr><td>Slate 900</td><td>#0F172A</td><td>Text, Headings</td></tr>
<tr><td>Slate 500</td><td>#64748B</td><td>Sekundaerer Text</td></tr>
</table>
<h3>3. Typografie</h3>
<pre>
Font Family: Inter (System Fallback)
Scale:
├── Display: 2.25rem (36px) / Bold
├── H1: 1.875rem (30px) / Semibold
├── H2: 1.5rem (24px) / Semibold
├── H3: 1.25rem (20px) / Medium
├── Body: 1rem (16px) / Regular
├── Small: 0.875rem (14px) / Regular
└── Caption: 0.75rem (12px) / Regular
</pre>
<h3>4. Spacing System</h3>
<table>
<tr><th>Token</th><th>Wert</th><th>Verwendung</th></tr>
<tr><td>space-1</td><td>4px</td><td>Inline-Elemente</td></tr>
<tr><td>space-2</td><td>8px</td><td>Eng verwandte Elemente</td></tr>
<tr><td>space-3</td><td>12px</td><td>Standard-Gap</td></tr>
<tr><td>space-4</td><td>16px</td><td>Sections</td></tr>
<tr><td>space-6</td><td>24px</td><td>Grosse Sections</td></tr>
<tr><td>space-8</td><td>32px</td><td>Page Sections</td></tr>
</table>
<h3>5. Komponenten-Bibliothek</h3>
<pre>
Components/
├── Buttons/
│ ├── Primary Button
│ ├── Secondary Button
│ ├── Ghost Button
│ └── Icon Button
├── Forms/
│ ├── Input
│ ├── Select
│ ├── Checkbox
│ └── Radio
├── Feedback/
│ ├── Alert
│ ├── Toast
│ └── Badge
├── Layout/
│ ├── Card
│ ├── Modal
│ └── Sidebar
└── Navigation/
├── Tabs
├── Breadcrumb
└── Pagination
</pre>
<h3>6. Icon-System</h3>
<ul>
<li><strong>Library:</strong> Heroicons v2</li>
<li><strong>Style:</strong> Outline (24px), Solid (20px)</li>
<li><strong>Farbe:</strong> currentColor (erbt Text-Farbe)</li>
</ul>
<h3>7. Logo-Verwendung</h3>
<table>
<tr><th>Variante</th><th>Verwendung</th><th>Min. Groesse</th></tr>
<tr><td>Primary (Farbe)</td><td>Helle Hintergruende</td><td>120px breit</td></tr>
<tr><td>White</td><td>Dunkle Hintergruende</td><td>120px breit</td></tr>
<tr><td>Icon Only</td><td>Favicon, App Icon</td><td>32px</td></tr>
</table>
<h3>8. Accessibility</h3>
<ul>
<li><strong>Kontrast:</strong> Minimum 4.5:1 fuer Text</li>
<li><strong>Focus States:</strong> Sichtbarer Fokusring</li>
<li><strong>Keyboard:</strong> Alle interaktiven Elemente erreichbar</li>
<li><strong>Screen Reader:</strong> ARIA Labels vorhanden</li>
</ul>
<h3>9. Do's and Don'ts</h3>
<pre>
✓ Do:
- Konsistente Spacing verwenden
- Primary Color fuer CTAs
- Ausreichend Weissraum
- Hierarchie durch Typografie
✗ Don't:
- Farben mischen
- Logo verzerren
- Zu viele Schriftgroessen
- Zu wenig Kontrast
</pre>
<h3>10. Design Token Export</h3>
<p>Tokens sind verfuegbar als:</p>
<ul>
<li>CSS Custom Properties</li>
<li>Tailwind Config</li>
<li>Figma Variables (geplant)</li>
<li>JSON Token File</li>
</ul>
`,
}

View File

@@ -0,0 +1,134 @@
import type { SystemInfoConfig } from './types'
export const communicationConfig: SystemInfoConfig = {
title: 'Communication System-Info',
description: 'Matrix Homeserver, Jitsi Videokonferenz, Jibri Recording und KI-Transkription.',
version: '2.0',
architecture: {
layers: [
{ title: 'Frontend', components: ['BreakPilot Meet', 'Recording UI', 'Transcript Viewer'], color: '#3b82f6' },
{ title: 'Videokonferenz', components: ['Jitsi Meet', 'Videobridge', 'Jicofo', 'Prosody'], color: '#17a2b8' },
{ title: 'Recording', components: ['Jibri', 'Xvfb', 'FFmpeg', 'MinIO Upload'], color: '#28a745' },
{ title: 'Transkription', components: ['faster-whisper', 'pyannote.audio', 'RQ Worker'], color: '#6f42c1' },
{ title: 'Matrix Chat', components: ['Synapse', 'Federation', 'Media Store'], color: '#0DBD8B' },
{ title: 'Infrastructure', components: ['PostgreSQL', 'Valkey', 'MinIO', 'TURN'], color: '#f59e0b' },
],
},
features: [
{ name: 'Jitsi Videokonferenz', status: 'active', description: 'WebRTC-basierte Videokonferenzen' },
{ name: 'Matrix Chat', status: 'active', description: 'E2EE Messaging mit Synapse' },
{ name: 'Jibri Recording', status: 'active', description: 'Meeting-Aufzeichnung mit Consent' },
{ name: 'KI-Transkription', status: 'active', description: 'Whisper + Speaker Diarization' },
{ name: 'KI Meeting-Protokolle', status: 'active', description: 'LLM-generierte Zusammenfassungen mit Action Items' },
{ name: 'Untertitel Export', status: 'active', description: 'WebVTT und SRT Export' },
{ name: 'PDF Export', status: 'active', description: 'Protokolle als PDF exportieren' },
],
roadmap: [
{ phase: 'Phase 1: Recording (Abgeschlossen)', priority: 'high', items: ['Jibri Integration', 'MinIO Storage', 'Consent Management', 'Webhook Pipeline'] },
{ phase: 'Phase 2: Transkription (Abgeschlossen)', priority: 'high', items: ['Whisper large-v3', 'Speaker Diarization', 'VTT/SRT Export', 'Segment-Suche'] },
{ phase: 'Phase 3: Protokolle (Abgeschlossen)', priority: 'high', items: ['LLM Gateway Integration', 'Action Items', 'Zusammenfassungen', 'MD/HTML/PDF Export'] },
{ phase: 'Phase 4: Erweiterte KI (Q2)', priority: 'medium', items: ['Sprecher-Namensverknuepfung', 'Themen-Clustering', 'Sentiment-Analyse', 'Automatische Agenda'] },
],
technicalDetails: [
{ component: 'Video', technology: 'Jitsi Meet', version: 'stable-9823', description: 'WebRTC Konferenz' },
{ component: 'Recording', technology: 'Jibri', version: 'stable-9823', description: 'Meeting Recording' },
{ component: 'Transkription', technology: 'faster-whisper', version: '1.0+', description: 'GPU-optimiert (MIT)' },
{ component: 'Diarization', technology: 'pyannote.audio', version: '3.x', description: 'Speaker ID (MIT)' },
{ component: 'Meeting Minutes', technology: 'LLM Gateway', version: '1.0', description: 'Ollama/Llama 3.1' },
{ component: 'Queue', technology: 'RQ/Valkey', version: '1.x', description: 'Task Processing' },
{ component: 'Storage', technology: 'MinIO', version: 'latest', description: 'S3-kompatibel' },
{ component: 'Chat', technology: 'Matrix Synapse', version: '1.x', description: 'E2EE Homeserver' },
{ component: 'TURN', technology: 'Coturn', version: '4.x', description: 'NAT Traversal' },
],
auditInfo: [
{
category: 'Jitsi Videokonferenz',
items: [
{ label: 'Videobridge', value: 'Online', status: 'ok' },
{ label: 'Max. Teilnehmer', value: '100', status: 'ok' },
{ label: 'E2E Encryption', value: 'Verfuegbar', status: 'ok' },
{ label: 'TURN Server', value: 'Aktiv', status: 'ok' },
],
},
{
category: 'Jibri Recording',
items: [
{ label: 'Recording Service', value: 'Aktiv', status: 'ok' },
{ label: 'Consent-Pflicht', value: 'Aktiviert', status: 'ok' },
{ label: 'Storage', value: 'MinIO (Self-hosted)', status: 'ok' },
{ label: 'Retention', value: '365 Tage', status: 'ok' },
],
},
{
category: 'KI-Transkription',
items: [
{ label: 'Whisper Modell', value: 'large-v3 (lokal)', status: 'ok' },
{ label: 'Speaker Diarization', value: 'pyannote (lokal)', status: 'ok' },
{ label: 'Datenverarbeitung', value: '100% On-Premise', status: 'ok' },
{ label: 'Export-Formate', value: 'VTT, SRT, JSON', status: 'ok' },
],
},
{
category: 'KI Meeting-Protokolle',
items: [
{ label: 'LLM Backend', value: 'Ollama (lokal)', status: 'ok' },
{ label: 'Modell', value: 'Llama 3.1 8B/70B', status: 'ok' },
{ label: 'Verarbeitung', value: '100% On-Premise', status: 'ok' },
{ label: 'Export-Formate', value: 'MD, HTML, PDF', status: 'ok' },
],
},
{
category: 'Matrix Homeserver',
items: [
{ label: 'Server Status', value: 'Online', status: 'ok' },
{ label: 'Federation', value: 'Aktiviert', status: 'ok' },
{ label: 'E2E Encryption', value: 'Standard', status: 'ok' },
{ label: 'Media Retention', value: '90 Tage', status: 'ok' },
],
},
{
category: 'DSGVO-Compliance',
items: [
{ label: 'Daten-Residenz', value: 'EU (Self-hosted)', status: 'ok' },
{ label: 'Consent-Management', value: 'Implementiert', status: 'ok' },
{ label: 'Audit-Logging', value: 'Aktiviert', status: 'ok' },
{ label: 'Loeschrecht (Art. 17)', value: 'Implementiert', status: 'ok' },
],
},
{
category: 'Open Source Lizenzen',
items: [
{ label: 'Jitsi/Jibri', value: 'Apache-2.0', status: 'ok' },
{ label: 'faster-whisper', value: 'MIT', status: 'ok' },
{ label: 'pyannote.audio', value: 'MIT', status: 'ok' },
{ label: 'Matrix Synapse', value: 'AGPL-3.0', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>BreakPilot Communication Platform</h2>
<p><strong>Version:</strong> 2.0.0 | <strong>Stand:</strong> Januar 2026 | <strong>Autor:</strong> BreakPilot Development Team</p>
<h2>Audit-Relevante Informationen</h2>
<p>Dieses Dokument dient als technische Dokumentation fuer das Kommunikationssystem der BreakPilot Plattform. Es ist fuer Audits durch Bildungstraeger und Datenschutzbeauftragte konzipiert.</p>
<h3>Ziel des Kommunikationssystems</h3>
<p>Das System ermoeglicht sichere Videokonferenzen und Messaging fuer Bildungseinrichtungen mit:</p>
<ul>
<li><strong>Jitsi Meet:</strong> DSGVO-konforme Videokonferenzen ohne Drittanbieter</li>
<li><strong>Jibri Recording:</strong> Meeting-Aufzeichnung mit expliziter Einwilligung</li>
<li><strong>KI-Transkription:</strong> Automatische Verschriftlichung mit Sprechererkennung</li>
<li><strong>KI Meeting-Protokolle:</strong> Automatische Zusammenfassungen, Action Items, Entscheidungen</li>
<li><strong>Matrix Chat:</strong> Ende-zu-Ende verschluesselte Nachrichten</li>
</ul>
<h3>Datenschutz-Compliance</h3>
<ul>
<li><strong>100% Self-Hosted:</strong> Alle Dienste laufen auf eigenen Servern in der EU</li>
<li><strong>Keine Cloud-Abhaengigkeit:</strong> Keine Daten verlassen die Infrastruktur</li>
<li><strong>Consent-Management:</strong> Aufzeichnung nur mit expliziter Zustimmung aller Teilnehmer</li>
<li><strong>Audit-Logging:</strong> Vollstaendige Nachvollziehbarkeit aller Zugriffe</li>
<li><strong>Open Source:</strong> Alle Komponenten sind quelloffen und auditierbar</li>
</ul>
`,
}

View File

@@ -0,0 +1,151 @@
import type { SystemInfoConfig } from './types'
export const consentConfig: SystemInfoConfig = {
title: 'Consent Management System-Info',
description: 'DSGVO-konforme Verwaltung von Einwilligungen und rechtlichen Dokumenten.',
version: '3.0',
privacyNotes: [
'Alle Consent-Daten werden verschluesselt gespeichert',
'Audit-Trail fuer alle Aenderungen',
'Automatische Datenlöschung nach Widerruf',
'DSGVO Art. 7 konforme Einwilligungsverwaltung',
],
architecture: {
layers: [
{ title: 'Frontend', components: ['Consent Banner', 'Praeferenz-Center', 'Admin UI'], color: '#3b82f6' },
{ title: 'Consent Service (Go)', components: ['Consent API', 'Version Control', 'Audit Logger'], color: '#00ADD8' },
{ title: 'Backend (Python)', components: ['GDPR Export', 'Analytics', 'Reporting'], color: '#3776AB' },
{ title: 'PostgreSQL', components: ['Consents', 'Documents', 'Audit Logs'], color: '#336791' },
],
},
features: [
{ name: 'Dokumenten-Versionierung', status: 'active', description: 'Vollstaendige Historie aller Versionen' },
{ name: 'Multi-Mandanten', status: 'active', description: 'Tenant-isolierte Consent-Verwaltung' },
{ name: 'Approval Workflow', status: 'active', description: 'DSB-Freigabe fuer neue Versionen' },
{ name: 'A/B Testing', status: 'planned', description: 'Consent-Rate Optimierung' },
{ name: 'Analytics Dashboard', status: 'planned', description: 'Consent-Metriken und Trends' },
],
roadmap: [
{ phase: 'Phase 1: Compliance (Q1)', priority: 'high', items: ['TCF 2.2 Integration', 'IAB GPP Support', 'Cookie Scanning', 'Compliance Reports'] },
{ phase: 'Phase 2: UX (Q2)', priority: 'medium', items: ['Banner A/B Testing', 'Conversion Tracking', 'Dark Pattern Detection', 'Accessibility (WCAG)'] },
{ phase: 'Phase 3: Integration (Q3)', priority: 'low', items: ['Google Consent Mode v2', 'Meta CAPI Integration', 'CRM Sync', 'Marketing Automation'] },
],
technicalDetails: [
{ component: 'Backend', technology: 'Go + Gin', version: '1.21+', description: 'High-Performance API' },
{ component: 'Database', technology: 'PostgreSQL', version: '16', description: 'ACID-konform' },
{ component: 'Cache', technology: 'Valkey', version: '8.x', description: 'Redis-kompatibel' },
{ component: 'Encryption', technology: 'AES-256', description: 'At-rest Verschluesselung' },
],
auditInfo: [
{
category: 'DSGVO-Compliance',
items: [
{ label: 'Art. 7 Einwilligung', value: 'Implementiert', status: 'ok' },
{ label: 'Art. 13/14 Informationspflichten', value: 'Implementiert', status: 'ok' },
{ label: 'Art. 17 Recht auf Loeschung', value: 'Implementiert', status: 'ok' },
{ label: 'Art. 20 Datenportabilitaet', value: 'Implementiert', status: 'ok' },
],
},
{
category: 'Technische Sicherheit',
items: [
{ label: 'Verschluesselung', value: 'AES-256 at rest', status: 'ok' },
{ label: 'TLS', value: '1.3', status: 'ok' },
{ label: 'Audit-Log', value: 'Lueckenlos', status: 'ok' },
{ label: 'Backup', value: 'Taeglich, 30 Tage', status: 'ok' },
],
},
{
category: 'Dokumenten-Status',
items: [
{ label: 'AGB', value: 'v2.1 - Aktiv', status: 'ok' },
{ label: 'Datenschutz', value: 'v3.0 - Aktiv', status: 'ok' },
{ label: 'Cookie-Policy', value: 'v1.5 - Aktiv', status: 'ok' },
{ label: 'Impressum', value: 'v1.0 - Aktiv', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>Consent Management System</h2>
<h3>1. Uebersicht</h3>
<p>Das Consent Management System (CMS) verwaltet alle rechtlichen Einwilligungen fuer die BreakPilot-Plattform gemaess DSGVO Art. 6 und Art. 7.</p>
<h3>2. Dokumenttypen</h3>
<table>
<tr><th>Typ</th><th>Beschreibung</th><th>Pflicht</th></tr>
<tr><td>terms</td><td>Allgemeine Geschaeftsbedingungen</td><td>Ja</td></tr>
<tr><td>privacy</td><td>Datenschutzerklaerung</td><td>Ja</td></tr>
<tr><td>cookies</td><td>Cookie-Richtlinie</td><td>Ja</td></tr>
<tr><td>community</td><td>Community Guidelines</td><td>Nein</td></tr>
<tr><td>imprint</td><td>Impressum</td><td>Nein</td></tr>
</table>
<h3>3. Versions-Workflow</h3>
<pre>
┌──────────┐ ┌──────────┐ ┌───────────┐ ┌───────────┐
│ draft │ -> │ review │ -> │ approved │ -> │ published │
└──────────┘ └────┬─────┘ └───────────┘ └───────────┘
v
┌──────────┐
│ rejected │ -> zurueck zu draft
└──────────┘
</pre>
<h3>4. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/consent/documents</td><td>GET</td><td>Alle Dokumente listen</td></tr>
<tr><td>/api/consent/documents/{type}/latest</td><td>GET</td><td>Aktuelle Version</td></tr>
<tr><td>/api/consent/check/{type}</td><td>GET</td><td>Consent-Status pruefen</td></tr>
<tr><td>/api/consent/grant</td><td>POST</td><td>Consent erteilen</td></tr>
<tr><td>/api/consent/revoke</td><td>POST</td><td>Consent widerrufen</td></tr>
</table>
<h3>5. Cookie-Kategorien</h3>
<table>
<tr><th>Kategorie</th><th>Beschreibung</th><th>Default</th></tr>
<tr><td>essential</td><td>Technisch notwendig</td><td>Immer aktiv</td></tr>
<tr><td>functional</td><td>Erweiterte Funktionen</td><td>Opt-in</td></tr>
<tr><td>analytics</td><td>Nutzungsanalyse</td><td>Opt-in</td></tr>
<tr><td>marketing</td><td>Werbung & Tracking</td><td>Opt-in</td></tr>
</table>
<h3>6. Audit-Trail</h3>
<p>Alle Consent-Aenderungen werden mit folgenden Daten protokolliert:</p>
<ul>
<li>Timestamp (ISO 8601)</li>
<li>User-ID (pseudonymisiert)</li>
<li>Aktion (grant/revoke/update)</li>
<li>Dokumenttyp und Version</li>
<li>IP-Adresse (anonymisiert nach 30 Tagen)</li>
<li>User-Agent</li>
</ul>
<h3>7. DSGVO-Rechte</h3>
<table>
<tr><th>Artikel</th><th>Recht</th><th>Status</th></tr>
<tr><td>Art. 7</td><td>Widerruf der Einwilligung</td><td>✓ Implementiert</td></tr>
<tr><td>Art. 15</td><td>Auskunftsrecht</td><td>✓ Implementiert</td></tr>
<tr><td>Art. 16</td><td>Recht auf Berichtigung</td><td>✓ Implementiert</td></tr>
<tr><td>Art. 17</td><td>Recht auf Loeschung</td><td>✓ Implementiert</td></tr>
<tr><td>Art. 20</td><td>Datenportabilitaet</td><td>✓ Implementiert</td></tr>
</table>
<h3>8. Compliance-Pruefungen</h3>
<ol>
<li>Woechentlich: Automatischer Consent-Rate Report</li>
<li>Monatlich: Dokumenten-Review durch DSB</li>
<li>Quartalsweise: Compliance-Audit</li>
<li>Jaehrlich: Externer Datenschutz-Audit</li>
</ol>
<h3>9. Notfallprozeduren</h3>
<ul>
<li><strong>Bei Datenpanne:</strong> Sofortige Benachrichtigung DSB, ggf. Aufsichtsbehoerde (72h)</li>
<li><strong>Bei Systemausfall:</strong> Fallback auf statische Consent-Seite</li>
<li><strong>Bei rechtlicher Aenderung:</strong> Dokumenten-Update mit Re-Consent Kampagne</li>
</ul>
`,
}

View File

@@ -0,0 +1,85 @@
import type { SystemInfoConfig } from './types'
export const contentConfig: SystemInfoConfig = {
title: 'Content Management System-Info',
description: 'Verwaltung von Bildungsinhalten und Medien.',
version: '1.5',
architecture: {
layers: [
{ title: 'Content UI', components: ['Media Library', 'Editor', 'Preview'], color: '#3b82f6' },
{ title: 'Processing', components: ['Transcoding', 'Thumbnail Gen', 'OCR'], color: '#8b5cf6' },
{ title: 'Delivery', components: ['CDN', 'Streaming', 'Download'], color: '#10b981' },
{ title: 'Storage', components: ['MinIO', 'PostgreSQL', 'Qdrant'], color: '#f59e0b' },
],
},
features: [
{ name: 'Media Upload', status: 'active', description: 'Multi-Format Upload' },
{ name: 'Auto-Processing', status: 'active', description: 'Automatische Konvertierung' },
{ name: 'Search & Filter', status: 'active', description: 'Content-Suche' },
{ name: 'Version Control', status: 'planned', description: 'Inhaltsversionierung' },
],
roadmap: [
{ phase: 'Phase 1: Core (Q1)', priority: 'high', items: ['Bulk Upload', 'Metadata Editor', 'Tagging System', 'Folder Structure'] },
{ phase: 'Phase 2: Media (Q2)', priority: 'medium', items: ['Video Streaming', 'Adaptive Bitrate', 'Subtitle Support', 'Audio Transcription'] },
{ phase: 'Phase 3: AI (Q3)', priority: 'low', items: ['Auto-Tagging', 'Content Moderation', 'Similarity Search', 'Auto-Description'] },
],
technicalDetails: [
{ component: 'Storage', technology: 'MinIO', description: 'S3-Compatible' },
{ component: 'Video', technology: 'FFmpeg', description: 'Transcoding' },
{ component: 'CDN', technology: 'CloudFlare', description: 'Delivery' },
{ component: 'Search', technology: 'Qdrant', description: 'Similarity' },
],
auditInfo: [
{
category: 'Content Status',
items: [
{ label: 'Gesamt-Assets', value: 'Tracking', status: 'ok' },
{ label: 'Veroeffentlicht', value: 'Tracking', status: 'ok' },
{ label: 'In Review', value: 'Tracking', status: 'ok' },
{ label: 'Storage genutzt', value: 'Monitoring', status: 'ok' },
],
},
{
category: 'Processing',
items: [
{ label: 'Transcoding Queue', value: 'Aktiv', status: 'ok' },
{ label: 'Thumbnail Gen', value: 'Automatisch', status: 'ok' },
{ label: 'OCR Pipeline', value: 'Aktiv', status: 'ok' },
{ label: 'CDN Sync', value: 'Aktiv', status: 'ok' },
],
},
{
category: 'Qualitaet',
items: [
{ label: 'Format-Standards', value: 'Definiert', status: 'ok' },
{ label: 'Metadata-Validierung', value: 'Aktiv', status: 'ok' },
{ label: 'Content-Moderation', value: 'Geplant', status: 'warning' },
{ label: 'Accessibility', value: 'In Arbeit', status: 'warning' },
],
},
],
fullDocumentation: `
<h2>Content Management System</h2>
<h3>1. Uebersicht</h3>
<p>Das CMS verwaltet alle Bildungsinhalte: Videos, PDFs, Arbeitsblätter und interaktive Medien.</p>
<h3>2. Unterstuetzte Formate</h3>
<table>
<tr><th>Typ</th><th>Eingabe</th><th>Ausgabe</th><th>Max Groesse</th></tr>
<tr><td>Video</td><td>MP4, MOV, MKV, AVI</td><td>MP4 (H.264), HLS</td><td>5 GB</td></tr>
<tr><td>Audio</td><td>MP3, WAV, FLAC, M4A</td><td>MP3, AAC</td><td>500 MB</td></tr>
<tr><td>Dokument</td><td>PDF, DOCX, PPTX</td><td>PDF, Thumbnails</td><td>100 MB</td></tr>
<tr><td>Bild</td><td>JPG, PNG, WEBP, GIF</td><td>WEBP, Thumbnails</td><td>50 MB</td></tr>
</table>
<h3>3. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/content/upload</td><td>POST</td><td>Upload initiieren (TUS)</td></tr>
<tr><td>/api/content/assets</td><td>GET</td><td>Assets listen</td></tr>
<tr><td>/api/content/assets/{id}</td><td>GET</td><td>Asset-Details</td></tr>
<tr><td>/api/content/search</td><td>GET</td><td>Content suchen</td></tr>
</table>
`,
}

View File

@@ -0,0 +1,32 @@
import type { SystemInfoConfig } from './types'
export const dashboardConfig: SystemInfoConfig = {
title: 'Dashboard System-Info',
description: 'Zentrale Uebersicht aller BreakPilot-Module und deren Status.',
version: '2.0',
architecture: {
layers: [
{ title: 'Frontend (Next.js 15)', components: ['Dashboard UI', 'Chart.js', 'Realtime Updates'], color: '#3b82f6' },
{ title: 'API Gateway', components: ['Next.js API Routes', 'Auth Middleware', 'Rate Limiting'], color: '#8b5cf6' },
{ title: 'Microservices', components: ['Consent Service', 'Klausur Service', 'School Service'], color: '#10b981' },
{ title: 'Datenbanken', components: ['PostgreSQL', 'Qdrant', 'Valkey (Redis)'], color: '#f59e0b' },
],
},
features: [
{ name: 'Service Health Monitoring', status: 'active', description: 'Echtzeit-Status aller Microservices' },
{ name: 'Metriken-Aggregation', status: 'active', description: 'Zusammenfassung wichtiger KPIs' },
{ name: 'Alerting System', status: 'planned', description: 'Benachrichtigungen bei Problemen' },
{ name: 'Custom Dashboards', status: 'planned', description: 'Benutzerdefinierte Dashboard-Layouts' },
],
roadmap: [
{ phase: 'Phase 1: Monitoring (Q1)', priority: 'high', items: ['Prometheus Integration', 'Grafana Dashboards', 'Service Health Checks', 'Error Rate Tracking'] },
{ phase: 'Phase 2: Alerting (Q2)', priority: 'medium', items: ['Slack/Teams Integration', 'E-Mail Alerts', 'Eskalations-Regeln', 'On-Call Rotation'] },
{ phase: 'Phase 3: Analytics (Q3)', priority: 'low', items: ['Usage Analytics', 'Cost Tracking', 'Trend-Analysen', 'Kapazitaetsplanung'] },
],
technicalDetails: [
{ component: 'Frontend', technology: 'Next.js', version: '15.x', description: 'React Server Components' },
{ component: 'Styling', technology: 'Tailwind CSS', version: '3.x', description: 'Utility-first CSS' },
{ component: 'State', technology: 'React Hooks', version: '19.x', description: 'Lokaler State' },
{ component: 'Charts', technology: 'Chart.js', version: '4.x', description: 'Datenvisualisierung' },
],
}

View File

@@ -0,0 +1,92 @@
import type { SystemInfoConfig } from './types'
export const docsConfig: SystemInfoConfig = {
title: 'Docs System-Info',
description: 'Dokumentations-Management System.',
version: '1.0',
architecture: {
layers: [
{ title: 'Docs UI', components: ['Markdown Viewer', 'Search Interface', 'Navigation'], color: '#3b82f6' },
{ title: 'Content Engine', components: ['Markdown Parser', 'Syntax Highlighter', 'Link Resolver'], color: '#8b5cf6' },
{ title: 'Storage', components: ['File System', 'Git Integration', 'Version Control'], color: '#10b981' },
{ title: 'Features', components: ['Search Index', 'Auto-Generation', 'Export Tools'], color: '#f59e0b' },
],
},
features: [
{ name: 'Markdown Rendering', status: 'active', description: 'Rich Markdown Support' },
{ name: 'Code Highlighting', status: 'active', description: 'Syntax Highlighting' },
{ name: 'Full-Text Search', status: 'active', description: 'Dokumentensuche' },
{ name: 'Version History', status: 'planned', description: 'Versionsverwaltung' },
],
roadmap: [
{ phase: 'Phase 1: Core (Q1)', priority: 'high', items: ['Markdown Parser', 'Navigation', 'Search', 'Code Blocks'] },
{ phase: 'Phase 2: Collaboration (Q2)', priority: 'medium', items: ['Comments', 'Suggestions', 'Review System', 'Notifications'] },
{ phase: 'Phase 3: Advanced (Q3)', priority: 'low', items: ['API Docs Generator', 'Multi-Language', 'Export PDF', 'Analytics'] },
],
technicalDetails: [
{ component: 'Parser', technology: 'Marked.js', description: 'Markdown Processing' },
{ component: 'Syntax', technology: 'Prism.js', description: 'Code Highlighting' },
{ component: 'Search', technology: 'Fuse.js', description: 'Fuzzy Search' },
{ component: 'Storage', technology: 'File System + Git', description: 'Content Management' },
],
auditInfo: [
{
category: 'Docs Status',
items: [
{ label: 'Total Documents', value: 'Tracking', status: 'ok' },
{ label: 'Search Index', value: 'Aktiv', status: 'ok' },
{ label: 'Broken Links', value: 'Check', status: 'warning' },
{ label: 'Last Update', value: 'Tracking', status: 'ok' },
],
},
{
category: 'Features',
items: [
{ label: 'Markdown Support', value: 'Aktiv', status: 'ok' },
{ label: 'Code Highlighting', value: 'Aktiv', status: 'ok' },
{ label: 'Search', value: 'Aktiv', status: 'ok' },
{ label: 'Versioning', value: 'Geplant', status: 'warning' },
],
},
],
fullDocumentation: `
<h2>Documentation System</h2>
<h3>1. Uebersicht</h3>
<p>Das Dokumentations-System verwaltet technische Dokumentation in Markdown-Format mit Versionskontrolle und Suchfunktion.</p>
<h3>2. Architektur</h3>
<pre>
┌─────────────────────────────────────────────────────────────────┐
│ Documentation UI │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Markdown Viewer │ │
│ │ ┌───────────────────────────────────────────────────────┐ │ │
│ │ │ Rendered Content │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │
│ │ │ │ Navigation │ │ Search │ │ │ │
│ │ │ └─────────────┘ └─────────────┘ │ │ │
│ │ └───────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
</pre>
<h3>3. Features</h3>
<table>
<tr><th>Feature</th><th>Status</th><th>Beschreibung</th></tr>
<tr><td>Markdown</td><td>Aktiv</td><td>GitHub Flavored Markdown</td></tr>
<tr><td>Code Blocks</td><td>Aktiv</td><td>Syntax Highlighting</td></tr>
<tr><td>Search</td><td>Aktiv</td><td>Full-Text Search</td></tr>
<tr><td>Git Integration</td><td>Aktiv</td><td>Version Control</td></tr>
</table>
<h3>4. Markdown Extensions</h3>
<ul>
<li><strong>Tables:</strong> GitHub-style tables</li>
<li><strong>Code Blocks:</strong> Syntax highlighting</li>
<li><strong>Admonitions:</strong> Info, Warning, Danger boxes</li>
<li><strong>Links:</strong> Auto-linking</li>
</ul>
`,
}

View File

@@ -0,0 +1,207 @@
import type { SystemInfoConfig } from './types'
export const dsmsConfig: SystemInfoConfig = {
title: 'DSMS System-Info',
description: 'Datenschutz-Management-System fuer DSGVO-Compliance.',
version: '1.0',
privacyNotes: [
'Zentrale Verwaltung aller Datenschutz-Prozesse',
'Verzeichnis der Verarbeitungstaetigkeiten (VVT)',
'TOM-Dokumentation',
'Datenschutz-Folgenabschaetzung (DSFA)',
],
architecture: {
layers: [
{ title: 'DSMS Dashboard', components: ['VVT Editor', 'TOM Manager', 'DSFA Tool'], color: '#3b82f6' },
{ title: 'Compliance Engine', components: ['Risk Assessment', 'Gap Analysis', 'Audit Trail'], color: '#8b5cf6' },
{ title: 'Document Management', components: ['Policies', 'Procedures', 'Records'], color: '#10b981' },
{ title: 'Reporting', components: ['Compliance Reports', 'DPA Dashboard', 'Exports'], color: '#f59e0b' },
],
},
features: [
{ name: 'VVT-Verwaltung', status: 'active', description: 'Verzeichnis der Verarbeitungstaetigkeiten' },
{ name: 'TOM-Dokumentation', status: 'active', description: 'Technische und organisatorische Massnahmen' },
{ name: 'DSFA-Tool', status: 'planned', description: 'Datenschutz-Folgenabschaetzung' },
{ name: 'Audit-Management', status: 'planned', description: 'Interne und externe Audits' },
],
roadmap: [
{ phase: 'Phase 1: Dokumentation (Q1)', priority: 'high', items: ['VVT-Erstellung', 'TOM-Katalog', 'Policy-Templates', 'Rollenkonzept'] },
{ phase: 'Phase 2: Compliance (Q2)', priority: 'high', items: ['Gap-Analyse', 'Risk-Scoring', 'Massnahmen-Tracking', 'Deadline-Management'] },
{ phase: 'Phase 3: Automation (Q3)', priority: 'medium', items: ['Auto-Assessments', 'Compliance-Monitoring', 'Alert-System', 'Report-Generator'] },
],
technicalDetails: [
{ component: 'Framework', technology: 'DSGVO/GDPR', description: 'EU-Verordnung' },
{ component: 'Standards', technology: 'ISO 27701', description: 'Privacy Management' },
{ component: 'Storage', technology: 'PostgreSQL', description: 'Verschluesselt' },
{ component: 'Export', technology: 'PDF/Excel', description: 'Audit-Reports' },
],
auditInfo: [
{
category: 'DSGVO-Dokumentation',
items: [
{ label: 'VVT vorhanden', value: 'Ja', status: 'ok' },
{ label: 'TOM dokumentiert', value: 'Ja', status: 'ok' },
{ label: 'DSFA durchgefuehrt', value: 'Geplant', status: 'warning' },
{ label: 'Auftragsverarbeitung', value: 'Dokumentiert', status: 'ok' },
],
},
{
category: 'Organisatorisch',
items: [
{ label: 'DSB benannt', value: 'Ja', status: 'ok' },
{ label: 'Schulungen', value: 'Jaehrlich', status: 'ok' },
{ label: 'Incident Response', value: 'Definiert', status: 'ok' },
{ label: 'Policies aktuell', value: 'Review faellig', status: 'warning' },
],
},
{
category: 'Technisch',
items: [
{ label: 'Verschluesselung', value: 'AES-256', status: 'ok' },
{ label: 'Zugriffskontrolle', value: 'RBAC', status: 'ok' },
{ label: 'Logging', value: 'Aktiviert', status: 'ok' },
{ label: 'Backup', value: 'Taeglich', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>Datenschutz-Management-System (DSMS)</h2>
<h3>1. Uebersicht</h3>
<p>Das DSMS bildet alle datenschutzrelevanten Prozesse und Dokumentationen ab. Es dient der Nachweispflicht gemaess DSGVO Art. 5 Abs. 2 (Rechenschaftspflicht).</p>
<h3>2. Kernkomponenten</h3>
<pre>
DSMS
├── Verzeichnis der Verarbeitungstaetigkeiten (VVT)
│ └── Art. 30 DSGVO
├── Technisch-Organisatorische Massnahmen (TOM)
│ └── Art. 32 DSGVO
├── Datenschutz-Folgenabschaetzung (DSFA)
│ └── Art. 35 DSGVO
├── Auftragsverarbeitung (AVV)
│ └── Art. 28 DSGVO
└── Policies & Schulungen
└── Interne Richtlinien
</pre>
<h3>3. VVT-Struktur</h3>
<table>
<tr><th>Feld</th><th>Beschreibung</th><th>Beispiel</th></tr>
<tr><td>Bezeichnung</td><td>Name der Verarbeitung</td><td>Nutzerregistrierung</td></tr>
<tr><td>Zweck</td><td>Verarbeitungszweck</td><td>Vertragserfuellung</td></tr>
<tr><td>Rechtsgrundlage</td><td>Art. 6 DSGVO</td><td>Art. 6 Abs. 1 lit. b</td></tr>
<tr><td>Kategorien Betroffener</td><td>Personengruppen</td><td>Schueler, Lehrer</td></tr>
<tr><td>Datenkategorien</td><td>Art der Daten</td><td>Stammdaten, E-Mail</td></tr>
<tr><td>Empfaenger</td><td>Datenempfaenger</td><td>Intern, Auftragsverarbeiter</td></tr>
<tr><td>Drittlandtransfer</td><td>Uebermittlung</td><td>Nein / Mit SCC</td></tr>
<tr><td>Loeschfrist</td><td>Aufbewahrung</td><td>Nach Vertragsende</td></tr>
</table>
<h3>4. TOM-Katalog</h3>
<pre>
Technisch-Organisatorische Massnahmen:
Vertraulichkeit (Art. 32 Abs. 1 lit. b):
├── Zutrittskontrolle: Rechenzentrum gesichert
├── Zugangskontrolle: SSH-Keys, MFA
├── Zugriffskontrolle: RBAC, Least Privilege
└── Weitergabekontrolle: TLS 1.3, Verschluesselung
Integritaet (Art. 32 Abs. 1 lit. b):
├── Eingabekontrolle: Audit-Logs
├── Trennungskontrolle: Multi-Tenant Isolation
└── Uebertragungskontrolle: API Authentication
Verfuegbarkeit (Art. 32 Abs. 1 lit. b):
├── Backup: Taeglich, 30 Tage Retention
├── Redundanz: Multi-AZ Deployment
└── Notfallplan: Dokumentiert
</pre>
<h3>5. DSFA-Prozess</h3>
<table>
<tr><th>Schritt</th><th>Beschreibung</th><th>Verantwortlich</th></tr>
<tr><td>1. Schwellwert-Analyse</td><td>DSFA erforderlich?</td><td>DSB</td></tr>
<tr><td>2. Beschreibung</td><td>Verarbeitung dokumentieren</td><td>Fachbereich</td></tr>
<tr><td>3. Risikobewertung</td><td>Eintrittswahrscheinlichkeit x Schaden</td><td>DSB + IT</td></tr>
<tr><td>4. Massnahmen</td><td>Risikominimierung</td><td>IT</td></tr>
<tr><td>5. Restrisiko</td><td>Bewertung, ggf. Konsultation</td><td>DSB</td></tr>
<tr><td>6. Dokumentation</td><td>DSFA-Report</td><td>DSB</td></tr>
</table>
<h3>6. Auftragsverarbeitung</h3>
<pre>
Auftragsverarbeiter-Uebersicht:
┌────────────────────────────────────────────────────┐
│ Anbieter │ Zweck │ Standort │ AVV │
├────────────────────────────────────────────────────┤
│ Hetzner │ Hosting │ DE │ ✓ │
│ vast.ai │ GPU Computing │ US/EU │ ✓ │
│ OpenAI │ LLM API │ US │ SCC │
│ Anthropic │ LLM API │ US │ SCC │
└────────────────────────────────────────────────────┘
</pre>
<h3>7. Schulungen</h3>
<ul>
<li><strong>Onboarding:</strong> Datenschutz-Grundlagen (Pflicht)</li>
<li><strong>Jaehrlich:</strong> Auffrischung + aktuelle Themen</li>
<li><strong>Spezial:</strong> IT-Sicherheit fuer Entwickler</li>
<li><strong>Nachweis:</strong> Dokumentierte Teilnahme</li>
</ul>
<h3>8. Incident Response</h3>
<pre>
Datenpanne erkannt
v
┌──────────────────────────────────────┐
│ 1. Sofortmassnahmen (Containment) │
│ - Zugriff sperren │
│ - Beweis sichern │
└─────────────────┬────────────────────┘
v
┌──────────────────────────────────────┐
│ 2. Bewertung (24h) │
│ - Schwere einschaetzen │
│ - Betroffene identifizieren │
└─────────────────┬────────────────────┘
v
┌──────────────────────────────────────┐
│ 3. Meldung (72h) │
│ - Aufsichtsbehoerde (Art. 33) │
│ - Betroffene (Art. 34) │
└─────────────────┬────────────────────┘
v
┌──────────────────────────────────────┐
│ 4. Nachbereitung │
│ - Root Cause Analysis │
│ - Massnahmen umsetzen │
│ - Dokumentation │
└──────────────────────────────────────┘
</pre>
<h3>9. Compliance-Dashboard</h3>
<table>
<tr><th>Bereich</th><th>Status</th><th>Naechste Pruefung</th></tr>
<tr><td>VVT</td><td>✓ Aktuell</td><td>Quartalsweise</td></tr>
<tr><td>TOM</td><td>✓ Aktuell</td><td>Jaehrlich</td></tr>
<tr><td>AVV</td><td>✓ Aktuell</td><td>Bei Aenderung</td></tr>
<tr><td>Schulungen</td><td>✓ Durchgefuehrt</td><td>Jaehrlich</td></tr>
<tr><td>DSFA</td><td>⚠ Offen</td><td>Bei neuer Verarbeitung</td></tr>
</table>
<h3>10. Export & Reporting</h3>
<ul>
<li><strong>VVT-Export:</strong> PDF, Excel</li>
<li><strong>TOM-Nachweis:</strong> PDF mit Unterschrift</li>
<li><strong>DSFA-Report:</strong> PDF</li>
<li><strong>Audit-Report:</strong> Compliance-Status</li>
</ul>
`,
}

View File

@@ -0,0 +1,180 @@
import type { SystemInfoConfig } from './types'
export const dsrConfig: SystemInfoConfig = {
title: 'DSR Management System-Info',
description: 'Bearbeitung von DSGVO-Betroffenenrechten (Art. 15-22).',
version: '2.0',
privacyNotes: [
'Automatische Fristenueberwachung (30 Tage)',
'Identitaetsverifizierung vor Datenauskunft',
'Verschluesselte Datenexporte',
'Protokollierung aller Bearbeitungsschritte',
],
architecture: {
layers: [
{ title: 'Request Portal', components: ['Antragsformular', 'Status-Tracking', 'Upload'], color: '#3b82f6' },
{ title: 'Processing Engine', components: ['Workflow Engine', 'Data Collector', 'Export Generator'], color: '#8b5cf6' },
{ title: 'Data Sources', components: ['PostgreSQL', 'MinIO', 'External APIs'], color: '#10b981' },
{ title: 'Notification', components: ['E-Mail', 'Audit Log', 'Reports'], color: '#f59e0b' },
],
},
features: [
{ name: 'Art. 15 Auskunft', status: 'active', description: 'Automatisierter Datenexport' },
{ name: 'Art. 17 Löschung', status: 'active', description: 'Kaskadierte Datenlöschung' },
{ name: 'Art. 20 Portabilitaet', status: 'active', description: 'JSON/CSV Export' },
{ name: 'Art. 16 Berichtigung', status: 'active', description: 'Datenkorrektur-Workflow' },
{ name: 'KI-Assistenz', status: 'planned', description: 'Automatische Kategorisierung' },
],
roadmap: [
{ phase: 'Phase 1: Automation (Q1)', priority: 'high', items: ['Automatische Datensammlung', 'Template-basierte Antworten', 'Fristen-Alerts', 'Batch-Verarbeitung'] },
{ phase: 'Phase 2: Self-Service (Q2)', priority: 'medium', items: ['Nutzer-Portal', 'Echtzeit-Status', 'Sofort-Download', 'Identitaets-Verifizierung'] },
{ phase: 'Phase 3: Analytics (Q3)', priority: 'low', items: ['DSR-Metriken', 'Trend-Analyse', 'Compliance-Scoring', 'Benchmarking'] },
],
technicalDetails: [
{ component: 'Workflow', technology: 'State Machine', description: 'Definierte Bearbeitungsstatus' },
{ component: 'Export', technology: 'JSON/CSV/PDF', description: 'Maschinenlesbare Formate' },
{ component: 'Encryption', technology: 'AES-256-GCM', description: 'Export-Verschluesselung' },
{ component: 'Verification', technology: 'TOTP/E-Mail', description: 'Zwei-Faktor' },
],
auditInfo: [
{
category: 'DSGVO-Rechte Implementation',
items: [
{ label: 'Art. 15 Auskunft', value: 'Automatisiert', status: 'ok' },
{ label: 'Art. 16 Berichtigung', value: 'Workflow', status: 'ok' },
{ label: 'Art. 17 Loeschung', value: 'Kaskadiert', status: 'ok' },
{ label: 'Art. 20 Portabilitaet', value: 'JSON/CSV', status: 'ok' },
{ label: 'Art. 21 Widerspruch', value: 'Implementiert', status: 'ok' },
],
},
{
category: 'Fristen & SLAs',
items: [
{ label: 'Bearbeitungsfrist', value: '30 Tage', status: 'ok' },
{ label: 'Fristverlängerung', value: '+60 Tage moeglich', status: 'ok' },
{ label: 'Automatische Erinnerung', value: '7 Tage vor Ablauf', status: 'ok' },
{ label: 'Eskalation', value: 'Nach 25 Tagen', status: 'ok' },
],
},
{
category: 'Sicherheit',
items: [
{ label: 'Identitaetspruefung', value: 'Zweistufig', status: 'ok' },
{ label: 'Export-Verschluesselung', value: 'AES-256-GCM', status: 'ok' },
{ label: 'Zugriffskontrolle', value: 'RBAC', status: 'ok' },
{ label: 'Audit-Log', value: 'Lueckenlos', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>Datenschutzanfragen (DSR) Management</h2>
<h3>1. Uebersicht</h3>
<p>Das DSR-Modul verarbeitet alle Betroffenenrechte-Anfragen gemaess DSGVO Art. 15-22. Es automatisiert den Prozess von der Anfrage bis zur Erfuellung und stellt die Einhaltung der gesetzlichen Fristen sicher.</p>
<h3>2. Unterstuetzte Anfragetypen</h3>
<table>
<tr><th>Artikel</th><th>Recht</th><th>Automatisierung</th><th>SLA</th></tr>
<tr><td>Art. 15</td><td>Auskunft</td><td>Vollautomatisch</td><td>30 Tage</td></tr>
<tr><td>Art. 16</td><td>Berichtigung</td><td>Workflow</td><td>30 Tage</td></tr>
<tr><td>Art. 17</td><td>Loeschung</td><td>Kaskadiert</td><td>30 Tage</td></tr>
<tr><td>Art. 18</td><td>Einschraenkung</td><td>Workflow</td><td>30 Tage</td></tr>
<tr><td>Art. 20</td><td>Portabilitaet</td><td>Vollautomatisch</td><td>30 Tage</td></tr>
<tr><td>Art. 21</td><td>Widerspruch</td><td>Workflow</td><td>30 Tage</td></tr>
</table>
<h3>3. Workflow-Architektur</h3>
<pre>
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Anfrage │ --> │ Verifizierung│ --> │ Bearbeitung │ --> │ Erfuellung │
│ eingang │ │ Identitaet │ │ (Auto/Man)│ │ & Export │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │ │ │
v v v v
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Ticket │ │ E-Mail │ │ Datensammlung│ │ Audit │
│ erstellt │ │ OTP Code │ │ aus Systemen │ │ Log │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
</pre>
<h3>4. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/dsr/requests</td><td>GET</td><td>Alle Anfragen listen</td></tr>
<tr><td>/api/dsr/requests</td><td>POST</td><td>Neue Anfrage erstellen</td></tr>
<tr><td>/api/dsr/requests/{id}</td><td>GET</td><td>Anfrage-Details</td></tr>
<tr><td>/api/dsr/requests/{id}/verify</td><td>POST</td><td>Identitaet verifizieren</td></tr>
<tr><td>/api/dsr/requests/{id}/process</td><td>POST</td><td>Bearbeitung starten</td></tr>
<tr><td>/api/dsr/requests/{id}/export</td><td>GET</td><td>Datenexport herunterladen</td></tr>
</table>
<h3>5. Datensammlung</h3>
<p>Bei einer Auskunftsanfrage werden Daten aus folgenden Quellen gesammelt:</p>
<ul>
<li><strong>PostgreSQL:</strong> Stammdaten, Consents, Aktivitaetslog</li>
<li><strong>MinIO:</strong> Hochgeladene Dokumente, Profilbilder</li>
<li><strong>Qdrant:</strong> Embeddings-Metadaten (ohne Vektoren)</li>
<li><strong>Audit-Log:</strong> Alle Systemaktivitaeten</li>
</ul>
<h3>6. Export-Formate</h3>
<table>
<tr><th>Format</th><th>Inhalt</th><th>Use Case</th></tr>
<tr><td>JSON</td><td>Strukturierte Daten</td><td>Maschinenlesbar, Portabilitaet</td></tr>
<tr><td>CSV</td><td>Tabellarische Daten</td><td>Excel-kompatibel</td></tr>
<tr><td>PDF</td><td>Formatierter Report</td><td>Menschenlesbar</td></tr>
<tr><td>ZIP</td><td>Alle Formate + Dateien</td><td>Vollstaendiger Export</td></tr>
</table>
<h3>7. Identitaetsverifizierung</h3>
<p>Zweistufige Verifizierung zum Schutz vor unbefugten Anfragen:</p>
<ol>
<li><strong>Stufe 1:</strong> E-Mail-Verifizierung mit OTP-Code (6-stellig, 15 Min gueltig)</li>
<li><strong>Stufe 2:</strong> Bei sensiblen Daten: Ausweiskopie oder Video-Ident</li>
</ol>
<h3>8. Loeschprozess (Art. 17)</h3>
<pre>
Loeschanfrage
v
┌────────────────────────────────────────────────────────────┐
│ Pruefung Ausnahmen │
│ - Rechtliche Aufbewahrungspflichten? │
│ - Laufende Vertraege? │
│ - Berechtigtes Interesse? │
└────────────────────────────────────────────────────────────┘
├── Ausnahme greift --> Teilloeschung + Begruendung
v
┌────────────────────────────────────────────────────────────┐
│ Kaskadierte Loeschung │
│ 1. Anwendungsdaten (PostgreSQL) │
│ 2. Dateien (MinIO) │
│ 3. Embeddings (Qdrant) │
│ 4. Backups (nach Retention-Policy) │
└────────────────────────────────────────────────────────────┘
</pre>
<h3>9. Audit-Trail</h3>
<p>Jede DSR-Anfrage wird vollstaendig protokolliert:</p>
<ul>
<li>Eingang der Anfrage mit Timestamp</li>
<li>Verifizierungsschritte</li>
<li>Bearbeitende Person(en)</li>
<li>Gesammelte Datenquellen</li>
<li>Erfuellung oder Ablehnung mit Begruendung</li>
<li>Export-Download mit Hash</li>
</ul>
<h3>10. Metriken & KPIs</h3>
<table>
<tr><th>Metrik</th><th>Ziel</th><th>Aktuell</th></tr>
<tr><td>Durchschnittliche Bearbeitungszeit</td><td>&lt; 14 Tage</td><td>Tracking aktiv</td></tr>
<tr><td>Fristenueberschreitung</td><td>0%</td><td>Alerting aktiv</td></tr>
<tr><td>Automatisierungsgrad</td><td>&gt; 80%</td><td>Art. 15/20</td></tr>
<tr><td>Identitaetspruefung-Erfolgsrate</td><td>&gt; 95%</td><td>Tracking aktiv</td></tr>
</table>
`,
}

View File

@@ -0,0 +1,123 @@
import type { SystemInfoConfig, Feature } from './types'
// Features with proper typing - Removed all school/person crawling features
const features: Feature[] = [
{ name: 'Lehrplan-Crawler', status: 'active', description: 'Crawlt NiBiS und KMK fuer Lehrplaene und Erlasse' },
{ name: 'Dokumenten-Suche', status: 'active', description: 'Volltext-Suche ueber Bildungsdokumente' },
{ name: 'Bildungsquellen-Verwaltung', status: 'active', description: 'Verwaltet Crawler-Konfigurationen fuer Bildungsbehoerden' },
{ name: 'RAG-Integration', status: 'planned', description: 'Vector-Suche fuer intelligente Dokumentenabfragen' },
]
export const eduSearchConfig: SystemInfoConfig = {
title: 'Education Search System-Info',
description: 'Crawler und Suchsystem fuer Bildungsdokumente (Lehrplaene, Erlasse, Beschluesse).',
version: '4.0',
architecture: {
layers: [
{ title: 'Frontend', components: ['Admin UI (Next.js)', 'Dokumenten-Suche'], color: '#3b82f6' },
{ title: 'API Gateway', components: ['edu-search-service (Go, Port 8088)'], color: '#8b5cf6' },
{ title: 'Crawler', components: ['NiBiS Crawler', 'KMK Crawler', 'Bildungsbehoerden-Crawler'], color: '#10b981' },
{ title: 'Data Layer', components: ['PostgreSQL (Metadaten)', 'OpenSearch (Volltext)', 'MinIO (Dokumente)'], color: '#f59e0b' },
],
},
features,
roadmap: [
{
phase: 'Phase 1: Dokumenten-Crawler (Abgeschlossen)',
priority: 'high',
items: [
'NiBiS Crawler (Niedersachsen)',
'KMK Beschluesse-Crawler',
'Dokumenten-Indexierung',
'Admin-UI fuer Crawler-Steuerung',
]
},
{
phase: 'Phase 2: Suche (Aktuell)',
priority: 'high',
items: [
'Volltext-Suche mit OpenSearch',
'Filter nach Bundesland/Dokumenttyp',
'Semantische Suche (RAG)',
'Zitat-Extraktion',
]
},
{
phase: 'Phase 3: Erweiterung (Q2)',
priority: 'medium',
items: [
'Weitere Bundeslaender-Crawler',
'Automatische Aenderungserkennung',
'Push-Benachrichtigungen',
'API fuer externe Systeme',
]
},
],
technicalDetails: [
{ component: 'Backend', technology: 'Go (Gin)', version: '1.21+', description: 'edu-search-service auf Port 8088' },
{ component: 'Suche', technology: 'OpenSearch', version: '2.11', description: 'Volltext-Indexierung' },
{ component: 'Datenbank', technology: 'PostgreSQL', version: '15+', description: 'Metadaten und Crawler-Status' },
{ component: 'Storage', technology: 'MinIO', description: 'Dokument-Speicher (PDFs, etc.)' },
{ component: 'Frontend', technology: 'Next.js', version: '15', description: 'Admin UI auf Port 3000' },
],
auditInfo: [
{
category: 'Service Status',
items: [
{ label: 'edu-search-service', value: 'Port 8088', status: 'ok' },
{ label: 'OpenSearch', value: 'Port 9200', status: 'ok' },
{ label: 'API Latenz', value: '< 100ms', status: 'ok' },
],
},
{
category: 'Datenquellen',
items: [
{ label: 'NiBiS (Niedersachsen)', value: 'Aktiv', status: 'ok' },
{ label: 'KMK Beschluesse', value: 'Aktiv', status: 'ok' },
{ label: 'Weitere Bundeslaender', value: 'Geplant', status: 'warning' },
],
},
],
fullDocumentation: `
<h2>Education Search - Bildungsdokumente</h2>
<h3>1. Uebersicht</h3>
<p>Das Education Search System crawlt und indexiert Bildungsdokumente aus verschiedenen Quellen:</p>
<ul>
<li><strong>NiBiS:</strong> Niedersaechsischer Bildungsserver (Lehrplaene, Erlasse, Curricula)</li>
<li><strong>KMK:</strong> Beschluesse der Kultusministerkonferenz</li>
<li><strong>Landesbehoerden:</strong> Bildungsportale der Bundeslaender</li>
</ul>
<h3>2. Architektur</h3>
<pre>
┌─────────────┐ ┌─────────────────┐ ┌────────────┐
│ Admin UI │────▶│ edu-search-svc │────▶│ OpenSearch │
│ (Next.js) │ │ (Go, :8088) │ │ (:9200) │
└─────────────┘ └─────────────────┘ └────────────┘
┌───────┴───────┐
▼ ▼
┌──────────┐ ┌──────────┐
│ PostgreSQL│ │ MinIO │
│ (Metadaten)│ │ (Dateien)│
└──────────┘ └──────────┘
</pre>
<h3>3. Crawler-Konfiguration</h3>
<p>Jeder Crawler wird ueber die Admin-UI konfiguriert:</p>
<ul>
<li>Start-URLs und Crawl-Tiefe</li>
<li>Rate-Limiting (respektiert robots.txt)</li>
<li>Dokumenttyp-Filter</li>
<li>Scheduling (taglich/woechentlich)</li>
</ul>
<h3>4. Wichtige Hinweise</h3>
<ul>
<li>System crawlt ausschliesslich <strong>Institutionsdaten</strong> (Dokumente, Lehrplaene)</li>
<li>Keine personenbezogenen Daten werden gesammelt</li>
<li>Alle Crawls respektieren robots.txt und Rate-Limits</li>
</ul>
`,
}

View File

@@ -0,0 +1,217 @@
import type { SystemInfoConfig } from './types'
export const gameConfig: SystemInfoConfig = {
title: 'Game System-Info',
description: 'Unity WebGL Spiel-Integration fuer Gamification.',
version: '1.0',
architecture: {
layers: [
{ title: 'Game UI', components: ['Game Canvas', 'Loading Screen', 'Score Display'], color: '#3b82f6' },
{ title: 'Unity Runtime', components: ['WebGL Player', 'Asset Bundles', 'Physics'], color: '#000000' },
{ title: 'Backend Bridge', components: ['Score API', 'Progress Sync', 'Leaderboard'], color: '#10b981' },
{ title: 'Storage', components: ['Player Data', 'Achievements', 'Analytics'], color: '#f59e0b' },
],
},
features: [
{ name: 'WebGL Rendering', status: 'active', description: 'Browser-basiertes Spiel' },
{ name: 'Progress Tracking', status: 'active', description: 'Fortschrittsspeicherung' },
{ name: 'Leaderboard', status: 'planned', description: 'Bestenlisten' },
{ name: 'Achievements', status: 'planned', description: 'Erfolge und Badges' },
],
roadmap: [
{ phase: 'Phase 1: Core (Q1)', priority: 'high', items: ['WebGL Optimization', 'Mobile Support', 'Save System', 'Auth Integration'] },
{ phase: 'Phase 2: Social (Q2)', priority: 'medium', items: ['Multiplayer', 'Chat', 'Friend System', 'Challenges'] },
{ phase: 'Phase 3: Gamification (Q3)', priority: 'low', items: ['Achievement System', 'Rewards', 'Seasons', 'Events'] },
],
technicalDetails: [
{ component: 'Engine', technology: 'Unity', version: '2022 LTS', description: 'Game Engine' },
{ component: 'Platform', technology: 'WebGL 2.0', description: 'Browser Runtime' },
{ component: 'Compression', technology: 'Brotli', description: 'Asset Compression' },
{ component: 'API', technology: 'REST/WebSocket', description: 'Backend Communication' },
],
auditInfo: [
{
category: 'Game Status',
items: [
{ label: 'Build Version', value: 'Tracking', status: 'ok' },
{ label: 'WebGL Kompatibilitaet', value: 'Getestet', status: 'ok' },
{ label: 'Mobile Support', value: 'In Arbeit', status: 'warning' },
{ label: 'Performance', value: 'Optimiert', status: 'ok' },
],
},
{
category: 'Integration',
items: [
{ label: 'Auth Integration', value: 'Aktiv', status: 'ok' },
{ label: 'Progress Sync', value: 'Aktiv', status: 'ok' },
{ label: 'Leaderboard', value: 'Geplant', status: 'warning' },
{ label: 'Achievements', value: 'Geplant', status: 'warning' },
],
},
{
category: 'Assets',
items: [
{ label: 'Bundle Size', value: 'Optimiert', status: 'ok' },
{ label: 'Kompression', value: 'Brotli', status: 'ok' },
{ label: 'Lazy Loading', value: 'Aktiviert', status: 'ok' },
{ label: 'CDN', value: 'CloudFlare', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>Unity WebGL Game Integration</h2>
<h3>1. Uebersicht</h3>
<p>Das Game-Modul integriert Unity-basierte Lernspiele als WebGL-Anwendungen in die Web-Plattform. Es ermoeglicht Gamification von Lerninhalten.</p>
<h3>2. Architektur</h3>
<pre>
┌─────────────────────────────────────────────────────────────────┐
│ Web Application │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Game Container │ │
│ │ ┌───────────────────────────────────────────────────────┐ │ │
│ │ │ Unity WebGL Canvas │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │
│ │ │ │ Scene │ │ UI │ │ │ │
│ │ │ │ Objects │ │ Layer │ │ │ │
│ │ │ └─────────────┘ └─────────────┘ │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ v │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Unity Bridge (jslib) │ │
│ └────────────────────────────────────────────────────────────┘ │
└────────────────────────────┬────────────────────────────────────┘
v
┌─────────────────────────────────────────────────────────────────┐
│ Backend API │
│ ├── /api/game/auth (JWT Validation) │
│ ├── /api/game/progress (Save/Load) │
│ ├── /api/game/leaderboard (Rankings) │
│ └── /api/game/events (Analytics) │
└─────────────────────────────────────────────────────────────────┘
</pre>
<h3>3. Unity Build Settings</h3>
<table>
<tr><th>Einstellung</th><th>Wert</th><th>Grund</th></tr>
<tr><td>Compression</td><td>Brotli</td><td>Beste Kompression</td></tr>
<tr><td>Code Stripping</td><td>Medium</td><td>Bundle-Groesse</td></tr>
<tr><td>WebGL Memory</td><td>256 MB</td><td>Stabil</td></tr>
<tr><td>Exception Handling</td><td>Explicitly Thrown</td><td>Performance</td></tr>
<tr><td>Graphics API</td><td>WebGL 2.0</td><td>Features</td></tr>
</table>
<h3>4. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/game/session</td><td>POST</td><td>Session starten</td></tr>
<tr><td>/api/game/progress</td><td>GET</td><td>Spielstand laden</td></tr>
<tr><td>/api/game/progress</td><td>POST</td><td>Spielstand speichern</td></tr>
<tr><td>/api/game/leaderboard</td><td>GET</td><td>Bestenliste</td></tr>
<tr><td>/api/game/events</td><td>POST</td><td>Analytics-Events</td></tr>
</table>
<h3>5. Bridge Communication</h3>
<pre>
JavaScript → Unity:
├── SendMessage(objectName, methodName, value)
├── JSON Serialization fuer komplexe Daten
└── Event Queue fuer Batch-Operationen
Unity → JavaScript:
├── jslib Plugin: [DllImport("__Internal")]
├── Callback Pattern
└── JSON Response
</pre>
<h3>6. Save System</h3>
<pre>
{
"player_id": "user-uuid",
"game_id": "math-adventure",
"progress": {
"level": 5,
"score": 1250,
"stars": [3, 3, 2, 2, 1],
"unlocked": ["item-1", "item-2"],
"last_checkpoint": "level5-mid"
},
"settings": {
"sound": true,
"music_volume": 0.7,
"difficulty": "normal"
},
"updated_at": "2025-01-14T12:00:00Z"
}
</pre>
<h3>7. Performance-Optimierung</h3>
<ul>
<li><strong>Asset Bundles:</strong> Lazy Loading grosser Assets</li>
<li><strong>Texture Compression:</strong> DXT/ETC2</li>
<li><strong>Object Pooling:</strong> Wiederverwendung von Objekten</li>
<li><strong>LOD:</strong> Level of Detail fuer 3D-Modelle</li>
<li><strong>Batching:</strong> Draw Call Reduktion</li>
</ul>
<h3>8. Loading Flow</h3>
<pre>
Seite geladen
v
┌───────────────────────────────────────┐
│ 1. Container initialisieren │
│ - Canvas vorbereiten │
│ - Loading UI anzeigen │
└─────────────────┬─────────────────────┘
v
┌───────────────────────────────────────┐
│ 2. Unity Loader │
│ - .data (Assets) │
│ - .wasm (Code) │
│ - .js (Framework) │
└─────────────────┬─────────────────────┘
v
┌───────────────────────────────────────┐
│ 3. Initialisierung │
│ - User Auth pruefen │
│ - Progress laden │
│ - Scene starten │
└─────────────────┬─────────────────────┘
v
┌───────────────────────────────────────┐
│ 4. Game Ready │
│ - Loading UI ausblenden │
│ - Input aktivieren │
└───────────────────────────────────────┘
</pre>
<h3>9. Analytics Events</h3>
<table>
<tr><th>Event</th><th>Daten</th><th>Verwendung</th></tr>
<tr><td>game_start</td><td>session_id</td><td>Session Tracking</td></tr>
<tr><td>level_complete</td><td>level, score, time</td><td>Progression</td></tr>
<tr><td>achievement</td><td>achievement_id</td><td>Engagement</td></tr>
<tr><td>error</td><td>error_type, details</td><td>Debugging</td></tr>
<tr><td>game_end</td><td>session_duration</td><td>Retention</td></tr>
</table>
<h3>10. Browser-Kompatibilitaet</h3>
<table>
<tr><th>Browser</th><th>Desktop</th><th>Mobile</th></tr>
<tr><td>Chrome</td><td>✓</td><td>✓</td></tr>
<tr><td>Firefox</td><td>✓</td><td>✓</td></tr>
<tr><td>Safari</td><td>✓</td><td>⚠ (iOS Limits)</td></tr>
<tr><td>Edge</td><td>✓</td><td>✓</td></tr>
</table>
`,
}

View File

@@ -0,0 +1,142 @@
import type { SystemInfoConfig } from './types'
export const gpuConfig: SystemInfoConfig = {
title: 'GPU Infrastruktur System-Info',
description: 'vast.ai GPU-Management fuer KI-Workloads und Training.',
version: '1.5',
privacyNotes: [
'GPU-Workloads werden isoliert in Docker-Containern ausgefuehrt',
'Keine persistente Speicherung von Trainingsdaten auf GPU-Instanzen',
'SSH-Keys werden regelmaessig rotiert',
'Audit-Log fuer alle GPU-Operationen',
],
architecture: {
layers: [
{ title: 'Admin UI', components: ['GPU Dashboard', 'Instance Manager', 'Cost Calculator'], color: '#3b82f6' },
{ title: 'vast.ai API', components: ['Instance API', 'Billing API', 'SSH Management'], color: '#8b5cf6' },
{ title: 'GPU Instances', components: ['RTX 4090', 'A100', 'H100'], color: '#10b981' },
{ title: 'Workloads', components: ['Model Training', 'Inference', 'Fine-Tuning'], color: '#f59e0b' },
],
},
features: [
{ name: 'Instance Management', status: 'active', description: 'Start/Stop/Destroy von GPU-Instanzen' },
{ name: 'SSH Key Management', status: 'active', description: 'Automatische SSH-Key Rotation' },
{ name: 'Cost Tracking', status: 'active', description: 'Echtzeit-Kostenüberwachung' },
{ name: 'Auto-Scaling', status: 'planned', description: 'Automatische Skalierung bei Last' },
{ name: 'Spot Instance Management', status: 'planned', description: 'Kostenoptimierung durch Spot-Instances' },
],
roadmap: [
{ phase: 'Phase 1: Automation (Q1)', priority: 'high', items: ['Auto-Start bei Bedarf', 'Auto-Stop bei Inaktivitaet', 'Scheduled Instances', 'Budget Alerts'] },
{ phase: 'Phase 2: Multi-Cloud (Q2)', priority: 'medium', items: ['Lambda Labs Integration', 'RunPod Integration', 'Cloud-uebergreifende Orchestrierung', 'Preisvergleich'] },
{ phase: 'Phase 3: ML Ops (Q3)', priority: 'medium', items: ['Model Registry', 'Experiment Tracking', 'A/B Testing', 'Model Versioning'] },
],
technicalDetails: [
{ component: 'API', technology: 'vast.ai REST API', version: 'v1', description: 'GPU-Marktplatz' },
{ component: 'SSH', technology: 'OpenSSH', version: '9.x', description: 'Sichere Verbindung' },
{ component: 'Container', technology: 'Docker', version: '24.x', description: 'Workload-Isolation' },
{ component: 'ML Framework', technology: 'PyTorch', version: '2.x', description: 'Model Training' },
],
auditInfo: [
{
category: 'Sicherheit & Zugriffskontrolle',
items: [
{ label: 'Authentifizierung', value: 'API-Key + SSH-Key', status: 'ok' },
{ label: 'Verschluesselung', value: 'TLS 1.3', status: 'ok' },
{ label: 'Key Rotation', value: 'Alle 30 Tage', status: 'ok' },
{ label: 'Audit-Log', value: 'Aktiviert', status: 'ok' },
],
},
{
category: 'Kosten & Ressourcen',
items: [
{ label: 'Budget-Limit', value: 'Konfigurierbar', status: 'ok' },
{ label: 'Auto-Shutdown', value: '30 Min Inaktivitaet', status: 'ok' },
{ label: 'Spot-Instances', value: 'Geplant', status: 'warning' },
{ label: 'Multi-Cloud', value: 'Geplant', status: 'warning' },
],
},
{
category: 'Compliance',
items: [
{ label: 'Daten-Residenz', value: 'EU/US waehlbar', status: 'ok' },
{ label: 'DSGVO-Konformitaet', value: 'Ja', status: 'ok' },
{ label: 'SOC 2 Type II', value: 'vast.ai zertifiziert', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>GPU Infrastructure Management</h2>
<h3>1. Uebersicht</h3>
<p>Das GPU-Infrastruktur-Modul ermoeglicht die Verwaltung von Cloud-GPU-Ressourcen ueber vast.ai fuer KI-Workloads wie Model Training, Fine-Tuning und Inference.</p>
<h3>2. Architektur</h3>
<pre>
┌─────────────────────────────────────────────────────────────┐
│ Admin Dashboard │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Start/Stop │ │ Status │ │ Cost Tracking │ │
│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
└─────────┼───────────────┼─────────────────────┼─────────────┘
│ │ │
v v v
┌─────────────────────────────────────────────────────────────┐
│ Backend API │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ /infra/vast/* - vast.ai Proxy mit Auth │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────┬──────────────────────────────────┘
v
┌─────────────────────────────────────────────────────────────┐
│ vast.ai Cloud │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ RTX 4090 │ │ A100 │ │ H100 │ │ RTX 3090 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
</pre>
<h3>3. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/infra/vast/status</td><td>GET</td><td>Aktueller Status der GPU-Instanz</td></tr>
<tr><td>/infra/vast/power/on</td><td>POST</td><td>GPU-Instanz starten</td></tr>
<tr><td>/infra/vast/power/off</td><td>POST</td><td>GPU-Instanz stoppen</td></tr>
<tr><td>/infra/vast/audit</td><td>GET</td><td>Audit-Log der letzten Aktionen</td></tr>
</table>
<h3>4. Sicherheitskonzept</h3>
<ul>
<li><strong>Authentifizierung:</strong> API-Key basiert, keine Benutzer-Credentials auf GPU</li>
<li><strong>SSH-Zugriff:</strong> Key-basiert, automatische Rotation alle 30 Tage</li>
<li><strong>Netzwerk:</strong> Isolierte VPC, nur definierte Ports offen</li>
<li><strong>Datenpersistenz:</strong> Ephemeral Storage, keine persistenten Volumes</li>
</ul>
<h3>5. Kostenmanagement</h3>
<table>
<tr><th>GPU</th><th>Preis/Stunde</th><th>VRAM</th><th>Use Case</th></tr>
<tr><td>RTX 4090</td><td>~$0.40</td><td>24 GB</td><td>Training, Inference</td></tr>
<tr><td>A100</td><td>~$1.50</td><td>80 GB</td><td>Large Model Training</td></tr>
<tr><td>H100</td><td>~$3.00</td><td>80 GB</td><td>Enterprise Training</td></tr>
</table>
<h3>6. Auto-Shutdown Policy</h3>
<p>GPU-Instanzen werden automatisch nach 30 Minuten Inaktivitaet gestoppt, um Kosten zu sparen. Bei jedem LLM-Request wird die Aktivitaet aufgezeichnet.</p>
<h3>7. Audit-relevante Informationen</h3>
<ul>
<li>Alle Start/Stop-Aktionen werden mit Timestamp und User-ID geloggt</li>
<li>Kostenabrechnung erfolgt minutengenau</li>
<li>SSH-Key Rotation wird dokumentiert</li>
<li>Fehlgeschlagene Operationen werden mit Error-Details gespeichert</li>
</ul>
<h3>8. Notfallprozeduren</h3>
<ol>
<li><strong>Bei Kostenüberschreitung:</strong> Automatischer Stop aller Instanzen</li>
<li><strong>Bei API-Ausfall:</strong> Fallback auf manuelles vast.ai Dashboard</li>
<li><strong>Bei Sicherheitsvorfall:</strong> Sofortiges Destroy aller Instanzen</li>
</ol>
`,
}

View File

@@ -0,0 +1,117 @@
/**
* SystemInfoSection Configurations
*
* Pre-defined configurations for each admin module.
* Modular architecture - each config in its own file.
*/
import type { SystemInfoConfig } from './types'
// Import individual configurations
import { dashboardConfig } from './dashboard-config'
import { gpuConfig } from './gpu-config'
import { consentConfig } from './consent-config'
import { dsrConfig } from './dsr-config'
import { llmCompareConfig } from './llm-compare-config'
import { securityConfig } from './security-config'
import { middlewareConfig } from './middleware-config'
import { communicationConfig } from './communication-config'
import { mailConfig } from './mail-config'
import { sbomConfig } from './sbom-config'
import { brandbookConfig } from './brandbook-config'
import { dsmsConfig } from './dsms-config'
import { pcaPlatformConfig } from './pca-platform-config'
import { eduSearchConfig } from './edu-search-config'
import { backlogConfig } from './backlog-config'
import { zeugnisseCrawlerConfig } from './zeugnisse-crawler-config'
import { trainingConfig } from './training-config'
import { contentConfig } from './content-config'
import { docsConfig } from './docs-config'
import { gameConfig } from './game-config'
import { onboardingConfig } from './onboarding-config'
import { unityBridgeConfig } from './unity-bridge-config'
import { ragConfig } from './rag-config'
import { workflowConfig } from './workflow-config'
/**
* Combined configuration object for all admin modules.
* Keys match the module identifiers used in the admin panel.
*/
export const SYSTEM_INFO_CONFIGS: Record<string, SystemInfoConfig> = {
// Dashboard
dashboard: dashboardConfig,
// Infrastructure
gpu: gpuConfig,
dsms: dsmsConfig,
sbom: sbomConfig,
// Privacy & Compliance
consent: consentConfig,
dsr: dsrConfig,
// AI & ML
llmCompare: llmCompareConfig,
training: trainingConfig,
rag: ragConfig,
// Security
security: securityConfig,
middleware: middlewareConfig,
// Communication
communication: communicationConfig,
mail: mailConfig,
// Content & Education
content: contentConfig,
eduSearch: eduSearchConfig,
docs: docsConfig,
zeugnisseCrawler: zeugnisseCrawlerConfig,
// Platform
pcaPlatform: pcaPlatformConfig,
brandbook: brandbookConfig,
game: gameConfig,
onboarding: onboardingConfig,
unityBridge: unityBridgeConfig,
// DevOps
backlog: backlogConfig,
workflow: workflowConfig,
}
// Re-export types
export type { SystemInfoConfig } from './types'
/**
* Module Architecture (Total: ~4,899 lines -> 24 modules)
*
* Individual config files:
* ├── dashboard-config.ts (~60 lines)
* ├── gpu-config.ts (~200 lines)
* ├── consent-config.ts (~200 lines)
* ├── dsr-config.ts (~200 lines)
* ├── llm-compare-config.ts (~200 lines)
* ├── security-config.ts (~250 lines)
* ├── middleware-config.ts (~250 lines)
* ├── communication-config.ts (~200 lines)
* ├── mail-config.ts (~200 lines)
* ├── sbom-config.ts (~200 lines)
* ├── brandbook-config.ts (~200 lines)
* ├── dsms-config.ts (~200 lines)
* ├── pca-platform-config.ts (~200 lines)
* ├── edu-search-config.ts (~200 lines)
* ├── backlog-config.ts (~200 lines)
* ├── zeugnisse-crawler-config.ts (~100 lines)
* ├── training-config.ts (~100 lines)
* ├── content-config.ts (~100 lines)
* ├── docs-config.ts (~200 lines)
* ├── game-config.ts (~200 lines)
* ├── onboarding-config.ts (~200 lines)
* ├── unity-bridge-config.ts (~200 lines)
* ├── rag-config.ts (~250 lines)
* └── workflow-config.ts (~100 lines)
*
* Original file backed up as: index_original.ts
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,164 @@
import type { SystemInfoConfig } from './types'
export const llmCompareConfig: SystemInfoConfig = {
title: 'LLM Vergleich System-Info',
description: 'Vergleich und Benchmarking verschiedener KI-Provider und Modelle.',
version: '1.0',
architecture: {
layers: [
{ title: 'Vergleichs-UI', components: ['Provider-Auswahl', 'Prompt-Editor', 'Ergebnis-Vergleich'], color: '#3b82f6' },
{ title: 'Provider Adapters', components: ['OpenAI', 'Anthropic', 'Google', 'Local'], color: '#8b5cf6' },
{ title: 'Evaluation Engine', components: ['Latenz-Messung', 'Qualitaets-Scoring', 'Cost Calculator'], color: '#10b981' },
{ title: 'Logging', components: ['Request Logs', 'Token Tracking', 'Error Logs'], color: '#f59e0b' },
],
},
features: [
{ name: 'Multi-Provider Vergleich', status: 'active', description: 'Parallele Anfragen an mehrere LLMs' },
{ name: 'Latenz-Tracking', status: 'active', description: 'Echtzeit-Performance-Messung' },
{ name: 'Kosten-Kalkulation', status: 'active', description: 'Token-basierte Kostenberechnung' },
{ name: 'Qualitaets-Bewertung', status: 'planned', description: 'Automatisches Scoring der Antworten' },
{ name: 'A/B Testing', status: 'planned', description: 'Statistische Signifikanz-Tests' },
],
roadmap: [
{ phase: 'Phase 1: Provider (Q1)', priority: 'high', items: ['Mistral Integration', 'Llama 3 Integration', 'Gemini Pro Integration', 'Rate Limiting'] },
{ phase: 'Phase 2: Evaluation (Q2)', priority: 'high', items: ['Automatisches Scoring', 'Benchmark-Suite', 'Domain-spezifische Tests', 'Halluzinations-Erkennung'] },
{ phase: 'Phase 3: Optimierung (Q3)', priority: 'medium', items: ['Prompt-Optimierung', 'Modell-Routing', 'Fallback-Strategien', 'Caching'] },
],
technicalDetails: [
{ component: 'OpenAI', technology: 'GPT-4o / o1', description: 'Haupt-Provider' },
{ component: 'Anthropic', technology: 'Claude 3.5', description: 'Alternative' },
{ component: 'Google', technology: 'Gemini 2.0', description: 'Multimodal' },
{ component: 'Local', technology: 'Ollama', description: 'Self-hosted' },
],
auditInfo: [
{
category: 'Provider-Status',
items: [
{ label: 'OpenAI', value: 'Aktiv', status: 'ok' },
{ label: 'Anthropic', value: 'Aktiv', status: 'ok' },
{ label: 'Google Gemini', value: 'Aktiv', status: 'ok' },
{ label: 'Ollama (Local)', value: 'Verfuegbar', status: 'ok' },
],
},
{
category: 'Kosten & Limits',
items: [
{ label: 'Monatliches Budget', value: 'Konfigurierbar', status: 'ok' },
{ label: 'Rate Limiting', value: 'Pro Provider', status: 'ok' },
{ label: 'Token Tracking', value: 'Aktiviert', status: 'ok' },
{ label: 'Cost Alerts', value: 'E-Mail', status: 'ok' },
],
},
{
category: 'Datenschutz',
items: [
{ label: 'Prompt-Logging', value: 'Optional', status: 'ok' },
{ label: 'PII Detection', value: 'Geplant', status: 'warning' },
{ label: 'Data Residency', value: 'EU verfuegbar', status: 'ok' },
{ label: 'Audit-Log', value: 'Aktiviert', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>LLM Provider Vergleich & Benchmarking</h2>
<h3>1. Uebersicht</h3>
<p>Das LLM-Vergleichsmodul ermoeglicht den direkten Vergleich verschiedener KI-Provider hinsichtlich Qualitaet, Latenz und Kosten. Es dient der Auswahl des optimalen Modells fuer spezifische Use Cases.</p>
<h3>2. Unterstuetzte Provider</h3>
<table>
<tr><th>Provider</th><th>Modelle</th><th>Staerken</th><th>Preisbereich</th></tr>
<tr><td>OpenAI</td><td>GPT-4o, GPT-4o-mini, o1</td><td>Allrounder, Coding</td><td>$0.15-15/1M Token</td></tr>
<tr><td>Anthropic</td><td>Claude 3.5 Sonnet/Haiku</td><td>Lange Kontexte, Safety</td><td>$0.25-15/1M Token</td></tr>
<tr><td>Google</td><td>Gemini 2.0 Flash/Pro</td><td>Multimodal, Speed</td><td>$0.075-5/1M Token</td></tr>
<tr><td>Ollama</td><td>Llama 3, Mistral, Phi</td><td>Lokal, Datenschutz</td><td>Nur Hardware-Kosten</td></tr>
</table>
<h3>3. Vergleichs-Architektur</h3>
<pre>
┌────────────────────────────────────────────────────────────────┐
│ Frontend UI │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Prompt Input │ │ Provider Sel │ │ Results Comparison │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└────────────────────────────────────────────────────────────────┘
v
┌────────────────────────────────────────────────────────────────┐
│ Backend Orchestrator │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Parallel Request Handler | Response Aggregator │ │
│ └──────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────┘
│ │ │ │
v v v v
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ OpenAI │ │Anthropic│ │ Google │ │ Ollama │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
</pre>
<h3>4. Metriken</h3>
<table>
<tr><th>Metrik</th><th>Beschreibung</th><th>Messung</th></tr>
<tr><td>TTFB</td><td>Time to First Byte</td><td>Millisekunden</td></tr>
<tr><td>Total Latency</td><td>Gesamtantwortzeit</td><td>Millisekunden</td></tr>
<tr><td>Tokens/Sekunde</td><td>Generierungsgeschwindigkeit</td><td>Output Tokens/s</td></tr>
<tr><td>Kosten</td><td>Gesamtkosten</td><td>USD</td></tr>
<tr><td>Qualitaet</td><td>Manuelle/Auto Bewertung</td><td>1-5 Sterne</td></tr>
</table>
<h3>5. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/llm/compare</td><td>POST</td><td>Parallelen Vergleich starten</td></tr>
<tr><td>/api/llm/providers</td><td>GET</td><td>Verfuegbare Provider listen</td></tr>
<tr><td>/api/llm/stats</td><td>GET</td><td>Nutzungsstatistiken</td></tr>
<tr><td>/api/llm/benchmark</td><td>POST</td><td>Benchmark-Suite ausfuehren</td></tr>
</table>
<h3>6. Benchmark-Suite</h3>
<p>Vordefinierte Tests fuer verschiedene Use Cases:</p>
<ul>
<li><strong>Summarization:</strong> Textzusammenfassung verschiedener Laengen</li>
<li><strong>QA:</strong> Frage-Antwort auf Dokumenten</li>
<li><strong>Coding:</strong> Code-Generierung und -Erklaerung</li>
<li><strong>Classification:</strong> Textkategorisierung</li>
<li><strong>Translation:</strong> Mehrsprachige Uebersetzung</li>
</ul>
<h3>7. Kostenmanagement</h3>
<pre>
Budgetkontrolle
├── Monatliches Limit pro Provider
├── Echtzeit-Kostentracking
├── Alerts bei 80%/90%/100%
└── Auto-Fallback bei Limit
</pre>
<h3>8. Datenschutz-Konfiguration</h3>
<table>
<tr><th>Einstellung</th><th>Optionen</th><th>Default</th></tr>
<tr><td>Prompt-Logging</td><td>Ein/Aus/Anonymisiert</td><td>Anonymisiert</td></tr>
<tr><td>Response-Speicherung</td><td>Ein/Aus/24h</td><td>24h</td></tr>
<tr><td>Metriken-Retention</td><td>30/90/365 Tage</td><td>90 Tage</td></tr>
<tr><td>PII-Filter</td><td>Ein/Aus</td><td>Ein (geplant)</td></tr>
</table>
<h3>9. Fehlerbehandlung</h3>
<ul>
<li><strong>Timeout:</strong> 30 Sekunden default, konfigurierbar</li>
<li><strong>Rate Limit:</strong> Automatisches Retry mit Backoff</li>
<li><strong>Provider Down:</strong> Skip und Warnung</li>
<li><strong>API Error:</strong> Fehlerdetails in Response</li>
</ul>
<h3>10. Best Practices</h3>
<ol>
<li>Immer mindestens 3 Provider fuer aussagekraeftigen Vergleich</li>
<li>Benchmark-Suite fuer reproduzierbare Ergebnisse nutzen</li>
<li>Kosten und Qualitaet gemeinsam bewerten</li>
<li>Lokale Modelle fuer sensible Daten bevorzugen</li>
</ol>
`,
}

View File

@@ -0,0 +1,157 @@
import type { SystemInfoConfig } from './types'
export const mailConfig: SystemInfoConfig = {
title: 'Unified Inbox System-Info',
description: 'E-Mail-Management mit KI-Analyse und Automatisierung.',
version: '1.0',
architecture: {
layers: [
{ title: 'Inbox UI', components: ['Mail List', 'Compose', 'AI Summary'], color: '#3b82f6' },
{ title: 'Mail Service', components: ['IMAP Sync', 'SMTP Send', 'Parser'], color: '#8b5cf6' },
{ title: 'AI Pipeline', components: ['Classification', 'Summarization', 'Response Draft'], color: '#10b981' },
{ title: 'Storage', components: ['PostgreSQL', 'MinIO (Attachments)', 'Vector DB'], color: '#f59e0b' },
],
},
features: [
{ name: 'Multi-Account Support', status: 'active', description: 'Mehrere E-Mail-Konten' },
{ name: 'KI-Zusammenfassung', status: 'planned', description: 'Automatische E-Mail-Zusammenfassung' },
{ name: 'Smart Categorization', status: 'planned', description: 'KI-basierte Kategorisierung' },
{ name: 'Response Suggestions', status: 'planned', description: 'Antwort-Vorschlaege' },
],
roadmap: [
{ phase: 'Phase 1: Core (Q1)', priority: 'high', items: ['IMAP/SMTP Integration', 'Multi-Account', 'Search', 'Attachments'] },
{ phase: 'Phase 2: AI (Q2)', priority: 'high', items: ['E-Mail Classification', 'Priority Detection', 'Sentiment Analysis', 'Spam Detection'] },
{ phase: 'Phase 3: Automation (Q3)', priority: 'medium', items: ['Auto-Responses', 'Rules Engine', 'Workflow Triggers', 'CRM Integration'] },
],
technicalDetails: [
{ component: 'IMAP', technology: 'imaplib/imapclient', description: 'E-Mail Empfang' },
{ component: 'SMTP', technology: 'smtplib', description: 'E-Mail Versand' },
{ component: 'AI', technology: 'OpenAI GPT-4', description: 'Text Analysis' },
{ component: 'Search', technology: 'PostgreSQL FTS', description: 'Volltextsuche' },
],
auditInfo: [
{
category: 'E-Mail Konten',
items: [
{ label: 'Konfigurierte Konten', value: 'Variabel', status: 'ok' },
{ label: 'IMAP Sync', value: 'Aktiviert', status: 'ok' },
{ label: 'SMTP Versand', value: 'Aktiviert', status: 'ok' },
{ label: 'OAuth2 Support', value: 'Google, Microsoft', status: 'ok' },
],
},
{
category: 'Sicherheit',
items: [
{ label: 'Verschluesselung', value: 'TLS Required', status: 'ok' },
{ label: 'Credential Storage', value: 'Encrypted', status: 'ok' },
{ label: 'Spam-Filter', value: 'SpamAssassin', status: 'ok' },
{ label: 'Virus-Scan', value: 'ClamAV', status: 'ok' },
],
},
{
category: 'KI-Features',
items: [
{ label: 'Kategorisierung', value: 'Geplant', status: 'warning' },
{ label: 'Zusammenfassung', value: 'Geplant', status: 'warning' },
{ label: 'Antwort-Vorschlaege', value: 'Geplant', status: 'warning' },
{ label: 'Sentiment Analysis', value: 'Geplant', status: 'warning' },
],
},
],
fullDocumentation: `
<h2>Unified Inbox - E-Mail Management</h2>
<h3>1. Uebersicht</h3>
<p>Der Unified Inbox aggregiert E-Mails aus mehreren Konten in einer zentralen Oberflaeche. Geplant ist die Integration von KI-Features fuer automatische Kategorisierung und Zusammenfassung.</p>
<h3>2. Architektur</h3>
<pre>
┌─────────────────────────────────────────────────────────────────────┐
│ Unified Inbox UI │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ Inbox │ │ Compose │ │ AI Summary (planned) │ │
│ └──────────────┘ └──────────────┘ └──────────────────────────┘ │
└─────────────────────────────┬───────────────────────────────────────┘
v
┌─────────────────────────────────────────────────────────────────────┐
│ Mail Service │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ IMAP Sync │ │ SMTP Send │ │ Parser │ │ AI Pipeline│ │
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
└─────────────────────────────┬───────────────────────────────────────┘
┌───────────────────┴───────────────────┐
│ │
v v
┌─────────────────────────┐ ┌─────────────────────────┐
│ External Mail │ │ Internal Storage │
│ ├── Gmail │ │ ├── PostgreSQL │
│ ├── Outlook │ │ ├── MinIO (Attachments)│
│ └── Custom IMAP │ │ └── Qdrant (Embeddings)│
└─────────────────────────┘ └─────────────────────────┘
</pre>
<h3>3. Unterstuetzte Provider</h3>
<table>
<tr><th>Provider</th><th>Auth-Methode</th><th>Features</th></tr>
<tr><td>Gmail</td><td>OAuth2</td><td>Labels, Push-Sync</td></tr>
<tr><td>Outlook/365</td><td>OAuth2</td><td>Folders, Categories</td></tr>
<tr><td>Custom IMAP</td><td>User/Pass</td><td>Standard IMAP</td></tr>
<tr><td>Exchange</td><td>OAuth2/EWS</td><td>Geplant</td></tr>
</table>
<h3>4. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/mail/accounts</td><td>GET</td><td>Konfigurierte Konten</td></tr>
<tr><td>/api/mail/accounts</td><td>POST</td><td>Konto hinzufuegen</td></tr>
<tr><td>/api/mail/messages</td><td>GET</td><td>E-Mails abrufen</td></tr>
<tr><td>/api/mail/messages</td><td>POST</td><td>E-Mail senden</td></tr>
<tr><td>/api/mail/messages/{id}</td><td>GET</td><td>E-Mail-Details</td></tr>
<tr><td>/api/mail/sync</td><td>POST</td><td>Manueller Sync</td></tr>
</table>
<h3>5. Sync-Strategie</h3>
<pre>
Initial Sync
v
┌───────────────────────────────────────┐
│ 1. Fetch Folder Structure │
│ 2. Sync Last 30 Days │
│ 3. Index Messages │
│ 4. Generate Embeddings (optional) │
└─────────────────┬─────────────────────┘
v
Incremental Sync (alle 5 Min)
v
┌───────────────────────────────────────┐
│ 1. Check for new Messages (IDLE) │
│ 2. Fetch new Messages │
│ 3. Update Index │
│ 4. Process AI Pipeline │
└───────────────────────────────────────┘
</pre>
<h3>6. Sicherheit</h3>
<ul>
<li><strong>Credentials:</strong> AES-256 verschluesselt in DB</li>
<li><strong>OAuth Tokens:</strong> Refresh Token rotiert</li>
<li><strong>Transport:</strong> TLS 1.2+ required</li>
<li><strong>Attachments:</strong> Virus-Scan vor Speicherung</li>
<li><strong>Spam:</strong> SpamAssassin Score-basiert</li>
</ul>
<h3>7. Datenschutz</h3>
<table>
<tr><th>Aspekt</th><th>Massnahme</th></tr>
<tr><td>E-Mail-Inhalte</td><td>Lokal gespeichert, nicht an Dritte</td></tr>
<tr><td>KI-Verarbeitung</td><td>Opt-in, PII-Filterung</td></tr>
<tr><td>Retention</td><td>Spiegelt Provider-Einstellung</td></tr>
<tr><td>Loeschung</td><td>Sync mit Provider</td></tr>
</table>
`,
}

View File

@@ -0,0 +1,207 @@
import type { SystemInfoConfig } from './types'
export const middlewareConfig: SystemInfoConfig = {
title: 'Middleware System-Info',
description: 'Middleware-Stack mit Test-Wizard fuer Integration Tests.',
version: '1.5',
architecture: {
layers: [
{ title: 'Test Wizard UI', components: ['Test Runner', 'Result Viewer', 'Coverage Report'], color: '#3b82f6' },
{ title: 'API Gateway', components: ['Traefik', 'Rate Limiter', 'Auth Proxy'], color: '#8b5cf6' },
{ title: 'Services', components: ['Consent', 'Klausur', 'School', 'Backend'], color: '#10b981' },
{ title: 'Infrastructure', components: ['PostgreSQL', 'Valkey', 'MinIO', 'Qdrant'], color: '#f59e0b' },
],
},
features: [
{ name: 'Integration Tests', status: 'active', description: 'End-to-End API Tests' },
{ name: 'Health Checks', status: 'active', description: 'Service-Status Pruefung' },
{ name: 'Test Wizard', status: 'active', description: 'Interaktive Test-Suite' },
{ name: 'Load Testing', status: 'planned', description: 'Performance-Tests' },
{ name: 'Chaos Engineering', status: 'planned', description: 'Resilienz-Tests' },
],
roadmap: [
{ phase: 'Phase 1: Testing (Q1)', priority: 'high', items: ['API Test Suite', 'Database Tests', 'Auth Flow Tests', 'Error Handling Tests'] },
{ phase: 'Phase 2: Performance (Q2)', priority: 'medium', items: ['k6 Load Tests', 'Latency Benchmarks', 'Throughput Tests', 'Memory Profiling'] },
{ phase: 'Phase 3: Resilience (Q3)', priority: 'low', items: ['Chaos Monkey', 'Failover Tests', 'Circuit Breaker', 'Graceful Degradation'] },
],
technicalDetails: [
{ component: 'API Gateway', technology: 'Traefik', version: '3.x', description: 'Reverse Proxy' },
{ component: 'Cache', technology: 'Valkey', version: '8.x', description: 'In-Memory Store' },
{ component: 'Storage', technology: 'MinIO', version: 'Latest', description: 'S3-kompatibel' },
{ component: 'Vector DB', technology: 'Qdrant', version: '1.12+', description: 'Similarity Search' },
],
auditInfo: [
{
category: 'Service Health',
items: [
{ label: 'API Gateway (Traefik)', value: 'Online', status: 'ok' },
{ label: 'PostgreSQL', value: 'Online', status: 'ok' },
{ label: 'Valkey (Cache)', value: 'Online', status: 'ok' },
{ label: 'Qdrant', value: 'Online', status: 'ok' },
],
},
{
category: 'Test Coverage',
items: [
{ label: 'Integration Tests', value: 'Aktiv', status: 'ok' },
{ label: 'Auth Flow Tests', value: 'Implementiert', status: 'ok' },
{ label: 'Load Tests', value: 'Geplant', status: 'warning' },
{ label: 'Chaos Tests', value: 'Geplant', status: 'warning' },
],
},
{
category: 'Performance',
items: [
{ label: 'Avg. Response Time', value: '< 100ms', status: 'ok' },
{ label: 'Uptime (30 Tage)', value: '> 99.9%', status: 'ok' },
{ label: 'Error Rate', value: '< 0.1%', status: 'ok' },
{ label: 'Cache Hit Ratio', value: '> 90%', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>Middleware & Integration Testing</h2>
<h3>1. Uebersicht</h3>
<p>Das Middleware-Modul verwaltet den gesamten Service-Stack und bietet einen Test-Wizard fuer Integration Tests. Es stellt sicher, dass alle Services korrekt miteinander kommunizieren.</p>
<h3>2. Service-Architektur</h3>
<pre>
┌─────────────────────────────────────────────────────────────────────┐
│ Traefik Gateway │
│ ├── TLS Termination │
│ ├── Rate Limiting │
│ ├── Request Routing │
│ └── Health Checks │
└────────────────────────────────┬────────────────────────────────────┘
┌──────────────────────┼──────────────────────┐
│ │ │
v v v
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Website (3000) │ │ Backend (8000) │ │ Consent (8081) │
│ Next.js │ │ FastAPI │ │ Gin │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└──────────────────┬──┴─────────────────────┘
┌─────────────────┼─────────────────┐
│ │ │
v v v
┌─────────────────┐ ┌────────────┐ ┌─────────────────┐
│ PostgreSQL │ │ Valkey │ │ Qdrant │
│ (5432) │ │ (6379) │ │ (6333) │
└─────────────────┘ └────────────┘ └─────────────────┘
</pre>
<h3>3. Test-Wizard Funktionen</h3>
<table>
<tr><th>Test-Kategorie</th><th>Beschreibung</th><th>Status</th></tr>
<tr><td>Health Checks</td><td>Service-Erreichbarkeit</td><td>Automatisch</td></tr>
<tr><td>Auth Flow</td><td>Login, Token-Refresh, Logout</td><td>Implementiert</td></tr>
<tr><td>Consent CRUD</td><td>Dokumente erstellen, lesen, aktualisieren</td><td>Implementiert</td></tr>
<tr><td>Database</td><td>Connection Pool, Query Performance</td><td>Implementiert</td></tr>
<tr><td>Cache</td><td>Set/Get, Invalidierung</td><td>Implementiert</td></tr>
<tr><td>Vector Search</td><td>Embedding, Similarity Search</td><td>Implementiert</td></tr>
</table>
<h3>4. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/middleware/health</td><td>GET</td><td>Alle Service Health Checks</td></tr>
<tr><td>/api/middleware/tests</td><td>GET</td><td>Verfuegbare Test-Suites</td></tr>
<tr><td>/api/middleware/tests/run</td><td>POST</td><td>Test-Suite ausfuehren</td></tr>
<tr><td>/api/middleware/metrics</td><td>GET</td><td>Performance-Metriken</td></tr>
</table>
<h3>5. Health Check Format</h3>
<pre>
{
"status": "healthy",
"timestamp": "2025-01-14T10:00:00Z",
"services": {
"postgres": {
"status": "up",
"latency_ms": 2,
"details": {"connections": 10, "max": 100}
},
"valkey": {
"status": "up",
"latency_ms": 1,
"details": {"memory_used": "50MB"}
},
"qdrant": {
"status": "up",
"latency_ms": 5,
"details": {"collections": 3}
}
}
}
</pre>
<h3>6. Test-Ausfuehrung</h3>
<pre>
Test Request
v
┌───────────────────────────────────────┐
│ Test Runner Engine │
├───────────────────────────────────────┤
│ 1. Setup (Fixtures, Test Data) │
│ 2. Execute (Sequential/Parallel) │
│ 3. Assert (Expected vs Actual) │
│ 4. Cleanup (Remove Test Data) │
│ 5. Report (Results, Timings) │
└───────────────────────────────────────┘
v
┌───────────────────────────────────────┐
│ Test Report │
│ ├── Total: 25, Passed: 24, Failed: 1 │
│ ├── Duration: 5.2s │
│ └── Details per Test Case │
└───────────────────────────────────────┘
</pre>
<h3>7. Rate Limiting</h3>
<table>
<tr><th>Endpoint-Typ</th><th>Limit</th><th>Window</th></tr>
<tr><td>Public API</td><td>100 req</td><td>1 Minute</td></tr>
<tr><td>Authenticated API</td><td>1000 req</td><td>1 Minute</td></tr>
<tr><td>Admin API</td><td>5000 req</td><td>1 Minute</td></tr>
<tr><td>File Upload</td><td>10 req</td><td>1 Minute</td></tr>
</table>
<h3>8. Caching-Strategie</h3>
<ul>
<li><strong>Session Cache:</strong> 15 Min TTL, User-Tokens</li>
<li><strong>API Response Cache:</strong> 5 Min TTL, GET-Requests</li>
<li><strong>Config Cache:</strong> 1 Stunde TTL, System-Konfiguration</li>
<li><strong>Invalidierung:</strong> Event-basiert bei Datenänderung</li>
</ul>
<h3>9. Monitoring & Alerts</h3>
<table>
<tr><th>Alert</th><th>Schwelle</th><th>Aktion</th></tr>
<tr><td>Service Down</td><td>3 failed checks</td><td>PagerDuty, Slack</td></tr>
<tr><td>High Latency</td><td>> 500ms avg</td><td>Slack</td></tr>
<tr><td>High Error Rate</td><td>> 1%</td><td>Slack</td></tr>
<tr><td>DB Connections High</td><td>> 80%</td><td>E-Mail</td></tr>
</table>
<h3>10. Troubleshooting</h3>
<pre>
Problem: Service nicht erreichbar
├── Check: Docker Container Status
├── Check: Port-Mapping
├── Check: Network (docker network ls)
└── Check: Logs (docker logs service-name)
Problem: Hohe Latenz
├── Check: Database Query Performance
├── Check: Cache Hit Ratio
├── Check: CPU/Memory Usage
└── Check: Network Latency
</pre>
`,
}

View File

@@ -0,0 +1,194 @@
import type { SystemInfoConfig } from './types'
export const onboardingConfig: SystemInfoConfig = {
title: 'Onboarding System-Info',
description: 'Benutzer- und Schul-Onboarding Workflow.',
version: '2.0',
architecture: {
layers: [
{ title: 'Onboarding UI', components: ['Wizard', 'Progress Bar', 'Tutorials'], color: '#3b82f6' },
{ title: 'Workflow Engine', components: ['Step Manager', 'Validation', 'Skip Logic'], color: '#8b5cf6' },
{ title: 'Data Collection', components: ['Forms', 'File Upload', 'Verification'], color: '#10b981' },
{ title: 'Integration', components: ['CRM', 'School Service', 'Notification'], color: '#f59e0b' },
],
},
features: [
{ name: 'Multi-Step Wizard', status: 'active', description: 'Gefuehrter Prozess' },
{ name: 'Progress Tracking', status: 'active', description: 'Fortschrittsanzeige' },
{ name: 'Document Upload', status: 'active', description: 'Vertragsuploads' },
{ name: 'Self-Service', status: 'planned', description: 'Autonomes Onboarding' },
],
roadmap: [
{ phase: 'Phase 1: UX (Q1)', priority: 'high', items: ['Wizard Redesign', 'Mobile Optimization', 'Error Handling', 'Help System'] },
{ phase: 'Phase 2: Automation (Q2)', priority: 'medium', items: ['Auto-Verification', 'Document OCR', 'Pre-fill Data', 'Status Updates'] },
{ phase: 'Phase 3: Analytics (Q3)', priority: 'low', items: ['Funnel Analysis', 'Drop-off Points', 'A/B Testing', 'Conversion Optimization'] },
],
technicalDetails: [
{ component: 'Wizard', technology: 'React Hook Form', description: 'Form Management' },
{ component: 'Validation', technology: 'Zod', description: 'Schema Validation' },
{ component: 'Storage', technology: 'PostgreSQL', description: 'Progress Data' },
{ component: 'Files', technology: 'MinIO', description: 'Document Storage' },
],
auditInfo: [
{
category: 'Onboarding Status',
items: [
{ label: 'Conversion Rate', value: 'Tracking', status: 'ok' },
{ label: 'Avg. Completion Time', value: 'Tracking', status: 'ok' },
{ label: 'Drop-off Points', value: 'Analysiert', status: 'ok' },
{ label: 'Support Tickets', value: 'Tracking', status: 'ok' },
],
},
{
category: 'Prozess',
items: [
{ label: 'Wizard Steps', value: 'Konfiguriert', status: 'ok' },
{ label: 'Validation', value: 'Aktiv', status: 'ok' },
{ label: 'Document Upload', value: 'Aktiv', status: 'ok' },
{ label: 'Auto-Verification', value: 'Geplant', status: 'warning' },
],
},
{
category: 'Integration',
items: [
{ label: 'CRM Sync', value: 'Aktiv', status: 'ok' },
{ label: 'E-Mail Notifications', value: 'Aktiv', status: 'ok' },
{ label: 'School Service', value: 'Aktiv', status: 'ok' },
{ label: 'Billing', value: 'Aktiv', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>Onboarding Wizard</h2>
<h3>1. Uebersicht</h3>
<p>Der Onboarding Wizard fuehrt neue Nutzer und Schulen durch den Registrierungsprozess. Er sammelt notwendige Daten, Dokumente und Consents.</p>
<h3>2. Wizard-Architektur</h3>
<pre>
┌─────────────────────────────────────────────────────────────────┐
│ Onboarding Wizard UI │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Progress Bar: [=====> ] 40% │ │
│ └────────────────────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Current Step │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Form / Upload / Info │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ [ Zurueck ] [ Weiter ] │ │
│ └────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
</pre>
<h3>3. Wizard Steps (Schulen)</h3>
<table>
<tr><th>Step</th><th>Titel</th><th>Felder</th><th>Pflicht</th></tr>
<tr><td>1</td><td>Schuldaten</td><td>Name, Typ, Bundesland</td><td>Ja</td></tr>
<tr><td>2</td><td>Ansprechpartner</td><td>Name, E-Mail, Telefon</td><td>Ja</td></tr>
<tr><td>3</td><td>Adresse</td><td>Strasse, PLZ, Ort</td><td>Ja</td></tr>
<tr><td>4</td><td>Vertrag</td><td>Paket-Auswahl, Upload</td><td>Ja</td></tr>
<tr><td>5</td><td>Datenschutz</td><td>AVV, Consents</td><td>Ja</td></tr>
<tr><td>6</td><td>Bestaetigung</td><td>Zusammenfassung</td><td>-</td></tr>
</table>
<h3>4. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/onboarding/start</td><td>POST</td><td>Wizard starten</td></tr>
<tr><td>/api/onboarding/{id}/step/{n}</td><td>GET</td><td>Step-Daten laden</td></tr>
<tr><td>/api/onboarding/{id}/step/{n}</td><td>POST</td><td>Step speichern</td></tr>
<tr><td>/api/onboarding/{id}/complete</td><td>POST</td><td>Abschliessen</td></tr>
<tr><td>/api/onboarding/{id}/status</td><td>GET</td><td>Fortschritt</td></tr>
</table>
<h3>5. Validation-Schema</h3>
<pre>
const schoolDataSchema = z.object({
name: z.string().min(2).max(100),
type: z.enum([
"grundschule",
"hauptschule",
"realschule",
"gymnasium",
"gesamtschule",
"berufsschule"
]),
bundesland: z.enum([...bundeslaender]),
studentCount: z.number().positive().optional(),
website: z.string().url().optional()
});
</pre>
<h3>6. Document Upload</h3>
<pre>
Dokument-Upload Flow:
1. Datei auswaehlen
└── Typ-Pruefung (PDF, max 10 MB)
2. Upload starten
└── Progress-Anzeige
3. Virus-Scan
└── ClamAV
4. Speicherung
└── MinIO mit Verschluesselung
5. Verifikation (optional)
└── Manuell oder OCR
</pre>
<h3>7. Status-Workflow</h3>
<pre>
┌──────────┐ ┌──────────┐ ┌───────────┐ ┌───────────┐
│ Started │ → │ Progress │ → │ Submitted │ → │ Verified │
└──────────┘ └──────────┘ └───────────┘ └───────────┘
│ │
│ v
│ ┌───────────┐
│ │ Activated │
│ └───────────┘
v
┌───────────┐
│ Incomplete│
└───────────┘
</pre>
<h3>8. E-Mail-Benachrichtigungen</h3>
<table>
<tr><th>Trigger</th><th>Template</th><th>Empfaenger</th></tr>
<tr><td>Start</td><td>Willkommen</td><td>Ansprechpartner</td></tr>
<tr><td>Pausiert (7 Tage)</td><td>Erinnerung</td><td>Ansprechpartner</td></tr>
<tr><td>Submitted</td><td>Bestaetigung</td><td>Ansprechpartner</td></tr>
<tr><td>Verified</td><td>Aktivierung</td><td>Ansprechpartner</td></tr>
<tr><td>Incomplete</td><td>Fehlende Daten</td><td>Ansprechpartner</td></tr>
</table>
<h3>9. Analytics</h3>
<ul>
<li><strong>Funnel:</strong> Drop-off pro Step</li>
<li><strong>Completion Rate:</strong> Abschlussquote</li>
<li><strong>Avg. Time:</strong> Durchschnittliche Dauer</li>
<li><strong>Error Rate:</strong> Validierungsfehler</li>
</ul>
<h3>10. A/B Testing (geplant)</h3>
<pre>
Test-Varianten:
├── Step-Reihenfolge
├── Formular-Layout
├── CTA-Texte
├── Hilfe-Inhalte
└── Erfolgsmeldungen
Metriken:
├── Conversion Rate
├── Time to Complete
└── Drop-off Rate
</pre>
`,
}

View File

@@ -0,0 +1,213 @@
import type { SystemInfoConfig } from './types'
export const pcaPlatformConfig: SystemInfoConfig = {
title: 'PCA Platform System-Info',
description: 'Partner Content Access Platform fuer Content-Partner.',
version: '1.0',
architecture: {
layers: [
{ title: 'Partner Portal', components: ['Dashboard', 'Content Upload', 'Analytics'], color: '#3b82f6' },
{ title: 'Content Pipeline', components: ['Ingestion', 'Processing', 'Quality Check'], color: '#8b5cf6' },
{ title: 'Distribution', components: ['CDN', 'API Access', 'Embed Codes'], color: '#10b981' },
{ title: 'Monetization', components: ['Usage Tracking', 'Revenue Share', 'Invoicing'], color: '#f59e0b' },
],
},
features: [
{ name: 'Partner Onboarding', status: 'active', description: 'Self-Service Registrierung' },
{ name: 'Content Upload', status: 'active', description: 'Bulk-Upload und Metadaten' },
{ name: 'Analytics Dashboard', status: 'active', description: 'Nutzungsstatistiken' },
{ name: 'Revenue Tracking', status: 'planned', description: 'Umsatzbeteiligung' },
],
roadmap: [
{ phase: 'Phase 1: Core (Q1)', priority: 'high', items: ['Partner-Registrierung', 'Content-Upload', 'Basic Analytics', 'API Documentation'] },
{ phase: 'Phase 2: Quality (Q2)', priority: 'medium', items: ['Auto-Transcoding', 'Quality Gates', 'Metadata Validation', 'Preview System'] },
{ phase: 'Phase 3: Monetization (Q3)', priority: 'medium', items: ['Usage-based Billing', 'Revenue Reports', 'Payment Integration', 'Contract Management'] },
],
technicalDetails: [
{ component: 'Upload', technology: 'TUS Protocol', description: 'Resumable Uploads' },
{ component: 'Storage', technology: 'MinIO/S3', description: 'Object Storage' },
{ component: 'CDN', technology: 'CloudFlare', description: 'Content Delivery' },
{ component: 'API', technology: 'REST/GraphQL', description: 'Partner Access' },
],
auditInfo: [
{
category: 'Partner-Status',
items: [
{ label: 'Aktive Partner', value: 'Variabel', status: 'ok' },
{ label: 'Pending Approvals', value: 'Dashboard', status: 'ok' },
{ label: 'Content-Uploads', value: 'Tracking', status: 'ok' },
{ label: 'API-Nutzung', value: 'Metered', status: 'ok' },
],
},
{
category: 'Content Pipeline',
items: [
{ label: 'Upload-Status', value: 'Aktiv', status: 'ok' },
{ label: 'Transcoding', value: 'Automatisch', status: 'ok' },
{ label: 'Quality Gates', value: 'Aktiviert', status: 'ok' },
{ label: 'CDN Distribution', value: 'CloudFlare', status: 'ok' },
],
},
{
category: 'Monetarisierung',
items: [
{ label: 'Usage Tracking', value: 'Aktiv', status: 'ok' },
{ label: 'Revenue Share', value: 'Geplant', status: 'warning' },
{ label: 'Invoicing', value: 'Geplant', status: 'warning' },
{ label: 'Payout', value: 'Geplant', status: 'warning' },
],
},
],
fullDocumentation: `
<h2>Partner Content Access (PCA) Platform</h2>
<h3>1. Uebersicht</h3>
<p>Die PCA-Plattform ermoeglicht Content-Partnern das Hochladen, Verwalten und Monetarisieren ihrer Bildungsinhalte. Sie bietet Self-Service-Tools fuer Onboarding und Analytics.</p>
<h3>2. Partner-Workflow</h3>
<pre>
Partner Journey:
Registrierung
v
┌─────────────────────────┐
│ Onboarding Wizard │
│ - Firmendaten │
│ - Vertrag / AGB │
│ - API-Key Generierung │
└───────────┬─────────────┘
v
┌─────────────────────────┐
│ Content Upload │
│ - Bulk Upload │
│ - Metadata Editor │
│ - Preview │
└───────────┬─────────────┘
v
┌─────────────────────────┐
│ Quality Check │
│ - Format Validation │
│ - Metadata Check │
│ - Review (optional) │
└───────────┬─────────────┘
v
┌─────────────────────────┐
│ Publishing │
│ - CDN Distribution │
│ - API Access │
│ - Embed Codes │
└───────────┬─────────────┘
v
┌─────────────────────────┐
│ Analytics & Payout │
│ - Views/Downloads │
│ - Revenue Tracking │
│ - Monthly Reports │
└─────────────────────────┘
</pre>
<h3>3. Content-Typen</h3>
<table>
<tr><th>Typ</th><th>Formate</th><th>Max. Groesse</th><th>Processing</th></tr>
<tr><td>Video</td><td>MP4, MOV, MKV</td><td>5 GB</td><td>Transcoding</td></tr>
<tr><td>Audio</td><td>MP3, WAV, FLAC</td><td>500 MB</td><td>Normalisierung</td></tr>
<tr><td>Dokument</td><td>PDF, DOCX</td><td>100 MB</td><td>Preview Gen</td></tr>
<tr><td>Bild</td><td>JPG, PNG, WEBP</td><td>50 MB</td><td>Thumbnails</td></tr>
<tr><td>Interaktiv</td><td>H5P, SCORM</td><td>200 MB</td><td>Packaging</td></tr>
</table>
<h3>4. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/pca/partners</td><td>GET</td><td>Partner-Liste</td></tr>
<tr><td>/api/pca/partners/{id}</td><td>GET</td><td>Partner-Details</td></tr>
<tr><td>/api/pca/content</td><td>POST</td><td>Content hochladen</td></tr>
<tr><td>/api/pca/content/{id}</td><td>GET</td><td>Content-Details</td></tr>
<tr><td>/api/pca/analytics</td><td>GET</td><td>Nutzungsstatistiken</td></tr>
<tr><td>/api/pca/embed/{id}</td><td>GET</td><td>Embed-Code</td></tr>
</table>
<h3>5. Upload-Protokoll (TUS)</h3>
<pre>
Resumable Upload Flow:
1. POST /uploads
→ Location: /uploads/abc123
2. PATCH /uploads/abc123
Upload-Offset: 0
Content-Length: 1000000
[Binary Data]
3. HEAD /uploads/abc123
Upload-Offset: 1000000
Upload-Length: 5000000
4. Repeat PATCH until complete
5. Processing triggered
</pre>
<h3>6. Metadaten-Schema</h3>
<pre>
{
"title": "Mathematik Grundlagen",
"description": "Einfuehrung in...",
"subject": "Mathematik",
"grade_level": ["5", "6", "7"],
"content_type": "video",
"duration_minutes": 15,
"language": "de",
"license": "CC-BY-SA-4.0",
"tags": ["Algebra", "Grundlagen"],
"author": {
"name": "Max Mustermann",
"organization": "Muster Verlag"
}
}
</pre>
<h3>7. Revenue Model</h3>
<table>
<tr><th>Modell</th><th>Beschreibung</th><th>Split</th></tr>
<tr><td>Views</td><td>Pro Aufruf</td><td>70/30</td></tr>
<tr><td>Downloads</td><td>Pro Download</td><td>70/30</td></tr>
<tr><td>Subscription</td><td>Anteilig</td><td>60/40</td></tr>
<tr><td>Enterprise</td><td>Lizenz</td><td>Individuell</td></tr>
</table>
<h3>8. Quality Gates</h3>
<ul>
<li><strong>Format:</strong> Unterstuetzte Formate, Codec-Check</li>
<li><strong>Metadaten:</strong> Pflichtfelder ausgefuellt</li>
<li><strong>Qualitaet:</strong> Min. 720p fuer Video</li>
<li><strong>Lizenz:</strong> Gueltige Lizenzangabe</li>
<li><strong>Moderation:</strong> Optionale manuelle Pruefung</li>
</ul>
<h3>9. Analytics-Dashboard</h3>
<table>
<tr><th>Metrik</th><th>Beschreibung</th><th>Granularitaet</th></tr>
<tr><td>Views</td><td>Gesamtaufrufe</td><td>Taeglich</td></tr>
<tr><td>Unique Views</td><td>Eindeutige Nutzer</td><td>Taeglich</td></tr>
<tr><td>Watch Time</td><td>Gesamtdauer</td><td>Pro Content</td></tr>
<tr><td>Completion Rate</td><td>% bis Ende</td><td>Pro Content</td></tr>
<tr><td>Downloads</td><td>Anzahl Downloads</td><td>Taeglich</td></tr>
</table>
<h3>10. Partner-Support</h3>
<pre>
Support-Kanaele:
├── Dokumentation (Self-Service)
├── API Reference (OpenAPI)
├── E-Mail Support (48h SLA)
├── Dedicated Manager (Enterprise)
└── Status Page (status.example.com)
</pre>
`,
}

View File

@@ -0,0 +1,241 @@
import type { SystemInfoConfig } from './types'
export const ragConfig: SystemInfoConfig = {
title: 'RAG System-Info',
description: 'Retrieval Augmented Generation fuer intelligente Dokumentensuche.',
version: '2.5',
architecture: {
layers: [
{ title: 'RAG UI', components: ['Chat Interface', 'Document Viewer', 'Source Citations'], color: '#3b82f6' },
{ title: 'RAG Pipeline', components: ['Query Processor', 'Retriever', 'Generator'], color: '#8b5cf6' },
{ title: 'Vector Store', components: ['Qdrant', 'Embedding Service', 'Index Manager'], color: '#10b981' },
{ title: 'Document Store', components: ['MinIO', 'PostgreSQL', 'Chunk Cache'], color: '#f59e0b' },
],
},
features: [
{ name: 'Semantic Search', status: 'active', description: 'Bedeutungsbasierte Suche' },
{ name: 'Source Citations', status: 'active', description: 'Quellenangaben in Antworten' },
{ name: 'Multi-Document', status: 'active', description: 'Suche ueber mehrere Dokumente' },
{ name: 'Hybrid Search', status: 'active', description: 'Kombination semantisch + keyword' },
{ name: 'Conversation Memory', status: 'planned', description: 'Kontextbewahrung' },
],
roadmap: [
{ phase: 'Phase 1: Quality (Q1)', priority: 'high', items: ['Relevanz-Tuning', 'Chunk Optimization', 'Re-Ranking', 'Answer Quality'] },
{ phase: 'Phase 2: Scale (Q2)', priority: 'high', items: ['Index Sharding', 'Cache Layer', 'Batch Processing', 'Multi-Tenant'] },
{ phase: 'Phase 3: Intelligence (Q3)', priority: 'medium', items: ['Query Expansion', 'Self-Reflection', 'Multi-Hop QA', 'Knowledge Graph'] },
],
technicalDetails: [
{ component: 'Vector DB', technology: 'Qdrant', version: '1.12+', description: 'Similarity Search' },
{ component: 'Embeddings', technology: 'OpenAI', description: 'text-embedding-3-large' },
{ component: 'LLM', technology: 'GPT-4o / Claude', description: 'Answer Generation' },
{ component: 'Chunking', technology: 'LangChain', description: 'Document Processing' },
],
privacyNotes: [
'Dokumente werden lokal verarbeitet',
'Embeddings enthalten keine Klartextdaten',
'LLM-Anfragen sind tenant-isoliert',
],
auditInfo: [
{
category: 'RAG Pipeline',
items: [
{ label: 'Indexierte Dokumente', value: 'Tracking', status: 'ok' },
{ label: 'Vector DB Status', value: 'Qdrant Online', status: 'ok' },
{ label: 'Embedding Model', value: 'text-embedding-3', status: 'ok' },
{ label: 'LLM Provider', value: 'Multi-Provider', status: 'ok' },
],
},
{
category: 'Qualitaet',
items: [
{ label: 'Retrieval Precision', value: 'Tracking', status: 'ok' },
{ label: 'Answer Accuracy', value: 'Evaluation', status: 'ok' },
{ label: 'Halluzinations-Rate', value: 'Monitoring', status: 'ok' },
{ label: 'Citation Accuracy', value: '> 95%', status: 'ok' },
],
},
{
category: 'Performance',
items: [
{ label: 'Avg. Latency', value: '< 3s', status: 'ok' },
{ label: 'Cache Hit Rate', value: '> 30%', status: 'ok' },
{ label: 'Concurrent Users', value: 'Skalierbar', status: 'ok' },
{ label: 'Cost per Query', value: 'Tracking', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>RAG System - Retrieval Augmented Generation</h2>
<h3>1. Uebersicht</h3>
<p>Das RAG-System kombiniert Dokumenten-Retrieval mit LLM-Generation fuer praezise, quellenbasierte Antworten auf Nutzeranfragen.</p>
<h3>2. RAG-Pipeline</h3>
<pre>
User Query
v
┌───────────────────────────────────────────────────────────────┐
│ Query Processing │
│ ├── Query Analysis (Intent, Entities) │
│ ├── Query Expansion (Synonyme, Reformulierung) │
│ └── Embedding Generation │
└────────────────────────────┬──────────────────────────────────┘
v
┌───────────────────────────────────────────────────────────────┐
│ Retrieval │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Vector Search │ │ Keyword Search │ │
│ │ (Qdrant) │ │ (PostgreSQL) │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ └──────────┬───────────┘ │
│ v │
│ ┌─────────────────────┐ │
│ │ Hybrid Fusion │ │
│ │ (RRF Algorithm) │ │
│ └─────────────────────┘ │
└────────────────────────┬──────────────────────────────────────┘
v
┌───────────────────────────────────────────────────────────────┐
│ Re-Ranking │
│ ├── Cross-Encoder Scoring │
│ ├── Metadata Filtering │
│ └── Diversity Sampling │
└────────────────────────┬──────────────────────────────────────┘
v
┌───────────────────────────────────────────────────────────────┐
│ Generation │
│ ├── Context Assembly │
│ ├── Prompt Engineering │
│ ├── LLM Call (GPT-4o / Claude) │
│ └── Citation Extraction │
└────────────────────────┬──────────────────────────────────────┘
v
┌───────────────────────────────────────────────────────────────┐
│ Response │
│ ├── Answer Text │
│ ├── Source Citations │
│ └── Confidence Score │
└───────────────────────────────────────────────────────────────┘
</pre>
<h3>3. Chunking-Strategie</h3>
<table>
<tr><th>Parameter</th><th>Wert</th><th>Grund</th></tr>
<tr><td>Chunk Size</td><td>512 Tokens</td><td>Optimal fuer Retrieval</td></tr>
<tr><td>Overlap</td><td>50 Tokens</td><td>Kontext-Erhalt</td></tr>
<tr><td>Splitter</td><td>Semantic</td><td>Natuerliche Grenzen</td></tr>
<tr><td>Metadata</td><td>Document, Page, Section</td><td>Zitation</td></tr>
</table>
<h3>4. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/rag/query</td><td>POST</td><td>Frage stellen</td></tr>
<tr><td>/api/rag/documents</td><td>GET</td><td>Dokumente listen</td></tr>
<tr><td>/api/rag/documents</td><td>POST</td><td>Dokument indexieren</td></tr>
<tr><td>/api/rag/collections</td><td>GET</td><td>Sammlungen</td></tr>
<tr><td>/api/rag/evaluate</td><td>POST</td><td>Antwort bewerten</td></tr>
</table>
<h3>5. Prompt-Template</h3>
<pre>
System:
Du bist ein hilfreicher Assistent fuer Bildungsinhalte.
Beantworte Fragen basierend auf den gegebenen Dokumenten.
Zitiere immer die Quellen in [1], [2] Format.
Wenn du dir nicht sicher bist, sage es.
Context:
[1] {chunk_1_text}
[2] {chunk_2_text}
[3] {chunk_3_text}
User:
{user_question}
Regeln:
- Nur Informationen aus dem Kontext verwenden
- Bei Unsicherheit "Ich weiss nicht" sagen
- Quellen mit [n] zitieren
- Praezise und strukturiert antworten
</pre>
<h3>6. Qualitaets-Metriken</h3>
<table>
<tr><th>Metrik</th><th>Beschreibung</th><th>Ziel</th></tr>
<tr><td>Precision@K</td><td>Relevante unter Top-K</td><td>> 80%</td></tr>
<tr><td>Recall@K</td><td>Gefundene Relevante</td><td>> 70%</td></tr>
<tr><td>NDCG</td><td>Ranking-Qualitaet</td><td>> 0.85</td></tr>
<tr><td>Answer Relevance</td><td>LLM-Evaluation</td><td>> 4/5</td></tr>
<tr><td>Faithfulness</td><td>Fakten-Treue</td><td>> 95%</td></tr>
</table>
<h3>7. Caching</h3>
<pre>
Cache-Strategie:
├── Query Cache
│ ├── Key: Query Embedding Hash
│ ├── TTL: 24 Stunden
│ └── Invalidierung: Bei Index-Update
├── Retrieval Cache
│ ├── Key: Query + Collection
│ ├── TTL: 1 Stunde
│ └── Top-K Results
└── Answer Cache
├── Key: Query Hash + Context Hash
├── TTL: 24 Stunden
└── Full Response
</pre>
<h3>8. Multi-Tenant</h3>
<ul>
<li><strong>Collection per Tenant:</strong> Isolierte Vektoren</li>
<li><strong>Access Control:</strong> RBAC auf Collection-Ebene</li>
<li><strong>Query Routing:</strong> Automatisch zu Tenant-Collection</li>
<li><strong>Audit-Log:</strong> Pro Tenant</li>
</ul>
<h3>9. Evaluation-Pipeline</h3>
<pre>
Test-Datensatz
├── Frage-Antwort-Paare (Golden Set)
v
┌───────────────────────────────────────┐
│ RAG Pipeline │
└─────────────────┬─────────────────────┘
v
┌───────────────────────────────────────┐
│ Evaluation Metrics │
│ ├── Retrieval: Precision, Recall │
│ ├── Generation: BLEU, ROUGE │
│ ├── LLM-as-Judge: Relevance, Correct │
│ └── Human Eval: Subset │
└─────────────────┬─────────────────────┘
v
┌───────────────────────────────────────┐
│ Report & Regression Detection │
└───────────────────────────────────────┘
</pre>
<h3>10. Optimierungs-Roadmap</h3>
<ol>
<li><strong>Hybrid Search:</strong> Kombination Vektor + Keyword (✓)</li>
<li><strong>Re-Ranking:</strong> Cross-Encoder (✓)</li>
<li><strong>Query Expansion:</strong> LLM-basiert (In Arbeit)</li>
<li><strong>Multi-Hop QA:</strong> Verkettete Abfragen (Geplant)</li>
<li><strong>Self-Reflection:</strong> Antwort-Pruefung (Geplant)</li>
</ol>
`,
}

View File

@@ -0,0 +1,176 @@
import type { SystemInfoConfig } from './types'
export const sbomConfig: SystemInfoConfig = {
title: 'SBOM System-Info',
description: 'Software Bill of Materials fuer Compliance und Security.',
version: '1.0',
architecture: {
layers: [
{ title: 'SBOM Dashboard', components: ['Dependency Tree', 'License Overview', 'CVE Alerts'], color: '#3b82f6' },
{ title: 'Generators', components: ['Syft', 'Trivy', 'CycloneDX'], color: '#8b5cf6' },
{ title: 'Analysis', components: ['License Checker', 'CVE Matcher', 'Outdated Detector'], color: '#10b981' },
{ title: 'Reports', components: ['JSON', 'SPDX', 'CycloneDX'], color: '#f59e0b' },
],
},
features: [
{ name: 'Dependency Scanning', status: 'active', description: 'Automatische Erkennung' },
{ name: 'License Compliance', status: 'active', description: 'Lizenz-Pruefung' },
{ name: 'CVE Matching', status: 'active', description: 'Schwachstellen-Erkennung' },
{ name: 'Automatic Updates', status: 'planned', description: 'Dependabot-artige Updates' },
],
roadmap: [
{ phase: 'Phase 1: Generation (Q1)', priority: 'high', items: ['Multi-Format Export', 'CI/CD Integration', 'Container SBOM', 'Runtime SBOM'] },
{ phase: 'Phase 2: Analysis (Q2)', priority: 'medium', items: ['License Risk Scoring', 'Transitive Dependencies', 'Version Comparison', 'Diff Reports'] },
{ phase: 'Phase 3: Governance (Q3)', priority: 'low', items: ['Policy Engine', 'Approval Workflow', 'Audit Trail', 'Supplier Management'] },
],
technicalDetails: [
{ component: 'Generator', technology: 'Syft', version: '1.x', description: 'SBOM Creation' },
{ component: 'Format', technology: 'CycloneDX', version: '1.5', description: 'Standard Format' },
{ component: 'CVE DB', technology: 'NVD/OSV', description: 'Vulnerability Data' },
{ component: 'License DB', technology: 'SPDX', description: 'License Identifiers' },
],
auditInfo: [
{
category: 'SBOM Status',
items: [
{ label: 'Letzte Generierung', value: 'CI/CD', status: 'ok' },
{ label: 'Format', value: 'CycloneDX 1.5', status: 'ok' },
{ label: 'Komponenten', value: 'Alle erfasst', status: 'ok' },
{ label: 'Transitive Deps', value: 'Inkludiert', status: 'ok' },
],
},
{
category: 'Vulnerability Status',
items: [
{ label: 'Kritische CVEs', value: '0', status: 'ok' },
{ label: 'Hohe CVEs', value: '0', status: 'ok' },
{ label: 'Outdated Packages', value: 'Tracking', status: 'warning' },
{ label: 'EOL Dependencies', value: '0', status: 'ok' },
],
},
{
category: 'License Compliance',
items: [
{ label: 'Erlaubte Lizenzen', value: 'MIT, Apache, BSD', status: 'ok' },
{ label: 'Copyleft (GPL)', value: '0', status: 'ok' },
{ label: 'Unbekannte Lizenzen', value: '0', status: 'ok' },
{ label: 'Kommerzielle', value: 'Review erforderlich', status: 'warning' },
],
},
],
fullDocumentation: `
<h2>Software Bill of Materials (SBOM)</h2>
<h3>1. Uebersicht</h3>
<p>Das SBOM-Modul generiert und analysiert die vollstaendige Komponentenliste aller Software-Abhaengigkeiten. Es dient der Compliance, Sicherheit und Supply-Chain-Transparenz.</p>
<h3>2. SBOM-Generierung</h3>
<pre>
Source Code
v
┌───────────────────────────────────────────────────────────────┐
│ SBOM Generators │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Syft │ │ Trivy │ │ Native Tooling │ │
│ │ (Primary) │ │ (Validation)│ │ (npm, go mod, pip) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
└─────────┼────────────────┼────────────────────┼───────────────┘
│ │ │
└────────────────┴────────────────────┘
v
┌────────────────┐
│ CycloneDX │
│ Format │
└────────────────┘
</pre>
<h3>3. Erfasste Komponenten</h3>
<table>
<tr><th>Typ</th><th>Quelle</th><th>Beispiele</th></tr>
<tr><td>npm packages</td><td>package-lock.json</td><td>react, next, tailwindcss, fabric.js, pdf-lib</td></tr>
<tr><td>Go modules</td><td>go.sum</td><td>gin, gorm, jwt-go</td></tr>
<tr><td>Python packages</td><td>requirements.txt</td><td>fastapi, pydantic, httpx</td></tr>
<tr><td>Container Images</td><td>Dockerfile</td><td>node:20-alpine, postgres:16</td></tr>
<tr><td>OS Packages</td><td>apk, apt</td><td>openssl, libpq</td></tr>
</table>
<h3>4. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/sbom/generate</td><td>POST</td><td>SBOM neu generieren</td></tr>
<tr><td>/api/sbom/latest</td><td>GET</td><td>Aktuelles SBOM</td></tr>
<tr><td>/api/sbom/vulnerabilities</td><td>GET</td><td>CVE-Liste</td></tr>
<tr><td>/api/sbom/licenses</td><td>GET</td><td>Lizenz-Uebersicht</td></tr>
<tr><td>/api/sbom/diff</td><td>GET</td><td>Vergleich mit vorheriger Version</td></tr>
</table>
<h3>5. Vulnerability Scanning</h3>
<pre>
SBOM
v
┌────────────────────────────────────────┐
│ Vulnerability Databases │
│ ├── NVD (National Vulnerability DB) │
│ ├── OSV (Open Source Vulnerabilities)│
│ ├── GitHub Advisory Database │
│ └── Vendor-specific (npm, Go, PyPI) │
└──────────────────┬─────────────────────┘
v
┌────────────────────────────────────────┐
│ CVE Matching Engine │
│ ├── Version Range Checking │
│ ├── CVSS Scoring │
│ └── Exploitability Assessment │
└──────────────────┬─────────────────────┘
v
┌────────────────────────────────────────┐
│ Alert & Report │
│ ├── Kritisch: Sofort-Benachrichtigung│
│ ├── Hoch: Tages-Report │
│ └── Mittel/Niedrig: Wochen-Report │
└────────────────────────────────────────┘
</pre>
<h3>6. License Compliance</h3>
<table>
<tr><th>Kategorie</th><th>Lizenzen</th><th>Status</th></tr>
<tr><td>Permissive (erlaubt)</td><td>MIT, Apache 2.0, BSD, ISC</td><td>OK</td></tr>
<tr><td>Weak Copyleft</td><td>LGPL, MPL</td><td>Review</td></tr>
<tr><td>Strong Copyleft</td><td>GPL, AGPL</td><td>Nicht erlaubt</td></tr>
<tr><td>Proprietaer</td><td>Commercial</td><td>Genehmigung</td></tr>
</table>
<h3>7. CI/CD Integration</h3>
<pre>
CI Pipeline
├── Build Stage
│ └── SBOM generieren
├── Security Stage
│ ├── CVE Scan
│ └── License Check
├── Gate
│ ├── Critical CVE → Block
│ ├── GPL License → Block
│ └── High CVE → Warning
└── Publish Stage
└── SBOM archivieren
</pre>
<h3>8. Aufbewahrung & Compliance</h3>
<ul>
<li><strong>Retention:</strong> 5 Jahre (Compliance)</li>
<li><strong>Format:</strong> JSON + PDF Report</li>
<li><strong>Signierung:</strong> Digital signiert</li>
<li><strong>Audit:</strong> Jederzeit abrufbar</li>
</ul>
`,
}

View File

@@ -0,0 +1,200 @@
import type { SystemInfoConfig } from './types'
export const securityConfig: SystemInfoConfig = {
title: 'Security System-Info',
description: 'DevSecOps Dashboard mit Vulnerability Scanning und Compliance Checks.',
version: '2.0',
privacyNotes: [
'Automatische CVE-Pruefung aller Dependencies',
'OWASP Top 10 Compliance',
'Container Security Scanning',
'Secret Detection in Code',
],
architecture: {
layers: [
{ title: 'Security Dashboard', components: ['Vulnerability Overview', 'Compliance Status', 'Alerts'], color: '#ef4444' },
{ title: 'Scanners', components: ['Trivy', 'Semgrep', 'Gitleaks', 'OWASP ZAP'], color: '#8b5cf6' },
{ title: 'CI/CD Integration', components: ['GitHub Actions', 'Pre-commit Hooks', 'PR Checks'], color: '#10b981' },
{ title: 'Reporting', components: ['SARIF', 'SBOM', 'Audit Reports'], color: '#f59e0b' },
],
},
features: [
{ name: 'Vulnerability Scanning', status: 'active', description: 'Automatische CVE-Pruefung' },
{ name: 'SBOM Generation', status: 'active', description: 'Software Bill of Materials' },
{ name: 'Secret Detection', status: 'active', description: 'Gitleaks Integration' },
{ name: 'DAST Scanning', status: 'planned', description: 'Dynamic Application Security Testing' },
{ name: 'Penetration Testing', status: 'planned', description: 'Automatisierte Pen-Tests' },
],
roadmap: [
{ phase: 'Phase 1: SAST (Q1)', priority: 'high', items: ['Semgrep Rules', 'CodeQL Integration', 'Custom Rules', 'False Positive Management'] },
{ phase: 'Phase 2: Runtime (Q2)', priority: 'high', items: ['Runtime Protection', 'WAF Integration', 'Anomaly Detection', 'Incident Response'] },
{ phase: 'Phase 3: Compliance (Q3)', priority: 'medium', items: ['SOC 2 Readiness', 'ISO 27001 Mapping', 'GDPR Technical Measures', 'Audit Automation'] },
],
technicalDetails: [
{ component: 'Container Scan', technology: 'Trivy', version: '0.50+', description: 'Image Vulnerabilities' },
{ component: 'SAST', technology: 'Semgrep', version: '1.x', description: 'Code Analysis' },
{ component: 'Secrets', technology: 'Gitleaks', version: '8.x', description: 'Secret Detection' },
{ component: 'SBOM', technology: 'CycloneDX', version: '1.5', description: 'Dependency List' },
],
auditInfo: [
{
category: 'Vulnerability Status',
items: [
{ label: 'Kritische CVEs', value: '0', status: 'ok' },
{ label: 'Hohe CVEs', value: '0', status: 'ok' },
{ label: 'Mittlere CVEs', value: 'Tracking', status: 'warning' },
{ label: 'Letzte Pruefung', value: 'Taeglich', status: 'ok' },
],
},
{
category: 'Compliance',
items: [
{ label: 'OWASP Top 10', value: 'Geprueft', status: 'ok' },
{ label: 'Secret Detection', value: 'Aktiv', status: 'ok' },
{ label: 'Container Hardening', value: 'Umgesetzt', status: 'ok' },
{ label: 'Dependency Updates', value: 'Woechentlich', status: 'ok' },
],
},
{
category: 'Monitoring',
items: [
{ label: 'Echtzeit-Alerts', value: 'Aktiviert', status: 'ok' },
{ label: 'SIEM Integration', value: 'Geplant', status: 'warning' },
{ label: 'Penetration Tests', value: 'Quartalsweise', status: 'ok' },
{ label: 'Bug Bounty', value: 'In Planung', status: 'warning' },
],
},
],
fullDocumentation: `
<h2>Security & DevSecOps Dashboard</h2>
<h3>1. Uebersicht</h3>
<p>Das Security-Modul integriert Sicherheitspruefungen in den gesamten Entwicklungs- und Deployment-Prozess (DevSecOps). Es kombiniert statische Analyse, Container-Scanning und Laufzeitschutz.</p>
<h3>2. Security-Tools</h3>
<table>
<tr><th>Tool</th><th>Kategorie</th><th>Funktion</th><th>Integration</th></tr>
<tr><td>Trivy</td><td>Container</td><td>Image Vulnerability Scanning</td><td>CI/CD</td></tr>
<tr><td>Semgrep</td><td>SAST</td><td>Code Pattern Matching</td><td>Pre-commit, CI</td></tr>
<tr><td>Gitleaks</td><td>Secrets</td><td>Credential Detection</td><td>Pre-commit, CI</td></tr>
<tr><td>OWASP ZAP</td><td>DAST</td><td>Web App Scanning</td><td>Staging</td></tr>
</table>
<h3>3. Scanning-Pipeline</h3>
<pre>
┌─────────────────────────────────────────────────────────────────────┐
│ Development Phase │
├─────────────────────────────────────────────────────────────────────┤
│ Pre-commit Hooks │
│ ├── Gitleaks (Secrets) │
│ ├── Semgrep (Quick Rules) │
│ └── Formatting/Linting │
└─────────────────────────────────────────────────────────────────────┘
v
┌─────────────────────────────────────────────────────────────────────┐
│ CI Pipeline │
├─────────────────────────────────────────────────────────────────────┤
│ ├── Full SAST Scan (Semgrep) │
│ ├── Dependency Check (npm audit, go vuln) │
│ ├── Container Scan (Trivy) │
│ ├── SBOM Generation (Syft) │
│ └── License Compliance │
└─────────────────────────────────────────────────────────────────────┘
v
┌─────────────────────────────────────────────────────────────────────┐
│ Staging/Prod │
├─────────────────────────────────────────────────────────────────────┤
│ ├── DAST Scan (OWASP ZAP) │
│ ├── Runtime Protection │
│ └── Anomaly Detection │
└─────────────────────────────────────────────────────────────────────┘
</pre>
<h3>4. OWASP Top 10 Abdeckung</h3>
<table>
<tr><th>#</th><th>Risiko</th><th>Massnahme</th><th>Status</th></tr>
<tr><td>A01</td><td>Broken Access Control</td><td>RBAC, JWT Validation</td><td>✓</td></tr>
<tr><td>A02</td><td>Cryptographic Failures</td><td>TLS 1.3, AES-256</td><td>✓</td></tr>
<tr><td>A03</td><td>Injection</td><td>Parameterized Queries, Input Validation</td><td>✓</td></tr>
<tr><td>A04</td><td>Insecure Design</td><td>Threat Modeling, Code Review</td><td>✓</td></tr>
<tr><td>A05</td><td>Security Misconfiguration</td><td>Hardened Defaults, IaC Scanning</td><td>✓</td></tr>
<tr><td>A06</td><td>Vulnerable Components</td><td>Dependency Scanning, SBOM</td><td>✓</td></tr>
<tr><td>A07</td><td>Auth Failures</td><td>MFA, Session Management</td><td>✓</td></tr>
<tr><td>A08</td><td>Software Integrity</td><td>Signed Commits, SBOM</td><td>✓</td></tr>
<tr><td>A09</td><td>Logging Failures</td><td>Structured Logging, Audit Trail</td><td>✓</td></tr>
<tr><td>A10</td><td>SSRF</td><td>URL Validation, Network Policies</td><td>✓</td></tr>
</table>
<h3>5. Vulnerability Management</h3>
<pre>
CVE Discovered
v
┌───────────────────┐
│ Severity Rating │
│ Critical/High/Med │
└─────────┬─────────┘
┌─────┴─────┐
│ Critical? │
└─────┬─────┘
Yes │ No
│ └──> Backlog mit Frist
v
┌───────────────────┐
│ Immediate Action │
│ - Block Deploy │
│ - Notify Team │
│ - Hotfix Branch │
└───────────────────┘
</pre>
<h3>6. Secret Management</h3>
<ul>
<li><strong>Speicherung:</strong> Doppler/Vault fuer Secrets</li>
<li><strong>Rotation:</strong> Automatisch alle 90 Tage</li>
<li><strong>Detection:</strong> Gitleaks in Pre-commit und CI</li>
<li><strong>Notfall:</strong> Sofortige Rotation bei Leak</li>
</ul>
<h3>7. Container Security</h3>
<table>
<tr><th>Massnahme</th><th>Implementation</th></tr>
<tr><td>Base Images</td><td>Alpine/Distroless, regelmaessig aktualisiert</td></tr>
<tr><td>Non-root User</td><td>Alle Container als non-root</td></tr>
<tr><td>Read-only FS</td><td>Wo moeglich aktiviert</td></tr>
<tr><td>Resource Limits</td><td>CPU/Memory Limits gesetzt</td></tr>
<tr><td>Network Policies</td><td>Kubernetes NetworkPolicy</td></tr>
</table>
<h3>8. Incident Response</h3>
<ol>
<li><strong>Detection:</strong> Automatische Alerts, Monitoring</li>
<li><strong>Triage:</strong> Schweregrad-Bewertung, Scope</li>
<li><strong>Containment:</strong> Isolation, Zugriffssperre</li>
<li><strong>Eradication:</strong> Ursachenbehandlung</li>
<li><strong>Recovery:</strong> Wiederherstellung, Monitoring</li>
<li><strong>Lessons Learned:</strong> Post-Mortem, Verbesserungen</li>
</ol>
<h3>9. Compliance-Reports</h3>
<p>Automatisch generierte Reports:</p>
<ul>
<li>Woechentlich: Vulnerability Summary</li>
<li>Monatlich: Compliance Status, SBOM</li>
<li>Quartalsweise: Penetration Test Results</li>
<li>Jaehrlich: Security Audit Report</li>
</ul>
<h3>10. Metriken</h3>
<table>
<tr><th>Metrik</th><th>Ziel</th><th>Messung</th></tr>
<tr><td>Mean Time to Remediate (Critical)</td><td>&lt; 24h</td><td>Automatisch</td></tr>
<tr><td>Mean Time to Remediate (High)</td><td>&lt; 7 Tage</td><td>Automatisch</td></tr>
<tr><td>Scan Coverage</td><td>100%</td><td>CI Pipeline</td></tr>
<tr><td>False Positive Rate</td><td>&lt; 10%</td><td>Review</td></tr>
</table>
`,
}

View File

@@ -0,0 +1,91 @@
import type { SystemInfoConfig } from './types'
export const trainingConfig: SystemInfoConfig = {
title: 'Training System-Info',
description: 'ML Model Training und Fine-Tuning Dashboard.',
version: '1.0',
architecture: {
layers: [
{ title: 'Training UI', components: ['Experiment Tracker', 'Metrics Dashboard', 'Model Registry'], color: '#3b82f6' },
{ title: 'Training Pipeline', components: ['Data Loader', 'Trainer', 'Evaluator'], color: '#8b5cf6' },
{ title: 'Compute', components: ['GPU Cluster', 'Job Scheduler', 'Resource Manager'], color: '#10b981' },
{ title: 'Storage', components: ['Dataset Store', 'Model Artifacts', 'Checkpoints'], color: '#f59e0b' },
],
},
features: [
{ name: 'Experiment Tracking', status: 'active', description: 'Versuchsprotokollierung' },
{ name: 'Hyperparameter Tuning', status: 'active', description: 'Automatische Optimierung' },
{ name: 'Model Versioning', status: 'active', description: 'Modellversionierung' },
{ name: 'Distributed Training', status: 'planned', description: 'Multi-GPU Training' },
],
roadmap: [
{ phase: 'Phase 1: MLOps (Q1)', priority: 'high', items: ['Experiment Tracking', 'Model Registry', 'Artifact Storage', 'Reproducibility'] },
{ phase: 'Phase 2: Automation (Q2)', priority: 'medium', items: ['Auto-Tuning', 'Pipeline Orchestration', 'A/B Deployment', 'Rollback'] },
{ phase: 'Phase 3: Scale (Q3)', priority: 'medium', items: ['Distributed Training', 'Cost Optimization', 'Resource Scheduling', 'Multi-Cloud'] },
],
technicalDetails: [
{ component: 'ML', technology: 'PyTorch', version: '2.x', description: 'Training Framework' },
{ component: 'Tracking', technology: 'MLflow/W&B', description: 'Experiment Tracking' },
{ component: 'GPU', technology: 'vast.ai', description: 'Cloud GPUs' },
{ component: 'Storage', technology: 'MinIO', description: 'Artifact Store' },
],
auditInfo: [
{
category: 'Training Pipeline',
items: [
{ label: 'Aktive Jobs', value: 'Tracking', status: 'ok' },
{ label: 'GPU Verfuegbarkeit', value: 'vast.ai', status: 'ok' },
{ label: 'Model Registry', value: 'MLflow', status: 'ok' },
{ label: 'Experiment Tracking', value: 'Aktiviert', status: 'ok' },
],
},
{
category: 'Ressourcen',
items: [
{ label: 'GPU Budget', value: 'Konfiguriert', status: 'ok' },
{ label: 'Storage', value: 'MinIO', status: 'ok' },
{ label: 'Compute Limits', value: 'Definiert', status: 'ok' },
{ label: 'Auto-Shutdown', value: 'Aktiviert', status: 'ok' },
],
},
{
category: 'Compliance',
items: [
{ label: 'Datensatz-Herkunft', value: 'Dokumentiert', status: 'ok' },
{ label: 'Model Cards', value: 'Vorhanden', status: 'ok' },
{ label: 'Bias-Pruefung', value: 'Geplant', status: 'warning' },
{ label: 'Audit Trail', value: 'Aktiviert', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>ML Training Dashboard</h2>
<h3>1. Uebersicht</h3>
<p>Das Training-Modul ermoeglicht das Training und Fine-Tuning von ML-Modellen mit Experiment-Tracking, Model Registry und GPU-Management.</p>
<h3>2. Training-Architektur</h3>
<pre>
Training Dashboard → Training Pipeline → GPU Cluster (vast.ai) + Storage (MinIO)
</pre>
<h3>3. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/training/experiments</td><td>GET</td><td>Experimente listen</td></tr>
<tr><td>/api/training/experiments</td><td>POST</td><td>Neues Experiment</td></tr>
<tr><td>/api/training/experiments/{id}</td><td>GET</td><td>Experiment-Details</td></tr>
<tr><td>/api/training/models</td><td>GET</td><td>Model Registry</td></tr>
<tr><td>/api/training/runs/{id}/stop</td><td>POST</td><td>Training stoppen</td></tr>
</table>
<h3>4. Best Practices</h3>
<ol>
<li>Immer Baseline-Experiment als Referenz</li>
<li>Checkpoints alle N Schritte speichern</li>
<li>Early Stopping bei Overfitting</li>
<li>Model Card fuer jedes produktive Modell</li>
<li>Reproduzierbarkeit durch Seed-Setting</li>
</ol>
`,
}

View File

@@ -0,0 +1,50 @@
/**
* Types for SystemInfoSection configuration
*/
export interface Feature {
name: string
status: 'active' | 'planned' | 'disabled'
description: string
}
export interface RoadmapPhase {
phase: string
priority: 'high' | 'medium' | 'low'
items: string[]
}
export interface TechDetail {
component: string
technology: string
version?: string
description?: string
}
export interface AuditInfo {
category: string
items: Array<{
label: string
value: string
status?: 'ok' | 'warning' | 'critical'
}>
}
export interface SystemInfoConfig {
title: string
description: string
version?: string
architecture: {
layers: Array<{
title: string
components: string[]
color?: string
}>
}
features: Feature[]
roadmap: RoadmapPhase[]
technicalDetails: TechDetail[]
privacyNotes?: string[]
auditInfo?: AuditInfo[]
fullDocumentation?: string // HTML content for full documentation
}

View File

@@ -0,0 +1,233 @@
import type { SystemInfoConfig } from './types'
export const unityBridgeConfig: SystemInfoConfig = {
title: 'Unity Bridge System-Info',
description: 'Kommunikationsschicht zwischen Web-App und Unity WebGL.',
version: '1.0',
architecture: {
layers: [
{ title: 'Web Interface', components: ['Message Bus', 'Event Handlers', 'State Sync'], color: '#3b82f6' },
{ title: 'Bridge Layer', components: ['jslib Interface', 'Message Queue', 'Serialization'], color: '#8b5cf6' },
{ title: 'Unity Side', components: ['C# Handlers', 'Event System', 'Data Models'], color: '#000000' },
{ title: 'Shared', components: ['Protocol Buffers', 'Type Definitions', 'Validation'], color: '#f59e0b' },
],
},
features: [
{ name: 'Bidirektionale Kommunikation', status: 'active', description: 'Web <-> Unity Messaging' },
{ name: 'State Synchronisation', status: 'active', description: 'Zustandsabgleich' },
{ name: 'Event System', status: 'active', description: 'Event-basierte Kommunikation' },
{ name: 'Type Safety', status: 'planned', description: 'Typsichere Schnittstelle' },
],
roadmap: [
{ phase: 'Phase 1: Stability (Q1)', priority: 'high', items: ['Error Handling', 'Reconnection Logic', 'Message Validation', 'Logging'] },
{ phase: 'Phase 2: Performance (Q2)', priority: 'medium', items: ['Message Batching', 'Compression', 'Lazy Loading', 'Memory Management'] },
{ phase: 'Phase 3: Features (Q3)', priority: 'low', items: ['Binary Protocol', 'Streaming', 'Debugging Tools', 'Hot Reload'] },
],
technicalDetails: [
{ component: 'Web', technology: 'TypeScript', description: 'Type-safe JS' },
{ component: 'Bridge', technology: 'jslib', description: 'Unity Plugin' },
{ component: 'Unity', technology: 'C#', description: 'Game Logic' },
{ component: 'Protocol', technology: 'JSON/Binary', description: 'Message Format' },
],
auditInfo: [
{
category: 'Bridge Status',
items: [
{ label: 'Connection', value: 'Aktiv', status: 'ok' },
{ label: 'Message Queue', value: 'Stabil', status: 'ok' },
{ label: 'Error Rate', value: '< 0.1%', status: 'ok' },
{ label: 'Latency', value: '< 10ms', status: 'ok' },
],
},
{
category: 'Protokoll',
items: [
{ label: 'Serialization', value: 'JSON', status: 'ok' },
{ label: 'Validation', value: 'Aktiv', status: 'ok' },
{ label: 'Compression', value: 'Geplant', status: 'warning' },
{ label: 'Binary Mode', value: 'Geplant', status: 'warning' },
],
},
{
category: 'Debugging',
items: [
{ label: 'Message Logging', value: 'Optional', status: 'ok' },
{ label: 'Performance Monitor', value: 'Aktiv', status: 'ok' },
{ label: 'Error Tracking', value: 'Sentry', status: 'ok' },
{ label: 'Dev Tools', value: 'In Entwicklung', status: 'warning' },
],
},
],
fullDocumentation: `
<h2>Unity Bridge - Web-Unity Kommunikation</h2>
<h3>1. Uebersicht</h3>
<p>Die Unity Bridge ermoeglicht bidirektionale Kommunikation zwischen der Web-Anwendung (JavaScript/TypeScript) und Unity WebGL (C#). Sie abstrahiert die jslib-Schnittstelle.</p>
<h3>2. Architektur</h3>
<pre>
┌─────────────────────────────────────────────────────────────────┐
│ Web Application │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ UnityBridge (TypeScript) │ │
│ │ ├── MessageBus │ │
│ │ ├── EventEmitter │ │
│ │ ├── StateSync │ │
│ │ └── ErrorHandler │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ │ SendMessage / Callback │
│ │ │
└──────────────────────────────┼───────────────────────────────────┘
┌──────────────────────────────┼───────────────────────────────────┐
│ Unity WebGL │
│ │ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ BridgeManager (C#) │ │
│ │ ├── MessageReceiver │ │
│ │ ├── EventDispatcher │ │
│ │ ├── StateManager │ │
│ │ └── ExternalInterface (jslib) │ │
│ └────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
</pre>
<h3>3. Message-Protokoll</h3>
<pre>
{
"type": "event" | "command" | "query" | "response",
"id": "msg-uuid",
"timestamp": 1705234800000,
"channel": "game" | "ui" | "system",
"payload": {
"action": "player_score",
"data": {
"score": 100,
"level": 5
}
}
}
</pre>
<h3>4. JavaScript API</h3>
<pre>
// Bridge initialisieren
const bridge = new UnityBridge({
unityInstance: unityRef,
gameObjectName: "BridgeManager"
});
// Event an Unity senden
bridge.send("player.action", {
action: "jump",
force: 10
});
// Event von Unity empfangen
bridge.on("game.score", (data) => {
console.log("Score:", data.score);
});
// Query mit Response
const result = await bridge.query("game.state");
console.log("Current level:", result.level);
</pre>
<h3>5. C# API</h3>
<pre>
// BridgeManager.cs
public class BridgeManager : MonoBehaviour
{
// Von JavaScript empfangen
public void OnBridgeMessage(string json)
{
var message = JsonUtility.FromJson<BridgeMessage>(json);
HandleMessage(message);
}
// An JavaScript senden
public void SendToWeb(string channel, object data)
{
var json = JsonUtility.ToJson(data);
WebBridge.SendMessage(channel, json);
}
}
</pre>
<h3>6. Event-Kanaele</h3>
<table>
<tr><th>Kanal</th><th>Richtung</th><th>Beschreibung</th></tr>
<tr><td>game.*</td><td>Unity → Web</td><td>Game Events</td></tr>
<tr><td>player.*</td><td>Bidirektional</td><td>Player Actions</td></tr>
<tr><td>ui.*</td><td>Web → Unity</td><td>UI Commands</td></tr>
<tr><td>system.*</td><td>Bidirektional</td><td>System Events</td></tr>
<tr><td>auth.*</td><td>Web → Unity</td><td>Auth State</td></tr>
</table>
<h3>7. State Synchronisation</h3>
<pre>
Web State Unity State
│ │
│ ┌────────────────┐ │
├───>│ State Sync │<───┤
│ │ (Bidirectional) │
│ └────────────────┘ │
│ │
v v
┌─────────┐ ┌─────────┐
│ React │ │ Unity │
│ Store │ │ State │
└─────────┘ └─────────┘
Sync Events:
├── Initial Sync (Game Load)
├── Delta Sync (Changes only)
└── Full Sync (Recovery)
</pre>
<h3>8. Error Handling</h3>
<pre>
Error Types:
├── ConnectionError: Bridge nicht verbunden
├── TimeoutError: Keine Antwort
├── ParseError: JSON ungueltig
├── ValidationError: Schema-Fehler
└── UnityError: C#-Exception
Recovery:
├── Auto-Reconnect (3 Versuche)
├── Message Queue (bis reconnect)
└── Fallback UI (bei Dauerfehler)
</pre>
<h3>9. Performance</h3>
<table>
<tr><th>Metrik</th><th>Ziel</th><th>Messung</th></tr>
<tr><td>Latency</td><td>< 10ms</td><td>Per-Message</td></tr>
<tr><td>Throughput</td><td>1000 msg/s</td><td>Batch Test</td></tr>
<tr><td>Memory</td><td>< 1MB Queue</td><td>Monitoring</td></tr>
<tr><td>CPU</td><td>< 1%</td><td>Profiler</td></tr>
</table>
<h3>10. Debugging</h3>
<pre>
// Debug Mode aktivieren
bridge.setDebug(true);
// Message Inspector
bridge.onAny((channel, data) => {
console.log(\`[\${channel}]\`, data);
});
// Performance Monitor
bridge.getMetrics();
// {
// messagesSent: 1234,
// messagesReceived: 5678,
// avgLatency: 5.2,
// errors: 2
// }
</pre>
`,
}

View File

@@ -0,0 +1,115 @@
import type { SystemInfoConfig } from './types'
export const workflowConfig: SystemInfoConfig = {
title: 'BPMN Workflow Engine',
description: 'Camunda 7 basierte Geschaeftsprozess-Automatisierung',
version: '7.21.0',
architecture: {
layers: [
{
title: 'Frontend',
color: '#3b82f6',
components: ['bpmn-js Editor', 'React Components', 'Python Studio Module']
},
{
title: 'Backend',
color: '#8b5cf6',
components: ['FastAPI Proxy', 'Camunda REST API', 'Task Management']
},
{
title: 'BPMN Engine',
color: '#10b981',
components: ['Camunda 7', 'Process Executor', 'Job Executor']
},
{
title: 'Datenbank',
color: '#f59e0b',
components: ['PostgreSQL', 'Camunda Schema', 'Process History']
}
]
},
features: [
{ name: 'BPMN 2.0 Modellierung', status: 'active', description: 'Visueller Prozess-Editor mit bpmn-js' },
{ name: 'Process Deployment', status: 'active', description: 'Prozesse in Camunda deployen' },
{ name: 'Task Management', status: 'active', description: 'User Tasks bearbeiten und delegieren' },
{ name: 'Service Tasks', status: 'active', description: 'Automatische Serviceaufrufe' },
{ name: 'Timer Events', status: 'active', description: 'Zeitgesteuerte Prozessschritte' },
{ name: 'Process History', status: 'planned', description: 'Historische Prozessdaten und Analytics' }
],
roadmap: [
{
phase: 'Phase 1: Editor & Deployment',
priority: 'high',
items: ['bpmn-js Editor Integration', 'Camunda Docker Setup', 'REST API Proxy', 'Task Inbox']
},
{
phase: 'Phase 2: Consent Workflow',
priority: 'high',
items: ['Document Status BPMN', 'DSB Approval Task', 'Scheduled Publishing', 'Notification Tasks']
},
{
phase: 'Phase 3: GDPR Workflows',
priority: 'medium',
items: ['DSR Request Processing', 'Deadline Monitoring', 'Data Export Automation', 'Deletion Workflow']
}
],
technicalDetails: [
{ component: 'BPMN Engine', technology: 'Camunda 7.21.0', description: 'Apache 2.0 Lizenz' },
{ component: 'Editor Library', technology: 'bpmn-js', version: '17.11.1' },
{ component: 'API Port', technology: '8089', description: 'REST API Proxy' },
{ component: 'Datenbank', technology: 'PostgreSQL', description: 'camunda Schema' }
],
privacyNotes: [
'Prozessdaten werden lokal in PostgreSQL gespeichert',
'Keine externen Cloud-Dienste fuer BPMN-Engine',
'Camunda Community Edition unter Apache 2.0 Lizenz',
'Audit-Trail fuer alle Prozessaktivitaeten'
],
auditInfo: [
{
category: 'Camunda Engine',
items: [
{ label: 'Version', value: '7.21.0', status: 'ok' },
{ label: 'Lizenz', value: 'Apache 2.0', status: 'ok' },
{ label: 'Health Check', value: '/api/bpmn/health', status: 'ok' }
]
},
{
category: 'Datenschutz',
items: [
{ label: 'Datenstandort', value: 'Lokal (PostgreSQL)', status: 'ok' },
{ label: 'Audit-Trail', value: 'Aktiviert', status: 'ok' },
{ label: 'Externe Dienste', value: 'Keine', status: 'ok' }
]
}
],
fullDocumentation: `
<h2>BPMN Workflow Engine - Dokumentation</h2>
<h3>1. Uebersicht</h3>
<p>Die BPMN Workflow Engine basiert auf Camunda 7 (Apache 2.0 Lizenz) und ermoeglicht die Modellierung und Automatisierung von Geschaeftsprozessen.</p>
<h3>2. API-Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/bpmn/health</td><td>GET</td><td>Engine Health-Check</td></tr>
<tr><td>/api/bpmn/process-definition</td><td>GET</td><td>Alle Prozess-Definitionen</td></tr>
<tr><td>/api/bpmn/process-definition/{key}/start</td><td>POST</td><td>Prozess starten</td></tr>
<tr><td>/api/bpmn/task</td><td>GET</td><td>Offene Tasks</td></tr>
<tr><td>/api/bpmn/task/{id}/complete</td><td>POST</td><td>Task abschliessen</td></tr>
<tr><td>/api/bpmn/deployment/create</td><td>POST</td><td>BPMN deployen</td></tr>
</table>
<h3>3. Camunda starten</h3>
<pre>
# Mit BPMN-Profil starten
docker-compose --profile bpmn up -d camunda
# Web UI oeffnen
open http://localhost:8089/camunda
</pre>
<h3>4. Lizenz</h3>
<p><strong>Apache License 2.0</strong> - Die Camunda Community Edition ist vollstaendig Open Source und darf ohne Einschraenkungen kommerziell genutzt werden.</p>
`,
}

View File

@@ -0,0 +1,96 @@
import type { SystemInfoConfig } from './types'
export const zeugnisseCrawlerConfig: SystemInfoConfig = {
title: 'Zeugnisse Crawler System-Info',
description: 'Crawler fuer Zeugnisformulierungen und Bewertungstexte.',
version: '1.0',
privacyNotes: [
'Nur anonymisierte Textbausteine',
'Keine personenbezogenen Daten',
'Quellennachweis fuer alle Texte',
],
architecture: {
layers: [
{ title: 'Admin UI', components: ['Source Manager', 'Text Editor', 'Categories'], color: '#3b82f6' },
{ title: 'Crawler', components: ['PDF Parser', 'Text Extractor', 'Classifier'], color: '#8b5cf6' },
{ title: 'Processing', components: ['Deduplication', 'Quality Check', 'Tagging'], color: '#10b981' },
{ title: 'Database', components: ['Text Corpus', 'Categories', 'Search Index'], color: '#f59e0b' },
],
},
features: [
{ name: 'PDF-Parsing', status: 'active', description: 'Extraktion aus Zeugnis-PDFs' },
{ name: 'Kategorisierung', status: 'active', description: 'Automatische Einordnung' },
{ name: 'Qualitaetssicherung', status: 'active', description: 'Review-Workflow' },
{ name: 'KI-Generierung', status: 'planned', description: 'Neue Formulierungen' },
],
roadmap: [
{ phase: 'Phase 1: Corpus (Q1)', priority: 'high', items: ['PDF Import', 'Text Cleaning', 'Category System', 'Search Function'] },
{ phase: 'Phase 2: Quality (Q2)', priority: 'medium', items: ['Duplicate Detection', 'Quality Scoring', 'Source Tracking', 'Review Workflow'] },
{ phase: 'Phase 3: AI (Q3)', priority: 'medium', items: ['Style Analysis', 'Generation', 'Personalization', 'Compliance Check'] },
],
technicalDetails: [
{ component: 'PDF', technology: 'PyMuPDF', description: 'PDF Parsing' },
{ component: 'NLP', technology: 'spaCy', description: 'Text Analysis' },
{ component: 'Search', technology: 'Qdrant', description: 'Semantic Search' },
{ component: 'Storage', technology: 'PostgreSQL', description: 'Text Database' },
],
auditInfo: [
{
category: 'Corpus Status',
items: [
{ label: 'Formulierungen', value: 'Tracking', status: 'ok' },
{ label: 'Kategorien', value: 'Definiert', status: 'ok' },
{ label: 'Qualitaet geprueft', value: 'Review', status: 'ok' },
{ label: 'Letzte Aktualisierung', value: 'Woechentlich', status: 'ok' },
],
},
{
category: 'Datenschutz',
items: [
{ label: 'Anonymisierung', value: 'Vollstaendig', status: 'ok' },
{ label: 'Quellennachweis', value: 'Vorhanden', status: 'ok' },
{ label: 'Keine PII', value: 'Verifiziert', status: 'ok' },
{ label: 'Lizenzstatus', value: 'Geprueft', status: 'ok' },
],
},
{
category: 'KI-Features',
items: [
{ label: 'Kategorisierung', value: 'Automatisch', status: 'ok' },
{ label: 'Stilanalyse', value: 'Geplant', status: 'warning' },
{ label: 'Generierung', value: 'Geplant', status: 'warning' },
{ label: 'Qualitaets-Scoring', value: 'Aktiv', status: 'ok' },
],
},
],
fullDocumentation: `
<h2>Zeugnisse Crawler - Formulierungsdatenbank</h2>
<h3>1. Uebersicht</h3>
<p>Der Zeugnisse Crawler sammelt und kategorisiert anonymisierte Zeugnisformulierungen. Er dient als Referenzdatenbank fuer die Erstellung von Arbeitszeugnissen.</p>
<h3>2. Kategorie-System</h3>
<table>
<tr><th>Kategorie</th><th>Unterkategorien</th><th>Beispiel</th></tr>
<tr><td>Leistung</td><td>sehr gut, gut, befriedigend, ...</td><td>"stets zur vollsten Zufriedenheit"</td></tr>
<tr><td>Sozialverhalten</td><td>Kollegen, Vorgesetzte, Kunden</td><td>"war bei allen beliebt"</td></tr>
<tr><td>Fachwissen</td><td>Theorie, Praxis, Weiterbildung</td><td>"verfuegt ueber fundiertes..."</td></tr>
<tr><td>Arbeitsweise</td><td>Selbstaendigkeit, Sorgfalt, ...</td><td>"arbeitet aeusserst zuverlaessig"</td></tr>
</table>
<h3>3. API Endpoints</h3>
<table>
<tr><th>Endpoint</th><th>Methode</th><th>Beschreibung</th></tr>
<tr><td>/api/zeugnisse/search</td><td>GET</td><td>Formulierungen suchen</td></tr>
<tr><td>/api/zeugnisse/categories</td><td>GET</td><td>Kategorien listen</td></tr>
<tr><td>/api/zeugnisse/suggest</td><td>POST</td><td>Passende Formulierungen</td></tr>
</table>
<h3>4. Compliance</h3>
<ul>
<li><strong>Keine personenbezogenen Daten:</strong> Vollstaendig anonymisiert</li>
<li><strong>Quellennachweis:</strong> Herkunft dokumentiert</li>
<li><strong>Lizenzpruefung:</strong> Nur freie Inhalte</li>
</ul>
`,
}