'use client' import { useState, useEffect } from 'react' import { GitBranch, Terminal, Server, Database, CheckCircle2, ArrowRight, Laptop, HardDrive, RefreshCw, Clock, Shield, Users, FileCode, Play, Eye, Download, AlertTriangle, Info, Container } from 'lucide-react' interface WorkflowStep { id: number title: string description: string command?: string icon: React.ReactNode location: 'macbook' | 'macmini' } interface BackupInfo { lastRun: string | null nextRun: string status: 'ok' | 'warning' | 'error' } export default function WorkflowPage() { const [activeStep, setActiveStep] = useState(1) const [backupInfo, setBackupInfo] = useState({ lastRun: null, nextRun: '02:00 Uhr', status: 'ok' }) const workflowSteps: WorkflowStep[] = [ { id: 1, title: 'Code bearbeiten', description: 'Arbeite mit Claude Code im Terminal. Beschreibe was du brauchst und Claude schreibt den Code.', command: 'claude', icon: , location: 'macbook' }, { id: 2, title: 'Änderungen stagen', description: 'Füge die geänderten Dateien zum nächsten Commit hinzu.', command: 'git add ', icon: , location: 'macbook' }, { id: 3, title: 'Commit erstellen', description: 'Erstelle einen Commit mit einer aussagekräftigen Nachricht.', command: 'git commit -m "feat: neue Funktion"', icon: , location: 'macbook' }, { id: 4, title: 'Push zum Server', description: 'Sende die Änderungen an den Mac Mini. Dies startet automatisch die CI/CD Pipeline.', command: 'git push origin main', icon: , location: 'macbook' }, { id: 5, title: 'CI/CD Pipeline', description: 'Woodpecker führt automatisch Tests aus und baut die Container.', command: '(automatisch)', icon: , location: 'macmini' }, { id: 6, title: 'Integration Tests', description: 'Docker Compose Test-Umgebung mit Backend, DB und Consent-Service fuer vollstaendige E2E-Tests.', command: 'docker compose -f docker-compose.test.yml up -d', icon: , location: 'macmini' }, { id: 7, title: 'Frontend testen', description: 'Teste die Änderungen im Browser auf dem Mac Mini.', command: 'http://macmini:3000', icon: , location: 'macbook' } ] const services = [ { name: 'Website', url: 'http://macmini:3000', port: 3000, status: 'running' }, { name: 'Admin v2', url: 'http://macmini:3002', port: 3002, status: 'running' }, { name: 'Studio v2', url: 'http://macmini:3001', port: 3001, status: 'running' }, { name: 'Backend', url: 'http://macmini:8000', port: 8000, status: 'running' }, { name: 'Gitea', url: 'http://macmini:3003', port: 3003, status: 'running' }, { name: 'Klausur-Service', url: 'http://macmini:8086', port: 8086, status: 'running' }, ] const commitTypes = [ { type: 'feat:', description: 'Neue Funktion', example: 'feat: add user login' }, { type: 'fix:', description: 'Bugfix', example: 'fix: resolve login timeout' }, { type: 'docs:', description: 'Dokumentation', example: 'docs: update API docs' }, { type: 'style:', description: 'Formatierung', example: 'style: fix indentation' }, { type: 'refactor:', description: 'Code-Umbau', example: 'refactor: extract helper' }, { type: 'test:', description: 'Tests', example: 'test: add unit tests' }, { type: 'chore:', description: 'Wartung', example: 'chore: update deps' }, ] return (
{/* Header */}

Entwicklungs-Workflow

Wie wir bei BreakPilot entwickeln - von der Idee bis zum Deployment

{/* Architecture Overview */}

Systemarchitektur

{/* MacBook */}

MacBook (Entwicklung)

Dein Arbeitsplatz

  • Terminal + Claude Code
  • Lokales Git Repository
  • Browser für Frontend-Tests
  • Backup manuell (MacBook nachts aus)
{/* Mac Mini */}

Mac Mini (Server)

192.168.178.100

  • Gitea (Git Server)
  • Woodpecker (CI/CD)
  • Docker Container (alle Services)
  • PostgreSQL Datenbank
  • Automatisches Backup (02:00 Uhr lokal)
{/* Workflow Steps */}

Entwicklungs-Schritte

{workflowSteps.map((step, index) => (
setActiveStep(step.id)} > {/* Step Number */}
{step.id}
{/* Content */}

{step.title}

{step.location === 'macbook' ? 'MacBook' : 'Mac Mini'}

{step.description}

{step.command && ( {step.command} )}
{/* Icon */}
{step.icon}
{/* Connector Line */} {index < workflowSteps.length - 1 && (
)}
))}
{/* Services & URLs */}

Services & URLs zum Testen

{services.map((service) => (

{service.name}

Port {service.port}

))}
{/* Commit Convention */}

Commit-Konventionen

{commitTypes.map((item) => (
{item.type}

{item.description}

{item.example}

))}
{/* Backup Info */}

Backup & Sicherheit

{/* Mac Mini - Automatisches lokales Backup */}

Mac Mini (Auto)

  • • Automatisch um 02:00 Uhr
  • • PostgreSQL-Dump lokal
  • • Git Repository gesichert
  • • 7 Tage Aufbewahrung
~/Projekte/backup-logs/
{/* MacBook - Manuelles Backup */}

MacBook (Manuell)

  • • MacBook nachts aus (02:00)
  • • Keine Auto-Synchronisation
  • • Backup manuell anstoßen
rsync -avz macmini:~/Projekte/ ~/Projekte/
{/* Manuelles Backup starten */}

Backup Script

Backup jederzeit manuell starten:

~/Projekte/breakpilot-pwa/scripts/daily-backup.sh
{/* Quick Commands */}

Wichtige Befehle

# CI/CD Logs ansehen

ssh macmini "docker logs breakpilot-pwa-backend --tail 50"

# Container neu starten

ssh macmini "docker compose restart backend"

# Alle Container Status

ssh macmini "docker ps"

# Pipeline Status (Gitea)

open http://macmini:3003
{/* Team Workflow with Feature Branches */}

Team-Workflow (3+ Entwickler)

Feature Branch Workflow

main feature/neue-funktion Entwicklung Pull Request Code Review main

1. Feature Branch erstellen

git checkout -b feature/mein-feature

2. Änderungen committen

git commit -m "feat: beschreibung"

3. Branch pushen

git push -u origin feature/mein-feature

4. Pull Request in Gitea

http://macmini:3003 → Pull Request

Branch-Namenskonvention

feature/ Neue Funktion
fix/ Bugfix
hotfix/ Dringender Fix
refactor/ Code-Umbau
{/* Team Rules */}

Team-Regeln

Feature Branches nutzen

Nie direkt auf main pushen - immer über Pull Request

Code Review erforderlich

Mindestens 1 Approval vor dem Merge

Tests müssen grün sein

CI/CD Pipeline muss erfolgreich durchlaufen

Aussagekräftige Commits

Nutze Conventional Commits (feat:, fix:, etc.)

Branch aktuell halten

Regelmäßig main in deinen Branch mergen

Nie Force-Push auf main

Geschichte von main nie überschreiben

{/* CI/CD Infrastruktur - Automatisierte OAuth Integration */}

CI/CD Infrastruktur (Automatisiert)

Warum automatisiert?

Die OAuth-Integration zwischen Woodpecker und Gitea ist vollautomatisiert. Dies ist eine DevSecOps Best Practice: Credentials werden in HashiCorp Vault gespeichert und können bei Bedarf automatisch regeneriert werden.

{/* Architektur */}

Architektur

Gitea Port 3003 Git Server
OAuth 2.0
Woodpecker Port 8090 CI/CD Server
Credentials
Vault Port 8200 Secrets Manager
{/* Credentials Speicherort */}

Credentials Speicherorte

HashiCorp Vault
secret/cicd/woodpecker

Client ID + Secret (Quelle der Wahrheit)

.env Datei
WOODPECKER_GITEA_CLIENT/SECRET

Für Docker Compose (aus Vault geladen)

Gitea PostgreSQL
oauth2_application

OAuth App Registration (gehashtes Secret)

{/* Troubleshooting */}

Troubleshooting: OAuth Fehler beheben

Falls der Fehler "Client ID not registered" oder "user does not exist" auftritt:

# Credentials automatisch regenerieren

./scripts/sync-woodpecker-credentials.sh --regenerate

# Oder manuell: Vault → Gitea → .env → Restart

rsync .env macmini:~/Projekte/breakpilot-pwa/

ssh macmini "cd ~/Projekte/breakpilot-pwa && docker compose up -d --force-recreate woodpecker-server"

{/* Team Members Info */}

Team-Kommunikation

💬

Pull Request Kommentare

Code-Diskussionen im PR

📋

Issues in Gitea

Bugs & Features tracken

🔔

CI/CD Notifications

Pipeline-Status per Mail

) }