fix: QC-Ratings aus 7 älteren Artikeln entfernt (CHECK 10)

This commit is contained in:
Hermes Agent
2026-06-23 23:47:51 +02:00
parent e73e0e88de
commit 4d90e4249d
656 changed files with 2602398 additions and 3 deletions
+261
View File
@@ -0,0 +1,261 @@
# BSN Server-Architektur — Split-Plan
**Stand:** 18.06.2026 | **Autor:** Basti (Chef vom Dienst)
**Status:** Planungsphase — noch nicht umgesetzt
---
## Ziel
Das BSN-Chatsystem von einem Monolithen auf zwei spezialisierte Dienste aufteilen:
| Server | Rolle | Optimiert für |
|---|---|---|
| **Server A** (aktuell, 4C/8GB) | Web-Frontend + Datenbank | I/O, HTTP-Requests |
| **Server B** (lokal, 24C/32GB) | Sprachverarbeitung | CPU, parallele Jobs |
## Ist-Analyse
### Aktueller Monolith (Port 5002)
```
app.py (Flask) — EIN Prozess, alles drin:
├── WhatsApp Webhook (I/O-leicht)
├── Telegram Webhook (I/O-leicht)
├── Public Frontend (I/O-leicht)
├── Admin Dashboard (I/O-leicht)
├── faster-whisper Transkription (CPU-schwer, 3060s, 1 Kern)
├── Piper TTS (CPU-mittel, 13s)
├── ffmpeg Video-Thumbnails (CPU-mittel, 25s)
├── DeepSeek LLM-Calls (Netzwerk, kein CPU-Problem)
└── SQLite DB (I/O)
```
### Ressourcen-Profil pro Aufgabe
| Aufgabe | CPU | RAM | Dauer | Parallelfähig |
|---|---|---|---|---|
| WhatsApp-Request | <1% | 5 MB | 50ms | ✅ Beliebig |
| Frontend-Rendering | 2% | 10 MB | 100ms | ✅ Beliebig |
| **Whisper Transkription** | 100% (1 Kern) | 1,5 GB | 3060s | ⚠️ 23 gleichzeitig |
| **Piper TTS** | 50% (1 Kern) | 200 MB | 13s | ✅ 45 |
| **ffmpeg Thumbnail** | 80% (1 Kern) | 100 MB | 25s | ⚠️ 23 |
| LLM API-Call | 0% | 20 MB | 25s | ✅ Beliebig |
### Kritischer Pfad: SPIEL Essen Messe
Während der Messe (4 Tage, ~10h/Tag) ist mit **Spitzen von 2050 parallelen Requests** zu rechnen.
Der aktuelle 4-Kern-Server würde bei 34 gleichzeitigen Transkriptionen **alle Kerne blockieren** — Web-Requests würden timeouten.
---
## Ziel-Architektur
```
┌─────────────────────────────────────────────────────┐
│ Server A — "Web & Data" │
│ 4 Kerne, 8 GB RAM │
│ Port 5002 (intern) │
│ │
│ Flask (app.py), schlank: │
│ ├── WhatsApp/Telegram Webhook │
│ ├── Public Frontend + Admin │
│ ├── SQLite (bsn_intake.db) │
│ ├── DeepSeek LLM-Calls │
│ └── HTTP-Client → Server B │
│ │
│ NUTZT: whisperclient.py (sendet Audio an Server B) │
└──────────────────────┬──────────────────────────────┘
HTTP (lokal, <1ms Latenz)
POST /transcribe {audio_file} → {text}
POST /speak {text} → {audio_file}
POST /thumbnail {video_file} → {thumbnail}
┌──────────────────────▼──────────────────────────────┐
│ Server B — "Language Processor" │
│ 24 Kerne, 32 GB RAM (lokal) │
│ Port 5003 (intern) │
│ │
│ Flask/FastAPI (language_server.py): │
│ ├── POST /transcribe │
│ │ └── faster-whisper 'base' model │
│ ├── POST /speak │
│ │ └── Piper TTS (de_DE-thorsten-medium) │
│ ├── POST /thumbnail │
│ │ └── ffmpeg -ss 1 -vframes 1 │
│ └── GET /health │
│ │
│ Worker-Pool: 810 parallele Transkriptionen │
│ RAM: 1,5 GB pro Whisper-Instanz ≈ 15 GB nutzbar │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ Server C — "Fallback & Test" │
│ 24 Kerne, 32 GB RAM (lokal) │
│ │
│ Optional: │
│ ├── Redundanz: Failover wenn Server B ausfällt │
│ ├── Testumgebung: Staging für neue Features │
│ └── Proxmox-Host: mehrere isolierte VMs │
└─────────────────────────────────────────────────────┘
```
---
## API-Spezifikation (Server A ↔ Server B)
### `POST /transcribe`
```
Request: multipart/form-data
file: audio.ogg (WhatsApp voice memo)
Response: 200 JSON
{
"ok": true,
"text": "Transkribierter deutscher Text...",
"duration_seconds": 12.5,
"processing_time_ms": 3420
}
Fehler: { "ok": false, "error": "..." }
```
### `POST /speak`
```
Request: JSON
{
"text": "Hallo Daniel, hier ist deine Antwort.",
"voice": "de_DE-thorsten-medium" // optional, default
}
Response: 200 audio/wav
(binary WAV data)
Fehler: { "ok": false, "error": "..." }
```
### `POST /thumbnail`
```
Request: multipart/form-data
file: video.mp4
Response: 200 image/jpeg
(binary JPEG, 320px wide)
Fehler: { "ok": false, "error": "..." }
```
### `GET /health`
```
Response: 200 JSON
{
"ok": true,
"workers_busy": 2,
"workers_available": 8,
"uptime_seconds": 86400
}
```
---
## Dateigrößen & Netzwerk
| Medientyp | Typische Größe | Übertragung (1 Gbit/s lokal) |
|---|---|---|
| WhatsApp Sprachnachricht | 50500 KB | < 5 ms |
| WhatsApp Audio (2 Min.) | 25 MB | ~40 ms |
| WhatsApp Video (1 Min.) | 550 MB | ~400 ms |
| WAV-Audio (TTS Output) | 100500 KB | < 5 ms |
| JPEG Thumbnail | 1050 KB | < 1 ms |
**Fazit:** Dateigrößen sind kein Bottleneck. Selbst 50-MB-Videos gehen in <500ms über das lokale Netz.
---
## Migrationsplan (6 Schritte)
### Phase 1: Language Server extrahieren (2h)
1. `language_server.py` schreiben — Flask-App mit `/transcribe`, `/speak`, `/thumbnail`, `/health`
2. Whisper/Piper/ffmpeg-Code aus `app.py` in `language_server.py` verschieben
3. Auf Server B deployen und testen
4. healthcheck einrichten
### Phase 2: Web Server umbauen (1h)
5. `whisperclient.py` schreiben — HTTP-Client für Language Server
6. In `app.py`: direkte Funktionsaufrufe ersetzen durch `whisperclient.transcribe(audio_path)`
7. Fallback: wenn Language Server nicht erreichbar → Submission als "Transkription ausstehend" markieren
### Phase 3: Testen (1h)
8. WhatsApp-Sprachnachricht senden → Transkription via Server B verifizieren
9. TTS via Server B verifizieren
10. Video-Thumbnail via Server B verifizieren
11. Lasttest: 10 parallele Sprachnachrichten
### Phase 4: Proxmox (Daniel)
12. Proxmox auf Server B installieren
13. VM mit 12 Kernen + 16 GB RAM für Language Server
14. SSH-Zugang für Basti
### Phase 5: Redundanz (optional)
15. Language Server auch auf Server C deployen
16. Web Server mit Failover: wenn B nicht antwortet → C anfragen
### Phase 6: Monitoring
17. Health-Checks via cron (alle 60s)
18. Alert an Telegram wenn Language Server down
---
## Voraussetzungen
### Was Daniel bereitstellen muss
- [ ] Server B: Proxmox installiert, VM bereit
- [ ] Server B: SSH-Zugang für Basti
- [ ] Server B: Linux (Debian/Ubuntu), Python 3.11+
- [ ] Lokales Netzwerk: Server A kann Server B erreichen (ping, HTTP)
### Was auf Server B installiert wird
```bash
# System
apt install python3 python3-pip python3-venv ffmpeg espeak-ng
# Python
pip install faster-whisper flask requests
# Piper TTS (pre-built binary)
# Voices: de_DE-thorsten-medium.onnx (~61 MB)
```
---
## Risiken & Fallbacks
| Risiko | Eintritts-WSK | Fallback |
|---|---|---|
| Server B nicht erreichbar | Niedrig (lokales Netz) | Submission markiert als "Transkription ausstehend", retry in 30s |
| Whisper-Modell zu langsam | Niedrig (24 Kerne) | Kleinere `tiny`-Variante laden |
| RAM voll (zu viele parallele Jobs) | Mittel (unter Last) | Worker-Pool begrenzen, Queue |
| Piper TTS fehlende Library | Niedrig | LD_LIBRARY_PATH + ESPEAK_DATA_PATH gesetzt |
---
## Kosten-Nutzen
**Vor dem Split (aktuell):**
- 4-Kern-Server: Web + Transkription + TTS = alles in einem
- SPIEL Essen: 3 parallele Transkriptionen = alle Kerne blockiert = Web timeouts
**Nach dem Split:**
- 4-Kern-Server: NUR Web = ~100 gleichzeitige Requests möglich
- 24-Kern-Server: NUR Sprache = 810 parallele Transkriptionen
- Web-Server bleibt IMMER responsiv, egal wie viele Sprachnachrichten reinkommen
---
## Nächste Schritte
1. Daniel installiert Proxmox auf Server B
2. Daniel gibt SSH-Zugang
3. Basti deployt `language_server.py`
4. Basti baut `app.py` um
5. Integrationstest
6. Produktiv setzen