Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website, Klausur-Service, School-Service, Voice-Service, Geo-Service, BreakPilot Drive, Agent-Core Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
992 lines
38 KiB
TypeScript
992 lines
38 KiB
TypeScript
'use client'
|
|
|
|
/**
|
|
* Production Readiness Backlog
|
|
*
|
|
* Comprehensive checklist of items needed before going live with BreakPilot
|
|
* Includes CI/CD, Security, RBAC, Data Protection, and Release Workflows
|
|
*
|
|
* Migrated from website/app/admin/backlog/page.tsx
|
|
* Updated: 2026-02-03
|
|
*/
|
|
|
|
import { useState, useEffect } from 'react'
|
|
import { PagePurpose } from '@/components/common/PagePurpose'
|
|
import { metaModules } from '@/lib/navigation'
|
|
import {
|
|
ChevronRight,
|
|
Search,
|
|
Package,
|
|
RefreshCw,
|
|
Shield,
|
|
ClipboardCheck,
|
|
Users,
|
|
GitBranch,
|
|
Tag,
|
|
Database,
|
|
FileText,
|
|
CheckSquare,
|
|
AlertTriangle,
|
|
} from 'lucide-react'
|
|
|
|
interface BacklogItem {
|
|
id: string
|
|
title: string
|
|
description: string
|
|
category: string
|
|
priority: 'critical' | 'high' | 'medium' | 'low'
|
|
status: 'not_started' | 'in_progress' | 'review' | 'completed' | 'blocked'
|
|
assignee?: string
|
|
dueDate?: string
|
|
notes?: string
|
|
subtasks?: { id: string; title: string; completed: boolean }[]
|
|
}
|
|
|
|
interface BacklogCategory {
|
|
id: string
|
|
name: string
|
|
icon: React.ReactNode
|
|
color: string
|
|
bgColor: string
|
|
description: string
|
|
}
|
|
|
|
const categories: BacklogCategory[] = [
|
|
{
|
|
id: 'modules',
|
|
name: 'Module Progress',
|
|
icon: <Package className="w-5 h-5" />,
|
|
color: 'text-violet-700',
|
|
bgColor: 'bg-violet-100 border-violet-300',
|
|
description: 'Fertigstellungsgrad aller Services & Module',
|
|
},
|
|
{
|
|
id: 'cicd',
|
|
name: 'CI/CD Pipelines',
|
|
icon: <RefreshCw className="w-5 h-5" />,
|
|
color: 'text-blue-700',
|
|
bgColor: 'bg-blue-100 border-blue-300',
|
|
description: 'Build, Test & Deployment Automation',
|
|
},
|
|
{
|
|
id: 'security',
|
|
name: 'Security & Vulnerability',
|
|
icon: <Shield className="w-5 h-5" />,
|
|
color: 'text-red-700',
|
|
bgColor: 'bg-red-100 border-red-300',
|
|
description: 'Security Scans, Dependency Checks & Penetration Testing',
|
|
},
|
|
{
|
|
id: 'testing',
|
|
name: 'Testing & Quality',
|
|
icon: <ClipboardCheck className="w-5 h-5" />,
|
|
color: 'text-emerald-700',
|
|
bgColor: 'bg-emerald-100 border-emerald-300',
|
|
description: 'Unit Tests, Integration Tests & E2E Testing',
|
|
},
|
|
{
|
|
id: 'rbac',
|
|
name: 'RBAC & Access Control',
|
|
icon: <Users className="w-5 h-5" />,
|
|
color: 'text-purple-700',
|
|
bgColor: 'bg-purple-100 border-purple-300',
|
|
description: 'Developer Roles, Permissions & Team Management',
|
|
},
|
|
{
|
|
id: 'git',
|
|
name: 'Git & Branch Protection',
|
|
icon: <GitBranch className="w-5 h-5" />,
|
|
color: 'text-orange-700',
|
|
bgColor: 'bg-orange-100 border-orange-300',
|
|
description: 'Protected Branches, Merge Requests & Code Reviews',
|
|
},
|
|
{
|
|
id: 'release',
|
|
name: 'Release Management',
|
|
icon: <Tag className="w-5 h-5" />,
|
|
color: 'text-green-700',
|
|
bgColor: 'bg-green-100 border-green-300',
|
|
description: 'Versioning, Changelog & Release Notes',
|
|
},
|
|
{
|
|
id: 'data',
|
|
name: 'Data Protection',
|
|
icon: <Database className="w-5 h-5" />,
|
|
color: 'text-cyan-700',
|
|
bgColor: 'bg-cyan-100 border-cyan-300',
|
|
description: 'Backup, Migration & Customer Data Safety',
|
|
},
|
|
{
|
|
id: 'compliance',
|
|
name: 'Compliance & SBOM',
|
|
icon: <FileText className="w-5 h-5" />,
|
|
color: 'text-teal-700',
|
|
bgColor: 'bg-teal-100 border-teal-300',
|
|
description: 'SBOM, Lizenzen & Open Source Compliance',
|
|
},
|
|
{
|
|
id: 'approval',
|
|
name: 'Approval Workflow',
|
|
icon: <CheckSquare className="w-5 h-5" />,
|
|
color: 'text-indigo-700',
|
|
bgColor: 'bg-indigo-100 border-indigo-300',
|
|
description: 'Developer Approval, QA Sign-off & Release Gates',
|
|
},
|
|
]
|
|
|
|
// UPDATED: 2026-02-03 - Reflects actual project state
|
|
const initialBacklogItems: BacklogItem[] = [
|
|
// ==================== MODULE PROGRESS ====================
|
|
{
|
|
id: 'mod-1',
|
|
title: 'Consent Service (Go) - 90% fertig',
|
|
description: 'DSGVO Consent Management Microservice - Production Ready',
|
|
category: 'modules',
|
|
priority: 'high',
|
|
status: 'in_progress',
|
|
notes: 'Port 8081. Umfangreiche Tests. JWT Auth, OAuth 2.0, TOTP 2FA, DSR Workflow, Matrix/Jitsi Integration, Session Management, PII Redactor.',
|
|
subtasks: [
|
|
{ id: 'mod-1-1', title: 'Core Consent API (CRUD, Versioning)', completed: true },
|
|
{ id: 'mod-1-2', title: 'Authentication (JWT, OAuth 2.0, TOTP)', completed: true },
|
|
{ id: 'mod-1-3', title: 'DSR Workflow (Art. 15-21)', completed: true },
|
|
{ id: 'mod-1-4', title: 'Email Templates & Notifications', completed: true },
|
|
{ id: 'mod-1-5', title: 'Matrix/Jitsi Integration', completed: true },
|
|
{ id: 'mod-1-6', title: 'Session Management & Middleware', completed: true },
|
|
{ id: 'mod-1-7', title: 'PII Redactor & Security Headers', completed: true },
|
|
{ id: 'mod-1-8', title: 'Performance Tests (High-Load)', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'mod-2',
|
|
title: 'Admin-v2 Frontend (Next.js 15) - 95% fertig',
|
|
description: 'Neues Admin Dashboard - Feature Complete',
|
|
category: 'modules',
|
|
priority: 'critical',
|
|
status: 'completed',
|
|
notes: 'Port 3002. 73 Seiten, 154 Dateien, 50k+ Zeilen Code. Alle Module migriert.',
|
|
subtasks: [
|
|
{ id: 'mod-2-1', title: 'Layout mit Sidebar Navigation', completed: true },
|
|
{ id: 'mod-2-2', title: 'AI Module (Agents, RAG, Quality, LLM Compare)', completed: true },
|
|
{ id: 'mod-2-3', title: 'Compliance Module (AI Act, DSFA, Controls, Evidence)', completed: true },
|
|
{ id: 'mod-2-4', title: 'Communication Module (Mail, Matrix, Video-Chat, Alerts)', completed: true },
|
|
{ id: 'mod-2-5', title: 'DSGVO Module (Advisory Board, Consent, DSR, TOM, VVT)', completed: true },
|
|
{ id: 'mod-2-6', title: 'Infrastructure Module (CI/CD, GPU, SBOM, Security, Tests)', completed: true },
|
|
{ id: 'mod-2-7', title: 'Education Module (Edu-Search, Foerderantrag)', completed: true },
|
|
{ id: 'mod-2-8', title: 'Wizard Framework (Stepper, TestRunner, etc.)', completed: true },
|
|
{ id: 'mod-2-9', title: 'API Proxy Routes', completed: true },
|
|
{ id: 'mod-2-10', title: 'E2E Tests mit Playwright', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'mod-3',
|
|
title: 'Studio-v2 Frontend (Next.js 15) - 90% fertig',
|
|
description: 'Lehrer/Schueler Studio mit Apple Weather UI',
|
|
category: 'modules',
|
|
priority: 'high',
|
|
status: 'completed',
|
|
notes: 'Port 3001. 21 Seiten, 111 Dateien, 38k+ Zeilen. Experimental Dashboard, Korrektur, Geo-Lernwelt.',
|
|
subtasks: [
|
|
{ id: 'mod-3-1', title: 'Experimental Dashboard (Glassmorphism)', completed: true },
|
|
{ id: 'mod-3-2', title: 'Korrektur-System mit Fairness-Analyse', completed: true },
|
|
{ id: 'mod-3-3', title: 'Geo-Lernwelt (Maps, AOI)', completed: true },
|
|
{ id: 'mod-3-4', title: 'Voice Components', completed: true },
|
|
{ id: 'mod-3-5', title: 'Worksheet Editor', completed: true },
|
|
{ id: 'mod-3-6', title: 'Alerts & B2B Migration Wizard', completed: true },
|
|
{ id: 'mod-3-7', title: 'Document Upload & QR Code', completed: true },
|
|
{ id: 'mod-3-8', title: 'Messages & Meet Integration', completed: true },
|
|
],
|
|
},
|
|
{
|
|
id: 'mod-4',
|
|
title: 'Backend (Python FastAPI) - 85% fertig',
|
|
description: 'Hauptbackend mit umfangreichen Erweiterungen',
|
|
category: 'modules',
|
|
priority: 'critical',
|
|
status: 'in_progress',
|
|
notes: 'Port 8000. 238 Dateien, 94k+ Zeilen. Alerts Agent, Compliance, Classroom Engine, Game, Klausur.',
|
|
subtasks: [
|
|
{ id: 'mod-4-1', title: 'Alerts Agent (Rules, Digests, Actions)', completed: true },
|
|
{ id: 'mod-4-2', title: 'Compliance Module (AI Act, ISMS, Audit)', completed: true },
|
|
{ id: 'mod-4-3', title: 'Classroom Engine (FSM, Analytics, Timer)', completed: true },
|
|
{ id: 'mod-4-4', title: 'Game API (Learning Rules, Quiz)', completed: true },
|
|
{ id: 'mod-4-5', title: 'Klausur Backend (OCR, Correction)', completed: true },
|
|
{ id: 'mod-4-6', title: 'Unit API & Analytics', completed: true },
|
|
{ id: 'mod-4-7', title: 'Middleware (Rate Limiter, Security)', completed: true },
|
|
{ id: 'mod-4-8', title: 'Session Management (RBAC)', completed: true },
|
|
{ id: 'mod-4-9', title: 'Transcription Worker', completed: true },
|
|
{ id: 'mod-4-10', title: 'Alembic Migrations', completed: true },
|
|
{ id: 'mod-4-11', title: 'Integration Tests erweitern', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'mod-5',
|
|
title: 'Klausur Service (Python) - 85% fertig',
|
|
description: 'BYOEH Abitur-Klausurkorrektur System',
|
|
category: 'modules',
|
|
priority: 'critical',
|
|
status: 'in_progress',
|
|
notes: 'Port 8086. 45 Dateien, 20k+ Zeilen. BYOEH, Qdrant RAG, Embedding Service, Legal Corpus.',
|
|
subtasks: [
|
|
{ id: 'mod-5-1', title: 'BYOEH Upload & Encryption', completed: true },
|
|
{ id: 'mod-5-2', title: 'Key-Sharing zwischen Pruefern', completed: true },
|
|
{ id: 'mod-5-3', title: 'Qdrant RAG Integration', completed: true },
|
|
{ id: 'mod-5-4', title: 'Hybrid Search (Keyword + Semantic)', completed: true },
|
|
{ id: 'mod-5-5', title: 'Embedding Service', completed: true },
|
|
{ id: 'mod-5-6', title: 'Legal Corpus Ingestion', completed: true },
|
|
{ id: 'mod-5-7', title: 'PDF Export', completed: true },
|
|
{ id: 'mod-5-8', title: 'OCR Pipeline (TrOCR, Vision)', completed: true },
|
|
{ id: 'mod-5-9', title: 'Vocab Worksheet API', completed: true },
|
|
{ id: 'mod-5-10', title: 'KI-gestuetzte Korrektur verbessern', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'mod-6',
|
|
title: 'Agent-Core - 80% fertig',
|
|
description: 'Multi-Agent Architecture Framework',
|
|
category: 'modules',
|
|
priority: 'high',
|
|
status: 'in_progress',
|
|
notes: 'Neuer Service. Sessions, Shared Brain, Orchestrator, SOUL Files.',
|
|
subtasks: [
|
|
{ id: 'mod-6-1', title: 'Session Management & Heartbeat', completed: true },
|
|
{ id: 'mod-6-2', title: 'Checkpoint System', completed: true },
|
|
{ id: 'mod-6-3', title: 'Memory Store (mit TTL)', completed: true },
|
|
{ id: 'mod-6-4', title: 'Context Manager', completed: true },
|
|
{ id: 'mod-6-5', title: 'Knowledge Graph', completed: true },
|
|
{ id: 'mod-6-6', title: 'Message Bus (Pub/Sub)', completed: true },
|
|
{ id: 'mod-6-7', title: 'Supervisor & Task Router', completed: true },
|
|
{ id: 'mod-6-8', title: 'SOUL Files (Agent Personalities)', completed: true },
|
|
{ id: 'mod-6-9', title: 'Integration mit Voice Service', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'mod-7',
|
|
title: 'AI Compliance SDK (Go) - 75% fertig',
|
|
description: 'UCCA Obligations Framework',
|
|
category: 'modules',
|
|
priority: 'high',
|
|
status: 'in_progress',
|
|
notes: 'Neuer Go Service. AI Act, DSGVO, NIS2 Module. Policy Engine.',
|
|
subtasks: [
|
|
{ id: 'mod-7-1', title: 'UCCA Obligations Framework', completed: true },
|
|
{ id: 'mod-7-2', title: 'AI Act Module', completed: true },
|
|
{ id: 'mod-7-3', title: 'DSGVO Module', completed: true },
|
|
{ id: 'mod-7-4', title: 'NIS2 Module', completed: true },
|
|
{ id: 'mod-7-5', title: 'Policy Engine', completed: true },
|
|
{ id: 'mod-7-6', title: 'Legal RAG Integration', completed: true },
|
|
{ id: 'mod-7-7', title: 'Audit Trail & Export', completed: true },
|
|
{ id: 'mod-7-8', title: 'Escalation System', completed: false },
|
|
{ id: 'mod-7-9', title: 'Funding/Foerderantrag Wizard', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'mod-8',
|
|
title: 'Geo Service (Python) - 70% fertig',
|
|
description: 'Geographic Data Service fuer Geo-Lernwelt',
|
|
category: 'modules',
|
|
priority: 'medium',
|
|
status: 'in_progress',
|
|
notes: 'Neuer Service. AOI Packager, DEM Service, Tile Server.',
|
|
subtasks: [
|
|
{ id: 'mod-8-1', title: 'AOI Packager', completed: true },
|
|
{ id: 'mod-8-2', title: 'DEM Service', completed: true },
|
|
{ id: 'mod-8-3', title: 'OSM Extractor', completed: true },
|
|
{ id: 'mod-8-4', title: 'Tile Server', completed: true },
|
|
{ id: 'mod-8-5', title: 'Learning Generator', completed: true },
|
|
{ id: 'mod-8-6', title: 'License Checker', completed: true },
|
|
{ id: 'mod-8-7', title: 'Unity Integration', completed: false },
|
|
{ id: 'mod-8-8', title: 'Performance Optimization', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'mod-9',
|
|
title: 'Edu-Search Service (Go) - 65% fertig',
|
|
description: 'Educational Search mit Policy Engine',
|
|
category: 'modules',
|
|
priority: 'medium',
|
|
status: 'in_progress',
|
|
notes: 'Policy Handlers, Bundeslaender Policies, PII Detector.',
|
|
subtasks: [
|
|
{ id: 'mod-9-1', title: 'Policy Enforcer', completed: true },
|
|
{ id: 'mod-9-2', title: 'PII Detector', completed: true },
|
|
{ id: 'mod-9-3', title: 'Bundeslaender Policies', completed: true },
|
|
{ id: 'mod-9-4', title: 'German Universities Data', completed: true },
|
|
{ id: 'mod-9-5', title: 'Search API erweitern', completed: false },
|
|
{ id: 'mod-9-6', title: 'Caching Layer', completed: false },
|
|
],
|
|
},
|
|
|
|
// ==================== CI/CD PIPELINES ====================
|
|
{
|
|
id: 'cicd-1',
|
|
title: 'Woodpecker CI Setup',
|
|
description: 'Self-hosted CI/CD auf Mac Mini',
|
|
category: 'cicd',
|
|
priority: 'critical',
|
|
status: 'completed',
|
|
notes: 'Implementiert. Woodpecker CI laeuft auf macmini:8082. Pipelines fuer alle Services.',
|
|
subtasks: [
|
|
{ id: 'cicd-1-1', title: 'Woodpecker Server & Agent installiert', completed: true },
|
|
{ id: 'cicd-1-2', title: 'Gitea Integration', completed: true },
|
|
{ id: 'cicd-1-3', title: 'Docker Build Pipelines', completed: true },
|
|
{ id: 'cicd-1-4', title: 'Test Pipelines (Go, Python, Node)', completed: true },
|
|
],
|
|
},
|
|
{
|
|
id: 'cicd-2',
|
|
title: 'SBOM Generation Pipeline',
|
|
description: 'Automatische SBOM-Generierung in CI',
|
|
category: 'cicd',
|
|
priority: 'high',
|
|
status: 'completed',
|
|
notes: 'Implementiert in .gitea/workflows/sbom.yaml',
|
|
subtasks: [
|
|
{ id: 'cicd-2-1', title: 'CycloneDX SBOM Generation', completed: true },
|
|
{ id: 'cicd-2-2', title: 'Artifact Upload', completed: true },
|
|
{ id: 'cicd-2-3', title: 'SBOM Viewer in Admin', completed: true },
|
|
],
|
|
},
|
|
{
|
|
id: 'cicd-3',
|
|
title: 'Production Deployment Pipeline',
|
|
description: 'Kontrolliertes Deployment mit Rollback',
|
|
category: 'cicd',
|
|
priority: 'critical',
|
|
status: 'not_started',
|
|
subtasks: [
|
|
{ id: 'cicd-3-1', title: 'Blue-Green oder Canary Strategy', completed: false },
|
|
{ id: 'cicd-3-2', title: 'Automatischer Rollback', completed: false },
|
|
{ id: 'cicd-3-3', title: 'Health Checks nach Deploy', completed: false },
|
|
{ id: 'cicd-3-4', title: 'Deployment Notifications', completed: false },
|
|
],
|
|
},
|
|
|
|
// ==================== SECURITY ====================
|
|
{
|
|
id: 'sec-1',
|
|
title: 'Dependency Vulnerability Scanning',
|
|
description: 'Automatische Pruefung auf Schwachstellen',
|
|
category: 'security',
|
|
priority: 'critical',
|
|
status: 'completed',
|
|
notes: 'Dependabot konfiguriert fuer Go, Python, npm, Docker.',
|
|
subtasks: [
|
|
{ id: 'sec-1-1', title: 'Dependabot fuer Go', completed: true },
|
|
{ id: 'sec-1-2', title: 'Dependabot fuer Python', completed: true },
|
|
{ id: 'sec-1-3', title: 'Dependabot fuer npm', completed: true },
|
|
{ id: 'sec-1-4', title: 'Block Merge bei kritischen CVEs', completed: true },
|
|
],
|
|
},
|
|
{
|
|
id: 'sec-2',
|
|
title: 'Container Image Scanning',
|
|
description: 'Trivy Scans fuer alle Docker Images',
|
|
category: 'security',
|
|
priority: 'high',
|
|
status: 'completed',
|
|
notes: 'Trivy in CI integriert.',
|
|
subtasks: [
|
|
{ id: 'sec-2-1', title: 'Trivy Integration', completed: true },
|
|
{ id: 'sec-2-2', title: 'Base Image Policy', completed: true },
|
|
{ id: 'sec-2-3', title: 'Scan Report bei Build', completed: true },
|
|
],
|
|
},
|
|
{
|
|
id: 'sec-3',
|
|
title: 'SAST (Static Application Security Testing)',
|
|
description: 'Code-Analyse auf Sicherheitsluecken',
|
|
category: 'security',
|
|
priority: 'high',
|
|
status: 'completed',
|
|
notes: 'Gosec, Bandit, npm audit in CI.',
|
|
subtasks: [
|
|
{ id: 'sec-3-1', title: 'Gosec fuer Go', completed: true },
|
|
{ id: 'sec-3-2', title: 'Bandit fuer Python', completed: true },
|
|
{ id: 'sec-3-3', title: 'npm audit', completed: true },
|
|
{ id: 'sec-3-4', title: 'Semgrep Regeln', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'sec-4',
|
|
title: 'Secret Scanning',
|
|
description: 'Verhindern dass Secrets in Git landen',
|
|
category: 'security',
|
|
priority: 'critical',
|
|
status: 'completed',
|
|
notes: 'Gitleaks in CI. SSH Keys in .gitignore.',
|
|
subtasks: [
|
|
{ id: 'sec-4-1', title: 'Gitleaks Pre-commit', completed: true },
|
|
{ id: 'sec-4-2', title: 'SSH Keys in .gitignore', completed: true },
|
|
{ id: 'sec-4-3', title: 'Historische Commits gescannt', completed: true },
|
|
],
|
|
},
|
|
|
|
// ==================== TESTING ====================
|
|
{
|
|
id: 'test-1',
|
|
title: 'Backend Test Coverage erweitern',
|
|
description: 'Integration & E2E Tests fuer Backend APIs',
|
|
category: 'testing',
|
|
priority: 'high',
|
|
status: 'in_progress',
|
|
notes: '238 Backend-Dateien, davon 20+ Test-Dateien.',
|
|
subtasks: [
|
|
{ id: 'test-1-1', title: 'Alerts Agent Tests', completed: true },
|
|
{ id: 'test-1-2', title: 'Compliance API Tests', completed: true },
|
|
{ id: 'test-1-3', title: 'Classroom API Tests', completed: true },
|
|
{ id: 'test-1-4', title: 'Session Middleware Tests', completed: true },
|
|
{ id: 'test-1-5', title: 'Load Testing mit k6', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'test-2',
|
|
title: 'Frontend E2E Tests',
|
|
description: 'Playwright Tests fuer Admin-v2 und Studio-v2',
|
|
category: 'testing',
|
|
priority: 'critical',
|
|
status: 'not_started',
|
|
notes: 'Kritischer Mangel - keine E2E Tests!',
|
|
subtasks: [
|
|
{ id: 'test-2-1', title: 'Playwright Setup', completed: false },
|
|
{ id: 'test-2-2', title: 'Admin-v2 Critical Paths', completed: false },
|
|
{ id: 'test-2-3', title: 'Studio-v2 User Flows', completed: false },
|
|
{ id: 'test-2-4', title: 'Visual Regression', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'test-3',
|
|
title: 'Agent-Core Tests',
|
|
description: 'Unit Tests fuer Multi-Agent Framework',
|
|
category: 'testing',
|
|
priority: 'high',
|
|
status: 'completed',
|
|
notes: 'Umfangreiche Test-Suite vorhanden.',
|
|
subtasks: [
|
|
{ id: 'test-3-1', title: 'Session Manager Tests', completed: true },
|
|
{ id: 'test-3-2', title: 'Memory Store Tests', completed: true },
|
|
{ id: 'test-3-3', title: 'Message Bus Tests', completed: true },
|
|
{ id: 'test-3-4', title: 'Task Router Tests', completed: true },
|
|
{ id: 'test-3-5', title: 'Heartbeat Tests', completed: true },
|
|
],
|
|
},
|
|
|
|
// ==================== RBAC ====================
|
|
{
|
|
id: 'rbac-1',
|
|
title: 'Gitea Team Permissions',
|
|
description: 'Team-basierte Zugriffsrechte',
|
|
category: 'rbac',
|
|
priority: 'high',
|
|
status: 'not_started',
|
|
subtasks: [
|
|
{ id: 'rbac-1-1', title: 'Maintainers Team (Full Access)', completed: false },
|
|
{ id: 'rbac-1-2', title: 'Developers Team (Write)', completed: false },
|
|
{ id: 'rbac-1-3', title: 'Reviewers Team (Read + Review)', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'rbac-2',
|
|
title: 'Admin Panel Access Control',
|
|
description: 'Rollenbasierte Zugriffsrechte im Admin',
|
|
category: 'rbac',
|
|
priority: 'medium',
|
|
status: 'in_progress',
|
|
notes: 'RBAC Middleware im Backend implementiert.',
|
|
subtasks: [
|
|
{ id: 'rbac-2-1', title: 'RBAC Middleware', completed: true },
|
|
{ id: 'rbac-2-2', title: 'Session Store', completed: true },
|
|
{ id: 'rbac-2-3', title: 'Protected Routes', completed: true },
|
|
{ id: 'rbac-2-4', title: 'Admin Authentication UI', completed: false },
|
|
],
|
|
},
|
|
|
|
// ==================== GIT ====================
|
|
{
|
|
id: 'git-1',
|
|
title: 'Protected Branches Setup',
|
|
description: 'Schutz fuer main Branch',
|
|
category: 'git',
|
|
priority: 'critical',
|
|
status: 'not_started',
|
|
subtasks: [
|
|
{ id: 'git-1-1', title: 'No direct push to main', completed: false },
|
|
{ id: 'git-1-2', title: 'Require PR with Approval', completed: false },
|
|
{ id: 'git-1-3', title: 'Require Status Checks', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'git-2',
|
|
title: 'Alle Dateien committet',
|
|
description: 'Keine ungetrackten Produktionsdateien',
|
|
category: 'git',
|
|
priority: 'critical',
|
|
status: 'completed',
|
|
notes: 'Am 2026-02-03 bereinigt: ~870 Dateien, 329k Zeilen committet.',
|
|
subtasks: [
|
|
{ id: 'git-2-1', title: 'admin-v2 (154 Dateien)', completed: true },
|
|
{ id: 'git-2-2', title: 'studio-v2 (111 Dateien)', completed: true },
|
|
{ id: 'git-2-3', title: 'backend (238 Dateien)', completed: true },
|
|
{ id: 'git-2-4', title: 'website (120 Dateien)', completed: true },
|
|
{ id: 'git-2-5', title: 'klausur-service (45 Dateien)', completed: true },
|
|
{ id: 'git-2-6', title: 'consent-service (15 Dateien)', completed: true },
|
|
{ id: 'git-2-7', title: 'Neue Services (161 Dateien)', completed: true },
|
|
{ id: 'git-2-8', title: '.gitignore aktualisiert', completed: true },
|
|
],
|
|
},
|
|
|
|
// ==================== RELEASE ====================
|
|
{
|
|
id: 'rel-1',
|
|
title: 'Semantic Versioning',
|
|
description: 'Automatische Versionierung nach SemVer',
|
|
category: 'release',
|
|
priority: 'high',
|
|
status: 'not_started',
|
|
subtasks: [
|
|
{ id: 'rel-1-1', title: 'Conventional Commits', completed: false },
|
|
{ id: 'rel-1-2', title: 'Automatische Git Tags', completed: false },
|
|
{ id: 'rel-1-3', title: 'CHANGELOG Generation', completed: false },
|
|
],
|
|
},
|
|
|
|
// ==================== DATA ====================
|
|
{
|
|
id: 'data-1',
|
|
title: 'Database Backup Strategy',
|
|
description: 'Automatische Backups mit Retention',
|
|
category: 'data',
|
|
priority: 'critical',
|
|
status: 'not_started',
|
|
subtasks: [
|
|
{ id: 'data-1-1', title: 'Taegliche Backups', completed: false },
|
|
{ id: 'data-1-2', title: 'Point-in-Time Recovery', completed: false },
|
|
{ id: 'data-1-3', title: 'Backup Encryption', completed: false },
|
|
{ id: 'data-1-4', title: 'Restore Test dokumentieren', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'data-2',
|
|
title: 'Customer Data Protection',
|
|
description: 'Schutz von Stammdaten & Dokumenten',
|
|
category: 'data',
|
|
priority: 'critical',
|
|
status: 'in_progress',
|
|
subtasks: [
|
|
{ id: 'data-2-1', title: 'Encryption at Rest', completed: true },
|
|
{ id: 'data-2-2', title: 'Audit Log fuer Consent', completed: true },
|
|
{ id: 'data-2-3', title: 'PII Masking in Logs', completed: true },
|
|
{ id: 'data-2-4', title: 'Secure Document Storage', completed: false },
|
|
],
|
|
},
|
|
|
|
// ==================== COMPLIANCE ====================
|
|
{
|
|
id: 'sbom-1',
|
|
title: 'SBOM erstellt und dokumentiert',
|
|
description: 'Software Bill of Materials',
|
|
category: 'compliance',
|
|
priority: 'high',
|
|
status: 'completed',
|
|
notes: 'Umfassende SBOM in /admin/sbom verfuegbar.',
|
|
subtasks: [
|
|
{ id: 'sbom-1-1', title: 'Go Dependencies', completed: true },
|
|
{ id: 'sbom-1-2', title: 'Python Dependencies', completed: true },
|
|
{ id: 'sbom-1-3', title: 'npm Dependencies', completed: true },
|
|
{ id: 'sbom-1-4', title: 'Docker Base Images', completed: true },
|
|
{ id: 'sbom-1-5', title: 'CycloneDX Export', completed: true },
|
|
],
|
|
},
|
|
{
|
|
id: 'sbom-2',
|
|
title: 'Lizenz-Compliance',
|
|
description: 'Alle Lizenzen geprueft',
|
|
category: 'compliance',
|
|
priority: 'high',
|
|
status: 'in_progress',
|
|
subtasks: [
|
|
{ id: 'sbom-2-1', title: 'Lizenzen identifiziert', completed: true },
|
|
{ id: 'sbom-2-2', title: 'Kompatibilitaet geprueft', completed: false },
|
|
{ id: 'sbom-2-3', title: 'LICENSES.md erstellt', completed: false },
|
|
],
|
|
},
|
|
|
|
// ==================== APPROVAL ====================
|
|
{
|
|
id: 'appr-1',
|
|
title: 'Release Approval Gates',
|
|
description: 'Mehrstufige Freigabe',
|
|
category: 'approval',
|
|
priority: 'critical',
|
|
status: 'not_started',
|
|
subtasks: [
|
|
{ id: 'appr-1-1', title: 'QA Sign-off', completed: false },
|
|
{ id: 'appr-1-2', title: 'Security Review', completed: false },
|
|
{ id: 'appr-1-3', title: 'Product Owner Freigabe', completed: false },
|
|
],
|
|
},
|
|
{
|
|
id: 'appr-2',
|
|
title: 'Post-Deployment Verification',
|
|
description: 'Checks nach Deployment',
|
|
category: 'approval',
|
|
priority: 'high',
|
|
status: 'not_started',
|
|
subtasks: [
|
|
{ id: 'appr-2-1', title: 'Smoke Tests', completed: false },
|
|
{ id: 'appr-2-2', title: 'Error Rate Monitoring', completed: false },
|
|
{ id: 'appr-2-3', title: 'Rollback Kriterien', completed: false },
|
|
],
|
|
},
|
|
]
|
|
|
|
const statusLabels: Record<BacklogItem['status'], { label: string; color: string }> = {
|
|
not_started: { label: 'Nicht begonnen', color: 'bg-slate-100 text-slate-600' },
|
|
in_progress: { label: 'In Arbeit', color: 'bg-blue-100 text-blue-700' },
|
|
review: { label: 'In Review', color: 'bg-yellow-100 text-yellow-700' },
|
|
completed: { label: 'Abgeschlossen', color: 'bg-green-100 text-green-700' },
|
|
blocked: { label: 'Blockiert', color: 'bg-red-100 text-red-700' },
|
|
}
|
|
|
|
const priorityLabels: Record<BacklogItem['priority'], { label: string; color: string }> = {
|
|
critical: { label: 'Kritisch', color: 'bg-red-500 text-white' },
|
|
high: { label: 'Hoch', color: 'bg-orange-500 text-white' },
|
|
medium: { label: 'Mittel', color: 'bg-yellow-500 text-white' },
|
|
low: { label: 'Niedrig', color: 'bg-slate-500 text-white' },
|
|
}
|
|
|
|
export default function BacklogPage() {
|
|
const module = metaModules.find((m) => m.id === 'backlog')
|
|
const [items, setItems] = useState<BacklogItem[]>(initialBacklogItems)
|
|
const [selectedCategory, setSelectedCategory] = useState<string | null>(null)
|
|
const [selectedPriority, setSelectedPriority] = useState<string | null>(null)
|
|
const [expandedItems, setExpandedItems] = useState<Set<string>>(new Set())
|
|
const [searchQuery, setSearchQuery] = useState('')
|
|
|
|
// Load saved state from localStorage
|
|
useEffect(() => {
|
|
const saved = localStorage.getItem('backlogItems-v2')
|
|
if (saved) {
|
|
try {
|
|
setItems(JSON.parse(saved))
|
|
} catch (e) {
|
|
console.error('Failed to load backlog items:', e)
|
|
}
|
|
}
|
|
}, [])
|
|
|
|
// Save state to localStorage
|
|
useEffect(() => {
|
|
localStorage.setItem('backlogItems-v2', JSON.stringify(items))
|
|
}, [items])
|
|
|
|
const filteredItems = items.filter((item) => {
|
|
if (selectedCategory && item.category !== selectedCategory) return false
|
|
if (selectedPriority && item.priority !== selectedPriority) return false
|
|
if (searchQuery) {
|
|
const query = searchQuery.toLowerCase()
|
|
return (
|
|
item.title.toLowerCase().includes(query) ||
|
|
item.description.toLowerCase().includes(query) ||
|
|
item.subtasks?.some((st) => st.title.toLowerCase().includes(query))
|
|
)
|
|
}
|
|
return true
|
|
})
|
|
|
|
const toggleExpand = (id: string) => {
|
|
const newExpanded = new Set(expandedItems)
|
|
if (newExpanded.has(id)) {
|
|
newExpanded.delete(id)
|
|
} else {
|
|
newExpanded.add(id)
|
|
}
|
|
setExpandedItems(newExpanded)
|
|
}
|
|
|
|
const updateItemStatus = (id: string, status: BacklogItem['status']) => {
|
|
setItems(items.map((item) => (item.id === id ? { ...item, status } : item)))
|
|
}
|
|
|
|
const toggleSubtask = (itemId: string, subtaskId: string) => {
|
|
setItems(
|
|
items.map((item) => {
|
|
if (item.id !== itemId) return item
|
|
return {
|
|
...item,
|
|
subtasks: item.subtasks?.map((st) =>
|
|
st.id === subtaskId ? { ...st, completed: !st.completed } : st
|
|
),
|
|
}
|
|
})
|
|
)
|
|
}
|
|
|
|
const getProgress = () => {
|
|
const total = items.length
|
|
const completed = items.filter((i) => i.status === 'completed').length
|
|
return { total, completed, percentage: Math.round((completed / total) * 100) }
|
|
}
|
|
|
|
const getCategoryProgress = (categoryId: string) => {
|
|
const categoryItems = items.filter((i) => i.category === categoryId)
|
|
const completed = categoryItems.filter((i) => i.status === 'completed').length
|
|
return { total: categoryItems.length, completed }
|
|
}
|
|
|
|
const resetToDefaults = () => {
|
|
if (confirm('Backlog auf Standardwerte zuruecksetzen? Alle lokalen Aenderungen gehen verloren.')) {
|
|
setItems(initialBacklogItems)
|
|
localStorage.removeItem('backlogItems-v2')
|
|
}
|
|
}
|
|
|
|
const progress = getProgress()
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{module && (
|
|
<PagePurpose
|
|
title={module.name}
|
|
purpose={module.purpose}
|
|
audience={module.audience}
|
|
collapsible={true}
|
|
defaultCollapsed={true}
|
|
/>
|
|
)}
|
|
|
|
{/* Overall Progress */}
|
|
<div className="bg-white rounded-xl border border-slate-200 p-6">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<div>
|
|
<h2 className="text-lg font-semibold text-slate-900">Gesamtfortschritt</h2>
|
|
<p className="text-sm text-slate-500">
|
|
{progress.completed} von {progress.total} Aufgaben abgeschlossen
|
|
</p>
|
|
</div>
|
|
<div className="flex items-center gap-4">
|
|
<button
|
|
onClick={resetToDefaults}
|
|
className="text-sm text-slate-500 hover:text-slate-700"
|
|
>
|
|
Zuruecksetzen
|
|
</button>
|
|
<div className="text-3xl font-bold text-blue-600">{progress.percentage}%</div>
|
|
</div>
|
|
</div>
|
|
<div className="w-full bg-slate-200 rounded-full h-3">
|
|
<div
|
|
className="bg-blue-600 h-3 rounded-full transition-all duration-500"
|
|
style={{ width: `${progress.percentage}%` }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Category Cards */}
|
|
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-3">
|
|
{categories.map((cat) => {
|
|
const catProgress = getCategoryProgress(cat.id)
|
|
return (
|
|
<button
|
|
key={cat.id}
|
|
onClick={() => setSelectedCategory(selectedCategory === cat.id ? null : cat.id)}
|
|
className={`p-3 rounded-xl border-2 text-left transition-all ${
|
|
selectedCategory === cat.id
|
|
? `${cat.bgColor} ring-2 ring-offset-2`
|
|
: 'bg-white border-slate-200 hover:border-slate-300'
|
|
}`}
|
|
>
|
|
<div className="flex items-center gap-2 mb-1">
|
|
<span className={selectedCategory === cat.id ? cat.color : 'text-slate-500'}>
|
|
{cat.icon}
|
|
</span>
|
|
<span className="font-medium text-xs truncate">{cat.name}</span>
|
|
</div>
|
|
<div className="text-xs text-slate-500">
|
|
{catProgress.completed}/{catProgress.total}
|
|
</div>
|
|
</button>
|
|
)
|
|
})}
|
|
</div>
|
|
|
|
{/* Filters & Search */}
|
|
<div className="flex flex-wrap gap-4">
|
|
<div className="flex-1 min-w-[200px] relative">
|
|
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
|
|
<input
|
|
type="text"
|
|
placeholder="Suchen..."
|
|
value={searchQuery}
|
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
className="w-full pl-10 pr-4 py-2 border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
/>
|
|
</div>
|
|
<select
|
|
value={selectedPriority || ''}
|
|
onChange={(e) => setSelectedPriority(e.target.value || null)}
|
|
className="px-4 py-2 border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
>
|
|
<option value="">Alle Prioritaeten</option>
|
|
<option value="critical">Kritisch</option>
|
|
<option value="high">Hoch</option>
|
|
<option value="medium">Mittel</option>
|
|
<option value="low">Niedrig</option>
|
|
</select>
|
|
{(selectedCategory || selectedPriority || searchQuery) && (
|
|
<button
|
|
onClick={() => {
|
|
setSelectedCategory(null)
|
|
setSelectedPriority(null)
|
|
setSearchQuery('')
|
|
}}
|
|
className="px-4 py-2 text-sm text-slate-600 hover:text-slate-900"
|
|
>
|
|
Filter zuruecksetzen
|
|
</button>
|
|
)}
|
|
</div>
|
|
|
|
{/* Backlog Items */}
|
|
<div className="space-y-3">
|
|
{filteredItems.map((item) => {
|
|
const category = categories.find((c) => c.id === item.category)
|
|
const isExpanded = expandedItems.has(item.id)
|
|
const completedSubtasks = item.subtasks?.filter((st) => st.completed).length || 0
|
|
const totalSubtasks = item.subtasks?.length || 0
|
|
|
|
return (
|
|
<div
|
|
key={item.id}
|
|
className="bg-white rounded-xl border border-slate-200 overflow-hidden"
|
|
>
|
|
<div
|
|
className="p-4 cursor-pointer hover:bg-slate-50 transition-colors"
|
|
onClick={() => toggleExpand(item.id)}
|
|
>
|
|
<div className="flex items-start gap-3">
|
|
{/* Expand Icon */}
|
|
<button className="mt-1 text-slate-400">
|
|
<ChevronRight
|
|
className={`w-5 h-5 transition-transform ${isExpanded ? 'rotate-90' : ''}`}
|
|
/>
|
|
</button>
|
|
|
|
{/* Content */}
|
|
<div className="flex-1 min-w-0">
|
|
<div className="flex items-center gap-2 mb-1 flex-wrap">
|
|
<h3 className="font-semibold text-slate-900">{item.title}</h3>
|
|
<span
|
|
className={`px-2 py-0.5 rounded text-xs font-medium ${
|
|
priorityLabels[item.priority].color
|
|
}`}
|
|
>
|
|
{priorityLabels[item.priority].label}
|
|
</span>
|
|
</div>
|
|
<p className="text-sm text-slate-500 mb-2">{item.description}</p>
|
|
{item.notes && (
|
|
<p className="text-xs text-slate-400 mb-2 italic">{item.notes}</p>
|
|
)}
|
|
<div className="flex items-center gap-3 text-xs">
|
|
<span className={`px-2 py-1 rounded border ${category?.bgColor}`}>
|
|
{category?.name}
|
|
</span>
|
|
{totalSubtasks > 0 && (
|
|
<span className="text-slate-500">
|
|
{completedSubtasks}/{totalSubtasks} Teilaufgaben
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Status */}
|
|
<select
|
|
value={item.status}
|
|
onChange={(e) => {
|
|
e.stopPropagation()
|
|
updateItemStatus(item.id, e.target.value as BacklogItem['status'])
|
|
}}
|
|
onClick={(e) => e.stopPropagation()}
|
|
className={`px-3 py-1.5 rounded-lg text-sm font-medium border-0 cursor-pointer ${
|
|
statusLabels[item.status].color
|
|
}`}
|
|
>
|
|
{Object.entries(statusLabels).map(([value, { label }]) => (
|
|
<option key={value} value={value}>
|
|
{label}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
|
|
{/* Progress Bar */}
|
|
{totalSubtasks > 0 && (
|
|
<div className="mt-3 ml-8">
|
|
<div className="w-full bg-slate-200 rounded-full h-1.5">
|
|
<div
|
|
className="bg-green-500 h-1.5 rounded-full transition-all"
|
|
style={{ width: `${(completedSubtasks / totalSubtasks) * 100}%` }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Expanded Subtasks */}
|
|
{isExpanded && item.subtasks && item.subtasks.length > 0 && (
|
|
<div className="border-t border-slate-200 bg-slate-50 p-4 pl-12">
|
|
<h4 className="text-sm font-medium text-slate-700 mb-3">Teilaufgaben</h4>
|
|
<ul className="space-y-2">
|
|
{item.subtasks.map((subtask) => (
|
|
<li key={subtask.id} className="flex items-center gap-3">
|
|
<input
|
|
type="checkbox"
|
|
checked={subtask.completed}
|
|
onChange={() => toggleSubtask(item.id, subtask.id)}
|
|
className="w-4 h-4 rounded border-slate-300 text-blue-600 focus:ring-blue-500"
|
|
/>
|
|
<span
|
|
className={`text-sm ${
|
|
subtask.completed ? 'text-slate-400 line-through' : 'text-slate-700'
|
|
}`}
|
|
>
|
|
{subtask.title}
|
|
</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
|
|
{filteredItems.length === 0 && (
|
|
<div className="text-center py-12 text-slate-500">
|
|
Keine Aufgaben gefunden. Versuche einen anderen Filter.
|
|
</div>
|
|
)}
|
|
|
|
{/* Info Box */}
|
|
<div className="bg-amber-50 border border-amber-200 rounded-xl p-6">
|
|
<div className="flex items-start gap-4">
|
|
<AlertTriangle className="w-6 h-6 text-amber-600 flex-shrink-0 mt-0.5" />
|
|
<div>
|
|
<h3 className="font-semibold text-amber-900">Wichtiger Hinweis</h3>
|
|
<p className="text-sm text-amber-800 mt-1">
|
|
Diese Backlog-Liste muss vollstaendig abgearbeitet sein, bevor BreakPilot in den
|
|
Produktivbetrieb gehen kann. Alle kritischen Items muessen abgeschlossen sein. Der
|
|
Fortschritt wird lokal im Browser gespeichert und kann mit "Zuruecksetzen"
|
|
auf die Standardwerte zurueckgesetzt werden.
|
|
</p>
|
|
<p className="text-xs text-amber-700 mt-2">
|
|
Letzte Aktualisierung: 2026-02-03
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|