
v0.31.0
20. Juni 2026“Einsatz-Cockpit, Skalierungssprung & Tenant-Abschluss”
41
Commits
92
Dateien
+4137 / -440
Zeilen
Der Einsatz-Drawer zeigt jetzt alle zugewiesenen Fahrzeuge auf einen Blick — während unter der Haube der Web-Prozess zustandslos wird, der Game-Tick in einen eigenen Container zieht und MAYDAY SIM bereit für echte Mehrspieler-Last ist.
🔵 NEUES FEATURE
→ Der Einsatz-Drawer zeigt jetzt alle aktuell zugewiesenen Fahrzeuge direkt in der Einsatz-Liste an, damit Dispatcher bei parallel laufenden Lagen sofort sehen welche Einheiten bereits gebunden sind — ohne jeden Einsatz einzeln öffnen zu müssen.—Key[DerHalbe]
- Stell dir vor, drei Einsätze laufen gleichzeitig und du willst wissen ob HLF 1 noch verfügbar ist — ein Blick in den Drawer reicht jetzt, kein Hin- und Herklicken mehr.
- Alle zugewiesenen Fahrzeuge werden kompakt inline im Einsatz-Listenelement angezeigt.
- Kein Wechsel zwischen Einsatz-Detail-Ansicht und Fahrzeug-Übersicht mehr nötig.
🔴 BUGFIX
→ CLI-Entrypoint für das SB1-Backfill-Skript und ein korrigiertes Cutover-Runbook stellen sicher, dass der Wechsel auf Postgres als Event-Store-Backend reproduzierbar dokumentiert und ausführbar ist.—
Shadow
- Der Migrationspfad von Redis-Stream zu Postgres Event-Store ist jetzt direkt per CLI-Skript ausführbar.
- Cutover-Runbook enthält korrekten Ablauf inkl. aktuellem Status — verhindert Fehler beim nächsten Operator-Handoff.
🛡️ INFRASTRUKTUR
→ Der Game-Tick und alle Background-Jobs laufen jetzt in einem eigenen `leitstelle-scheduler`-Container statt im Web-Prozess, was den Web-Layer zustandslos macht und horizontale Skalierung ohne Doppel-Tick erst möglich macht.—
Shadow
- Auto-Spawner, Eskalation, Phasen-Ticker, PendingTimer-Tick und Event-Relay sind vollständig aus dem Web-Prozess ausgelagert.
- Umschaltung über ein einziges Flag: `RUN_BACKGROUND_JOBS=false` im Web, `=true` im Scheduler-Container.
- Voraussetzung waren SB1 (durables Event-Log, Postgres als Source-of-Truth) und SB2 (atomares Timer-Claim via `claimedBy`/`claimedUntil`) — ohne diese Basis hätten zwei Ticker denselben Timer doppelt verarbeitet.
→ Der Scheduler unterstützt jetzt Sharding via `SHARD_INDEX`/`SHARD_COUNT`, sodass mehrere Scheduler-Instanzen denselben Job-Pool sauber aufteilen — ohne Überschneidung, ohne manuelle Partitionierung.—
Shadow
- Hashtext-basierte DB-seitige Partitionierung: jede Instanz verarbeitet nur die Jobs ihres Shards.
- Standardwert N=1 ist rückwärtskompatibel — bestehende Deployments brauchen keine Änderung.
- Background-Jobs sind shard-aware: Voice-Jobs laufen immer auf Shard 0, URL-Param-Test positiv abgeschlossen.
→ Die Web-Schicht läuft jetzt in N Replicas hinter Traefik Sticky-Sessions, PgBouncer übernimmt das Connection-Management zur Datenbank — SB3–SB5 sind abgeschlossen und MAYDAY SIM ist bereit für echte Mehrspieler-Last.—
Shadow
- Zwei Web-Replicas (app-leitstelle-web-1/2) standardmäßig hinter Traefik mit Sticky-Sessions — kein Spieler verliert seine Session beim Load-Balancing.
- PgBouncer pooled Verbindungen: bei 20 gleichzeitigen Disponenten sieht Postgres einen stabilen Pool statt 20 offener Verbindungen.
- leitstelle-web hat keinen direkten Host-Port mehr — Zugang ausschließlich über https://maydaysim.de via Traefik.
- Health-Checks laufen jetzt über Traefik statt direkt auf :3200, was dem tatsächlichen Produktionspfad entspricht.
🟠 VERBESSERT
→ Das Tenancy-CONTRACT-Fundament ist vollständig abgeschlossen: sechs Tabellen haben jetzt `saveId NOT NULL`, Tenant-Isolation ist strukturell auf Datenbankebene erzwungen und per DMMF-Drift-Test dauerhaft messbar.—Key[DerHalbe]+
Shadow
- ~85 Tenancy-Warnings aus Slice A beseitigt — der Compiler zeigt diese nicht mehr als Rauschen.
- 6 Kern-Tabellen mit `saveId NOT NULL`: kein Save kann mehr versehentlich tenant-global werden oder in einen fremden Spielstand schreiben.
- DMMF-Drift-Test schlägt automatisch an, wenn zukünftige Schema-Änderungen die Tenancy-Invarianten verletzen.
- CONTRACT-Runbook dokumentiert Abschluss-Status und gibt klare Regeln für neue Tabellen vor.
→ Rund 85 exhaustive-deps-Warnings im Frontend beseitigt, was subtile React-Hook-Bugs durch veraltete Closure-Referenzen strukturell verhindert.—Key[DerHalbe]
- Betrifft Phase C der #516-Sweep-Serie — Hooks haben jetzt vollständige Dependency-Arrays.
- Keine Verhaltensänderung für Dispatcher, aber deutlich weniger Risiko für subtile State-Bugs wenn sich Einsatz- oder Fahrzeugdaten zwischen Renders ändern.