Macht aus dem digitalen Kroki ein echtes taktisches Lagebild:
Karte:
- Nordpfeil-Overlay (dreht mit dem Karten-Bearing mit)
- Windrichtung in 8 Richtungen setzbar (Windrose mit Drift-Pfeil + Label
"Wind aus NW"), pro Einsatz gespeichert (Project.windDirection)
Export (PNG & PDF):
- Nordpfeil, Massstabsbalken und Windanzeige werden in die Karte eingebrannt
- PDF zusätzlich: Symbol-Legende (Namen aus /api/icons) + bestehende Kopfzeile
(Einsatz/Ort/Zeit/Nr) → fertiges, weitergebbares Krokier-Dokument
Technik:
- windDirection: Schema + idempotente Migration + Zod-Validierung + Typ
- Neue Komponente MapCompass (Nordpfeil/Windrose/Wind-Setzer)
- MapView verfolgt Bearing über 'rotate'-Event
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ursache: finishMeasure schaltete auf 'select' um → der Reset-Effekt
(drawMode !== 'measure') löschte die eben gezeichnete Linie sofort; die
Höhen-Labels kamen asynchron danach und blieben, die Linie nicht.
- Nach dem Abschliessen bleibt der Mess-Modus aktiv → Linie + Labels + Panel
bleiben stehen (Tippen fügt keinen Punkt mehr hinzu, da bereits fertig)
- Gemeinsamer clearMeasurement-Helfer: Panel-X und „Neue Messung" räumen jetzt
Linie, Marker, Höhen-Labels und Panel vollständig auf
- Beenden weiterhin über „Neue Messung" oder Wahl eines anderen Werkzeugs
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nach dem Topbar-Umbau zeigte die Tour auf nicht (mehr) vorhandene bzw.
grössenlose Elemente:
- data-tour="toolbar" lag auf einem display:contents-Div (0×0) → jetzt auf der
echten Werkzeug-<aside>
- data-tour="sidebar" wurde als Prop an RightSidebar gegeben, aber nie ins DOM
durchgereicht → jetzt direkt auf der Sidebar-<aside>
- updateHighlight ignoriert fehlende/unsichtbare/off-canvas Ziele (z.B. Sidebar
auf dem Handy) und zeigt den Tooltip zentriert statt einer kaputten Box
- Tooltip responsiv (max-w statt fix 340px) → kein Überlauf auf schmalen Handys
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Unabhängige Security-Review bestätigte: keine Autorisierungs-/Mandanten-Lücken
(Tenant-Isolation via getProjectWithTenantCheck, VIEWER-Schreibsperre, keine
Injection). Zwei Härtungspunkte umgesetzt:
- module_items data-Payload auf 20 KB pro Zeile begrenzt (POST+PUT) → kein
DB-Bloat/DoS durch beliebig grosse JSON-Objekte
- moduleId-Länge auf 64 Zeichen begrenzt (verhindert pathologische Keys)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Übungen zeigen jetzt zusätzlich zu Zielen/Auswertung dieselben eigenen
Tabellen-Module wie Einsätze (z.B. Atemschutz, Kräfte vor Ort)
- Live-Sync der Modul-Zeilen auch in der Übung (journal-updated Socket)
- docs/TESTPLAN.md: strukturierter Handy-/Einsatz-Testplan
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Rapport öffnen sammelt jetzt auch die Daten der eigenen Tabellen-Module
(Atemschutz, Kräfte vor Ort, Lagemeldungen, eigene Checklisten)
- Neue Rapport-Sektion rendert jede Modul-Tabelle mit ihren Spalten
(Text / Haken / Zeit) im PDF unter Pendenzen
- Vorschau der Module auch im Rapport-Dialog
- Zeit-Spalten: ISO → HH:MM, Haken → ✓/—
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Tap-to-place bleibt scharf: mehrere gleiche Symbole nacheinander setzen
(z.B. 4 Hydranten), Hinweis zeigt Anzahl + "Fertig"-Knopf
- Zeichen-Werkzeug wählen beendet den Platzier-Modus
- GPS: eigene Position dauerhaft mit Genauigkeitskreis + Blickrichtung
- Beim Öffnen bleibt die Karte auf dem Einsatzort (springt nicht mehr auf
die eigene Position, wenn ein Einsatzort gesetzt ist)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Kopfzeile war überladen (~11 konkurrierende Buttons in rot/blau/amber) und die
Versionsnummer kaum lesbar. Neu wie ein Einsatz-Cockpit — ruhig, dreizonig:
- Zone 1 Identität: Logo + "LAGEPLAN" + gut lesbare Version (mono)
- Zone 2 Blickfang: aktiver Einsatz als Pille (Status-Punkt rot=Einsatz /
blau=Übung, Einsatz-Nr mono, Titel, Ort) — mittig, flex-1, statt xl-only-Box
- Zone 3: grosse Uhr + Speichern + "+ Neu ▾" (Split-Button Einsatz/Übung) +
Werkzeug-Menü (Export, Präsentation, Vollbild, Tag/Nacht, Einsätze
verwalten, Schlaucheinstellungen) + Beenden + Benutzer
- Nur noch EIN Farbakzent (Status-Punkt) statt rot+blau+amber-Buttons
- 4 einzelne Icon-Buttons (Theme/Vollbild/Präsentation) → ein Zahnrad-Menü
- Zwei farbige "Neuer Einsatz/Neue Übung"-Buttons → ein "Neu"-Split-Button
- Mobile-Menü entschlackt (Erstellen liegt jetzt im Neu-Button)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ursache: react-dnd TouchBackend (delayTouchStart:150) unterdrückt auf Touch-
Geräten den onClick der Drag-Quelle → Tap-to-place löste auf dem Handy nie aus,
und echtes Touch-Drag über die MapLibre-Karte ist ohnehin unzuverlässig.
- DraggableSymbol erkennt Taps jetzt über echte Touch-Events (onTouchStart/End):
kurzer, ortsfester Tipp (<12px, <600ms) = Auswahl → Karte antippen platziert
- preventDefault verhindert Doppel-Auslösung durch den synthetischen Klick
- onClick bleibt für Desktop/Maus erhalten
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Der härteste Einsatztauglich-Punkt: bisher war die Karte ohne Empfang nur dort
verfügbar, wo man schon einmal hingezoomt hatte. Jetzt:
- Beim Öffnen eines Einsatzes werden die OSM-Kacheln des Einsatzgebiets im
Hintergrund vorgeladen (Zoom 13-18, ~800m Radius, max. 400 Kacheln)
- Exakt das MapLibre-Subdomain-Schema (x+y)%3 → Cache-Keys stimmen überein
- Bereits gecachte Kacheln werden übersprungen (schont OSM-Server + Akku)
- Parallelität 6, Start 4s nach Projektladen (Karte rendert zuerst)
- Marker pro Einsatz in localStorage, Auffrischung nach 14 Tagen
- Toast "Karte offline verfügbar" nach Abschluss
- Neue Bibliothek src/lib/offline-tiles.ts (Web-Mercator-Kachelmathematik)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Jede Feuerwehr stellt ihr Cockpit selbst zusammen (Wunsch: modular & einfach):
M0 – Zerlegt:
- SOMA + Pendenzen als eigenständige Modul-Komponenten, gemeinsame Typen
(journal/types.ts), einheitliche ModuleCard-Hülle
M1 – Registry & Verwaltung:
- Modul-Registry src/lib/modules.ts, Konfiguration pro Mandant in
tenants.modulesConfig (JSONB, idempotente Migration)
- API GET/PUT /api/tenant/modules (normalisiert + validiert via normalizeModules)
- "Module"-Button im Journal (Admins): an/aus, Reihenfolge hoch/runter,
eigene Module löschen
M2 – Eigene Module:
- Generisches Tabellen-Modul: frei definierbare Spalten (Text / Haken mit
Zeitstempel / Auto-Zeit), max 8 Spalten
- Generische Daten-API /api/projects/[id]/modules/[moduleId]/items (+ [itemId]),
neue Tabelle module_items, Live-Sync über journal-refresh Events
M3 – Feld-Vorlagen:
- Checkliste, Atemschutz-Überwachung (Trupp/Druck/Zeit/Draussen),
Kräfte vor Ort (Name/Funktion/seit/Weg), Lagemeldungen (Hauptbereich),
leeres Modul mit Spalten-Editor
Eingebaute Module (Journal/SOMA/Pendenzen) bleiben ohne Konfiguration exakt
wie bisher — kaputte Configs fallen sicher auf den Standard zurück.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Komplett-Check nach den UX-Umbauten (Typecheck + Produktions-Build + Code-Review):
- Tastenkürzel (V/L/G/...) lösen jetzt ebenfalls die Auto-Bearbeitung aus —
vorher umgingen sie ensureEditing und der erste Strich wurde nicht gesynct
- ensureEditing feuert nicht mehr mehrfach parallel (editingLoading-Guard)
- Onboarding-Tour aktualisiert: Schritt "Bearbeitung starten" (Button existiert
nicht mehr) → "Einfach loszeichnen"; Symbol-Schritt erwähnt Tap-to-place
Geprüft, ohne Befund: Auto-Save-Gating, Status-Zeile, flache Sidebar,
Linientyp-Dialog inkl. Gefahrenzone, Demo-Seite, Produktions-Build (Exit 0).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Auto-Bearbeitung (Lock vereinfacht):
- Kein manuelles "Bearbeitung starten" mehr: beim Werkzeugwählen/Zeichnen/Symbol-
Antippen wird der Editier-Lock still übernommen (ensureEditing), sofern die Karte
frei ist. Lock/Konflikt-Anzeige erscheint nur noch bei echtem Mehrpersonen-Zugriff.
- handleStartEditing bekommt silent-Option + boolean-Rückgabe.
- "Karte freigeben" bleibt als kleine Aktion für Übergabe.
Banner → eine kompakte Status-Zeile:
- Übung/Offline/E-Mail/Bearbeitung nicht mehr bis zu 4 Zeilen gestapelt, sondern
eine einzige Chip-Zeile, die nur zeigt was zutrifft (sonst gar nichts).
Symbol-Sidebar flacher:
- Statt zwei verschachtelter Klapp-Sektionen (Meine Symbole/Bibliothek) mit Unter-
Kategorie-Tabs jetzt EINE Chip-Reihe (Mandant + Bibliothek) + ein Raster.
- Suche zeigt Treffer flach über alle Kategorien.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Mobile Vollbild-Button schwebend oben links auf der Karte (versteckt Browser-Leiste,
document.fullscreen); Icon wechselt zwischen Vollbild/Verlassen
- Neuer Einsatz: aktueller Standort wird beim Öffnen automatisch als Einsatzort
vorgeschlagen (Reverse-Geocoding via Nominatim), plus "Mein Standort"-Button
- Setzt zugleich mapCenter → Karte startet direkt am Standort
- Bei verweigertem/fehlendem Standort klarer Hinweis, manuelle Eingabe bleibt möglich
- Adress-Anzeige in gemeinsamen buildDisplayName() ausgelagert
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Beim Zeichnen von Linie/Pfeil fragt der Dialog jetzt den Linientyp ab:
Normal (gewählte Farbe), Leitung (blau, dicker), Rettungsachse (grün, gestrichelt)
- Typ in properties.lineType gespeichert; Leitung/Rettungsachse setzen konventionelle
Farbe + Stärke, Normal behält die Zeichenfarbe
- Eigener MapLibre-Layer mit Dash-Muster für Rettungsachse (klar als freizuhaltende Achse erkennbar)
- Typ-Auswahl auch ohne Label übernehmbar; Änderung wird live gesynct
- ROADMAP: 5.1 abgehakt
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Tap-to-place: Symbol antippen → auf Karte tippen platziert es (Alternative zu Drag&Drop, mobil-tauglich); schwebender Hinweis mit Abbrechen
- Mobile Bottom-Navigation: Karte / Journal(Auswertung) / Symbole ohne Menü erreichbar
- FAB entfernt; Karten-Steuerung (Zoom/Standort/Massstab) hebt sich mobil über die Bottom-Nav
- Touch-Ziele in der Werkzeugleiste auf 44px vergrössert
- "Einsatz/Übung beenden" jetzt auch im Mobile-Overflow-Menü
- Banner (Übung/Offline/E-Mail/Live) mobil kompakt: kleinere Höhe, gekürzte Texte, truncate
- Einsatz-beenden-Bestätigung als In-App-Dialog statt Browser-confirm()
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Verhindert stilles Überschreiben neuerer Änderungen durch veralteten Stand
(z.B. nach Offline-Reconnect oder Lock-Ablauf bei Multi-Device).
- Project.featuresVersion (Schema + Auto-Migration), pro Features-Speichern +1
- Features-PUT: optimistischer Lock in interaktiver Transaktion
(updateMany WHERE featuresVersion=baseVersion -> atomar; count=0 => 409 Konflikt)
- Bei Konflikt liefert der Server den aktuellen Stand zurück (409 + features + version)
- Client sendet baseVersion (Auto-Save, manuell, Beacon, Offline-Queue), übernimmt
bei 409 den Server-Stand und warnt den Nutzer (statt still zu überschreiben)
- Offline-Queue verwirft konfligierende 4xx (kein Clobber beim Reconnect)
- Transaktions-Timeout 15s für grosse Zeichnungen auf langsamer DB
Version 1.4.11
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Neue lib src/lib/hose-calc.ts: EINZIGE Quelle der Druckformel (typisiert),
inkl. Schlauchanzahl aus lengthPerPieceM (Feld war vorher tot) + 10% Verlegereserve
- MeasurePanel als echte React-Komponente ersetzt das innerHTML/Inline-CSS-Overlay
in map-view.tsx (~130 Zeilen DOM-Gebastel entfernt)
- Schlauchtyp im Messergebnis wählbar (Standard vorausgewählt) statt alle gestapelt
- Strahlrohrdruck einstellbar (4/5/6/8 bar), Ergebnis rechnet live neu
- Höhendaten-Quelle ehrlich ausgewiesen; sichtbare Warnung wenn keine Höhendaten
(vorher stilles "alles flach")
- hose-settings-dialog nutzt die zentrale Formel (Duplikat entfernt)
- Version 1.4.9
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Editor-Lock aufgeteilt: canEditMap (Lock-geschützt) vs. canEditJournal (nur Rolle)
- Eine Person kann zeichnen, während eine andere parallel Journal führt
(Führungsstab-Szenario: Zeichner + Journalführer)
- Journal-Live-Sync existierte bereits (Socket journal-updated -> journal-refresh)
- Banner-Texte präzisiert ("bearbeitet die Karte", "Journal bleibt bearbeitbar")
- Version 1.4.8
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Super-Admin sieht jetzt ALLE Benutzer über alle Mandanten in einer Tabelle
(statt nur Server-Admins). Neue Spalten: Mandant, Letzte Anmeldung, Status
- Einzelne Benutzer sperren/entsperren: User.isActive (Schema + Auto-Migration),
Login-Sperre für deaktivierte Konten, PATCH /api/admin/users/[id] { isActive }
- GET /api/admin/users liefert jetzt lastLoginAt + isActive
- Selbstsperre verhindert; admin@lageplan.local geschützt
- Version 1.4.6
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Dockerfile: --mount=type=cache für /root/.npm (npm ci) und /app/.next/cache
(inkrementeller next build statt jedes Mal von Null)
- deploy.yml: cache-to mode=max -> mode=min (spart auf dem NAS den ~12 Min
Cache-Export, der bisher grösster Einzelposten war)
- provenance/sbom aus (weniger Attestation-Export)
- ENV-Legacy-Warnungen behoben (ENV key=value)
- Version 1.4.5
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Topbar: direkte Buttons "Neuer Einsatz" (rot) und "Neue Übung" (blau)
statt versteckt im Menü; öffnen den Dialog direkt im richtigen Modus
- Übungs-Cockpit ersetzt bei Übungen das Journal: Übungsziele mit
Zielerreichung (Offen/Erreicht/Teilweise/Nicht erreicht) + Auswertung
- Neues Model ExerciseGoal + Project.exerciseEvaluation (Auto-Migration)
- API-Routen /projects/[id]/exercise-goals (Liste/Erstellen/Update/Löschen)
- Deutliches "ÜBUNG"-Banner gegen Verwechslung mit echtem Einsatz
- Sidebar-Tab heisst bei Übung "Auswertung"
- Version 1.4.4
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Feld mode (EINSATZ/UEBUNG) am Projekt + idempotente Auto-Migration
- Auswahl beim Erstellen (Segmented-Control mit Lucide-Icons)
- Badge "Einsatz"/"Übung" in der Projektliste
- Eigene Nummerierung für Übungen (Ü-YYYY-NNNN, getrennt gezählt)
- Journal-Titel wird bei Übung zu "Übungs-Journal"
- ROADMAP.md mit Verbesserungs-Fahrplan ergänzt
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>