feat: BreakPilot PWA - Full codebase (clean push without large binaries)
Some checks failed
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
ci/woodpecker/manual/build-ci-image Pipeline was successful
ci/woodpecker/manual/main Pipeline failed
Some checks failed
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
ci/woodpecker/manual/build-ci-image Pipeline was successful
ci/woodpecker/manual/main Pipeline failed
All services: admin-v2, studio-v2, website, ai-compliance-sdk, consent-service, klausur-service, voice-service, and infrastructure. Large PDFs and compiled binaries excluded via .gitignore.
This commit is contained in:
425
.claude/CLAUDE.md
Normal file
425
.claude/CLAUDE.md
Normal file
@@ -0,0 +1,425 @@
|
||||
# BreakPilot PWA - Projekt-Kontext für Claude
|
||||
|
||||
## Entwicklungsumgebung (WICHTIG - IMMER ZUERST LESEN)
|
||||
|
||||
### Zwei-Rechner-Setup
|
||||
|
||||
| Gerät | Rolle | Aufgaben |
|
||||
|-------|-------|----------|
|
||||
| **MacBook** | Client | Claude Terminal, Browser (Frontend-Tests) |
|
||||
| **Mac Mini** | Server | Docker, alle Services, Code-Ausführung, Tests, Git |
|
||||
|
||||
**WICHTIG:** Die Entwicklung findet vollständig auf dem **Mac Mini** statt!
|
||||
- Alle Befehle (docker, git, tests, builds) per SSH auf dem Mac Mini ausführen
|
||||
- Das MacBook dient nur als Terminal und Browser für Frontend-Tests
|
||||
- Dateien werden auf dem Mac Mini bearbeitet, nicht lokal auf dem MacBook
|
||||
|
||||
### SSH-Verbindung
|
||||
|
||||
```bash
|
||||
# Verbindung zum Mac Mini im lokalen Netzwerk
|
||||
ssh macmini
|
||||
|
||||
# Projektverzeichnis auf Mac Mini
|
||||
cd /Users/benjaminadmin/Projekte/breakpilot-pwa
|
||||
|
||||
# Oder direkt (BEVORZUGT für einzelne Befehle):
|
||||
ssh macmini "<befehl>"
|
||||
```
|
||||
|
||||
**Hostname:** `macmini` (im lokalen Netzwerk via Bonjour)
|
||||
**User:** `benjaminadmin`
|
||||
**Projekt:** `/Users/benjaminadmin/Projekte/breakpilot-pwa`
|
||||
|
||||
### Beispiele für korrekte Befehlsausführung
|
||||
|
||||
```bash
|
||||
# ✅ RICHTIG: Befehle auf Mac Mini ausführen
|
||||
ssh macmini "docker compose ps"
|
||||
ssh macmini "cd /Users/benjaminadmin/Projekte/breakpilot-pwa && git status"
|
||||
ssh macmini "cd /Users/benjaminadmin/Projekte/breakpilot-pwa/backend && source venv/bin/activate && pytest -v"
|
||||
|
||||
# ❌ FALSCH: Lokale Befehle auf MacBook (Docker/Services laufen dort nicht!)
|
||||
docker compose ps
|
||||
pytest -v
|
||||
```
|
||||
|
||||
### Browser-Tests (auf MacBook)
|
||||
|
||||
Frontend im Browser testen via:
|
||||
- https://macmini/ (Studio)
|
||||
- https://macmini:3002/ (Admin)
|
||||
- https://macmini:3000/ (Website)
|
||||
|
||||
---
|
||||
## Kernprinzipien (IMMER BEACHTEN)
|
||||
|
||||
### 1. Open Source Policy
|
||||
- **NUR Open Source mit kommerziell nutzbarer Lizenz verwenden**
|
||||
- Erlaubte Lizenzen: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, MPL-2.0, LGPL
|
||||
- **VERBOTEN:** GPL (außer LGPL), AGPL, proprietäre Software, "free for non-commercial use"
|
||||
- **Bei jeder neuen Dependency:** SBOM aktualisieren unter https://macmini:3002/infrastructure/sbom
|
||||
|
||||
### 2. Testing & Dokumentation
|
||||
- **Tests sind Pflicht:** Unit Tests, Integration Tests für jede Änderung
|
||||
- **Dokumentation aktualisieren:** https://macmini:3002/development/docs (MKDocs)
|
||||
- Siehe `@.claude/rules/testing.md` und `@.claude/rules/documentation.md`
|
||||
|
||||
### 3. Architektur & Visualisierung aktualisieren
|
||||
Nach größeren Änderungen diese Dashboards aktualisieren:
|
||||
- **Architektur:** https://macmini:3002/architecture
|
||||
- **Screenflows:** https://macmini:3002/development/screen-flow
|
||||
- **Dashboard:** https://macmini:3002/dashboard
|
||||
- **Security Tools:** https://macmini:3002/infrastructure/security
|
||||
|
||||
### 4. CI/CD Pipeline
|
||||
Alle Security-Tools müssen nach der Pipeline durchlaufen:
|
||||
- Trivy (Container-Scanning)
|
||||
- Semgrep (SAST)
|
||||
- Gitleaks (Secret-Detection)
|
||||
- SBOM-Generierung
|
||||
|
||||
---
|
||||
|
||||
## Projektübersicht
|
||||
|
||||
**Projektname:** BreakPilot PWA
|
||||
**Typ:** DSGVO-konforme EdTech-Plattform für den DACH-Raum
|
||||
**Architektur:** Microservices mit Docker Compose
|
||||
**Plattform:** Mac Mini M2 (Apple Silicon / ARM64)
|
||||
|
||||
---
|
||||
|
||||
## Haupt-URLs (HTTPS via Nginx)
|
||||
|
||||
| URL | Service | Beschreibung |
|
||||
|-----|---------|--------------|
|
||||
| https://macmini/ | Studio v2 | Lehrer-/Schüler-Interface |
|
||||
| https://macmini:3000/ | Website | Öffentliche Website |
|
||||
| https://macmini:3002/ | Admin v2 | **Admin-Dashboard (Hauptzugang)** |
|
||||
| https://macmini:8000/ | Backend API | FastAPI Backend |
|
||||
| https://macmini:8086/ | Klausur Service | Prüfungs-/Klausurservice |
|
||||
| https://macmini:8443/ | Jitsi Meet | Videokonferenzen |
|
||||
| wss://macmini:8091/ | Voice Service | Spracheingabe WebSocket |
|
||||
| https://macmini:3002/infrastructure/night-mode | Night Mode | Nachtabschaltung UI |
|
||||
|
||||
### AI Compliance SDK (DSGVO-Tools)
|
||||
|
||||
| URL | Modul | Beschreibung |
|
||||
|-----|-------|--------------|
|
||||
| https://macmini:3002/sdk | SDK Admin | Haupt-SDK mit allen Modulen |
|
||||
| https://macmini:3002/sdk/tom | TOM | Technisch-Organisatorische Maßnahmen |
|
||||
| https://macmini:3002/sdk/dsfa | DSFA | Datenschutz-Folgenabschätzung |
|
||||
| https://macmini:3002/sdk/vvt | VVT | Verzeichnis von Verarbeitungstätigkeiten |
|
||||
| https://macmini:3002/sdk/loeschfristen | Löschfristen | Löschfristen-Verwaltung |
|
||||
| https://macmini:3002/developers | Developer Portal | API-Dokumentation für Kunden |
|
||||
| https://macmini:8093/ | SDK API | Backend-API für SDK |
|
||||
|
||||
### Interne Dienste
|
||||
|
||||
| URL | Service |
|
||||
|-----|---------|
|
||||
| http://macmini:8200/ | Vault UI (Secrets) |
|
||||
| http://macmini:8025/ | Mailpit (E-Mail Dev) |
|
||||
| http://macmini:9001/ | MinIO Console (S3) |
|
||||
| http://macmini:3003/ | Gitea (Git-Server) |
|
||||
| http://macmini:8090/ | Woodpecker CI |
|
||||
| http://macmini:8089/ | Camunda (BPMN) |
|
||||
| http://macmini:8096/ | Night Scheduler API |
|
||||
| http://macmini:8009/ | MkDocs (Projekt-Doku) |
|
||||
|
||||
### AI Tools (Admin v2)
|
||||
|
||||
| URL | Tool | Beschreibung |
|
||||
|-----|------|--------------|
|
||||
| https://macmini:3002/ai/llm-compare | LLM Vergleich | KI-Provider vergleichen |
|
||||
| https://macmini:3002/ai/ocr-compare | OCR Vergleich | OCR-Methoden & Vokabel-Extraktion |
|
||||
| https://macmini:3002/ai/ocr-labeling | OCR Labeling | Trainingsdaten erstellen |
|
||||
| https://macmini:3002/ai/test-quality | Test Quality (BQAS) | Golden Suite & Tests |
|
||||
| https://macmini:3002/ai/gpu | GPU Infrastruktur | vast.ai Management |
|
||||
| https://macmini:3002/ai/rag-pipeline | RAG Pipeline | Retrieval Augmented Generation |
|
||||
| https://macmini:3002/ai/magic-help | Magic Help | KI-Assistent |
|
||||
|
||||
### Lehrer-Tools (Studio v2)
|
||||
|
||||
| URL | Tool | Beschreibung |
|
||||
|-----|------|--------------|
|
||||
| https://macmini/vocab-worksheet | Vokabel-Arbeitsblatt | OCR-Scan & Arbeitsblatt-Generator |
|
||||
| https://macmini/korrektur | Korrekturplattform | Abiturklausur-Korrektur |
|
||||
| https://macmini:8000/app | Dashboard (alt) | Altes Dashboard |
|
||||
|
||||
---
|
||||
|
||||
## Services (49 Container)
|
||||
|
||||
### Kern-Applikationen
|
||||
|
||||
| Service | Tech | Port | Beschreibung |
|
||||
|---------|------|------|--------------|
|
||||
| `studio-v2` | Next.js | 443 | Lehrer-/Schüler-Studio |
|
||||
| `admin-v2` | Next.js | 3002 | Admin-Dashboard |
|
||||
| `website` | Next.js | 3000 | Öffentliche Website |
|
||||
| `backend` | Python/FastAPI | 8000 | API Backend |
|
||||
| `consent-service` | Go/Gin | 8081 | Consent-Management |
|
||||
|
||||
### Bildungs-Services
|
||||
|
||||
| Service | Tech | Port | Beschreibung |
|
||||
|---------|------|------|--------------|
|
||||
| `klausur-service` | Python/FastAPI | 8086 | Prüfungen, OCR, RAG |
|
||||
| `school-service` | Python | 8082 | Schulverwaltung |
|
||||
| `edu-search-service` | Python | 8088 | Bildungssuche |
|
||||
| `breakpilot-drive` | Node.js | 8087 | Dateiablage (IPFS) |
|
||||
| `geo-service` | Python | 8084 | Geo-Daten (PostGIS) |
|
||||
| `voice-service` | Python | 8091 | Spracheingabe |
|
||||
|
||||
### KI & Compliance
|
||||
|
||||
| Service | Tech | Port | Beschreibung |
|
||||
|---------|------|------|--------------|
|
||||
| `ai-compliance-sdk` | Python | 8093 | DSGVO-konforme KI-Nutzung |
|
||||
| `embedding-service` | Python | 8083 | Text-Embeddings |
|
||||
| `paddleocr-service` | Python | - | OCR für Dokumente |
|
||||
| `transcription-worker` | Python | - | Audio-Transkription |
|
||||
|
||||
### Kommunikation
|
||||
|
||||
| Service | Tech | Port | Beschreibung |
|
||||
|---------|------|------|--------------|
|
||||
| `jitsi-web` | Jitsi | 8443 | Videokonferenzen |
|
||||
| `jitsi-xmpp` | Prosody | - | XMPP Server |
|
||||
| `jitsi-jicofo` | Jicofo | - | Konferenz-Fokus |
|
||||
| `jitsi-jvb` | JVB | 8080 | Video Bridge |
|
||||
| `jibri` | Jibri | - | Aufnahme/Streaming |
|
||||
| `synapse` | Matrix | 8008 | Chat-Server |
|
||||
|
||||
### Datenbanken & Storage
|
||||
|
||||
| Service | Tech | Port | Beschreibung |
|
||||
|---------|------|------|--------------|
|
||||
| `postgres` | PostGIS 16 | 5432 | Hauptdatenbank |
|
||||
| `valkey` | Valkey 8 | 6379 | Session-Cache (Redis-Fork) |
|
||||
| `qdrant` | Qdrant | 6333/6334 | Vektordatenbank |
|
||||
| `minio` | MinIO | 9000/9001 | S3-kompatibler Storage |
|
||||
|
||||
### Infrastructure & DevOps
|
||||
|
||||
| Service | Tech | Port | Beschreibung |
|
||||
|---------|------|------|--------------|
|
||||
| `nginx` | Nginx | 80/443 | Reverse Proxy + TLS |
|
||||
| `vault` | HashiCorp Vault | 8200 | Secrets Management |
|
||||
| `vault-agent` | Vault | - | Zertifikatserneuerung |
|
||||
| `gitea` | Gitea | 3003 | Git-Server |
|
||||
| `woodpecker-server` | Woodpecker | 8090 | CI/CD Server |
|
||||
| `woodpecker-agent` | Woodpecker | - | CI/CD Agent |
|
||||
| `night-scheduler` | Python/FastAPI | 8096 | Auto-Shutdown/Startup |
|
||||
| `mailpit` | Mailpit | 8025/1025 | E-Mail (Dev) |
|
||||
|
||||
### ERP & Billing
|
||||
|
||||
| Service | Tech | Port | Beschreibung |
|
||||
|---------|------|------|--------------|
|
||||
| `erpnext-frontend` | ERPNext | 8009 | ERP Frontend |
|
||||
| `erpnext-backend` | ERPNext | - | ERP Backend |
|
||||
| `erpnext-db` | MariaDB | - | ERP Datenbank |
|
||||
| `billing-service` | Python | - | Abrechnungsservice |
|
||||
|
||||
### DSMS (Data Sharing)
|
||||
|
||||
| Service | Tech | Port | Beschreibung |
|
||||
|---------|------|------|--------------|
|
||||
| `dsms-node` | Node.js | 4001/5001 | IPFS Node |
|
||||
| `dsms-gateway` | Node.js | 8085 | IPFS Gateway |
|
||||
|
||||
### Prozesse
|
||||
|
||||
| Service | Tech | Port | Beschreibung |
|
||||
|---------|------|------|--------------|
|
||||
| `camunda` | Camunda | 8089 | BPMN Engine |
|
||||
|
||||
---
|
||||
|
||||
## Tech-Stack nach Sprache
|
||||
|
||||
### Go
|
||||
- `consent-service`: Gin, GORM, JWT
|
||||
|
||||
### Python
|
||||
- `backend`: FastAPI, SQLAlchemy, Pydantic
|
||||
- `klausur-service`: FastAPI, PaddleOCR, RAG
|
||||
- `ai-compliance-sdk`: FastAPI, Langfuse
|
||||
- `embedding-service`: FastAPI, Sentence-Transformers
|
||||
- `voice-service`: FastAPI, Whisper
|
||||
- `geo-service`: FastAPI, PostGIS
|
||||
- `school-service`: FastAPI
|
||||
- `night-scheduler`: FastAPI
|
||||
|
||||
### TypeScript/Next.js
|
||||
- `studio-v2`: Next.js 15, React, TailwindCSS
|
||||
- `admin-v2`: Next.js 15, React, TailwindCSS
|
||||
- `website`: Next.js 14
|
||||
|
||||
### Node.js
|
||||
- `breakpilot-drive`: Express, IPFS
|
||||
- `dsms-node`: IPFS
|
||||
- `dsms-gateway`: Express
|
||||
|
||||
---
|
||||
|
||||
## Verzeichnisstruktur
|
||||
|
||||
```
|
||||
breakpilot-pwa/
|
||||
├── .claude/ # Claude-Konfiguration
|
||||
│ ├── CLAUDE.md # Diese Datei
|
||||
│ ├── rules/ # Automatische Regeln
|
||||
│ │ ├── testing.md
|
||||
│ │ ├── documentation.md
|
||||
│ │ ├── night-scheduler.md
|
||||
│ │ ├── open-source-policy.md
|
||||
│ │ ├── compliance-checklist.md
|
||||
│ │ ├── abiturkorrektur.md
|
||||
│ │ ├── vocab-worksheet.md
|
||||
│ │ ├── multi-agent-architecture.md
|
||||
│ │ └── experimental-dashboard.md
|
||||
│ └── settings.json
|
||||
├── admin-v2/ # Admin Dashboard (Next.js)
|
||||
├── studio-v2/ # Lehrer-/Schüler-Studio (Next.js)
|
||||
├── website/ # Öffentliche Website (Next.js)
|
||||
├── backend/ # Python Backend (FastAPI)
|
||||
├── consent-service/ # Go Consent Service
|
||||
├── klausur-service/ # Klausur/OCR Service
|
||||
├── ai-compliance-sdk/ # KI-Compliance SDK
|
||||
├── voice-service/ # Spracheingabe
|
||||
├── geo-service/ # Geo-Daten
|
||||
├── school-service/ # Schulverwaltung
|
||||
├── edu-search-service/ # Bildungssuche
|
||||
├── breakpilot-drive/ # Dateiablage
|
||||
├── night-scheduler/ # Auto-Shutdown
|
||||
├── nginx/ # Reverse Proxy Config
|
||||
├── vault/ # Vault Config
|
||||
├── docs-src/ # MKDocs Quellen
|
||||
├── docs-site/ # MKDocs Build
|
||||
├── docker-compose.yml # Haupt-Docker-Config
|
||||
└── mkdocs.yml # MKDocs Config
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dokumentation (MKDocs)
|
||||
|
||||
**Live-URL:** https://macmini:3002/development/docs
|
||||
**Quellen:** `/docs-src/`
|
||||
**Build:** `/docs-site/`
|
||||
**Config:** `mkdocs.yml`
|
||||
|
||||
### Dokumentation bearbeiten
|
||||
|
||||
```bash
|
||||
# MKDocs lokal starten (Live-Reload)
|
||||
cd /Users/benjaminadmin/Projekte/breakpilot-pwa
|
||||
mkdocs serve -a 0.0.0.0:8008
|
||||
|
||||
# Build
|
||||
mkdocs build
|
||||
```
|
||||
|
||||
### Struktur
|
||||
|
||||
- `docs-src/index.md` - Startseite
|
||||
- `docs-src/architecture/` - Architektur-Docs
|
||||
- `docs-src/services/` - Service-Dokumentation
|
||||
- `docs-src/api/` - API-Dokumentation
|
||||
- `docs-src/development/` - Entwickler-Guides
|
||||
|
||||
---
|
||||
|
||||
## Häufige Befehle
|
||||
|
||||
### Docker (via SSH auf Mac Mini)
|
||||
|
||||
```bash
|
||||
# Alle Services starten
|
||||
ssh macmini "/usr/local/bin/docker compose -f /Users/benjaminadmin/Projekte/breakpilot-pwa/docker-compose.yml up -d"
|
||||
|
||||
# Einzelnen Service neu bauen & starten
|
||||
ssh macmini "/usr/local/bin/docker compose -f /Users/benjaminadmin/Projekte/breakpilot-pwa/docker-compose.yml build --no-cache <service-name>"
|
||||
ssh macmini "/usr/local/bin/docker compose -f /Users/benjaminadmin/Projekte/breakpilot-pwa/docker-compose.yml up -d <service-name>"
|
||||
|
||||
# Logs anzeigen
|
||||
ssh macmini "/usr/local/bin/docker compose -f /Users/benjaminadmin/Projekte/breakpilot-pwa/docker-compose.yml logs -f <service-name>"
|
||||
|
||||
# Status aller Container
|
||||
ssh macmini "/usr/local/bin/docker compose -f /Users/benjaminadmin/Projekte/breakpilot-pwa/docker-compose.yml ps"
|
||||
```
|
||||
|
||||
**WICHTIG:** Docker-Pfad auf Mac Mini ist `/usr/local/bin/docker` (nicht im Standard-PATH bei SSH).
|
||||
|
||||
### Tests (via SSH)
|
||||
|
||||
```bash
|
||||
# Go Tests (Consent Service)
|
||||
ssh macmini "cd /Users/benjaminadmin/Projekte/breakpilot-pwa/consent-service && go test -v ./..."
|
||||
|
||||
# Python Tests
|
||||
ssh macmini "cd /Users/benjaminadmin/Projekte/breakpilot-pwa/backend && source venv/bin/activate && pytest -v"
|
||||
```
|
||||
|
||||
### Git
|
||||
|
||||
```bash
|
||||
# Remote ist localhost:3003 (Gitea laeuft als Container auf Mac Mini)
|
||||
# Vom MacBook aus: http://macmini:3003/pilotadmin/breakpilot-pwa.git
|
||||
# Vom Mac Mini aus: http://localhost:3003/pilotadmin/breakpilot-pwa.git
|
||||
|
||||
# Git-Befehle auf Mac Mini ausfuehren (ohne cd):
|
||||
ssh macmini "git -C /Users/benjaminadmin/Projekte/breakpilot-pwa status"
|
||||
ssh macmini "git -C /Users/benjaminadmin/Projekte/breakpilot-pwa pull --no-rebase origin main"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rollen & Berechtigungen
|
||||
|
||||
| Rolle | Beschreibung |
|
||||
|-------|--------------|
|
||||
| `user` | Normaler Benutzer (Schüler/Lehrer) |
|
||||
| `admin` | Administrator |
|
||||
| `data_protection_officer` | Datenschutzbeauftragter |
|
||||
| `school_admin` | Schuladministrator |
|
||||
|
||||
---
|
||||
|
||||
## Compliance & Sicherheit
|
||||
|
||||
### DSGVO
|
||||
- Consent-Management via `consent-service`
|
||||
- Datenexport-Funktionen
|
||||
- Löschkonzept implementiert
|
||||
|
||||
### AI Act
|
||||
- `ai-compliance-sdk` für konforme KI-Nutzung
|
||||
- Risikobewertung für KI-Funktionen
|
||||
- Audit-Logging
|
||||
|
||||
### BSI
|
||||
- BSI-TR-03161 Dokumentation vorhanden
|
||||
- Security-Scanning in CI/CD
|
||||
|
||||
---
|
||||
|
||||
## Sensitive Dateien
|
||||
|
||||
**NIEMALS ändern oder committen:**
|
||||
- `.env`, `.env.local`, `.env.backup`
|
||||
- `secrets/`
|
||||
- Vault-Tokens
|
||||
- SSL-Zertifikate
|
||||
|
||||
---
|
||||
|
||||
## Ansprechpartner
|
||||
|
||||
- **Git-Server:** http://macmini:3003 (Gitea)
|
||||
- **CI/CD:** http://macmini:8090 (Woodpecker)
|
||||
- **Issue-Tracker:** Gitea Issues
|
||||
263
.claude/plans/embedding-service-separation.md
Normal file
263
.claude/plans/embedding-service-separation.md
Normal file
@@ -0,0 +1,263 @@
|
||||
# Plan: Embedding-Service Separation
|
||||
|
||||
## Ziel
|
||||
Trennung der ML/Embedding-Komponenten vom klausur-service in einen eigenständigen `embedding-service`, um die Build-Zeit von ~20 Minuten auf ~30 Sekunden zu reduzieren.
|
||||
|
||||
## Aktuelle Situation
|
||||
|
||||
| Service | Build-Zeit | Image-Größe | Problem |
|
||||
|---------|------------|-------------|---------|
|
||||
| klausur-service | ~20 min | ~2.5 GB | PyTorch + sentence-transformers werden bei jedem Build installiert |
|
||||
|
||||
## Ziel-Architektur
|
||||
|
||||
```
|
||||
┌─────────────────┐ HTTP ┌──────────────────┐
|
||||
│ klausur-service │ ───────────→ │ embedding-service │
|
||||
│ (FastAPI) │ │ (FastAPI) │
|
||||
│ Port 8086 │ │ Port 8087 │
|
||||
│ ~200 MB │ │ ~2.5 GB │
|
||||
│ Build: 30s │ │ Build: 15 min │
|
||||
└─────────────────┘ └──────────────────┘
|
||||
│ │
|
||||
└────────────┬───────────────────┘
|
||||
▼
|
||||
┌───────────────┐
|
||||
│ Qdrant │
|
||||
│ Port 6333 │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
## Phase 1: Neuen Embedding-Service erstellen
|
||||
|
||||
### 1.1 Verzeichnisstruktur anlegen
|
||||
```
|
||||
klausur-service/
|
||||
├── embedding-service/ # NEU
|
||||
│ ├── Dockerfile
|
||||
│ ├── requirements.txt
|
||||
│ ├── main.py # FastAPI App
|
||||
│ ├── eh_pipeline.py # Kopie
|
||||
│ ├── reranker.py # Kopie
|
||||
│ ├── hyde.py # Kopie
|
||||
│ ├── hybrid_search.py # Kopie
|
||||
│ ├── pdf_extraction.py # Kopie
|
||||
│ └── config.py # Embedding-Konfiguration
|
||||
├── backend/ # Bestehend (wird angepasst)
|
||||
└── frontend/ # Bestehend
|
||||
```
|
||||
|
||||
### 1.2 Dateien in embedding-service erstellen
|
||||
|
||||
**requirements.txt** (ML-spezifisch):
|
||||
```
|
||||
fastapi>=0.109.0
|
||||
uvicorn[standard]>=0.27.0
|
||||
torch>=2.0.0
|
||||
sentence-transformers>=2.2.0
|
||||
qdrant-client>=1.7.0
|
||||
unstructured>=0.12.0
|
||||
pypdf>=4.0.0
|
||||
httpx>=0.26.0
|
||||
pydantic>=2.0.0
|
||||
python-dotenv>=1.0.0
|
||||
```
|
||||
|
||||
**main.py** - API-Endpoints:
|
||||
- `POST /embed` - Generiert Embeddings für Text/Liste von Texten
|
||||
- `POST /embed-single` - Einzelnes Embedding
|
||||
- `POST /rerank` - Re-Ranking von Suchergebnissen
|
||||
- `POST /extract-pdf` - PDF-Text-Extraktion
|
||||
- `GET /health` - Health-Check
|
||||
- `GET /models` - Verfügbare Modelle
|
||||
|
||||
### 1.3 Dockerfile (embedding-service)
|
||||
```dockerfile
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# PyTorch CPU-only für kleinere Images
|
||||
RUN pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cpu
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Modelle vorab laden (Layer-Cache)
|
||||
RUN python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('BAAI/bge-m3')"
|
||||
RUN python -c "from sentence_transformers import CrossEncoder; CrossEncoder('BAAI/bge-reranker-v2-m3')"
|
||||
|
||||
COPY . .
|
||||
|
||||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8087"]
|
||||
```
|
||||
|
||||
## Phase 2: Klausur-Service anpassen
|
||||
|
||||
### 2.1 ML-Dependencies aus requirements.txt entfernen
|
||||
Entfernen:
|
||||
- `torch`
|
||||
- `sentence-transformers`
|
||||
- `unstructured`
|
||||
- `pypdf`
|
||||
|
||||
Behalten:
|
||||
- `fastapi`, `uvicorn`, `httpx`
|
||||
- `qdrant-client` (für Suche)
|
||||
- `cryptography` (BYOEH)
|
||||
- Alle Business-Logic-Dependencies
|
||||
|
||||
### 2.2 Embedding-Client erstellen
|
||||
Neue Datei `backend/embedding_client.py`:
|
||||
```python
|
||||
class EmbeddingClient:
|
||||
def __init__(self, base_url: str = "http://embedding-service:8087"):
|
||||
self.base_url = base_url
|
||||
|
||||
async def generate_embeddings(self, texts: list[str]) -> list[list[float]]:
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.post(f"{self.base_url}/embed", json={"texts": texts})
|
||||
return response.json()["embeddings"]
|
||||
|
||||
async def rerank(self, query: str, documents: list[str]) -> list[dict]:
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.post(f"{self.base_url}/rerank",
|
||||
json={"query": query, "documents": documents})
|
||||
return response.json()["results"]
|
||||
```
|
||||
|
||||
### 2.3 Bestehende Aufrufe umleiten
|
||||
Dateien anpassen:
|
||||
- `backend/main.py`: `generate_single_embedding()` → `embedding_client.generate_embeddings()`
|
||||
- `backend/admin_api.py`: Embedding-Aufrufe über Client
|
||||
- `backend/qdrant_service.py`: Bleibt für Suche, Indexierung nutzt Client
|
||||
|
||||
## Phase 3: Docker-Compose Integration
|
||||
|
||||
### 3.1 docker-compose.dev.yml erweitern
|
||||
```yaml
|
||||
services:
|
||||
klausur-service:
|
||||
build:
|
||||
context: ./klausur-service
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "8086:8086"
|
||||
environment:
|
||||
- EMBEDDING_SERVICE_URL=http://embedding-service:8087
|
||||
depends_on:
|
||||
- embedding-service
|
||||
- qdrant
|
||||
|
||||
embedding-service:
|
||||
build:
|
||||
context: ./klausur-service/embedding-service
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "8087:8087"
|
||||
environment:
|
||||
- EMBEDDING_BACKEND=local
|
||||
- LOCAL_EMBEDDING_MODEL=BAAI/bge-m3
|
||||
- LOCAL_RERANKER_MODEL=BAAI/bge-reranker-v2-m3
|
||||
volumes:
|
||||
- embedding-models:/root/.cache/huggingface # Model-Cache
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 4G
|
||||
|
||||
qdrant:
|
||||
image: qdrant/qdrant:latest
|
||||
ports:
|
||||
- "6333:6333"
|
||||
volumes:
|
||||
- qdrant-data:/qdrant/storage
|
||||
|
||||
volumes:
|
||||
embedding-models:
|
||||
qdrant-data:
|
||||
```
|
||||
|
||||
## Phase 4: Tests und Validierung
|
||||
|
||||
### 4.1 Unit Tests für Embedding-Service
|
||||
- Test Embedding-Generierung
|
||||
- Test Re-Ranking
|
||||
- Test PDF-Extraktion
|
||||
- Test Health-Endpoint
|
||||
|
||||
### 4.2 Integration Tests
|
||||
- Test klausur-service → embedding-service Kommunikation
|
||||
- Test RAG-Query End-to-End
|
||||
- Test EH-Upload mit Embedding
|
||||
|
||||
### 4.3 Performance-Validierung
|
||||
- Build-Zeit klausur-service messen (Ziel: <1 min)
|
||||
- Embedding-Latenz messen (Ziel: <500ms für einzelnes Embedding)
|
||||
- Re-Ranking-Latenz messen (Ziel: <1s für 10 Dokumente)
|
||||
|
||||
## Implementierungsreihenfolge
|
||||
|
||||
1. **embedding-service/main.py** - FastAPI App mit Endpoints
|
||||
2. **embedding-service/config.py** - Konfiguration
|
||||
3. **embedding-service/requirements.txt** - Dependencies
|
||||
4. **embedding-service/Dockerfile** - Container-Build
|
||||
5. **backend/embedding_client.py** - HTTP-Client
|
||||
6. **backend/requirements.txt** - ML-Deps entfernen
|
||||
7. **backend/main.py** - Aufrufe umleiten
|
||||
8. **backend/admin_api.py** - Aufrufe umleiten
|
||||
9. **docker-compose.dev.yml** - Service hinzufügen
|
||||
10. **Tests** - Validierung
|
||||
|
||||
## Zu bewegende Dateien (Referenz)
|
||||
|
||||
| Datei | Zeilen | Aktion |
|
||||
|-------|--------|--------|
|
||||
| eh_pipeline.py | 777 | Kopieren → embedding-service |
|
||||
| reranker.py | 253 | Kopieren → embedding-service |
|
||||
| hyde.py | 209 | Kopieren → embedding-service |
|
||||
| hybrid_search.py | 285 | Kopieren → embedding-service |
|
||||
| pdf_extraction.py | 479 | Kopieren → embedding-service |
|
||||
|
||||
## Umgebungsvariablen
|
||||
|
||||
### embedding-service
|
||||
```
|
||||
EMBEDDING_BACKEND=local
|
||||
LOCAL_EMBEDDING_MODEL=BAAI/bge-m3
|
||||
LOCAL_RERANKER_MODEL=BAAI/bge-reranker-v2-m3
|
||||
OPENAI_API_KEY= # Optional für OpenAI-Backend
|
||||
PDF_EXTRACTION_BACKEND=auto
|
||||
LOG_LEVEL=INFO
|
||||
```
|
||||
|
||||
### klausur-service (neu)
|
||||
```
|
||||
EMBEDDING_SERVICE_URL=http://embedding-service:8087
|
||||
```
|
||||
|
||||
## Risiken und Mitigationen
|
||||
|
||||
| Risiko | Mitigation |
|
||||
|--------|------------|
|
||||
| Netzwerk-Latenz zwischen Services | Model-Caching, Connection-Pooling |
|
||||
| embedding-service nicht erreichbar | Health-Checks, Retry-Logik, Graceful Degradation |
|
||||
| Inkonsistente Embedding-Modelle | Versionierung, Model-Hash-Prüfung |
|
||||
| Erhöhter RAM-Bedarf (2 Container) | Memory-Limits in Docker, Model-Offloading |
|
||||
|
||||
## Erwartete Ergebnisse
|
||||
|
||||
| Metrik | Vorher | Nachher |
|
||||
|--------|--------|---------|
|
||||
| Build-Zeit klausur-service | ~20 min | ~30 sec |
|
||||
| Build-Zeit embedding-service | - | ~15 min |
|
||||
| Image-Größe klausur-service | ~2.5 GB | ~200 MB |
|
||||
| Image-Größe embedding-service | - | ~2.5 GB |
|
||||
| Entwickler-Iteration | Langsam | Schnell |
|
||||
|
||||
## Nicht vergessen (Task A)
|
||||
|
||||
Nach Abschluss der Service-Trennung:
|
||||
- [ ] EH-Upload-Wizard mit Test-Klausur testen
|
||||
- [ ] Security-Infobox im Wizard verifizieren
|
||||
- [ ] End-to-End RAG-Query testen
|
||||
614
.claude/rules/abiturkorrektur.md
Normal file
614
.claude/rules/abiturkorrektur.md
Normal file
@@ -0,0 +1,614 @@
|
||||
# Abiturkorrektur-System - Entwicklerdokumentation
|
||||
|
||||
**WICHTIG: Diese Datei wird bei jedem Compacting gelesen. Alle Implementierungsdetails hier dokumentieren!**
|
||||
|
||||
---
|
||||
|
||||
## 1. Projektziel
|
||||
|
||||
Entwicklung eines KI-gestützten Korrektur-Systems für Deutsch-Abiturklausuren:
|
||||
- **Zielgruppe**: Lehrer in Niedersachsen (Pilot), später alle Bundesländer
|
||||
- **Kernproblem**: Erstkorrektur dauert 6 Stunden pro Arbeit
|
||||
- **Lösung**: KI schlägt Bewertungen vor, Lehrer bestätigt/korrigiert
|
||||
|
||||
---
|
||||
|
||||
## 2. Architektur-Übersicht
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Frontend (Next.js) │
|
||||
│ /website/app/admin/klausur-korrektur/ │
|
||||
│ - page.tsx (Klausur-Liste) │
|
||||
│ - [klausurId]/page.tsx (Studenten-Liste) │
|
||||
│ - [klausurId]/[studentId]/page.tsx (Korrektur-Workspace) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ klausur-service (FastAPI) │
|
||||
│ Port 8086 - /klausur-service/backend/main.py │
|
||||
│ - Klausur CRUD (/api/v1/klausuren) │
|
||||
│ - Student Work (/api/v1/students) │
|
||||
│ - Annotations (/api/v1/annotations) [NEU] │
|
||||
│ - Gutachten Generation │
|
||||
│ - Fairness Analysis │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Infrastruktur │
|
||||
│ - Qdrant (Vektor-DB für RAG) │
|
||||
│ - MinIO (Datei-Storage) │
|
||||
│ - PostgreSQL (Metadaten) │
|
||||
│ - Embedding-Service (Port 8087) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Bestehende Backend-Komponenten (NUTZEN!)
|
||||
|
||||
### 3.1 Klausur-Service API (main.py)
|
||||
|
||||
```python
|
||||
# Bereits implementiert:
|
||||
GET/POST /api/v1/klausuren # Klausur CRUD
|
||||
GET /api/v1/klausuren/{id} # Klausur Details
|
||||
POST /api/v1/klausuren/{id}/students # Student Work hochladen
|
||||
GET /api/v1/klausuren/{id}/students # Studenten-Liste
|
||||
PUT /api/v1/students/{id}/criteria # Kriterien bewerten
|
||||
PUT /api/v1/students/{id}/gutachten # Gutachten speichern
|
||||
POST /api/v1/students/{id}/gutachten/generate # Gutachten generieren (KI)
|
||||
GET /api/v1/klausuren/{id}/fairness # Fairness-Analyse
|
||||
GET /api/v1/grade-info # Notensystem-Info
|
||||
```
|
||||
|
||||
### 3.2 Datenmodelle (main.py)
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class Klausur:
|
||||
id: str
|
||||
title: str
|
||||
subject: str = "Deutsch"
|
||||
year: int = 2025
|
||||
semester: str = "Abitur"
|
||||
modus: str = "abitur" # oder "vorabitur"
|
||||
eh_id: Optional[str] = None # Erwartungshorizont-Referenz
|
||||
|
||||
@dataclass
|
||||
class StudentKlausur:
|
||||
id: str
|
||||
klausur_id: str
|
||||
anonym_id: str
|
||||
file_path: str
|
||||
ocr_text: str = ""
|
||||
criteria_scores: Dict[str, int] = field(default_factory=dict)
|
||||
gutachten: str = ""
|
||||
status: str = "UPLOADED"
|
||||
raw_points: int = 0
|
||||
grade_points: int = 0
|
||||
|
||||
# Status-Workflow:
|
||||
# UPLOADED → OCR_PROCESSING → OCR_COMPLETE → ANALYZING →
|
||||
# FIRST_EXAMINER → SECOND_EXAMINER → COMPLETED
|
||||
```
|
||||
|
||||
### 3.3 Notensystem (15-Punkte)
|
||||
|
||||
```python
|
||||
GRADE_THRESHOLDS = {
|
||||
15: 95, 14: 90, 13: 85, 12: 80, 11: 75,
|
||||
10: 70, 9: 65, 8: 60, 7: 55, 6: 50,
|
||||
5: 45, 4: 40, 3: 33, 2: 27, 1: 20, 0: 0
|
||||
}
|
||||
|
||||
DEFAULT_CRITERIA = {
|
||||
"rechtschreibung": {"name": "Rechtschreibung", "weight": 15},
|
||||
"grammatik": {"name": "Grammatik", "weight": 15},
|
||||
"inhalt": {"name": "Inhalt", "weight": 40},
|
||||
"struktur": {"name": "Struktur", "weight": 15},
|
||||
"stil": {"name": "Stil", "weight": 15}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. NEU ZU IMPLEMENTIEREN
|
||||
|
||||
### Phase 1: Korrektur-Workspace MVP
|
||||
|
||||
#### 4.1 Frontend-Struktur
|
||||
|
||||
```
|
||||
/website/app/admin/klausur-korrektur/
|
||||
├── page.tsx # Klausur-Übersicht (Liste aller Klausuren)
|
||||
├── types.ts # TypeScript Interfaces
|
||||
├── [klausurId]/
|
||||
│ ├── page.tsx # Studenten-Liste einer Klausur
|
||||
│ └── [studentId]/
|
||||
│ └── page.tsx # Korrektur-Workspace (2/3-1/3)
|
||||
└── components/
|
||||
├── KlausurCard.tsx # Klausur in Liste
|
||||
├── StudentList.tsx # Studenten-Übersicht
|
||||
├── DocumentViewer.tsx # PDF/Bild-Anzeige (links, 2/3)
|
||||
├── AnnotationLayer.tsx # SVG-Overlay für Markierungen
|
||||
├── AnnotationToolbar.tsx # Werkzeuge
|
||||
├── CorrectionPanel.tsx # Bewertungs-Panel (rechts, 1/3)
|
||||
├── CriteriaScoreCard.tsx # Einzelnes Kriterium
|
||||
├── EHSuggestionPanel.tsx # EH-Vorschläge via RAG
|
||||
├── GutachtenEditor.tsx # Gutachten bearbeiten
|
||||
└── StudentNavigation.tsx # Prev/Next Navigation
|
||||
```
|
||||
|
||||
#### 4.2 Annotations-Backend (NEU in main.py)
|
||||
|
||||
```python
|
||||
# Neues Datenmodell:
|
||||
@dataclass
|
||||
class Annotation:
|
||||
id: str
|
||||
student_work_id: str
|
||||
page: int
|
||||
position: dict # {x, y, width, height} in % (0-100)
|
||||
type: str # 'rechtschreibung' | 'grammatik' | 'inhalt' | 'struktur' | 'stil' | 'comment'
|
||||
text: str # Kommentar-Text
|
||||
severity: str # 'minor' | 'major' | 'critical'
|
||||
suggestion: str # Korrekturvorschlag (bei RS/Gram)
|
||||
created_by: str # User-ID (EK oder ZK)
|
||||
created_at: datetime
|
||||
role: str # 'first_examiner' | 'second_examiner'
|
||||
linked_criterion: Optional[str] # Verknüpfung zu Kriterium
|
||||
|
||||
# Neue Endpoints:
|
||||
POST /api/v1/students/{id}/annotations # Erstellen
|
||||
GET /api/v1/students/{id}/annotations # Abrufen
|
||||
PUT /api/v1/annotations/{id} # Ändern
|
||||
DELETE /api/v1/annotations/{id} # Löschen
|
||||
```
|
||||
|
||||
#### 4.3 UI-Layout Spezifikation
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────┐
|
||||
│ Header: Klausur-Titel | Student: Anonym-123 | [← Prev] [5/24] [Next →]│
|
||||
├─────────────────────────────────────────┬────────────────────────────┤
|
||||
│ │ Tabs: [Kriterien] [Gutachten]│
|
||||
│ ┌─────────────────────────────────┐ │ │
|
||||
│ │ │ │ ▼ Rechtschreibung (15%) │
|
||||
│ │ Dokument-Anzeige │ │ [====|====] 70/100 │
|
||||
│ │ (PDF/Bild mit Zoom) │ │ 12 Fehler markiert │
|
||||
│ │ │ │ │
|
||||
│ │ + Annotation-Overlay │ │ ▼ Grammatik (15%) │
|
||||
│ │ (SVG Layer) │ │ [====|====] 80/100 │
|
||||
│ │ │ │ │
|
||||
│ │ │ │ ▼ Inhalt (40%) │
|
||||
│ │ │ │ [====|====] 65/100 │
|
||||
│ │ │ │ EH-Vorschläge: [Laden] │
|
||||
│ └─────────────────────────────────┘ │ │
|
||||
│ │ ▼ Struktur (15%) │
|
||||
│ Toolbar: [RS] [Gram] [Kommentar] │ [====|====] 75/100 │
|
||||
│ [Zoom+] [Zoom-] [Fit] │ │
|
||||
│ │ ▼ Stil (15%) │
|
||||
│ Seiten: [1] [2] [3] [4] [5] │ [====|====] 70/100 │
|
||||
│ │ │
|
||||
│ │ ━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
||||
│ │ Gesamtnote: 10 Punkte (2-) │
|
||||
│ │ [Gutachten generieren] │
|
||||
│ │ [Speichern] [Abschließen] │
|
||||
├─────────────────────────────────────────┴────────────────────────────┤
|
||||
│ 2/3 Breite │ 1/3 Breite │
|
||||
└──────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Implementierungs-Reihenfolge
|
||||
|
||||
### Phase 1.1: Grundgerüst (AKTUELL)
|
||||
1. ✅ Dokumentation erstellen
|
||||
2. [ ] `/website/app/admin/klausur-korrektur/page.tsx` - Klausur-Liste
|
||||
3. [ ] `/website/app/admin/klausur-korrektur/types.ts` - TypeScript Types
|
||||
4. [ ] Navigation in AdminLayout.tsx hinzufügen
|
||||
5. [ ] Deploy + Test
|
||||
|
||||
### Phase 1.2: Korrektur-Workspace
|
||||
1. [ ] `[klausurId]/page.tsx` - Studenten-Liste
|
||||
2. [ ] `[klausurId]/[studentId]/page.tsx` - Workspace
|
||||
3. [ ] `components/DocumentViewer.tsx` - Bild/PDF Anzeige
|
||||
4. [ ] `components/CorrectionPanel.tsx` - Bewertungs-Panel
|
||||
5. [ ] Deploy + Test mit Lehrer
|
||||
|
||||
### Phase 1.3: Annotations-System
|
||||
1. [ ] Backend: Annotations-Endpoints in main.py
|
||||
2. [ ] `components/AnnotationLayer.tsx` - SVG Overlay
|
||||
3. [ ] `components/AnnotationToolbar.tsx` - Werkzeuge
|
||||
4. [ ] Farbkodierung: RS=rot, Gram=blau, Inhalt=grün
|
||||
5. [ ] Deploy + Test
|
||||
|
||||
### Phase 1.4: EH-Integration
|
||||
1. [ ] `components/EHSuggestionPanel.tsx`
|
||||
2. [ ] Backend: `/api/v1/students/{id}/eh-suggestions`
|
||||
3. [ ] RAG-Query mit Student-Text
|
||||
4. [ ] Deploy + Test
|
||||
|
||||
### Phase 1.5: Gutachten-Editor
|
||||
1. [ ] `components/GutachtenEditor.tsx`
|
||||
2. [ ] Beleg-Verlinkung zu Annotations
|
||||
3. [ ] Gutachten-Generierung Button
|
||||
4. [ ] Deploy + Test
|
||||
|
||||
---
|
||||
|
||||
## 6. API-Konfiguration
|
||||
|
||||
```typescript
|
||||
// Frontend API Base URLs
|
||||
const KLAUSUR_SERVICE = process.env.NEXT_PUBLIC_KLAUSUR_SERVICE_URL || 'http://localhost:8086'
|
||||
|
||||
// Endpoints:
|
||||
// Klausuren
|
||||
GET ${KLAUSUR_SERVICE}/api/v1/klausuren
|
||||
POST ${KLAUSUR_SERVICE}/api/v1/klausuren
|
||||
GET ${KLAUSUR_SERVICE}/api/v1/klausuren/{id}
|
||||
GET ${KLAUSUR_SERVICE}/api/v1/klausuren/{id}/students
|
||||
|
||||
// Studenten
|
||||
GET ${KLAUSUR_SERVICE}/api/v1/students/{id}
|
||||
GET ${KLAUSUR_SERVICE}/api/v1/students/{id}/file // Dokument-Download
|
||||
PUT ${KLAUSUR_SERVICE}/api/v1/students/{id}/criteria
|
||||
PUT ${KLAUSUR_SERVICE}/api/v1/students/{id}/gutachten
|
||||
POST ${KLAUSUR_SERVICE}/api/v1/students/{id}/gutachten/generate
|
||||
|
||||
// Annotations (NEU)
|
||||
GET ${KLAUSUR_SERVICE}/api/v1/students/{id}/annotations
|
||||
POST ${KLAUSUR_SERVICE}/api/v1/students/{id}/annotations
|
||||
PUT ${KLAUSUR_SERVICE}/api/v1/annotations/{id}
|
||||
DELETE ${KLAUSUR_SERVICE}/api/v1/annotations/{id}
|
||||
|
||||
// System
|
||||
GET ${KLAUSUR_SERVICE}/api/v1/grade-info
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Deployment-Prozess
|
||||
|
||||
```bash
|
||||
# 1. Dateien auf Mac Mini synchronisieren
|
||||
rsync -avz --delete \
|
||||
--exclude 'node_modules' --exclude '.next' --exclude '.git' \
|
||||
/Users/benjaminadmin/Projekte/breakpilot-pwa/website/ \
|
||||
macmini:/Users/benjaminadmin/Projekte/breakpilot-pwa/website/
|
||||
|
||||
# 2. Website-Container neu bauen
|
||||
ssh macmini "/usr/local/bin/docker compose \
|
||||
-f /Users/benjaminadmin/Projekte/breakpilot-pwa/docker-compose.yml \
|
||||
build --no-cache website"
|
||||
|
||||
# 3. Container neu starten
|
||||
ssh macmini "/usr/local/bin/docker compose \
|
||||
-f /Users/benjaminadmin/Projekte/breakpilot-pwa/docker-compose.yml \
|
||||
up -d website"
|
||||
|
||||
# 4. Testen unter:
|
||||
# http://macmini:3000/admin/klausur-korrektur
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Bundesland-Spezifika (Niedersachsen Pilot)
|
||||
|
||||
```json
|
||||
// /klausur-service/backend/policies/bundeslaender.json
|
||||
{
|
||||
"NI": {
|
||||
"name": "Niedersachsen",
|
||||
"grading_mode": "points_15",
|
||||
"requires_gutachten": true,
|
||||
"zk_visibility": "full", // ZK sieht EK-Korrektur
|
||||
"third_correction_threshold": 4, // Ab 4 Punkte Diff
|
||||
"colors": {
|
||||
"first_examiner": "#dc2626", // Rot
|
||||
"second_examiner": "#16a34a" // Grün
|
||||
},
|
||||
"criteria_weights": {
|
||||
"rechtschreibung": 15,
|
||||
"grammatik": 15,
|
||||
"inhalt": 40,
|
||||
"struktur": 15,
|
||||
"stil": 15
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Wichtige Dateien (Referenz)
|
||||
|
||||
| Datei | Beschreibung |
|
||||
|-------|--------------|
|
||||
| `/klausur-service/backend/main.py` | Haupt-API, alle Endpoints |
|
||||
| `/klausur-service/backend/eh_pipeline.py` | BYOEH Verarbeitung |
|
||||
| `/klausur-service/backend/qdrant_service.py` | RAG Vector-Suche |
|
||||
| `/klausur-service/backend/hybrid_search.py` | Hybrid Search |
|
||||
| `/website/components/admin/AdminLayout.tsx` | Admin Navigation |
|
||||
| `/website/app/admin/ocr-labeling/page.tsx` | Referenz für 2/3-1/3 Layout |
|
||||
|
||||
---
|
||||
|
||||
## 10. Testing-Checkliste
|
||||
|
||||
### Nach jeder Phase:
|
||||
- [ ] Seite lädt ohne Fehler
|
||||
- [ ] API-Calls funktionieren (DevTools Network)
|
||||
- [ ] Responsives Layout korrekt
|
||||
- [ ] Lehrer kann Workflow durchführen
|
||||
|
||||
### Lehrer-Test-Szenarien:
|
||||
1. Klausur erstellen
|
||||
2. 3+ Studentenarbeiten hochladen
|
||||
3. Erste Arbeit korrigieren (alle Kriterien)
|
||||
4. Annotations setzen
|
||||
5. Gutachten generieren
|
||||
6. Zur nächsten Arbeit navigieren
|
||||
7. Fairness-Check nach allen Arbeiten
|
||||
|
||||
---
|
||||
|
||||
## 11. Phase 2: Zweitkorrektur-System (NEU)
|
||||
|
||||
### 11.1 Neue Backend-Endpoints (main.py)
|
||||
|
||||
```python
|
||||
# Zweitkorrektur Workflow
|
||||
POST /api/v1/students/{id}/start-zweitkorrektur # ZK starten (nach EK)
|
||||
POST /api/v1/students/{id}/submit-zweitkorrektur # ZK-Ergebnis abgeben
|
||||
|
||||
# Einigung (bei Diff 3 Punkte)
|
||||
POST /api/v1/students/{id}/einigung # Einigung einreichen
|
||||
|
||||
# Drittkorrektur (bei Diff >= 4 Punkte)
|
||||
POST /api/v1/students/{id}/assign-drittkorrektor # DK zuweisen
|
||||
POST /api/v1/students/{id}/submit-drittkorrektur # DK-Ergebnis (final)
|
||||
|
||||
# Workflow-Status & Visibility-Filtering
|
||||
GET /api/v1/students/{id}/examiner-workflow # Workflow-Status abrufen
|
||||
GET /api/v1/students/{id}/annotations-filtered # Policy-gefilterte Annotations
|
||||
```
|
||||
|
||||
### 11.2 Workflow-Status
|
||||
|
||||
```python
|
||||
class ExaminerWorkflowStatus(str, Enum):
|
||||
NOT_STARTED = "not_started"
|
||||
EK_IN_PROGRESS = "ek_in_progress"
|
||||
EK_COMPLETED = "ek_completed"
|
||||
ZK_ASSIGNED = "zk_assigned"
|
||||
ZK_IN_PROGRESS = "zk_in_progress"
|
||||
ZK_COMPLETED = "zk_completed"
|
||||
EINIGUNG_REQUIRED = "einigung_required"
|
||||
EINIGUNG_COMPLETED = "einigung_completed"
|
||||
DRITTKORREKTUR_REQUIRED = "drittkorrektur_required"
|
||||
DRITTKORREKTUR_ASSIGNED = "drittkorrektur_assigned"
|
||||
DRITTKORREKTUR_IN_PROGRESS = "drittkorrektur_in_progress"
|
||||
COMPLETED = "completed"
|
||||
```
|
||||
|
||||
### 11.3 Visibility-Regeln (aus bundeslaender.json)
|
||||
|
||||
| Modus | ZK sieht EK-Annotations | ZK sieht EK-Note | ZK sieht EK-Gutachten |
|
||||
|-------|-------------------------|------------------|----------------------|
|
||||
| `blind` | Nein | Nein | Nein |
|
||||
| `semi` (Bayern) | Ja | Nein | Nein |
|
||||
| `full` (NI, Default) | Ja | Ja | Ja |
|
||||
|
||||
### 11.4 Konsens-Regeln
|
||||
|
||||
| Differenz EK-ZK | Aktion |
|
||||
|-----------------|--------|
|
||||
| 0-2 Punkte | Auto-Konsens (Durchschnitt) |
|
||||
| 3 Punkte | Einigung erforderlich |
|
||||
| >= 4 Punkte | Drittkorrektur erforderlich |
|
||||
|
||||
---
|
||||
|
||||
## 12. Aktueller Stand
|
||||
|
||||
**Datum**: 2026-01-21
|
||||
**Phase**: Alle Phasen abgeschlossen
|
||||
**Status**: MVP komplett - bereit fuer Produktionstest
|
||||
|
||||
### Abgeschlossen:
|
||||
- [x] Phase 1: Korrektur-Workspace MVP
|
||||
- [x] Phase 1.1: Grundgerüst (Klausur-Liste, Studenten-Liste)
|
||||
- [x] Phase 1.2: Annotations-System
|
||||
- [x] Phase 1.3: RS/Grammatik Overlays
|
||||
- [x] Phase 1.4: EH-Vorschläge via RAG
|
||||
- [x] Phase 2.1 Backend: Zweitkorrektur-Endpoints
|
||||
- [x] Phase 2.2 Backend: Einigung-Endpoint
|
||||
- [x] Phase 2.3 Backend: Drittkorrektur-Trigger
|
||||
- [x] Phase 2.1 Frontend: ZK-Modus UI
|
||||
- [x] Phase 2.2 Frontend: Einigung-Screen
|
||||
- [x] Phase 3.1: Fairness-Dashboard Frontend
|
||||
- [x] Phase 3.2: Ausreißer-Liste mit Quick-Adjust
|
||||
- [x] Phase 3.3: Noten-Histogramm & Heatmap
|
||||
- [x] Phase 4.1: PDF-Export Backend (reportlab)
|
||||
- [x] Phase 4.2: PDF-Export Frontend
|
||||
- [x] Phase 4.3: Vorabitur-Modus mit EH-Templates
|
||||
|
||||
### URLs:
|
||||
- Klausur-Korrektur: `/admin/klausur-korrektur`
|
||||
- Fairness-Dashboard: `/admin/klausur-korrektur/[klausurId]/fairness`
|
||||
|
||||
### PDF-Export Endpoints:
|
||||
- `GET /api/v1/students/{id}/export/gutachten` - Einzelnes Gutachten als PDF
|
||||
- `GET /api/v1/students/{id}/export/annotations` - Anmerkungen als PDF
|
||||
- `GET /api/v1/klausuren/{id}/export/overview` - Notenübersicht als PDF
|
||||
- `GET /api/v1/klausuren/{id}/export/all-gutachten` - Alle Gutachten als PDF
|
||||
|
||||
### Vorabitur-Modus Endpoints:
|
||||
- `GET /api/v1/vorabitur/templates` - Liste aller EH-Templates
|
||||
- `GET /api/v1/vorabitur/templates/{aufgabentyp}` - Template-Details
|
||||
- `POST /api/v1/klausuren/{id}/vorabitur-eh` - Custom EH erstellen
|
||||
- `GET /api/v1/klausuren/{id}/vorabitur-eh` - Verknuepften EH abrufen
|
||||
- `PUT /api/v1/klausuren/{id}/vorabitur-eh` - EH aktualisieren
|
||||
|
||||
### Verfuegbare Aufgabentypen:
|
||||
- `textanalyse_pragmatisch` - Sachtexte, Reden, Kommentare
|
||||
- `gedichtanalyse` - Lyrik/Gedichte
|
||||
- `prosaanalyse` - Romane, Kurzgeschichten
|
||||
- `dramenanalyse` - Dramatische Texte
|
||||
- `eroerterung_textgebunden` - Textgebundene Eroerterung
|
||||
|
||||
---
|
||||
|
||||
## 13. Lehrer-Anleitung (Schritt-fuer-Schritt)
|
||||
|
||||
### 13.1 Zugang zum System
|
||||
|
||||
**Weg 1: Ueber das Haupt-Dashboard**
|
||||
1. Oeffnen Sie `http://macmini:8000/app` im Browser
|
||||
2. Klicken Sie auf die Kachel "Abiturklausuren"
|
||||
3. Sie werden automatisch zur Korrektur-Oberflaeche weitergeleitet
|
||||
|
||||
**Weg 2: Direkter Zugang**
|
||||
1. Oeffnen Sie direkt `http://macmini:3000/admin/klausur-korrektur`
|
||||
|
||||
### 13.2 Zwei Einstiegs-Optionen
|
||||
|
||||
Beim ersten Besuch sehen Sie die Willkommens-Seite mit zwei Optionen:
|
||||
|
||||
#### Option A: Schnellstart (Direkt hochladen)
|
||||
- Ideal wenn Sie sofort loslegen moechten
|
||||
- Keine manuelle Klausur-Erstellung erforderlich
|
||||
- System erstellt automatisch eine Klausur im Hintergrund
|
||||
|
||||
**Schritte:**
|
||||
1. Klicken Sie auf "Schnellstart - Direkt hochladen"
|
||||
2. **Schritt 1**: Ziehen Sie Ihre eingescannten Arbeiten (PDF/JPG/PNG) in den Upload-Bereich
|
||||
3. **Schritt 2**: Optional - Waehlen Sie den Aufgabentyp und beschreiben Sie die Aufgabenstellung
|
||||
4. **Schritt 3**: Pruefen Sie die Zusammenfassung und klicken "Korrektur starten"
|
||||
5. Sie werden automatisch zur Korrektur-Ansicht weitergeleitet
|
||||
|
||||
#### Option B: Neue Klausur erstellen (Standard)
|
||||
- Empfohlen fuer regelmaessige Nutzung
|
||||
- Volle Metadaten (Fach, Jahr, Kurs, Modus)
|
||||
- Unterstuetzt Zweitkorrektur-Workflow
|
||||
|
||||
**Schritte:**
|
||||
1. Klicken Sie auf "Neue Klausur erstellen"
|
||||
2. Geben Sie Titel, Fach, Jahr und Semester ein
|
||||
3. Waehlen Sie den Modus:
|
||||
- **Abitur**: Fuer offizielle Abitur-Pruefungen mit NiBiS-EH
|
||||
- **Vorabitur**: Fuer Uebungsklausuren mit eigenem EH
|
||||
4. Bei Vorabitur: Waehlen Sie Aufgabentyp und beschreiben Sie die Aufgabenstellung
|
||||
5. Klicken Sie "Klausur erstellen"
|
||||
|
||||
### 13.3 Arbeiten hochladen
|
||||
|
||||
Nach Erstellung der Klausur:
|
||||
1. Oeffnen Sie die Klausur aus der Liste
|
||||
2. Klicken Sie "Arbeiten hochladen"
|
||||
3. Waehlen Sie die eingescannten Dateien (PDF oder Bilder)
|
||||
4. Geben Sie optional anonyme IDs (z.B. "Arbeit-1", "Arbeit-2")
|
||||
5. Das System startet automatisch die OCR-Erkennung
|
||||
|
||||
### 13.4 Korrigieren
|
||||
|
||||
**Korrektur-Workspace (2/3-1/3 Layout):**
|
||||
- Links (2/3): Das Originaldokument mit Zoom-Funktion
|
||||
- Rechts (1/3): Bewertungspanel mit Kriterien
|
||||
|
||||
**Schritt fuer Schritt:**
|
||||
1. Oeffnen Sie eine Arbeit durch Klick auf "Korrigieren"
|
||||
2. Lesen Sie die Arbeit im linken Bereich (Zoom mit +/-)
|
||||
3. Setzen Sie Anmerkungen durch Klick auf das Dokument
|
||||
4. Waehlen Sie den Anmerkungstyp:
|
||||
- **RS** (rot): Rechtschreibfehler
|
||||
- **Gram** (blau): Grammatikfehler
|
||||
- **Inhalt** (gruen): Inhaltliche Anmerkungen
|
||||
- **Kommentar**: Allgemeine Bemerkungen
|
||||
5. Bewerten Sie die 5 Kriterien im rechten Panel:
|
||||
- Rechtschreibung (15%)
|
||||
- Grammatik (15%)
|
||||
- Inhalt (40%)
|
||||
- Struktur (15%)
|
||||
- Stil (15%)
|
||||
6. Klicken Sie "EH-Vorschlaege laden" fuer KI-Unterstuetzung
|
||||
7. Klicken Sie "Gutachten generieren" fuer einen KI-Vorschlag
|
||||
8. Bearbeiten Sie das Gutachten nach Bedarf
|
||||
9. Klicken Sie "Speichern" und dann "Naechste Arbeit"
|
||||
|
||||
### 13.5 Fairness-Analyse
|
||||
|
||||
Nach Korrektur mehrerer Arbeiten:
|
||||
1. Klicken Sie auf "Fairness-Dashboard" in der Klausur-Ansicht
|
||||
2. Pruefen Sie:
|
||||
- **Noten-Histogramm**: Ist die Verteilung realistisch?
|
||||
- **Ausreisser**: Gibt es ungewoehnlich hohe/niedrige Noten?
|
||||
- **Kriterien-Heatmap**: Sind Kriterien konsistent bewertet?
|
||||
3. Nutzen Sie "Quick-Adjust" um Anpassungen vorzunehmen
|
||||
|
||||
### 13.6 PDF-Export
|
||||
|
||||
1. In der Klausur-Ansicht klicken Sie "PDF-Export"
|
||||
2. Waehlen Sie:
|
||||
- **Einzelgutachten**: PDF fuer einen Schueler
|
||||
- **Alle Gutachten**: Gesamtes PDF fuer alle Arbeiten
|
||||
- **Notenuebersicht**: Uebersicht aller Noten
|
||||
- **Anmerkungen**: Alle Annotationen als PDF
|
||||
|
||||
### 13.7 Zweitkorrektur (Optional)
|
||||
|
||||
Fuer offizielle Abitur-Klausuren:
|
||||
1. Erstkorrektur abschliessen (Status: "Abgeschlossen")
|
||||
2. Klicken Sie "Zweitkorrektur starten"
|
||||
3. Der Zweitkorrektor bewertet unabhaengig
|
||||
4. Bei Differenz >= 3 Punkte: Einigung erforderlich
|
||||
5. Bei Differenz >= 4 Punkte: Drittkorrektur wird automatisch ausgeloest
|
||||
|
||||
### 13.8 Haeufige Fragen
|
||||
|
||||
**F: Kann ich eine Korrektur unterbrechen und spaeter fortsetzen?**
|
||||
A: Ja, alle Aenderungen werden automatisch gespeichert.
|
||||
|
||||
**F: Was passiert mit meinen Daten?**
|
||||
A: Alle Daten werden lokal auf dem Schulserver gespeichert. Keine Cloud-Speicherung.
|
||||
|
||||
**F: Kann ich den KI-Vorschlag komplett ueberschreiben?**
|
||||
A: Ja, das Gutachten ist frei editierbar. Der KI-Vorschlag ist nur ein Startpunkt.
|
||||
|
||||
**F: Wie funktioniert die OCR-Erkennung?**
|
||||
A: Das System erkennt Handschrift automatisch. Bei schlechter Lesbarkeit koennen Sie manuell nachbessern.
|
||||
|
||||
---
|
||||
|
||||
## 14. Integration Dashboard (Port 8000)
|
||||
|
||||
### 14.1 Aenderungen in dashboard.py
|
||||
|
||||
Die Funktion `openKlausurService()` wurde aktualisiert:
|
||||
|
||||
```javascript
|
||||
// Alte Version: Oeffnete Port 8086 (Backend)
|
||||
// Neue Version: Oeffnet Port 3000 (Next.js Frontend)
|
||||
function openKlausurService() {
|
||||
let baseUrl;
|
||||
if (window.location.hostname === 'macmini') {
|
||||
baseUrl = 'http://macmini:3000';
|
||||
} else {
|
||||
baseUrl = 'http://localhost:3000';
|
||||
}
|
||||
window.open(baseUrl + '/admin/klausur-korrektur', '_blank');
|
||||
}
|
||||
```
|
||||
|
||||
### 14.2 Neue Frontend-Features
|
||||
|
||||
- **Willkommens-Tab**: Erster Tab fuer neue Benutzer mit Workflow-Erklaerung
|
||||
- **Direktupload-Wizard**: 3-Schritt-Wizard fuer Schnellstart
|
||||
- **Drag & Drop**: Arbeiten per Drag & Drop hochladen
|
||||
- **localStorage-Persistenz**: System merkt sich wiederkehrende Benutzer
|
||||
141
.claude/rules/compliance-checklist.md
Normal file
141
.claude/rules/compliance-checklist.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# Compliance-Checkliste
|
||||
|
||||
## Wann diese Checkliste anwenden?
|
||||
|
||||
**AUTOMATISCH bei:**
|
||||
- Neuen Features mit Nutzerdaten
|
||||
- Änderungen an Datenflüssen
|
||||
- KI/ML-Funktionen
|
||||
- Neuen API-Endpoints
|
||||
- Datenbankschema-Änderungen
|
||||
|
||||
---
|
||||
|
||||
## 1. DSGVO-Check (Datenschutz-Grundverordnung)
|
||||
|
||||
### Rechtsgrundlage klären
|
||||
|
||||
| Rechtsgrundlage | Wann verwenden |
|
||||
|-----------------|----------------|
|
||||
| **Einwilligung (Art. 6 Abs. 1a)** | Optionale Features, Marketing, Analytics |
|
||||
| **Vertragserfüllung (Art. 6 Abs. 1b)** | Kernfunktionen der Plattform |
|
||||
| **Berechtigtes Interesse (Art. 6 Abs. 1f)** | Sicherheit, Betrugsprävention |
|
||||
| **Rechtliche Verpflichtung (Art. 6 Abs. 1c)** | Aufbewahrungspflichten |
|
||||
|
||||
### Datenminimierung
|
||||
|
||||
- [ ] Werden nur notwendige Daten erhoben?
|
||||
- [ ] Gibt es Felder, die optional sein könnten?
|
||||
- [ ] Werden Daten nach Zweckerfüllung gelöscht?
|
||||
|
||||
### Besondere Kategorien (Art. 9)
|
||||
|
||||
**ACHTUNG bei:**
|
||||
- Gesundheitsdaten (Krankheitstage, Atteste)
|
||||
- Biometrische Daten (Gesichtserkennung, Stimme)
|
||||
- Religiöse Überzeugungen
|
||||
- Politische Meinungen
|
||||
|
||||
→ **Explizite Einwilligung erforderlich!**
|
||||
|
||||
### Minderjährige (Art. 8)
|
||||
|
||||
**Breakpilot-spezifisch:**
|
||||
- Unter 16 Jahren: Einwilligung der Eltern
|
||||
- Altersverifikation implementieren
|
||||
- Kindgerechte Datenschutzerklärung
|
||||
|
||||
### Betroffenenrechte sicherstellen
|
||||
|
||||
- [ ] **Auskunft (Art. 15):** Kann der Nutzer seine Daten einsehen?
|
||||
- [ ] **Berichtigung (Art. 16):** Kann der Nutzer Daten korrigieren?
|
||||
- [ ] **Löschung (Art. 17):** Kann der Nutzer Löschung beantragen?
|
||||
- [ ] **Datenportabilität (Art. 20):** Export in maschinenlesbarem Format?
|
||||
|
||||
---
|
||||
|
||||
## 2. AI Act Check (KI-Verordnung)
|
||||
|
||||
### Risikokategorie bestimmen
|
||||
|
||||
| Kategorie | Beispiele | Anforderungen |
|
||||
|-----------|-----------|---------------|
|
||||
| **Unakzeptabel** | Social Scoring, Manipulation | ❌ VERBOTEN |
|
||||
| **Hochrisiko** | Bildungszugang, Prüfungsbewertung | Strenge Auflagen |
|
||||
| **Begrenzt** | Chatbots, Empfehlungen | Transparenzpflicht |
|
||||
| **Minimal** | Spam-Filter, Autokorrektur | Keine Auflagen |
|
||||
|
||||
### Breakpilot KI-Features prüfen
|
||||
|
||||
| Feature | Risiko | Maßnahmen |
|
||||
|---------|--------|-----------|
|
||||
| Klausur-OCR | Begrenzt | Transparenz, Human-in-Loop |
|
||||
| KI-Korrekturvorschläge | Hochrisiko | Audit-Log, Erklärbarkeit |
|
||||
| Lernempfehlungen | Begrenzt | Transparenz |
|
||||
| Spracherkennung | Begrenzt | Consent, Transparenz |
|
||||
|
||||
### Hochrisiko-KI Anforderungen
|
||||
|
||||
Wenn Hochrisiko:
|
||||
- [ ] Risikomanagementsystem dokumentiert
|
||||
- [ ] Qualität der Trainingsdaten sichergestellt
|
||||
- [ ] Technische Dokumentation vorhanden
|
||||
- [ ] Audit-Logging aktiviert
|
||||
- [ ] Human Oversight möglich
|
||||
- [ ] Genauigkeit/Robustheit getestet
|
||||
|
||||
---
|
||||
|
||||
## 3. Technische Maßnahmen (TOM)
|
||||
|
||||
### Verschlüsselung
|
||||
|
||||
- [ ] **Transit:** TLS 1.3 für alle Verbindungen
|
||||
- [ ] **Rest:** Datenbank-Verschlüsselung
|
||||
- [ ] **Secrets:** Vault für Credentials
|
||||
|
||||
### Zugriffskontrollen
|
||||
|
||||
- [ ] RBAC implementiert
|
||||
- [ ] Least Privilege Prinzip
|
||||
- [ ] Session-Timeouts
|
||||
|
||||
### Audit-Logging
|
||||
|
||||
```python
|
||||
# Beispiel: Audit-Event loggen
|
||||
audit_log.info({
|
||||
"action": "data_export",
|
||||
"user_id": user.id,
|
||||
"timestamp": datetime.utcnow(),
|
||||
"data_categories": ["grades", "personal"],
|
||||
"legal_basis": "Art. 20 DSGVO"
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Dokumentationspflichten
|
||||
|
||||
### Bei neuen Features aktualisieren
|
||||
|
||||
| Dokument | URL | Wann aktualisieren |
|
||||
|----------|-----|-------------------|
|
||||
| VVT | https://macmini:3002/sdk/vvt | Neue Verarbeitung |
|
||||
| TOM | https://macmini:3002/sdk/tom | Neue Schutzmaßnahme |
|
||||
| DSFA | https://macmini:3002/sdk/dsfa | Hochrisiko-Verarbeitung |
|
||||
| Löschfristen | https://macmini:3002/sdk/loeschfristen | Neue Datenkategorie |
|
||||
|
||||
---
|
||||
|
||||
## 5. Schnell-Check (5 Fragen)
|
||||
|
||||
Vor jedem Feature diese 5 Fragen beantworten:
|
||||
|
||||
1. **WER** sind die Betroffenen? (Schüler, Lehrer, Eltern)
|
||||
2. **WAS** für Daten werden verarbeitet?
|
||||
3. **WARUM** werden sie verarbeitet? (Rechtsgrundlage)
|
||||
4. **WIE LANGE** werden sie gespeichert?
|
||||
5. **WER** hat Zugriff?
|
||||
|
||||
Können alle 5 Fragen beantwortet werden? → Feature ist dokumentierbar.
|
||||
91
.claude/rules/documentation.md
Normal file
91
.claude/rules/documentation.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Dokumentations-Regeln
|
||||
|
||||
## Automatische Dokumentations-Aktualisierung
|
||||
|
||||
**WICHTIG:** Bei JEDER Code-Änderung muss die entsprechende Dokumentation aktualisiert werden!
|
||||
|
||||
## Wann Dokumentation aktualisieren?
|
||||
|
||||
### API-Änderungen
|
||||
Wenn du einen Endpoint änderst, hinzufügst oder entfernst:
|
||||
- Aktualisiere `/docs/api/consent-service-api.md` (Go Endpoints)
|
||||
- Aktualisiere `/docs/api/backend-api.md` (Python Endpoints)
|
||||
|
||||
### Neue Funktionen/Klassen
|
||||
Wenn du neue Funktionen, Klassen oder Module erstellst:
|
||||
- Aktualisiere `/docs/consent-service/README.md` (für Go)
|
||||
- Aktualisiere `/docs/backend/README.md` (für Python)
|
||||
|
||||
### Architektur-Änderungen
|
||||
Wenn du die Systemarchitektur änderst:
|
||||
- Aktualisiere `/docs/architecture/system-architecture.md`
|
||||
- Aktualisiere `/docs/architecture/data-model.md` (bei DB-Änderungen)
|
||||
|
||||
### Neue Konfigurationsoptionen
|
||||
Wenn du neue Umgebungsvariablen oder Konfigurationen hinzufügst:
|
||||
- Aktualisiere die entsprechende README
|
||||
- Füge zur `guides/local-development.md` hinzu
|
||||
|
||||
## Dokumentations-Format
|
||||
|
||||
### API-Endpoints dokumentieren
|
||||
|
||||
```markdown
|
||||
### METHOD /path/to/endpoint
|
||||
|
||||
Kurze Beschreibung.
|
||||
|
||||
**Request Body:**
|
||||
\`\`\`json
|
||||
{
|
||||
"field": "value"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Response (200):**
|
||||
\`\`\`json
|
||||
{
|
||||
"result": "value"
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
**Errors:**
|
||||
- `400`: Beschreibung
|
||||
- `401`: Beschreibung
|
||||
```
|
||||
|
||||
### Funktionen dokumentieren
|
||||
|
||||
```markdown
|
||||
### FunctionName (file.go:123)
|
||||
|
||||
\`\`\`go
|
||||
func FunctionName(param Type) ReturnType
|
||||
\`\`\`
|
||||
|
||||
**Beschreibung:** Was macht die Funktion?
|
||||
|
||||
**Parameter:**
|
||||
- `param`: Beschreibung
|
||||
|
||||
**Rückgabe:** Beschreibung
|
||||
```
|
||||
|
||||
## Checkliste nach Code-Änderungen
|
||||
|
||||
Vor dem Abschluss einer Aufgabe prüfe:
|
||||
|
||||
- [ ] Wurden neue API-Endpoints hinzugefügt? → API-Docs aktualisieren
|
||||
- [ ] Wurden Datenmodelle geändert? → data-model.md aktualisieren
|
||||
- [ ] Wurden neue Konfigurationen hinzugefügt? → README aktualisieren
|
||||
- [ ] Wurden neue Abhängigkeiten hinzugefügt? → requirements.txt/go.mod UND Docs
|
||||
- [ ] Wurde die Architektur geändert? → architecture/ aktualisieren
|
||||
|
||||
## Beispiel: Vollständige Dokumentation einer neuen Funktion
|
||||
|
||||
Wenn du z.B. `GetUserStats()` im Go Service hinzufügst:
|
||||
|
||||
1. **Code schreiben** in `internal/services/stats_service.go`
|
||||
2. **API-Doc aktualisieren** in `docs/api/consent-service-api.md`
|
||||
3. **Service-Doc aktualisieren** in `docs/consent-service/README.md`
|
||||
4. **Test schreiben** (siehe testing.md)
|
||||
250
.claude/rules/experimental-dashboard.md
Normal file
250
.claude/rules/experimental-dashboard.md
Normal file
@@ -0,0 +1,250 @@
|
||||
# Experimental Dashboard - Apple Weather Style UI
|
||||
|
||||
**Status:** In Entwicklung
|
||||
**Letzte Aktualisierung:** 2026-01-24
|
||||
**URL:** http://macmini:3001/dashboard-experimental
|
||||
|
||||
---
|
||||
|
||||
## Uebersicht
|
||||
|
||||
Das Experimental Dashboard implementiert einen **Apple Weather App Style** mit:
|
||||
- Ultra-transparenten Glassmorphism-Cards (~8% Opacity)
|
||||
- Dunklem Sternenhimmel-Hintergrund mit Parallax
|
||||
- Weisser Schrift auf monochromem Design
|
||||
- Schwebenden Nachrichten (FloatingMessage) mit ~4% Background
|
||||
- Nuetzlichen Widgets: Uhr, Wetter, Kompass, Diagramme
|
||||
|
||||
---
|
||||
|
||||
## Design-Prinzipien
|
||||
|
||||
| Prinzip | Umsetzung |
|
||||
|---------|-----------|
|
||||
| **Transparenz** | Cards mit 8% Opacity, Messages mit 4% |
|
||||
| **Verschmelzung** | Elemente verschmelzen mit dem Hintergrund |
|
||||
| **Monochrom** | Weisse Schrift, keine bunten Akzente |
|
||||
| **Subtilitaet** | Dezente Hover-Effekte, sanfte Animationen |
|
||||
| **Nuetzlichkeit** | Echte Informationen (Uhrzeit, Wetter) |
|
||||
|
||||
---
|
||||
|
||||
## Dateistruktur
|
||||
|
||||
```
|
||||
/studio-v2/
|
||||
├── app/
|
||||
│ └── dashboard-experimental/
|
||||
│ └── page.tsx # Haupt-Dashboard (740 Zeilen)
|
||||
│
|
||||
├── components/
|
||||
│ └── spatial-ui/
|
||||
│ ├── index.ts # Exports
|
||||
│ ├── SpatialCard.tsx # Original SpatialCard (nicht verwendet)
|
||||
│ └── FloatingMessage.tsx # Schwebende Nachrichten
|
||||
│
|
||||
└── lib/
|
||||
└── spatial-ui/
|
||||
├── index.ts # Exports
|
||||
├── depth-system.ts # Design Tokens
|
||||
├── PerformanceContext.tsx # Adaptive Qualitaet
|
||||
└── FocusContext.tsx # Focus-Modus
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Komponenten
|
||||
|
||||
### GlassCard
|
||||
Ultra-transparente Card fuer alle Inhalte.
|
||||
|
||||
```typescript
|
||||
interface GlassCardProps {
|
||||
children: React.ReactNode
|
||||
className?: string
|
||||
onClick?: () => void
|
||||
size?: 'sm' | 'md' | 'lg' // Padding: 16px, 20px, 24px
|
||||
delay?: number // Einblend-Verzoegerung in ms
|
||||
}
|
||||
```
|
||||
|
||||
**Styling:**
|
||||
- Background: `rgba(255, 255, 255, 0.08)` (8%)
|
||||
- Hover: `rgba(255, 255, 255, 0.12)` (12%)
|
||||
- Border: `1px solid rgba(255, 255, 255, 0.1)`
|
||||
- Blur: 24px (adaptiv)
|
||||
- Border-Radius: 24px (rounded-3xl)
|
||||
|
||||
### AnalogClock
|
||||
Analoge Uhr mit Sekundenzeiger.
|
||||
|
||||
- Stunden-Zeiger: Weiss, dick
|
||||
- Minuten-Zeiger: Weiss/80%, duenn
|
||||
- Sekunden-Zeiger: Orange (#fb923c)
|
||||
- 12 Stundenmarkierungen
|
||||
- Aktualisiert jede Sekunde
|
||||
|
||||
### Compass
|
||||
Kompass im Apple Weather Style.
|
||||
|
||||
```typescript
|
||||
interface CompassProps {
|
||||
direction?: number // Grad (0 = Nord, 90 = Ost, etc.)
|
||||
}
|
||||
```
|
||||
|
||||
- Nord-Nadel: Rot (#ef4444)
|
||||
- Sued-Nadel: Weiss
|
||||
- Kardinalrichtungen: N (rot), S, W, O
|
||||
|
||||
### BarChart
|
||||
Balkendiagramm fuer Wochen-Statistiken.
|
||||
|
||||
```typescript
|
||||
interface BarChartProps {
|
||||
data: { label: string; value: number; highlight?: boolean }[]
|
||||
maxValue?: number
|
||||
}
|
||||
```
|
||||
|
||||
- Highlight-Balken mit Gradient (blau → lila)
|
||||
- Normale Balken: 20% weiss
|
||||
- Labels unten, Werte oben
|
||||
|
||||
### ProgressRing
|
||||
Kreisfoermiger Fortschrittsanzeiger.
|
||||
|
||||
```typescript
|
||||
interface ProgressRingProps {
|
||||
progress: number // 0-100
|
||||
size?: number // Default: 80px
|
||||
strokeWidth?: number // Default: 6px
|
||||
label: string
|
||||
value: string
|
||||
color?: string // Farbe des Fortschritts
|
||||
}
|
||||
```
|
||||
|
||||
### TemperatureDisplay
|
||||
Wetter-Anzeige mit Icon und Temperatur.
|
||||
|
||||
```typescript
|
||||
interface TemperatureDisplayProps {
|
||||
temp: number
|
||||
condition: 'sunny' | 'cloudy' | 'rainy' | 'snowy' | 'partly_cloudy'
|
||||
}
|
||||
```
|
||||
|
||||
### FloatingMessage
|
||||
Schwebende Benachrichtigungen von rechts.
|
||||
|
||||
**Aktuell:**
|
||||
- Background: 4% Opacity
|
||||
- Blur: 24px
|
||||
- Border: `1px solid rgba(255, 255, 255, 0.12)`
|
||||
- Auto-Dismiss mit Progress-Bar
|
||||
- 3 Antwort-Optionen: Antworten, Oeffnen, Spaeter
|
||||
- Typewriter-Effekt fuer Text
|
||||
|
||||
---
|
||||
|
||||
## Farbpalette
|
||||
|
||||
| Element | Wert |
|
||||
|---------|------|
|
||||
| Background | `from-slate-900 via-indigo-950 to-slate-900` |
|
||||
| Card Background | `rgba(255, 255, 255, 0.08)` |
|
||||
| Card Hover | `rgba(255, 255, 255, 0.12)` |
|
||||
| Message Background | `rgba(255, 255, 255, 0.04)` |
|
||||
| Border | `rgba(255, 255, 255, 0.1)` |
|
||||
| Text Primary | `text-white` |
|
||||
| Text Secondary | `text-white/50` bis `text-white/40` |
|
||||
| Accent Blue | `#60a5fa` |
|
||||
| Accent Purple | `#a78bfa` |
|
||||
| Accent Orange | `#fb923c` (Sekundenzeiger) |
|
||||
| Accent Red | `#ef4444` (Kompass Nord) |
|
||||
|
||||
---
|
||||
|
||||
## Performance-System
|
||||
|
||||
Das Dashboard nutzt das **PerformanceContext** fuer adaptive Qualitaet:
|
||||
|
||||
| Quality Level | Blur | Parallax | Animationen |
|
||||
|---------------|------|----------|-------------|
|
||||
| high | 24px | Ja | Spring |
|
||||
| medium | 17px | Ja | Standard |
|
||||
| low | 0px | Nein | Reduziert |
|
||||
| minimal | 0px | Nein | Keine |
|
||||
|
||||
**FPS-Monitor** unten links zeigt:
|
||||
- Aktuelle FPS
|
||||
- Quality Level
|
||||
- Blur/Parallax Status
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
```bash
|
||||
# 1. Sync zu Mac Mini
|
||||
rsync -avz --delete \
|
||||
--exclude 'node_modules' --exclude '.next' --exclude '.git' \
|
||||
/Users/benjaminadmin/Projekte/breakpilot-pwa/studio-v2/ \
|
||||
macmini:/Users/benjaminadmin/Projekte/breakpilot-pwa/studio-v2/
|
||||
|
||||
# 2. Build
|
||||
ssh macmini "/usr/local/bin/docker compose \
|
||||
-f /Users/benjaminadmin/Projekte/breakpilot-pwa/docker-compose.yml \
|
||||
build --no-cache studio-v2"
|
||||
|
||||
# 3. Deploy
|
||||
ssh macmini "/usr/local/bin/docker compose \
|
||||
-f /Users/benjaminadmin/Projekte/breakpilot-pwa/docker-compose.yml \
|
||||
up -d studio-v2"
|
||||
|
||||
# 4. Testen
|
||||
http://macmini:3001/dashboard-experimental
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Offene Punkte / Ideen
|
||||
|
||||
### Kurzfristig
|
||||
- [ ] Echte Wetterdaten via API integrieren
|
||||
- [ ] Kompass-Richtung dynamisch (GPS oder manuell)
|
||||
- [ ] Klick auf Cards fuehrt zu Detailseiten
|
||||
- [ ] Light Mode Support (aktuell nur Dark)
|
||||
|
||||
### Mittelfristig
|
||||
- [ ] Drag & Drop fuer Card-Anordnung
|
||||
- [ ] Weitere Widgets: Kalender, Termine, Erinnerungen
|
||||
- [ ] Animierte Uebergaenge zwischen Seiten
|
||||
- [ ] Sound-Feedback bei Interaktionen
|
||||
|
||||
### Langfristig
|
||||
- [ ] Personalisierbare Widgets
|
||||
- [ ] Dashboard als Standard-Startseite
|
||||
- [ ] Mobile-optimierte Version
|
||||
- [ ] Integration mit Apple Health / Fitness Daten
|
||||
|
||||
---
|
||||
|
||||
## Referenzen
|
||||
|
||||
- **Apple Weather App** (iOS) - Hauptinspiration
|
||||
- **Dribbble Shot:** https://dribbble.com/shots/26339637-Smart-Home-Dashboard-Glassmorphism-UI
|
||||
- **Design Tokens:** `/studio-v2/lib/spatial-ui/depth-system.ts`
|
||||
|
||||
---
|
||||
|
||||
## Aenderungshistorie
|
||||
|
||||
| Datum | Aenderung |
|
||||
|-------|-----------|
|
||||
| 2026-01-24 | FloatingMessage auf 4% Opacity reduziert |
|
||||
| 2026-01-24 | Kompass, Balkendiagramm, Analog-Uhr hinzugefuegt |
|
||||
| 2026-01-24 | Cards auf 8% Opacity reduziert |
|
||||
| 2026-01-24 | Apple Weather Style implementiert |
|
||||
| 2026-01-24 | Erstes Spatial UI System erstellt |
|
||||
295
.claude/rules/multi-agent-architecture.md
Normal file
295
.claude/rules/multi-agent-architecture.md
Normal file
@@ -0,0 +1,295 @@
|
||||
# Multi-Agent Architektur - Entwicklerdokumentation
|
||||
|
||||
**Status:** Implementiert
|
||||
**Letzte Aktualisierung:** 2025-01-15
|
||||
**Modul:** `/agent-core/`
|
||||
|
||||
---
|
||||
|
||||
## 1. Übersicht
|
||||
|
||||
Die Multi-Agent-Architektur erweitert Breakpilot um ein verteiltes Agent-System basierend auf Mission Control Konzepten.
|
||||
|
||||
### Kernkomponenten
|
||||
|
||||
| Komponente | Pfad | Beschreibung |
|
||||
|------------|------|--------------|
|
||||
| Session Management | `/agent-core/sessions/` | Lifecycle & Recovery |
|
||||
| Shared Brain | `/agent-core/brain/` | Langzeit-Gedächtnis |
|
||||
| Orchestrator | `/agent-core/orchestrator/` | Koordination |
|
||||
| SOUL Files | `/agent-core/soul/` | Agent-Persönlichkeiten |
|
||||
|
||||
---
|
||||
|
||||
## 2. Agent-Typen
|
||||
|
||||
| Agent | Aufgabe | SOUL-Datei |
|
||||
|-------|---------|------------|
|
||||
| **TutorAgent** | Lernbegleitung, Fragen beantworten | `tutor-agent.soul.md` |
|
||||
| **GraderAgent** | Klausur-Korrektur, Bewertung | `grader-agent.soul.md` |
|
||||
| **QualityJudge** | BQAS Qualitätsprüfung | `quality-judge.soul.md` |
|
||||
| **AlertAgent** | Monitoring, Benachrichtigungen | `alert-agent.soul.md` |
|
||||
| **Orchestrator** | Task-Koordination | `orchestrator.soul.md` |
|
||||
|
||||
---
|
||||
|
||||
## 3. Wichtige Dateien
|
||||
|
||||
### Session Management
|
||||
```
|
||||
agent-core/sessions/
|
||||
├── session_manager.py # AgentSession, SessionManager, SessionState
|
||||
├── heartbeat.py # HeartbeatMonitor, HeartbeatClient
|
||||
└── checkpoint.py # CheckpointManager
|
||||
```
|
||||
|
||||
### Shared Brain
|
||||
```
|
||||
agent-core/brain/
|
||||
├── memory_store.py # MemoryStore, Memory (mit TTL)
|
||||
├── context_manager.py # ConversationContext, ContextManager
|
||||
└── knowledge_graph.py # KnowledgeGraph, Entity, Relationship
|
||||
```
|
||||
|
||||
### Orchestrator
|
||||
```
|
||||
agent-core/orchestrator/
|
||||
├── message_bus.py # MessageBus, AgentMessage, MessagePriority
|
||||
├── supervisor.py # AgentSupervisor, AgentInfo, AgentStatus
|
||||
└── task_router.py # TaskRouter, RoutingRule, RoutingResult
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Datenbank-Schema
|
||||
|
||||
Die Migration befindet sich in:
|
||||
`/backend/migrations/add_agent_core_tables.sql`
|
||||
|
||||
### Tabellen
|
||||
|
||||
1. **agent_sessions** - Session-Daten mit Checkpoints
|
||||
2. **agent_memory** - Langzeit-Gedächtnis mit TTL
|
||||
3. **agent_messages** - Audit-Trail für Inter-Agent Kommunikation
|
||||
|
||||
### Helper-Funktionen
|
||||
|
||||
```sql
|
||||
-- Abgelaufene Memories bereinigen
|
||||
SELECT cleanup_expired_agent_memory();
|
||||
|
||||
-- Inaktive Sessions bereinigen
|
||||
SELECT cleanup_stale_agent_sessions(48); -- 48 Stunden
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Integration Voice-Service
|
||||
|
||||
Der `EnhancedTaskOrchestrator` erweitert den bestehenden `TaskOrchestrator`:
|
||||
|
||||
```python
|
||||
# voice-service/services/enhanced_task_orchestrator.py
|
||||
|
||||
from agent_core.sessions import SessionManager
|
||||
from agent_core.orchestrator import MessageBus
|
||||
|
||||
class EnhancedTaskOrchestrator(TaskOrchestrator):
|
||||
# Nutzt Session-Checkpoints für Recovery
|
||||
# Routet komplexe Tasks an spezialisierte Agents
|
||||
# Führt Quality-Checks via BQAS durch
|
||||
```
|
||||
|
||||
**Wichtig:** Der Enhanced Orchestrator ist abwärtskompatibel und kann parallel zum Original verwendet werden.
|
||||
|
||||
---
|
||||
|
||||
## 6. Integration BQAS
|
||||
|
||||
Der `QualityJudgeAgent` integriert BQAS mit dem Multi-Agent-System:
|
||||
|
||||
```python
|
||||
# voice-service/bqas/quality_judge_agent.py
|
||||
|
||||
from bqas.judge import LLMJudge
|
||||
from agent_core.orchestrator import MessageBus
|
||||
|
||||
class QualityJudgeAgent:
|
||||
# Wertet Responses in Echtzeit aus
|
||||
# Nutzt Memory für konsistente Bewertungen
|
||||
# Empfängt Evaluierungs-Requests via Message Bus
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Code-Beispiele
|
||||
|
||||
### Session erstellen
|
||||
|
||||
```python
|
||||
from agent_core.sessions import SessionManager
|
||||
|
||||
manager = SessionManager(redis_client=redis, db_pool=pool)
|
||||
session = await manager.create_session(
|
||||
agent_type="tutor-agent",
|
||||
user_id="user-123"
|
||||
)
|
||||
```
|
||||
|
||||
### Memory speichern
|
||||
|
||||
```python
|
||||
from agent_core.brain import MemoryStore
|
||||
|
||||
store = MemoryStore(redis_client=redis, db_pool=pool)
|
||||
await store.remember(
|
||||
key="student:123:progress",
|
||||
value={"level": 5, "score": 85},
|
||||
agent_id="tutor-agent",
|
||||
ttl_days=30
|
||||
)
|
||||
```
|
||||
|
||||
### Nachricht senden
|
||||
|
||||
```python
|
||||
from agent_core.orchestrator import MessageBus, AgentMessage
|
||||
|
||||
bus = MessageBus(redis_client=redis)
|
||||
await bus.publish(AgentMessage(
|
||||
sender="orchestrator",
|
||||
receiver="grader-agent",
|
||||
message_type="grade_request",
|
||||
payload={"exam_id": "exam-1"}
|
||||
))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Tests ausführen
|
||||
|
||||
```bash
|
||||
# Alle Agent-Core Tests
|
||||
cd agent-core && pytest -v
|
||||
|
||||
# Mit Coverage-Report
|
||||
pytest --cov=. --cov-report=html
|
||||
|
||||
# Einzelne Module
|
||||
pytest tests/test_session_manager.py -v
|
||||
pytest tests/test_message_bus.py -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Deployment-Schritte
|
||||
|
||||
### 1. Migration ausführen
|
||||
|
||||
```bash
|
||||
psql -h localhost -U breakpilot -d breakpilot \
|
||||
-f backend/migrations/add_agent_core_tables.sql
|
||||
```
|
||||
|
||||
### 2. Voice-Service aktualisieren
|
||||
|
||||
```bash
|
||||
# Sync zu Server
|
||||
rsync -avz --exclude 'node_modules' --exclude '.git' \
|
||||
/path/to/breakpilot-pwa/ server:/path/to/breakpilot-pwa/
|
||||
|
||||
# Container neu bauen
|
||||
docker compose build --no-cache voice-service
|
||||
|
||||
# Starten
|
||||
docker compose up -d voice-service
|
||||
```
|
||||
|
||||
### 3. Verifizieren
|
||||
|
||||
```bash
|
||||
# Session-Tabelle prüfen
|
||||
psql -c "SELECT COUNT(*) FROM agent_sessions;"
|
||||
|
||||
# Memory-Tabelle prüfen
|
||||
psql -c "SELECT COUNT(*) FROM agent_memory;"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Monitoring
|
||||
|
||||
### Metriken
|
||||
|
||||
| Metrik | Beschreibung |
|
||||
|--------|--------------|
|
||||
| `agent_session_count` | Anzahl aktiver Sessions |
|
||||
| `agent_heartbeat_delay_ms` | Zeit seit letztem Heartbeat |
|
||||
| `agent_message_latency_ms` | Nachrichtenlatenz |
|
||||
| `agent_memory_count` | Gespeicherte Memories |
|
||||
| `agent_routing_success_rate` | Erfolgreiche Routings |
|
||||
|
||||
### Health-Check-Endpunkte
|
||||
|
||||
```
|
||||
GET /api/v1/agents/health # Supervisor Status
|
||||
GET /api/v1/agents/sessions # Aktive Sessions
|
||||
GET /api/v1/agents/memory/stats # Memory-Statistiken
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Troubleshooting
|
||||
|
||||
### Problem: Session nicht gefunden
|
||||
|
||||
1. Prüfen ob Valkey läuft: `redis-cli ping`
|
||||
2. Session-Timeout prüfen (default 24h)
|
||||
3. Heartbeat-Status checken
|
||||
|
||||
### Problem: Message Bus Timeout
|
||||
|
||||
1. Redis Pub/Sub Status prüfen
|
||||
2. Ziel-Agent registriert?
|
||||
3. Timeout erhöhen (default 30s)
|
||||
|
||||
### Problem: Memory nicht gefunden
|
||||
|
||||
1. Namespace korrekt?
|
||||
2. TTL abgelaufen?
|
||||
3. Cleanup-Job gelaufen?
|
||||
|
||||
---
|
||||
|
||||
## 12. Erweiterungen
|
||||
|
||||
### Neuen Agent hinzufügen
|
||||
|
||||
1. SOUL-Datei erstellen in `/agent-core/soul/`
|
||||
2. Routing-Regel in `task_router.py` hinzufügen
|
||||
3. Handler beim Supervisor registrieren
|
||||
4. Tests schreiben
|
||||
|
||||
### Neuen Memory-Typ hinzufügen
|
||||
|
||||
1. Key-Schema definieren (z.B. `student:*:progress`)
|
||||
2. TTL festlegen
|
||||
3. Access-Pattern dokumentieren
|
||||
|
||||
---
|
||||
|
||||
## 13. Referenzen
|
||||
|
||||
- **Agent-Core README:** `/agent-core/README.md`
|
||||
- **Migration:** `/backend/migrations/add_agent_core_tables.sql`
|
||||
- **Voice-Service Integration:** `/voice-service/services/enhanced_task_orchestrator.py`
|
||||
- **BQAS Integration:** `/voice-service/bqas/quality_judge_agent.py`
|
||||
- **Tests:** `/agent-core/tests/`
|
||||
|
||||
---
|
||||
|
||||
## 14. Änderungshistorie
|
||||
|
||||
| Datum | Version | Änderung |
|
||||
|-------|---------|----------|
|
||||
| 2025-01-15 | 1.0.0 | Initial Release |
|
||||
297
.claude/rules/night-scheduler.md
Normal file
297
.claude/rules/night-scheduler.md
Normal file
@@ -0,0 +1,297 @@
|
||||
# Night Scheduler - Entwicklerdokumentation
|
||||
|
||||
**Status:** Produktiv
|
||||
**Letzte Aktualisierung:** 2026-02-09
|
||||
**URL:** https://macmini:3002/infrastructure/night-mode
|
||||
**API:** http://macmini:8096
|
||||
|
||||
---
|
||||
|
||||
## Uebersicht
|
||||
|
||||
Der Night Scheduler ermoeglicht die automatische Nachtabschaltung der Docker-Services:
|
||||
- Zeitgesteuerte Abschaltung (Standard: 22:00)
|
||||
- Zeitgesteuerter Start (Standard: 06:00)
|
||||
- Manuelle Sofortaktionen (Start/Stop)
|
||||
- Dashboard-UI zur Konfiguration
|
||||
|
||||
---
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Admin Dashboard (Port 3002) │
|
||||
│ /infrastructure/night-mode │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ API Proxy: /api/admin/night-mode │
|
||||
│ - GET: Status abrufen │
|
||||
│ - POST: Konfiguration speichern │
|
||||
│ - POST /execute: Sofortaktion (start/stop) │
|
||||
│ - GET /services: Service-Liste │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ night-scheduler (Port 8096) │
|
||||
│ - Python/FastAPI Container │
|
||||
│ - Prueft jede Minute ob Aktion faellig │
|
||||
│ - Fuehrt docker compose start/stop aus │
|
||||
│ - Speichert Config in /config/night-mode.json │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dateien
|
||||
|
||||
| Pfad | Beschreibung |
|
||||
|------|--------------|
|
||||
| `night-scheduler/scheduler.py` | Python Scheduler mit FastAPI |
|
||||
| `night-scheduler/Dockerfile` | Container mit Docker CLI |
|
||||
| `night-scheduler/requirements.txt` | Dependencies |
|
||||
| `night-scheduler/config/night-mode.json` | Konfigurationsdatei |
|
||||
| `night-scheduler/tests/test_scheduler.py` | Unit Tests |
|
||||
| `admin-v2/app/api/admin/night-mode/route.ts` | API Proxy |
|
||||
| `admin-v2/app/api/admin/night-mode/execute/route.ts` | Execute Endpoint |
|
||||
| `admin-v2/app/api/admin/night-mode/services/route.ts` | Services Endpoint |
|
||||
| `admin-v2/app/(admin)/infrastructure/night-mode/page.tsx` | UI Seite |
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### GET /api/night-mode
|
||||
Status und Konfiguration abrufen.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"enabled": true,
|
||||
"shutdown_time": "22:00",
|
||||
"startup_time": "06:00",
|
||||
"last_action": "startup",
|
||||
"last_action_time": "2026-02-09T06:00:00",
|
||||
"excluded_services": ["night-scheduler", "nginx"]
|
||||
},
|
||||
"current_time": "14:30:00",
|
||||
"next_action": "shutdown",
|
||||
"next_action_time": "22:00",
|
||||
"time_until_next_action": "7h 30min",
|
||||
"services_status": {
|
||||
"backend": "running",
|
||||
"postgres": "running"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### POST /api/night-mode
|
||||
Konfiguration aktualisieren.
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"enabled": true,
|
||||
"shutdown_time": "23:00",
|
||||
"startup_time": "07:00",
|
||||
"excluded_services": ["night-scheduler", "nginx", "vault"]
|
||||
}
|
||||
```
|
||||
|
||||
### POST /api/night-mode/execute
|
||||
Sofortige Aktion ausfuehren.
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"action": "stop" // oder "start"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Aktion 'stop' erfolgreich ausgefuehrt fuer 25 Services"
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/night-mode/services
|
||||
Liste aller Services abrufen.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"all_services": ["backend", "postgres", "valkey", ...],
|
||||
"excluded_services": ["night-scheduler", "nginx"],
|
||||
"status": {
|
||||
"backend": "running",
|
||||
"postgres": "running"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Konfiguration
|
||||
|
||||
### Config-Format (night-mode.json)
|
||||
|
||||
```json
|
||||
{
|
||||
"enabled": true,
|
||||
"shutdown_time": "22:00",
|
||||
"startup_time": "06:00",
|
||||
"last_action": "startup",
|
||||
"last_action_time": "2026-02-09T06:00:00",
|
||||
"excluded_services": ["night-scheduler", "nginx"]
|
||||
}
|
||||
```
|
||||
|
||||
### Umgebungsvariablen
|
||||
|
||||
| Variable | Default | Beschreibung |
|
||||
|----------|---------|--------------|
|
||||
| `COMPOSE_PROJECT_NAME` | `breakpilot-pwa` | Docker Compose Projektname |
|
||||
|
||||
---
|
||||
|
||||
## Ausgeschlossene Services
|
||||
|
||||
Diese Services werden NICHT gestoppt:
|
||||
|
||||
1. **night-scheduler** - Muss laufen, um Services zu starten
|
||||
2. **nginx** - Optional, fuer HTTPS-Zugriff
|
||||
|
||||
Weitere Services koennen ueber die Konfiguration ausgeschlossen werden.
|
||||
|
||||
---
|
||||
|
||||
## Docker Compose Integration
|
||||
|
||||
```yaml
|
||||
night-scheduler:
|
||||
build: ./night-scheduler
|
||||
container_name: breakpilot-pwa-night-scheduler
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./night-scheduler/config:/config
|
||||
- ./docker-compose.yml:/app/docker-compose.yml:ro
|
||||
environment:
|
||||
- COMPOSE_PROJECT_NAME=breakpilot-pwa
|
||||
ports:
|
||||
- "8096:8096"
|
||||
networks:
|
||||
- breakpilot-pwa-network
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tests ausfuehren
|
||||
|
||||
```bash
|
||||
# Im Container
|
||||
docker exec -it breakpilot-pwa-night-scheduler pytest -v
|
||||
|
||||
# Lokal (mit Dependencies)
|
||||
cd night-scheduler
|
||||
pip install -r requirements.txt
|
||||
pytest -v tests/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
```bash
|
||||
# 1. Dateien synchronisieren
|
||||
rsync -avz night-scheduler/ macmini:.../night-scheduler/
|
||||
|
||||
# 2. Container bauen
|
||||
ssh macmini "docker compose -f .../docker-compose.yml build --no-cache night-scheduler"
|
||||
|
||||
# 3. Container starten
|
||||
ssh macmini "docker compose -f .../docker-compose.yml up -d night-scheduler"
|
||||
|
||||
# 4. Testen
|
||||
curl http://macmini:8096/health
|
||||
curl http://macmini:8096/api/night-mode
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Problem: Services werden nicht gestoppt/gestartet
|
||||
|
||||
1. Pruefen ob Docker Socket gemountet ist:
|
||||
```bash
|
||||
docker exec breakpilot-pwa-night-scheduler ls -la /var/run/docker.sock
|
||||
```
|
||||
|
||||
2. Pruefen ob docker compose CLI verfuegbar ist:
|
||||
```bash
|
||||
docker exec breakpilot-pwa-night-scheduler docker compose version
|
||||
```
|
||||
|
||||
3. Logs pruefen:
|
||||
```bash
|
||||
docker logs breakpilot-pwa-night-scheduler
|
||||
```
|
||||
|
||||
### Problem: Konfiguration wird nicht gespeichert
|
||||
|
||||
1. Pruefen ob /config beschreibbar ist:
|
||||
```bash
|
||||
docker exec breakpilot-pwa-night-scheduler touch /config/test
|
||||
```
|
||||
|
||||
2. Volume-Mount pruefen in docker-compose.yml
|
||||
|
||||
### Problem: API nicht erreichbar
|
||||
|
||||
1. Container-Status pruefen:
|
||||
```bash
|
||||
docker ps | grep night-scheduler
|
||||
```
|
||||
|
||||
2. Health-Check pruefen:
|
||||
```bash
|
||||
curl http://localhost:8096/health
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Sicherheitshinweise
|
||||
|
||||
- Der Container benoetigt Zugriff auf den Docker Socket
|
||||
- Nur interne Services koennen gestoppt/gestartet werden
|
||||
- Keine Authentifizierung (internes Netzwerk)
|
||||
- Keine sensitiven Daten in der Konfiguration
|
||||
|
||||
---
|
||||
|
||||
## Dependencies (SBOM)
|
||||
|
||||
| Package | Version | Lizenz |
|
||||
|---------|---------|--------|
|
||||
| FastAPI | 0.109.0 | MIT |
|
||||
| Uvicorn | 0.27.0 | BSD-3-Clause |
|
||||
| Pydantic | 2.5.3 | MIT |
|
||||
| pytest | 8.0.0 | MIT |
|
||||
| pytest-asyncio | 0.23.0 | Apache-2.0 |
|
||||
| httpx | 0.26.0 | BSD-3-Clause |
|
||||
|
||||
---
|
||||
|
||||
## Aenderungshistorie
|
||||
|
||||
| Datum | Aenderung |
|
||||
|-------|-----------|
|
||||
| 2026-02-09 | Initiale Implementierung |
|
||||
|
||||
99
.claude/rules/open-source-policy.md
Normal file
99
.claude/rules/open-source-policy.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Open Source Policy
|
||||
|
||||
## Lizenzprüfung (AUTOMATISCH BEI JEDER DEPENDENCY)
|
||||
|
||||
### Erlaubte Lizenzen ✅
|
||||
|
||||
| Lizenz | Typ | Kommerziell OK |
|
||||
|--------|-----|----------------|
|
||||
| MIT | Permissive | ✅ |
|
||||
| Apache-2.0 | Permissive | ✅ |
|
||||
| BSD-2-Clause | Permissive | ✅ |
|
||||
| BSD-3-Clause | Permissive | ✅ |
|
||||
| ISC | Permissive | ✅ |
|
||||
| MPL-2.0 | Weak Copyleft | ✅ |
|
||||
| LGPL-2.1 / LGPL-3.0 | Weak Copyleft | ✅ (nur linking) |
|
||||
| CC0-1.0 | Public Domain | ✅ |
|
||||
| Unlicense | Public Domain | ✅ |
|
||||
|
||||
### Verbotene Lizenzen ❌
|
||||
|
||||
| Lizenz | Grund |
|
||||
|--------|-------|
|
||||
| GPL-2.0 / GPL-3.0 | Copyleft - infiziert Projekt |
|
||||
| AGPL-3.0 | Network Copyleft - SaaS-Killer |
|
||||
| SSPL | Server Side Public License |
|
||||
| BSL | Business Source License |
|
||||
| "Non-Commercial" | Keine kommerzielle Nutzung |
|
||||
| "Educational Only" | Nur für Bildung |
|
||||
| Proprietary | Keine OSS |
|
||||
|
||||
---
|
||||
|
||||
## Workflow bei neuer Dependency
|
||||
|
||||
### 1. Vor dem Hinzufügen prüfen
|
||||
|
||||
```bash
|
||||
# NPM Package
|
||||
npm view <package> license
|
||||
|
||||
# Python Package
|
||||
pip show <package> | grep License
|
||||
|
||||
# Go Module
|
||||
go-licenses check <module>
|
||||
```
|
||||
|
||||
### 2. Bei Unklarheit
|
||||
|
||||
- README.md des Projekts lesen
|
||||
- LICENSE-Datei prüfen
|
||||
- SPDX-Identifier suchen
|
||||
- Im Zweifel: **NICHT verwenden**
|
||||
|
||||
### 3. Nach dem Hinzufügen
|
||||
|
||||
**SBOM aktualisieren:** https://macmini:3002/infrastructure/sbom
|
||||
|
||||
```bash
|
||||
# SBOM generieren
|
||||
cd /Users/benjaminadmin/Projekte/breakpilot-pwa
|
||||
|
||||
# Python
|
||||
pip-licenses --format=json > sbom/python-licenses.json
|
||||
|
||||
# Node.js
|
||||
npx license-checker --json > sbom/node-licenses.json
|
||||
|
||||
# Go
|
||||
go-licenses csv ./... > sbom/go-licenses.csv
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Grenzfälle
|
||||
|
||||
### Dual-Licensed Packages
|
||||
- Wenn MIT **oder** GPL angeboten wird → MIT wählen
|
||||
- Dokumentieren welche Lizenz gewählt wurde
|
||||
|
||||
### Transitive Dependencies
|
||||
- Auch indirekte Abhängigkeiten prüfen
|
||||
- `npm ls`, `pip-tree`, `go mod graph`
|
||||
|
||||
### Fonts & Assets
|
||||
- Google Fonts: ✅ (OFL)
|
||||
- Font Awesome Free: ✅ (CC BY 4.0 / OFL / MIT)
|
||||
- Icons8: ❌ (Attribution required, kompliziert)
|
||||
|
||||
---
|
||||
|
||||
## Checkliste bei PR/Commit
|
||||
|
||||
Wenn neue Dependencies hinzugefügt wurden:
|
||||
|
||||
- [ ] Lizenz ist in der Whitelist
|
||||
- [ ] SBOM wurde aktualisiert
|
||||
- [ ] Keine GPL/AGPL-Abhängigkeiten eingeschleppt
|
||||
- [ ] Bei Dual-License: MIT/Apache gewählt
|
||||
202
.claude/rules/testing.md
Normal file
202
.claude/rules/testing.md
Normal file
@@ -0,0 +1,202 @@
|
||||
# Test-Regeln
|
||||
|
||||
## Automatische Test-Erweiterung
|
||||
|
||||
**WICHTIG:** Bei JEDER Code-Änderung müssen entsprechende Tests erstellt oder aktualisiert werden!
|
||||
|
||||
## Wann Tests schreiben?
|
||||
|
||||
### IMMER wenn du:
|
||||
1. **Neue Funktionen** erstellst → Unit Test
|
||||
2. **Neue API-Endpoints** hinzufügst → Handler Test
|
||||
3. **Bugs fixst** → Regression Test (der Bug sollte nie wieder auftreten)
|
||||
4. **Bestehenden Code änderst** → Bestehende Tests anpassen
|
||||
|
||||
## Test-Struktur
|
||||
|
||||
### Go Tests (Consent Service)
|
||||
|
||||
**Speicherort:** Im gleichen Verzeichnis wie der Code
|
||||
|
||||
```
|
||||
internal/
|
||||
├── services/
|
||||
│ ├── auth_service.go
|
||||
│ └── auth_service_test.go ← Test hier
|
||||
├── handlers/
|
||||
│ ├── handlers.go
|
||||
│ └── handlers_test.go ← Test hier
|
||||
└── middleware/
|
||||
├── auth.go
|
||||
└── middleware_test.go ← Test hier
|
||||
```
|
||||
|
||||
**Test-Namenskonvention:**
|
||||
```go
|
||||
func TestFunctionName_Scenario_ExpectedResult(t *testing.T)
|
||||
|
||||
// Beispiele:
|
||||
func TestHashPassword_ValidPassword_ReturnsHash(t *testing.T)
|
||||
func TestLogin_InvalidCredentials_Returns401(t *testing.T)
|
||||
func TestCreateDocument_MissingTitle_ReturnsError(t *testing.T)
|
||||
```
|
||||
|
||||
**Test-Template:**
|
||||
```go
|
||||
func TestFunctionName(t *testing.T) {
|
||||
// Arrange
|
||||
service := &MyService{}
|
||||
input := "test-input"
|
||||
|
||||
// Act
|
||||
result, err := service.DoSomething(input)
|
||||
|
||||
// Assert
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
if result != expected {
|
||||
t.Errorf("Expected %v, got %v", expected, result)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Table-Driven Tests bevorzugen:**
|
||||
```go
|
||||
func TestValidateEmail(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
email string
|
||||
expected bool
|
||||
}{
|
||||
{"valid email", "test@example.com", true},
|
||||
{"missing @", "testexample.com", false},
|
||||
{"empty", "", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := ValidateEmail(tt.email)
|
||||
if result != tt.expected {
|
||||
t.Errorf("Expected %v, got %v", tt.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Python Tests (Backend)
|
||||
|
||||
**Speicherort:** `/backend/tests/`
|
||||
|
||||
```
|
||||
backend/
|
||||
├── consent_client.py
|
||||
├── gdpr_api.py
|
||||
└── tests/
|
||||
├── __init__.py
|
||||
├── test_consent_client.py ← Tests für consent_client.py
|
||||
└── test_gdpr_api.py ← Tests für gdpr_api.py
|
||||
```
|
||||
|
||||
**Test-Namenskonvention:**
|
||||
```python
|
||||
class TestClassName:
|
||||
def test_method_scenario_expected_result(self):
|
||||
pass
|
||||
|
||||
# Beispiele:
|
||||
class TestConsentClient:
|
||||
def test_check_consent_valid_token_returns_status(self):
|
||||
pass
|
||||
|
||||
def test_check_consent_expired_token_raises_error(self):
|
||||
pass
|
||||
```
|
||||
|
||||
**Test-Template:**
|
||||
```python
|
||||
import pytest
|
||||
from unittest.mock import AsyncMock, patch, MagicMock
|
||||
|
||||
class TestMyFeature:
|
||||
def test_sync_function(self):
|
||||
# Arrange
|
||||
input_data = "test"
|
||||
|
||||
# Act
|
||||
result = my_function(input_data)
|
||||
|
||||
# Assert
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_async_function(self):
|
||||
# Arrange
|
||||
client = MyClient()
|
||||
|
||||
# Act
|
||||
with patch("httpx.AsyncClient") as mock:
|
||||
mock_instance = AsyncMock()
|
||||
mock.return_value = mock_instance
|
||||
result = await client.fetch_data()
|
||||
|
||||
# Assert
|
||||
assert result is not None
|
||||
```
|
||||
|
||||
## Test-Kategorien
|
||||
|
||||
### 1. Unit Tests (Höchste Priorität)
|
||||
- Testen einzelne Funktionen/Methoden
|
||||
- Keine externen Abhängigkeiten (Mocks verwenden)
|
||||
- Schnell ausführbar
|
||||
|
||||
### 2. Integration Tests
|
||||
- Testen Zusammenspiel mehrerer Komponenten
|
||||
- Können echte DB verwenden (Test-DB)
|
||||
|
||||
### 3. Security Tests
|
||||
- Auth/JWT Validierung
|
||||
- Passwort-Hashing
|
||||
- Berechtigungsprüfung
|
||||
|
||||
## Checkliste vor Abschluss
|
||||
|
||||
Vor dem Abschluss einer Aufgabe:
|
||||
|
||||
- [ ] Gibt es Tests für alle neuen Funktionen?
|
||||
- [ ] Gibt es Tests für alle Edge Cases?
|
||||
- [ ] Gibt es Tests für Fehlerfälle?
|
||||
- [ ] Laufen alle bestehenden Tests noch? (`go test ./...` / `pytest`)
|
||||
- [ ] Ist die Test-Coverage angemessen?
|
||||
|
||||
## Tests ausführen
|
||||
|
||||
```bash
|
||||
# Go - Alle Tests
|
||||
cd consent-service && go test -v ./...
|
||||
|
||||
# Go - Mit Coverage
|
||||
cd consent-service && go test -cover ./...
|
||||
|
||||
# Python - Alle Tests
|
||||
cd backend && source venv/bin/activate && pytest -v
|
||||
|
||||
# Python - Mit Coverage
|
||||
cd backend && pytest --cov=. --cov-report=html
|
||||
```
|
||||
|
||||
## Beispiel: Vollständiger Test-Workflow
|
||||
|
||||
Wenn du z.B. eine neue `GetUserStats()` Funktion im Go Service hinzufügst:
|
||||
|
||||
1. **Funktion schreiben** in `internal/services/stats_service.go`
|
||||
2. **Test erstellen** in `internal/services/stats_service_test.go`:
|
||||
```go
|
||||
func TestGetUserStats_ValidUser_ReturnsStats(t *testing.T) {...}
|
||||
func TestGetUserStats_InvalidUser_ReturnsError(t *testing.T) {...}
|
||||
func TestGetUserStats_NoConsents_ReturnsEmptyStats(t *testing.T) {...}
|
||||
```
|
||||
3. **Tests ausführen**: `go test -v ./internal/services/...`
|
||||
4. **Dokumentation aktualisieren** (siehe documentation.md)
|
||||
205
.claude/rules/vocab-worksheet.md
Normal file
205
.claude/rules/vocab-worksheet.md
Normal file
@@ -0,0 +1,205 @@
|
||||
# Vokabel-Arbeitsblatt Generator - Entwicklerdokumentation
|
||||
|
||||
**Status:** Produktiv
|
||||
**Letzte Aktualisierung:** 2026-02-08
|
||||
**URL:** https://macmini/vocab-worksheet
|
||||
|
||||
---
|
||||
|
||||
## Uebersicht
|
||||
|
||||
Der Vokabel-Arbeitsblatt Generator ermoeglicht Lehrern:
|
||||
- Schulbuchseiten (PDF/Bild) zu scannen
|
||||
- Vokabeln automatisch per OCR zu extrahieren
|
||||
- Druckfertige Arbeitsblaetter in verschiedenen Formaten zu generieren
|
||||
|
||||
---
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
Browser (studio-v2) klausur-service (Port 8086) PostgreSQL
|
||||
│ │ │
|
||||
│ POST /upload-pdf-info │ │
|
||||
│ POST /process-single-page │ │
|
||||
│ POST /generate │ │
|
||||
│ POST /generate-nru │ ──── vocab_sessions ──────▶│
|
||||
│ GET /worksheets/{id}/pdf │ ──── vocab_entries ───────▶│
|
||||
│ │ ──── vocab_worksheets ────▶│
|
||||
└────────────────────────────┘ │
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Arbeitsblatt-Formate
|
||||
|
||||
### Standard-Format
|
||||
|
||||
Klassisches Arbeitsblatt mit waehlbaren Uebungstypen:
|
||||
- **Englisch → Deutsch**: Englische Woerter uebersetzen
|
||||
- **Deutsch → Englisch**: Deutsche Woerter uebersetzen
|
||||
- **Abschreibuebung**: Woerter mehrfach schreiben
|
||||
- **Lueckensaetze**: Saetze mit Luecken ausfuellen
|
||||
|
||||
### NRU-Format (Neu: 2026-02-08)
|
||||
|
||||
Spezielles Format fuer strukturiertes Vokabellernen:
|
||||
|
||||
**Seite 1 (pro gescannter Seite): Vokabeltabelle**
|
||||
| Englisch | Deutsch | Korrektur |
|
||||
|----------|---------|-----------|
|
||||
| word | (leer) | (leer) |
|
||||
|
||||
- Kind schreibt deutsche Uebersetzung
|
||||
- Eltern korrigieren, Kind schreibt ggf. korrigierte Version
|
||||
|
||||
**Seite 2 (pro gescannter Seite): Lernsaetze**
|
||||
| Deutscher Satz |
|
||||
|-----------------------------------|
|
||||
| (2 leere Zeilen fuer EN-Uebersetzung) |
|
||||
|
||||
- Deutscher Satz vorgegeben
|
||||
- Kind schreibt englische Uebersetzung
|
||||
|
||||
**Automatische Trennung:**
|
||||
- Einzelwoerter/Phrasen → Vokabeltabelle
|
||||
- Saetze (enden mit `.!?` oder > 50 Zeichen) → Lernsaetze
|
||||
|
||||
---
|
||||
|
||||
## API-Endpoints
|
||||
|
||||
### Standard-Format
|
||||
```
|
||||
POST /api/v1/vocab/sessions/{session_id}/generate
|
||||
Body: {
|
||||
"worksheet_types": ["en_to_de", "de_to_en", "copy", "gap_fill"],
|
||||
"title": "Vokabeln Unit 3",
|
||||
"include_solutions": true,
|
||||
"line_height": "normal" | "large" | "extra-large"
|
||||
}
|
||||
Response: { "id": "worksheet-uuid", ... }
|
||||
```
|
||||
|
||||
### NRU-Format
|
||||
```
|
||||
POST /api/v1/vocab/sessions/{session_id}/generate-nru
|
||||
Body: {
|
||||
"title": "Vokabeltest",
|
||||
"include_solutions": true,
|
||||
"specific_pages": [1, 2] // optional, 1-indexed
|
||||
}
|
||||
Response: {
|
||||
"worksheet_id": "uuid",
|
||||
"statistics": {
|
||||
"total_entries": 96,
|
||||
"vocabulary_count": 75,
|
||||
"sentence_count": 21,
|
||||
"source_pages": [1, 2, 3],
|
||||
"worksheet_pages": 6
|
||||
},
|
||||
"download_url": "/api/v1/vocab/worksheets/{id}/pdf",
|
||||
"solution_url": "/api/v1/vocab/worksheets/{id}/solution"
|
||||
}
|
||||
```
|
||||
|
||||
### PDF-Download
|
||||
```
|
||||
GET /api/v1/vocab/worksheets/{worksheet_id}/pdf
|
||||
GET /api/v1/vocab/worksheets/{worksheet_id}/solution
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dateien
|
||||
|
||||
### Backend (klausur-service)
|
||||
|
||||
| Datei | Beschreibung |
|
||||
|-------|--------------|
|
||||
| `vocab_worksheet_api.py` | Haupt-API Router mit allen Endpoints |
|
||||
| `nru_worksheet_generator.py` | NRU-Format HTML/PDF Generator |
|
||||
| `vocab_session_store.py` | PostgreSQL Datenbankoperationen |
|
||||
| `hybrid_vocab_extractor.py` | OCR-Extraktion (PaddleOCR + LLM) |
|
||||
| `tesseract_vocab_extractor.py` | Tesseract OCR Fallback |
|
||||
|
||||
### Frontend (studio-v2)
|
||||
|
||||
| Datei | Beschreibung |
|
||||
|-------|--------------|
|
||||
| `app/vocab-worksheet/page.tsx` | Haupt-UI mit Template-Auswahl |
|
||||
|
||||
---
|
||||
|
||||
## Datenbank-Schema
|
||||
|
||||
```sql
|
||||
-- Sessions
|
||||
CREATE TABLE vocab_sessions (
|
||||
id UUID PRIMARY KEY,
|
||||
name VARCHAR(255),
|
||||
status VARCHAR(50),
|
||||
vocabulary_count INT,
|
||||
source_language VARCHAR(10),
|
||||
target_language VARCHAR(10),
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- Vokabeln
|
||||
CREATE TABLE vocab_entries (
|
||||
id UUID PRIMARY KEY,
|
||||
session_id UUID REFERENCES vocab_sessions(id),
|
||||
english TEXT,
|
||||
german TEXT,
|
||||
example_sentence TEXT,
|
||||
source_page INT,
|
||||
source_row INT,
|
||||
source_column INT
|
||||
);
|
||||
|
||||
-- Generierte Arbeitsblaetter
|
||||
CREATE TABLE vocab_worksheets (
|
||||
id UUID PRIMARY KEY,
|
||||
session_id UUID REFERENCES vocab_sessions(id),
|
||||
worksheet_types JSONB,
|
||||
pdf_path VARCHAR(500),
|
||||
solution_path VARCHAR(500),
|
||||
generated_at TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
```bash
|
||||
# 1. Backend synchronisieren
|
||||
rsync -avz klausur-service/backend/ macmini:.../klausur-service/backend/
|
||||
|
||||
# 2. Frontend synchronisieren
|
||||
rsync -avz studio-v2/app/vocab-worksheet/ macmini:.../studio-v2/app/vocab-worksheet/
|
||||
|
||||
# 3. Container neu bauen
|
||||
ssh macmini "docker compose build --no-cache klausur-service studio-v2"
|
||||
|
||||
# 4. Container starten
|
||||
ssh macmini "docker compose up -d klausur-service studio-v2"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Erweiterung: Neue Formate hinzufuegen
|
||||
|
||||
1. **Backend**: Neuen Generator in `klausur-service/backend/` erstellen
|
||||
2. **API**: Neuen Endpoint in `vocab_worksheet_api.py` hinzufuegen
|
||||
3. **Frontend**: Format zu `worksheetFormats` Array in `page.tsx` hinzufuegen
|
||||
4. **Doku**: Diese Datei aktualisieren
|
||||
|
||||
---
|
||||
|
||||
## Aenderungshistorie
|
||||
|
||||
| Datum | Aenderung |
|
||||
|-------|-----------|
|
||||
| 2026-02-08 | NRU-Format und Template-Auswahl hinzugefuegt |
|
||||
| 2026-02-07 | Initiale Implementierung mit Standard-Format |
|
||||
117
.claude/session-status-2026-01-25.md
Normal file
117
.claude/session-status-2026-01-25.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Session Status - 25. Januar 2026 (Aktualisiert)
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
Open Data School Import erfolgreich implementiert. Schulbestand von 17,610 auf 30,355 erhoeht.
|
||||
|
||||
---
|
||||
|
||||
## Erledigte Aufgaben
|
||||
|
||||
### 1. Studio-v2 Build-Fehler (Vorherige Session)
|
||||
- **Status:** Erledigt
|
||||
- **Problem:** `Module not found: Can't resolve 'pdf-lib'`
|
||||
- **Loesung:** Falsches package.json auf macmini ersetzt, rsync mit --delete
|
||||
|
||||
### 2. Open Data School Importer
|
||||
- **Status:** Erledigt
|
||||
- **Datei:** `/edu-search-service/scripts/import_open_data.py`
|
||||
- **Erfolgreich importiert:**
|
||||
- **NRW:** 5,637 Schulen (CSV von schulministerium.nrw.de)
|
||||
- **Berlin:** 930 Schulen (WFS/GeoJSON von gdi.berlin.de)
|
||||
- **Hamburg:** 543 Schulen (WFS/GML von geodienste.hamburg.de)
|
||||
|
||||
---
|
||||
|
||||
## Aktuelle Schulstatistiken
|
||||
|
||||
```
|
||||
Total: 30,355 Schulen
|
||||
|
||||
Nach Bundesland:
|
||||
NW: 14,962 (inkl. Open Data Import)
|
||||
BY: 2,803
|
||||
NI: 2,192
|
||||
BE: 1,475 (inkl. WFS Import)
|
||||
SN: 1,425
|
||||
SH: 1,329
|
||||
HE: 1,290
|
||||
RP: 1,066
|
||||
HH: 902 (inkl. WFS Import)
|
||||
TH: 799
|
||||
BB: 562
|
||||
SL: 533
|
||||
MV: 367
|
||||
ST: 250
|
||||
BW: 200 (nur JedeSchule.de - BW Daten kostenpflichtig!)
|
||||
HB: 200
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Open Data Importer - Verfuegbare Quellen
|
||||
|
||||
| Bundesland | Status | Quelle | Format |
|
||||
|------------|--------|--------|--------|
|
||||
| NW | Funktioniert | schulministerium.nrw.de | CSV |
|
||||
| BE | Funktioniert | gdi.berlin.de | WFS/GeoJSON |
|
||||
| HH | Funktioniert | geodienste.hamburg.de | WFS/GML |
|
||||
| SN | 404 Error | schuldatenbank.sachsen.de | API |
|
||||
| BW | Kostenpflichtig | LOBW | - |
|
||||
| BY | Kein Open Data | - | - |
|
||||
|
||||
---
|
||||
|
||||
## Importer-Nutzung
|
||||
|
||||
```bash
|
||||
# Alle verfuegbaren Quellen importieren
|
||||
cd /Users/benjaminadmin/Projekte/breakpilot-pwa/edu-search-service/scripts
|
||||
python3 import_open_data.py --all --url http://macmini:8088
|
||||
|
||||
# Einzelnes Bundesland (Dry-Run)
|
||||
python3 import_open_data.py --state NW --dry-run
|
||||
|
||||
# Mit Server-URL
|
||||
python3 import_open_data.py --state HH --url http://macmini:8088
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Offene Punkte
|
||||
|
||||
### Bundeslaender ohne Open Data
|
||||
- **BW:** Schuldaten muessen GEKAUFT werden (LOBW)
|
||||
- **BY:** Keine Open Data API gefunden
|
||||
- **NI, HE, RP, etc.:** Keine zentralen Open Data Quellen bekannt
|
||||
|
||||
### Moegliche weitere Quellen
|
||||
- OSM (OpenStreetMap) - amenity=school
|
||||
- Statistisches Bundesamt
|
||||
- Lokale Schultraeger-Verzeichnisse
|
||||
|
||||
---
|
||||
|
||||
## Container-Status auf macmini
|
||||
|
||||
| Container | Port | Status |
|
||||
|-----------|------|--------|
|
||||
| website | 3000 | Laeuft |
|
||||
| studio-v2 | 3001 | Laeuft |
|
||||
| edu-search-service | 8088 | Laeuft |
|
||||
|
||||
---
|
||||
|
||||
## Wichtige URLs
|
||||
|
||||
- School Directory: http://macmini:3000/admin/school-directory
|
||||
- School Stats API: http://macmini:8088/api/v1/schools/stats
|
||||
- School Search API: http://macmini:8088/api/v1/schools?q=NAME
|
||||
|
||||
---
|
||||
|
||||
## Naechste moegliche Schritte
|
||||
|
||||
1. **OSM Import testen** - OpenStreetMap hat Schuldaten (amenity=school)
|
||||
2. **Weitere WFS-Quellen suchen** - Andere Bundeslaender koennten Geo-Portale haben
|
||||
3. **Deduplizierung** - Pruefen ob durch multiple Imports Duplikate entstanden sind
|
||||
36
.claude/settings.json
Normal file
36
.claude/settings.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"hooks": {
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Edit|Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ~/.claude/hooks/breakpilot-post-edit.py",
|
||||
"timeout": 15000
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Stop": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "prompt",
|
||||
"prompt": "Überprüfe ob bei dieser Aufgabe:\n1. Dokumentation aktualisiert werden muss (neue API, neue Funktion, Architektur-Änderung)\n2. Tests geschrieben/aktualisiert werden müssen (neue Funktion, Bug-Fix, Code-Änderung)\n3. Ein ADR (Architecture Decision Record) erstellt werden sollte (neues Modul, Technologiewechsel, signifikante Architektur-Entscheidung)\n\nWenn etwas fehlt, antworte mit {\"decision\": \"block\", \"reason\": \"Fehlend: [Details]\"}\nWenn alles erledigt ist, antworte mit {\"decision\": \"approve\", \"reason\": \"Alle Dokumentation, Tests und ADRs sind aktuell\"}",
|
||||
"timeout": 30000
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Read(docs/**)",
|
||||
"Read(.claude/**)",
|
||||
"Read(backend/tests/**)",
|
||||
"Read(consent-service/**/*_test.go)",
|
||||
"Write(docs/adr/**)"
|
||||
]
|
||||
}
|
||||
}
|
||||
82
.claude/settings.local.json
Normal file
82
.claude/settings.local.json
Normal file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(textutil -convert txt:*)",
|
||||
"Bash(find:*)",
|
||||
"Bash(grep:*)",
|
||||
"Bash(wc:*)",
|
||||
"Bash(/bin/bash -c \"source venv/bin/activate && pip install pyjwt --quiet 2>/dev/null && python -c \"\"import sys; sys.path.insert(0, ''.''); from llm_gateway.models.chat import ChatMessage; print(''Models import OK'')\"\"\")",
|
||||
"Bash(/Users/benjaminadmin/Projekte/breakpilot-pwa/backend/venv/bin/python:*)",
|
||||
"Bash(./venv/bin/pip install:*)",
|
||||
"Bash(brew install:*)",
|
||||
"Bash(brew services start:*)",
|
||||
"Bash(ollama list:*)",
|
||||
"Bash(ollama pull:*)",
|
||||
"Bash(export LLM_GATEWAY_ENABLED=true)",
|
||||
"Bash(export LLM_GATEWAY_DEBUG=true)",
|
||||
"Bash(export LLM_API_KEYS=test-key-123)",
|
||||
"Bash(export ANTHROPIC_API_KEY=\"$ANTHROPIC_API_KEY\")",
|
||||
"Bash(source:*)",
|
||||
"Bash(pytest:*)",
|
||||
"Bash(./venv/bin/pytest:*)",
|
||||
"Bash(python3 -m pytest:*)",
|
||||
"Bash(export TAVILY_API_KEY=\"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\")",
|
||||
"Bash(python3:*)",
|
||||
"Bash(curl:*)",
|
||||
"Bash(pip3 install:*)",
|
||||
"WebSearch",
|
||||
"Bash(export ALERTS_AGENT_ENABLED=true)",
|
||||
"Bash(export LLM_API_KEYS=test-key)",
|
||||
"WebFetch(domain:docs.vast.ai)",
|
||||
"Bash(docker compose:*)",
|
||||
"Bash(docker ps:*)",
|
||||
"Bash(docker inspect:*)",
|
||||
"Bash(docker logs:*)",
|
||||
"Bash(ls:*)",
|
||||
"Bash(docker exec:*)",
|
||||
"WebFetch(domain:www.librechat.ai)",
|
||||
"Bash(export TAVILY_API_KEY=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)",
|
||||
"Bash(/Users/benjaminadmin/Projekte/breakpilot-pwa/backend/venv/bin/pip install:*)",
|
||||
"Bash(/Users/benjaminadmin/Projekte/breakpilot-pwa/backend/venv/bin/pytest -v tests/test_integration/test_librechat_tavily.py -x)",
|
||||
"WebFetch(domain:vast.ai)",
|
||||
"Bash(/Users/benjaminadmin/Projekte/breakpilot-pwa/backend/venv/bin/pytest tests/test_infra/test_vast_client.py tests/test_infra/test_vast_power.py -v --tb=short)",
|
||||
"Bash(go build:*)",
|
||||
"Bash(go test:*)",
|
||||
"Bash(npm install)",
|
||||
"Bash(/usr/local/bin/node:*)",
|
||||
"Bash(/opt/homebrew/bin/node --version)",
|
||||
"Bash(docker --version:*)",
|
||||
"Bash(docker build:*)",
|
||||
"Bash(docker images:*)",
|
||||
"Bash(/Users/benjaminadmin/Projekte/breakpilot-pwa/backend/venv/bin/pytest:*)",
|
||||
"Bash(npm test:*)",
|
||||
"Bash(/opt/homebrew/bin/node /opt/homebrew/bin/npm test -- --passWithNoTests)",
|
||||
"Bash(/usr/libexec/java_home:*)",
|
||||
"Bash(/opt/homebrew/bin/node:*)",
|
||||
"Bash(docker restart:*)",
|
||||
"Bash(tree:*)",
|
||||
"Bash(go mod tidy:*)",
|
||||
"Bash(go mod vendor:*)",
|
||||
"Bash(python -m pytest:*)",
|
||||
"Bash(lsof:*)",
|
||||
"Bash(python scripts/load_initial_seeds.py:*)",
|
||||
"Bash(python:*)",
|
||||
"Bash(docker cp:*)",
|
||||
"Bash(node --check:*)",
|
||||
"Bash(cat:*)",
|
||||
"Bash(DATABASE_URL='postgresql://breakpilot:breakpilot123@localhost:5432/breakpilot_db' python3:*)",
|
||||
"Bash(docker volume:*)",
|
||||
"Bash(docker stop:*)",
|
||||
"Bash(docker rm:*)",
|
||||
"Bash(docker run:*)",
|
||||
"Bash(docker network:*)",
|
||||
"Bash(breakpilot-edu-search:latest)",
|
||||
"Bash(jq:*)",
|
||||
"Bash(docker port:*)",
|
||||
"Bash(/dev/null curl -X POST http://localhost:8086/v1/crawl/queue -H 'Authorization: Bearer dev-key' -H 'Content-Type: application/json' -d '{\"\"\"\"university_id\"\"\"\": \"\"\"\"783333a1-91a3-4015-9299-45d10537dae4\"\"\"\", \"\"\"\"priority\"\"\"\": 10}')",
|
||||
"Bash(1)",
|
||||
"WebFetch(domain:uol.de)",
|
||||
"Bash(xargs:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
237
.claude/skills/debug-framework.md
Normal file
237
.claude/skills/debug-framework.md
Normal file
@@ -0,0 +1,237 @@
|
||||
# Systematisches Debug-Framework
|
||||
|
||||
## Trigger
|
||||
|
||||
Dieses Skill aktivieren bei:
|
||||
- Fehlermeldungen / Exceptions
|
||||
- Unerwartetes Verhalten
|
||||
- Performance-Probleme
|
||||
- "Es funktioniert nicht"
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Reproduzieren (5 min max)
|
||||
|
||||
### Ziel: Bug in einen Test verwandeln
|
||||
|
||||
```bash
|
||||
# 1. Exakte Schritte dokumentieren
|
||||
# 2. Fehlermeldung/Symptom notieren
|
||||
# 3. Umgebung identifizieren
|
||||
```
|
||||
|
||||
**Fragen:**
|
||||
- [ ] Ist der Bug reproduzierbar?
|
||||
- [ ] Tritt er nur in bestimmten Umgebungen auf?
|
||||
- [ ] Seit wann tritt er auf? (letzter Deploy?)
|
||||
|
||||
### Breakpilot-spezifisch: Welcher Service?
|
||||
|
||||
```bash
|
||||
# Container-Status prüfen
|
||||
ssh macmini "docker compose ps | grep -E '(Exit|unhealthy)'"
|
||||
|
||||
# Logs der letzten 5 Minuten
|
||||
ssh macmini "docker compose logs --since 5m <service-name>"
|
||||
```
|
||||
|
||||
| Symptom | Wahrscheinlicher Service |
|
||||
|---------|-------------------------|
|
||||
| Login fehlgeschlagen | consent-service, backend |
|
||||
| 502 Bad Gateway | nginx, upstream-service |
|
||||
| Langsame Suche | qdrant, embedding-service |
|
||||
| Upload-Fehler | minio, backend |
|
||||
| OCR-Fehler | paddleocr-service, klausur-service |
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Hypothesen bilden (5 min max)
|
||||
|
||||
### 3-5 mögliche Ursachen auflisten
|
||||
|
||||
| # | Hypothese | Wahrscheinlichkeit | Test |
|
||||
|---|-----------|-------------------|------|
|
||||
| 1 | | Hoch/Mittel/Niedrig | |
|
||||
| 2 | | | |
|
||||
| 3 | | | |
|
||||
|
||||
### Häufige Ursachen bei Breakpilot
|
||||
|
||||
**Container/Docker:**
|
||||
- Container nicht gestartet
|
||||
- Volume-Mount-Problem
|
||||
- Netzwerk zwischen Containern unterbrochen
|
||||
- Resource-Limits erreicht
|
||||
|
||||
**Datenbank:**
|
||||
- Connection Pool erschöpft
|
||||
- Migration nicht ausgeführt
|
||||
- Deadlock
|
||||
|
||||
**API/Backend:**
|
||||
- JWT abgelaufen
|
||||
- CORS-Fehler
|
||||
- Rate-Limit erreicht
|
||||
- Falscher Content-Type
|
||||
|
||||
**Frontend:**
|
||||
- Cache-Problem (Safari!)
|
||||
- Build nicht aktualisiert
|
||||
- Umgebungsvariable fehlt
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Systematisch eliminieren (10 min max)
|
||||
|
||||
### Reihenfolge: Schnellste Tests zuerst
|
||||
|
||||
```bash
|
||||
# 1. Ist der Service überhaupt erreichbar?
|
||||
curl -s https://macmini:8000/health | jq
|
||||
|
||||
# 2. Container-Logs auf Fehler prüfen
|
||||
ssh macmini "docker compose logs --tail 50 <service> 2>&1 | grep -iE '(error|exception|failed|traceback)'"
|
||||
|
||||
# 3. Datenbank-Verbindung testen
|
||||
ssh macmini "docker exec breakpilot-pwa-postgres pg_isready"
|
||||
|
||||
# 4. Redis/Valkey erreichbar?
|
||||
ssh macmini "docker exec breakpilot-pwa-valkey valkey-cli ping"
|
||||
```
|
||||
|
||||
### Hypothese testen
|
||||
|
||||
Für jede Hypothese:
|
||||
1. **Test definieren** (wie prüfen wir das?)
|
||||
2. **Test ausführen**
|
||||
3. **Ergebnis:** Bestätigt ✅ / Widerlegt ❌
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Root Cause identifizieren
|
||||
|
||||
### Nicht das Symptom behandeln!
|
||||
|
||||
**Schlecht:** "Ich starte den Container neu"
|
||||
**Gut:** "Der Container crashed wegen OOM → Memory-Limit erhöhen"
|
||||
|
||||
### 5-Why-Methode
|
||||
|
||||
```
|
||||
Problem: API gibt 500 zurück
|
||||
↓ Warum?
|
||||
Datenbank-Query failed
|
||||
↓ Warum?
|
||||
Connection Pool erschöpft
|
||||
↓ Warum?
|
||||
Connections werden nicht freigegeben
|
||||
↓ Warum?
|
||||
Exception vor connection.close()
|
||||
↓ Warum?
|
||||
Fehlendes try/finally
|
||||
→ ROOT CAUSE: Fehlendes Resource-Cleanup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Fix implementieren
|
||||
|
||||
### Checkliste vor dem Fix
|
||||
|
||||
- [ ] Root Cause verstanden (nicht nur Symptom)
|
||||
- [ ] Fix adressiert Root Cause
|
||||
- [ ] Keine Seiteneffekte erwartet
|
||||
- [ ] Test geschrieben, der Regression verhindert
|
||||
|
||||
### Fix-Template
|
||||
|
||||
```python
|
||||
# VORHER: Bug
|
||||
def fetch_data():
|
||||
conn = get_connection()
|
||||
result = conn.query(...) # Exception hier → Leak!
|
||||
conn.close()
|
||||
return result
|
||||
|
||||
# NACHHER: Fix mit Erklärung
|
||||
def fetch_data():
|
||||
"""Fetch data with proper connection handling.
|
||||
|
||||
Fixed: Connection leak when query raises exception.
|
||||
See: https://macmini:3003/.../issues/123
|
||||
"""
|
||||
conn = get_connection()
|
||||
try:
|
||||
result = conn.query(...)
|
||||
return result
|
||||
finally:
|
||||
conn.close() # Immer ausgeführt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Regression verhindern
|
||||
|
||||
### Test schreiben
|
||||
|
||||
```python
|
||||
def test_connection_released_on_error():
|
||||
"""Regression test for connection leak bug.
|
||||
|
||||
Issue: #123
|
||||
Root cause: Missing finally block in fetch_data()
|
||||
"""
|
||||
initial_connections = get_pool_size()
|
||||
|
||||
with pytest.raises(DatabaseError):
|
||||
fetch_data_with_bad_query()
|
||||
|
||||
# Connection should be returned to pool
|
||||
assert get_pool_size() == initial_connections
|
||||
```
|
||||
|
||||
### Dokumentieren
|
||||
|
||||
```bash
|
||||
# Was haben wir gelernt?
|
||||
# → docs-src/development/debugging-notes.md ergänzen
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference: Breakpilot Debug Commands
|
||||
|
||||
```bash
|
||||
# Alle Container-Status
|
||||
ssh macmini "docker compose ps"
|
||||
|
||||
# Logs eines Services (live)
|
||||
ssh macmini "docker compose logs -f <service>"
|
||||
|
||||
# In Container einloggen
|
||||
ssh macmini "docker exec -it breakpilot-pwa-<service> sh"
|
||||
|
||||
# PostgreSQL Query
|
||||
ssh macmini "docker exec breakpilot-pwa-postgres psql -U breakpilot -d breakpilot_db -c 'SELECT 1'"
|
||||
|
||||
# Netzwerk-Debug
|
||||
ssh macmini "docker exec breakpilot-pwa-backend curl -s http://consent-service:8081/health"
|
||||
|
||||
# Resource-Nutzung
|
||||
ssh macmini "docker stats --no-stream"
|
||||
|
||||
# Vault-Status
|
||||
ssh macmini "docker exec breakpilot-pwa-vault vault status"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Anti-Patterns vermeiden
|
||||
|
||||
| ❌ Nicht machen | ✅ Stattdessen |
|
||||
|-----------------|----------------|
|
||||
| Random Code ändern | Hypothese bilden, dann testen |
|
||||
| console.log überall | Gezielt an verdächtigen Stellen |
|
||||
| Container neustarten und hoffen | Root Cause finden |
|
||||
| Stundenlang alleine debuggen | Nach 30 min Hilfe holen |
|
||||
| Fix ohne Test | Immer Regression-Test schreiben |
|
||||
Reference in New Issue
Block a user