Alle nennenswerten Änderungen an diesem Projekt werden hier dokumentiert.
Format orientiert sich an Keep a Changelog; das Projekt folgt Semantic Versioning.
4.0.0 — 2026-07-06
Neu
-
Einsätze endgültig löschen — berechtigte Rollen können Einsätze jetzt aus der Einsatz-Übersicht endgültig löschen: einzeln über das Papierkorb-Symbol in der Aktions-Zelle (neben „Zuweisen") oder mehrere auf einmal über den roten „Löschen"-Button in der Bulk-Auswahl. Jede Löschung verlangt eine Begründung, die ins Anwendungsprotokoll geschrieben wird — der Einsatz selbst wird samt Abschnitten, Einsatzmitteln, Kommentaren, Anhängen und Audit-Spuren hart entfernt und lässt sich nicht wiederherstellen. Das Recht heißt
einsatz.delete(„Einsatz löschen") und ist per Default an für Administrator, Einsatzleiter und Lage; es lässt sich pro Rolle abwählen und an weitere Rollen delegieren. Für eine gescopte Rolle (Dispo ohne „alle sehen") sind nur die eigenen Einsätze löschbar — der Endpoint erzwingt den Scope zusätzlich autoritativ. -
Digitaler Zwilling NRW als Karten-Link (#175) — neben TIM und HYD gibt es einen neuen grünen Karten-Link „DZ" zum Digitalen Zwilling NRW (dz.nrw.de), dem landesweiten 3D-Geo-Kartensystem. Er erscheint in der Einsatz-Detailseite (zwischen TIM und HYD, nur wenn der Einsatz Koordinaten hat) und in der Telegram-Alarm-Nachricht (Link-Reihe
TIM | DZ | OSM | H, DZ nur bei echten Einsatz-Koordinaten — kein Fallback aufs Ortszentrum). Der DZ arbeitet mit UTM-Koordinaten (EPSG:25832, Rechts-/Hochwert); die App berechnet diese automatisch aus den vorhandenen GPS-Koordinaten (WGS84) — kein manuelles Feld. Gesteuert über das neue Feature „Digitaler Zwilling NRW" (feature_dz_nrw_enabled) unter Administration → Konfiguration → Features (Default an): Feuerwehren außerhalb von NRW schalten es aus, dann verschwindet der DZ-Link überall. → einmaliger Schema-Check nach dem Update (neue Spaltenutm_ost/utm_nord+ einmaliger Backfill der UTM-Werte für Bestandseinsätze). -
UTM-Koordinaten in der Geocode-Übersicht (#175) — die Geocode-Übersicht (
/admin/geocode-admin.php) zeigt jetzt zwei zusätzliche Spalten „Rechtswert" und „Hochwert" (UTM / EPSG:25832). Sie sind nur Anzeige (abgeleitet, nicht editierbar) und aktualisieren sich automatisch, sobald Du die GPS-Koordinaten einer Zeile bearbeitest oder neu geocodierst. In der Einsatz-Detailseite und im Einsatz-Formular werden die UTM-Werte bewusst nicht angezeigt — sie dienen allein dem DZ-Link. -
Lagekarte: Einsatzmittel-Panel im Tablet-Hochformat als Vollbild (#179) — im Tablet-Hochformat (ca. 768–1024 px, Portrait) öffnet das Einsatzmittel-Panel auf der Lagekarte jetzt als Vollbild-Overlay über der Karte — genau wie am Smartphone. Bisher quetschte das feste Panel die Karte auf dem Tablet unbrauchbar schmal. Im Querformat (genug Platz für beides) bleibt das Panel wie gewohnt seitlich. Rein additiv, kein Schema-Check nötig.
-
Einsatz-Status-Farben admin-konfigurierbar (#164) — unter Administration → Einsatz-Status-Farben (
/admin/einsatz-status-farben.php, Rechtadmin.stammdaten) legst Du je Einsatz-Status (Neu, Disponent, In Bearbeitung, Erledigt, Abgeschlossen) eine Farbe fest — mit Farbwähler, Live-Vorschau und „Auf Standard zurücksetzen". Die Farbe wirkt überall: Status-Pillen, farbiger Zeilenbalken in der Einsatzliste, Status-Kacheln, Lagekarten-Marker und Status-Filter-Punkte. Die Textfarbe (schwarz/weiß) wählt das ETB automatisch kontraststark (WCAG AA). Die Status selbst (Namen/Keys) bleiben fest — nur die Farbe ist konfigurierbar. Kein Schema-Check nötig (Ablage in der bestehenden Konfig-Tabelle). Solange Du keine eigene Farbe setzt, bleiben die getrennt abgestimmten Hell-/Dunkel- Standardfarben unverändert; im Dark-Mode ist der Zeilenbalken für „Abgeschlossen" bewusst dezent (dunkle Statusfarbe) — die Status-Pille bleibt der gut sichtbare Haupt-Anzeiger. -
Stärke-Eingabe über drei Felder ZVF / GF / Ma (#168) — beim Zuweisen eines Einsatzmittels (Drag & Drop auf einen Einsatz) gibst Du die Stärke jetzt über drei kleine Zahlenfelder ein — ZVF (Zug- und Verbandführer), GF (Gruppenführer), Ma (Mannschaft). Die Gesamtstärke wird daneben automatisch berechnet und angezeigt. Gespeichert und angezeigt wird weiterhin das gewohnte Schema A/B/C/S — die drei Felder sind nur die bequemere Eingabe (statt einen Schrägstrich-String von Hand zu tippen). Kein Schema-Check nötig.
-
Zuletzt zugewiesene Stärke an der EM-Sidebar (#169) — in der Einsatzmittel-Seitenleiste steht hinter jedem Einsatzmittel klein in Klammern die zuletzt zugewiesene Stärke (Schema A/B/C/S, Gesamtzahl doppelt unterstrichen), sofern bei einer früheren Zuweisung eine erfasst wurde. Rein informativ fürs Disponieren; kein Schema-Check nötig.
-
Überörtliches Einsatzmittel direkt im Schwerpunkt-Wizard anlegen (#172) — im Schwerpunkt-Anlage-Wizard (Schritt 4, Einsatzmittel-Pool) gibt es den Button „Überörtliches Einsatzmittel anlegen" (nur mit dem Recht „üÖrt-EM beim Zuweisen neu anlegen",
em.uoert_create— das bisher nur den Zuweisen-Dialog freischaltete). Der Dialog fragt Name, Stärke (drei Felder ZVF/GF/Ma) und Kontakt ab; das Einsatzmittel wird als normales überörtliches EM angelegt und direkt in den Pool aufgenommen — ohne Umweg über die Stammdaten-Pflege. Legt zwei Spaltenem_stammdaten.default_anzahl/default_kontaktan → einmaliger Schema-Check nach dem Update.- Vorbelegung für die spätere Zuweisung: Stärke und Kontakt werden als Standard am Einsatzmittel gespeichert und beim ersten Drag & Drop auf einen Einsatz als Vorschlag angeboten (die Einsatz-Historie hat Vorrang, sobald es eine gibt).
- Sicherheit: Der Wizard-Zugang (
schwerpunkt.create) allein reicht nicht — das Anlegen verlangt zusätzlichem.uoert_create(Button und Server-Endpoint prüfen das). Die Kontakt-Vorbelegung bleibt für gescopte Disponenten verborgen (wie die Historien-Kontakte); die Stärke-Vorbelegung ist unkritisch und für alle sichtbar.
-
Wizard-EM-Pool per Tastatur bedienbar (#180) — die Einsatzmittel-Chips im Schwerpunkt-Anlage-Wizard (Schritt 4) sind jetzt vollständig per Tastatur bedienbar: Chip mit Tab anspringen, Enter / Leertaste nimmt ihn in den Pool auf bzw. entfernt ihn wieder; der Fokus folgt dem Einsatzmittel. Damit ist auch der letzte verbliebene Nur-Maus-Bereich der EM-Zuweisung barrierefrei (WCAG 2.1.1); der frühere Workaround-Hinweis im Handbuch entfällt. Kein Schema-Check nötig.
-
Mitscrollende EM-Übersicht + fixe Filterleiste (#166) — in der Einsatz-Übersicht bleibt auf breiten Bildschirmen die Einsatzmittel-Seitenleiste beim Scrollen der Liste rechts sichtbar (sie wandert mit), und die Filterleiste klebt oben am Rand — so lassen sich auch weit unten in einer langen Liste Einsatzmittel zuweisen und Filter setzen, ohne nach oben zu scrollen. Klappst Du die Filterleiste dabei auf, scrollt sie sanft in den Blick, statt Einsatzzeilen zu verdecken. Auf dem Smartphone (einspaltig) bleibt alles wie gehabt. Kein Schema-Check nötig.
-
Alarm-Knopf — Einsatz-Rolle übernehmen (#163) — je Alarm-Regel konfigurierbar (neuer Block „Alarm-Knopf — Einsatz-Rolle übernehmen": angebotene Rolle Lage oder Einsatzleiter plus Laufzeit 6–48 h in 6-h-Stufen). Löst die Regel aus (Alarm-Mail, „Alarm auslösen"-Knopf oder Bestätigungs-Banner), entsteht ein einmaliges Rollen-Angebot: Im Seitenmenü erscheint ein Blitz-Knopf neben dem Benutzernamen. → einmaliger Schema-Check nach dem Update legt die neue Tabelle und die Spalten an (
alarm_role_offer,users.temp_role_source,alarm_rule.temp_role_offer/…_hours).- Übernehmen (Disponent): ein Disponent ohne aktive Einsatz-Rolle übernimmt die Rolle per Bestätigungs-Dialog — sie wirkt sofort ohne Neuanmeldung, die Laufzeit zählt ab der Übernahme. Genau ein Gewinner (race-sicher); danach verschwindet der Knopf für alle.
- Entschärfen (höhere Rechte): Lage, Einsatzleiter und Administrator — auch wer per Einsatz-Rolle bereits höher ist — können das Angebot stattdessen entschärfen (verschwindet für alle, revisionssicher im Rollen-Audit).
- Weiterverleih-Ausnahme: die per Alarm-Knopf übernommene Lage darf ihrerseits Einsatz-Rollen vergeben (einzige Ausnahme von der Weiterverleih-Sperre, damit der erste Disponent die Führungsstruktur aufspannen kann — setzt voraus, dass die Rolle Lage das Recht „Einsatz-Rollen vergeben" hat, per Default aus); die Kette endet dort — von ihr ernannte Rollen und ein per Alarm-Knopf übernommener Einsatzleiter verleihen nicht weiter.
- Sicherheit: Gast und SP-Dispo sehen den Knopf nie (server-seitig
gesperrt); nur ein Angebot gleichzeitig und kein neues, solange eine
per Alarm übernommene Rolle läuft; ungenutzte Angebote verfallen nach
48 h, der ETB-Reset räumt sie ab; Übernahme und Entschärfen stehen im
Rollen-Audit (
temp_role_claim_alarm,alarm_offer_dismiss).
-
Schwerpunkt-Abschluss — Erledigen & endgültiges Abschließen (#170) — der Schwerpunkt-Lebenszyklus zieht mit dem Einsatz gleich. Die beiden Endzustände heißen jetzt „Erledigt" (früher „Geschlossen") und „Abgeschlossen" (früher „Archiviert"); die internen Keys bleiben. → einmaliger Schema-Check nach dem Update benennt unveränderte Werks-Labels um (selbst angepasste bleiben unberührt).
- „Erledigen"-Button im Schwerpunkt-Banner (Recht „Schwerpunkt
schließen / archivieren",
schwerpunkt.close, Default Lage/EL/Admin): setzt den Schwerpunkt auf Erledigt, sobald alle seine Einsätze mindestens erledigt sind — bereits erledigte Einsätze blockieren das SP-Erledigen nicht mehr (vorher mussten alle abgeschlossen sein). Bei offenen Einsätzen erklärt der Dialog den Weg über „Einsätze abschließen". - Sammel-Abschluss in der Schwerpunkt-Übersicht: der Button „Schwerpunkte abschließen (N)" öffnet ein Fenster mit allen erledigten Schwerpunkten — einzeln oder alle auf einmal endgültig abschließen; Zeilen mit zwischenzeitlich wieder geöffneten Einsätzen sind gesperrt. Der Erledigt-Zeitstempel bleibt beim Abschließen erhalten (Historie und Export zeigen weiter „Erledigt").
- Reaktivierung nur durch den Administrator: einen abgeschlossenen Schwerpunkt kann nur ein Admin (Basis-Rolle) wieder auf Aktiv/Pausiert stellen.
- Ort-Eindeutigkeit: ein Ort kann nur einem offenen Schwerpunkt zugeordnet sein — geprüft beim Zuordnen der Orte und bei der Reaktivierung; Orte erledigter/abgeschlossener Schwerpunkte sind wieder frei.
- „Erledigen"-Button im Schwerpunkt-Banner (Recht „Schwerpunkt
schließen / archivieren",
-
Blockierende Abschnitte direkt erledigen (#162) — überall dort, wo die Abschnitts-Sperre einen Einsatz am Erledigen/Abschließen hindert, lassen sich die betroffenen Abschnitte jetzt an Ort und Stelle erledigen (gleiches Recht wie das Abschnitts-Status-Dropdown,
abschnitt.status); kein Schema-Check nötig.- Das Fenster „Einsatz erledigen" arbeitet zweistufig: Bei Abschnitten in Arbeit zeigt es zuerst einen Warnhinweis samt Liste mit „Erledigen"-Button je Abschnitt (der Erledigen-Knopf des Einsatzes bleibt solange deaktiviert); sind alle erledigt, erscheint automatisch das Kommentarfeld. Ohne blockierende Abschnitte startet es direkt beim Kommentar.
- Die Status-Dropdowns (Übersicht und Detailseite) öffnen bei blockierenden Abschnitten den Dialog „Abschnitte noch in Arbeit" mit denselben Erledigen-Buttons — danach läuft der Statuswechsel automatisch weiter.
- Das Fenster „Einsätze abschließen" listet die blockierenden Abschnitte gesperrter Einsätze als Unterzeilen mit „Erledigen"-Button.
- Statuswechsel von oder zu „Erledigt"/„Abgeschlossen" laden die Detailseite neu — der „Einsatz erledigen"-Button erscheint bzw. verschwindet damit automatisch.
-
Adress-Suffix je Ort (#174) — in der Orts-Verwaltung gibt es je Ort den Haken „Eigenes Adress-Suffix" plus Textfeld: Es ersetzt beim Geocodieren (und im TIM-Kartenlink) das Standard-Suffix aus „System & Konfiguration" — gedacht für Orte außerhalb der eigenen Gemeinde (überörtliche Einsätze). Ein leeres Feld bei gesetztem Haken bedeutet bewusst „kein Suffix anhängen". → einmaliger Schema-Check nach dem Update legt die beiden Spalten an.
-
Direkt-Zugriff auf den Geocode-Cache (#171) — die Geocodes-Übersicht trägt für Admins den neuen Toolbar-Button „Geocode-Cache"; bisher war die Cache-Seite nur über den System-Status auffindbar. Kein Schema-Check nötig.
-
Stichwort-Katalog (Phase 1) — eine neue Admin-Seite „Stichwort-Katalog" (Bereich Feuerwehr, Recht
admin.stammdaten) zum Pflegen der Einsatzstichworte. Legt die neue Tabellestichwort_katalogan → einmaliger Schema-Check nach dem Update nötig.- Einzelpflege: pro Stichwort Kategorie (Combobox: vorhandene
wählen oder neue eintippen), volles Stichwort (eindeutig, z. B.
SU-B1-Sonstiges), Anzeige-Variante (was später in den Listen erscheint, z. B.B1-Sonstiges), Aliase (komma-getrennt) sowie Sortierung und Aktiv. - CSV-Import: Datei mit Kopfzeile
Kategorie;Stichworthochladen → Vorschau (inkl. abgeleiteter Anzeige-Spalte und Hinweis neu / aktualisiert) → übernehmen; bestehende Einträge werden über das volle Stichwort aktualisiert. Eine Beispiel-Datei steht zum Download bereit. - Ausblend-Präfixe: ein komma-getrenntes Feld über der Liste (z. B.
SU-). Daraus leitet das ETB die Anzeige-Variante aus dem vollen Stichwort ab (führendes Präfix abschneiden). Eine Änderung zeigt erst eine Vorschau der betroffenen Einträge, bevor alle Anzeige-Stichworte neu berechnet werden. - Erste Stufe eines größeren Vorhabens: Diese Stufe liefert nur die Katalog-Verwaltung im Admin. Die Auswahl im Einsatz-Formular, die automatische Erkennung und das Alarm-Auslösen folgen in späteren Ausbaustufen.
- Einzelpflege: pro Stichwort Kategorie (Combobox: vorhandene
wählen oder neue eintippen), volles Stichwort (eindeutig, z. B.
-
Stichwort-Auswahl im Einsatz-Formular (Stage 2) — beim Anlegen/Bearbeiten eines Einsatzes ist das Stichwort nun an den Stichwort-Katalog gekoppelt. Ergänzt die neue Spalte
einsaetze.stichwort_katalog_id(NULL = Freitext) → einmaliger Schema-Check nach dem Update nötig.- Zwei verkettete Auswahlfelder: zuerst Kategorie, dann das Stichwort dieser Kategorie (gezeigt wird die Anzeige-Variante aus dem Katalog). Nur aktive Katalog-Einträge erscheinen zur Auswahl.
- Freitext weiterhin möglich: über die Kategorie „— Freitext —" erscheint statt des Stichwort-Dropdowns ein freies Eingabefeld — für Stichworte, die (noch) nicht im Katalog stehen.
- Pflichtfeld bleibt: entweder eine Katalog-Auswahl oder ein Freitext. Beim Bearbeiten ist die bisherige Eingabe vorbelegt (Katalog-Stichwort mit Kategorie bzw. Freitext).
- Whitelist serverseitig: Eine übergebene Katalog-ID wird gegen den Katalog geprüft; das gespeicherte Stichwort kommt aus dem Katalog (Anzeige-Variante). Unbekannte/gelöschte IDs fallen sicher auf Freitext zurück und werden nie ungeprüft übernommen.
- Die automatische Erkennung aus Alarm-Mails und das Alarm-Auslösen bei manuellen Einsätzen folgen in späteren Ausbaustufen.
-
Alarm-Regeln auch bei manuellen Einsätzen (Stage 4) — Alarm-Regeln feuern bisher nur aus einer Leitstellen-Mail oder über den Knopf „Alarm auslösen" in der Übersicht. Jetzt prüft das ETB auch manuell angelegte oder bearbeitete Einsätze. Legt die neue Tabelle
alarm_einsatz_triggeran → einmaliger Schema-Check nach dem Update nötig.- Bestätigungs-Banner: Trifft das Stichwort eines manuell angelegten Einsatzes (oder ein geändertes Stichwort) eine aktive Alarm-Regel, erscheint auf der Einsatz-Ansicht ein Banner mit jeder treffenden Regel und einer Vorschau, wie viele Folge-Einsätze/-Abschnitte sie anlegen würde — plus Buttons Auslösen / Überspringen.
- Telegram standardmäßig aus: Eine Checkbox „Zusätzlich per Telegram alarmieren" steuert den Versand; sie ist hier nicht vorbelegt (anders als beim Knopf „Alarm auslösen"), damit eine Nachdokumentation nicht versehentlich den Alarm-Chat benachrichtigt.
- Berechtigung: Das Auslösen am Banner ist an „Einsatz-Stammdaten
bearbeiten" (
einsatz.edit, Default Lage/Einsatzleiter/Dispo + Admin) gebunden; Dispo und SP-Dispo nur im Rahmen ihres Einsatz-Scopes — derselbe Zugriffs-Schutz wie beim Bearbeiten. - Dedup: Eine Regel feuert pro Einsatz nur einmal; eine schon ausgelöste Regel erscheint nicht erneut, und der Server fängt gleichzeitige Doppel-Klicks ab (er löst nur noch wirklich offene Regeln aus).
- Vorschläge im Alarm-Regel-Editor: Das Feld Trigger-Stichworte
bietet jetzt Vorschläge aus dem Stichwort-Katalog (Anzeige-Varianten)
— ein Stichwort lässt sich picken oder weiterhin als Wildcard-Muster
(
B3*) tippen.
-
Arbeitsplatz „Einsätze abschließen" — ein dedizierter Prüf- und Abschluss-Weg in der Einsatz-Übersicht. Rein additiv, kein Schema-Check nötig; am Vier-Augen-Prinzip und der Abschluss-Sperre ändert sich nichts.
- Toolbar-Button: Wer das Recht „Einsatz abschließen"
(
einsatz.abschluss) hat (Default: Lage, Einsatzleiter, Admin), sieht in der Übersicht den Knopf „Einsätze abschließen" — mit einem Zähler der erledigten Einsätze, die auf den Abschluss warten. - Sammel-Modal: Der Knopf öffnet ein Fenster mit allen erledigten Einsätzen des aktuellen Bereichs (Nummer, Stichwort, Ort sowie wann und von wem erledigt). Einsätze lassen sich dort einzeln („Abschließen") oder gesammelt („Alle abschließen") abschließen.
- Abschluss-Sperre sichtbar: Einsätze mit noch offenen Abschnitten sind im Modal gesperrt (mit Hinweis, wie viele Abschnitte offen sind) und werden bei „Alle abschließen" übersprungen.
- Schwerpunkt-Einsätze im Schwerpunkt: Im normalen ETB zeigt und
zählt der Arbeitsplatz nur Einsätze ohne Schwerpunkt — erledigte
Einsätze eines Schwerpunkts erscheinen hier bewusst nicht (passend zur
Übersicht). Im Schwerpunkt-Tagebuch (
?schwerpunkt=<id>) erscheint derselbe Knopf, beschränkt auf die erledigten Einsätze dieses Schwerpunkts. - Der bisherige Weg über Status-Dropdown der Zeile und die Bulk-Aktion bleibt unverändert erhalten; die Mutationen laufen über dieselben abgesicherten Endpoints, die Sperre und der Vier-Augen-Check greifen serverseitig.
- Toolbar-Button: Wer das Recht „Einsatz abschließen"
(
-
Kontext-Hilfe-Schublade + seiten-genaues Handbuch (Etappe 7) — auf den meisten Seiten findest Du jetzt rechts in der Aktions-Leiste einen „?"-Knopf. Ein Klick öffnet rechts eine Hilfe-Schublade mit der genau zu dieser Seite passenden Handbuch-Erklärung; ein weiterer Klick, der ×-Knopf oder Esc (wenn der Fokus in der Schublade liegt) schließt sie wieder. Rein additiv, kein Schema-Check nötig, kein neues Recht.
- Dieselbe Quelle wie das Handbuch: Es ist derselbe Inhalt, den Du auch unter Hilfe liest — nur eben direkt im Kontext der Seite. Oben in der Schublade führt „Im Handbuch öffnen ↗" zur Vollansicht; auch Querverweise in der Schublade öffnen das Handbuch in einem neuen Tab, damit die Schublade beim Seiten-Thema bleibt.
- Seiten-genau statt grobem Kapitel: Jeder Bildschirm hat sein eigenes Thema (im Admin je Kachel eine eigene Seite). Das „?" erscheint nur, wo ein passendes Thema hinterlegt ist; reine Hintergrund-/Konzept-Themen (Rollen, Status-Lebenszyklus, FAQ, Glossar) tragen bewusst kein „?", werden aber aus den Seiten-Themen verlinkt. Anmelde-Seite und Setup-Wizard sind ausgenommen.
- Inhalt weicht aus, die Bedienung bleibt sichtbar: Die Schublade beginnt unter der Titelleiste und schiebt nur den Seiten-Inhalt nach links — Titelleiste und Aktions-Leiste (samt „?") bleiben stehen, nichts springt.
- Bleibt offen über Reload & Seitenwechsel: Hast Du die Schublade
geöffnet, bleibt sie es auch nach einem Seitenwechsel oder Neuladen
geöffnet und zeigt dann das Thema der neuen Seite (ohne den Fokus zu
stehlen). Der Zustand wird pro Browser gemerkt (
localStorage). - Breite anpassbar: Am linken Rand der Schublade kannst Du sie breiter oder schmaler ziehen; die gewählte Breite wird ebenfalls pro Browser gemerkt. Auf schmalen Bildschirmen (Smartphone, Tablet im Hochformat) und in der installierten App (PWA) ist die Schublade bewusst ausgeblendet — dort nutzt Du das vollständige Handbuch (Menü „Hilfe" oder das öffentliche Handbuch).
-
Öffentliches Handbuch ohne Login (
/handbuch.php, Etappe 7) — das komplette Handbuch ist jetzt auch ohne Anmeldung lesbar, unter/handbuch.php. Auf der Anmelde-Seite führt neben „Passwort vergessen?" ein neuer Link „Handbuch" dorthin (öffnet in neuem Tab).- Eigenes, schlankes Layout im App-Look mit aufklappbarem Themen-Menü und einem „← Zum Login"-Link; bewusst nur hell (kein Dark-Mode vor der Anmeldung).
- Read-only und dieselbe Quelle: Es liest dieselben Handbuch-Texte wie die In-App-Hilfe — der Inhalt wird also nur einmal gepflegt. Du kannst die Bedienungsanleitung so z. B. auf dem Tablet aufschlagen, ohne Dich erst anzumelden.
-
Hilfe-Menü als aufklappbare Gruppen (Etappe 7) — die Themenliste der In-App-Hilfe (
/hilfe.php) und des öffentlichen Handbuchs ist jetzt nach Gruppen gegliedert, die sich auf- und zuklappen lassen (Akkordeon). Beim Öffnen eines Themas klappt seine Gruppe automatisch auf und der aktive Eintrag rückt in Sicht. -
Design-Konsolidierung: Status-Kachel & Komfort/Kompakt-Umschalter (Etappe 6) — der „Mischung"-Rollout der Einsatz-Listen und -Detailansicht. Rein visuell bzw. additiv, keine geänderte Bedienung, kein Schema-Check nötig.
- Farbige Status-Kachel: Jede Einsatz-Zeile (Übersicht), der
Detail-Kopf und jeder Abschnitt tragen links eine Kachel mit der
laufenden Nummer (
#007bzw.A#001) und einem Kurz-Status — NEU, DISPO, AKTIV, FERTIG, ABG. Die Kachel ist in der Status-Farbe eingefärbt und zieht bei einem Inline-Statuswechsel (Dropdown der Zeile bzw. im Detail-Kopf) sofort in Farbe und Label nach. Die Abschnitts-Kachel nutzt die frei konfigurierbare Abschnitts-Status-Farbe; die Textfarbe wird luminanzbasiert gewählt, sodass sie auch auf hellen Status-Farben den WCAG-AA-Kontrast (1.4.3) einhält. - Ansicht „Komfort | Kompakt": Über der Einsatz-Liste schaltest du
zwischen Komfort (luftige Karten-Zeilen mit allen Spalten) und
Kompakt (dichte, einzeilige Darstellung; Neben-Spalten
ausgeblendet — für viele Einsätze auf einen Blick) um. Die Wahl wird
pro Browser gemerkt (
localStorage). - Abschnitte direkt in der Liste aufklappen: Einsätze mit Abschnitten tragen vor dem Stichwort einen Chevron (›), der die Abschnitte ohne Seitenwechsel ein-/ausklappt.
- Bulk-Auswahl als Overlay-Checkbox: Die Mehrfach-Auswahl-Checkbox sitzt jetzt filigran oben auf der Status-Kachel des Einsatzes (statt in einer eigenen Spalte) — sie erscheint nur bei Einsätzen, die du bearbeiten darfst. „Alle" in der Sortierleiste markiert die ganze Seite. Rein optisch, gleiche Bulk-Aktionen wie bisher.
- Lagekarte-Marker an Statusfarben: Die Einsatz-Marker der Lagekarte übernehmen die Status-Kachel (laufende Nummer + Status-Farbe), passend zur Liste.
- Farbige Status-Kachel: Jede Einsatz-Zeile (Übersicht), der
Detail-Kopf und jeder Abschnitt tragen links eine Kachel mit der
laufenden Nummer (
-
Mobil, Tablet & App (PWA) — die Anwendung ist jetzt durchgängig auf Smartphone und Tablet bedienbar. Rein additiv, kein Schema-Check nötig.
- Einsatzmittel per Tippen zuweisen: Auf Touch-Geräten genügt ein kurzer Tipp auf ein Einsatzmittel in der Seitenleiste — gibt es nur ein mögliches Ziel, wird sofort zugewiesen; bei mehreren öffnet ein Auswahl-Dialog mit den Einsätzen. Das bisherige Ziehen (lange drücken, dann ziehen) bleibt zusätzlich erhalten.
- Schmale Bildschirme: Formulare brechen sauber einspaltig um, breite Admin-Tabellen werden horizontal scrollbar statt abgeschnitten, der Einsatz-Detail-Kopf bricht um, und das Off-Canvas-Menü lässt sich per Tastatur bedienen (Esc schließt, der Fokus bleibt im Menü).
- Als App installierbar (PWA): Die Anmeldeseite ist jetzt PWA-tauglich (Manifest, an das Thema angepasste Status-Leiste, Service-Worker), sodass die als App installierte Anwendung auch bei abgelaufener Sitzung sauber startet. (Eigene App-Symbole folgen mit dem Produktiv-Deploy.)
-
Kommentare erweitert: Ziel-Auswahl Einsatz/Abschnitt (Etappe 4) — schließt #31. Erweiterungen rund ums Kommentieren in der Einsatz-Detailansicht:
- Ziel wählen (Einsatz oder Abschnitt): Hat ein Einsatz aktive Abschnitte, erscheint in der Einsatz-Detailansicht über dem Eingabe-Feld eine Auswahl „Ziel" — Einsatz (Standard) oder ein konkreter Abschnitt („A#001 …"). Anhänge landen an derselben Stelle wie der Kommentar. Ohne Abschnitte bleibt alles wie bisher (die Auswahl wird gar nicht erst angezeigt).
- Kombinierte Kommentar-Liste: Der Verlauf des Einsatzes zeigt Einsatz- und Abschnitts-Kommentare gemeinsam, chronologisch gemischt. Abschnitts-Kommentare tragen ein Herkunfts-Badge („A#001 …"); Bearbeiten/Löschen wirkt jeweils auf den richtigen Kommentar. Die Abschnitts-Detailseite zeigt weiterhin nur ihre eigenen Kommentare.
- Kommentieren hängt jetzt am Kommentar-Recht: Ein Einsatz-Kommentar
verlangt
einsatz.comment, ein Abschnitts-Kommentarabschnitt.comment— vorher war das Anlegen an das Bearbeiten-Recht (einsatz.edit) gekoppelt. Erledigte Abschnitte kann ein Dispo/SP-Dispo nicht kommentieren.
-
Alarmregeln manuell auslösen + Leitstellen-Adresse (Etappe 3) — schließt #115 (UW-ERSTALARM per Knopfdruck). Ein neuer Knopf „⚡ Alarm auslösen" in der Einsatz-Übersicht löst eine Alarmregel von Hand aus, wenn die Leitstelle keine Mail schickt.
- Er legt — exakt wie der echte Mail-Alarm — den Basis-Einsatz (Trigger-Stichwort der Regel) plus — je nach Regel-Typ — die hinterlegten Folge-Einsätze oder Folge-Abschnitte an der gewählten Adresse an; die Telegram-Alarmierung ist optional (Checkbox im Dialog, standardmäßig an — so lassen sich auch nur die Einsätze anlegen, ohne zu alarmieren). Eine Erfolgsmeldung bestätigt anschließend, wie viele Einsätze angelegt wurden und ob mit oder ohne Telegram; per „Zum Einsatz" geht es weiter zum neuen Basis-Einsatz.
- Auslöse-Dialog: Regel wählen (alle aktiven Regeln — Folge- Einsätze und Folge-Abschnitte, der Typ steht hinter dem Namen) → Adresse prüfen (vorbelegt, immer überschreibbar, Straße Pflicht) → Telegram-Haken optional setzen → „Alarm auslösen". Ein roter Warnhinweis macht die echte Auslösung deutlich.
- Adress-Quelle pro Regel (im Alarm-Regel-Editor): Lokale Leitstelle (Adresse aus „Organisation & Branding"), Feste Adresse (an der Regel) oder Bei Auslösung eingeben (leer). Dafür gibt es unter Admin → Organisation & Branding die neue Karte „Leitstelle" (Straße + Ort).
- Schutz gegen Doppelauslösung: dieselbe Regel ist nach dem Auslösen 60 Sekunden gesperrt, höchstens 10 manuelle Auslösungen pro Stunde je Regel. Die Sperre hängt an der Regel (nicht am Benutzer); der Mail-Alarm bleibt unberührt.
- Neues Recht „Alarm manuell auslösen" (
alarm.trigger_manual, Gruppe „Einsätze") — per Default bei Lage und Einsatzleiter, Administrator über den Failsafe; nicht an Dispo/SP-Dispo/Gast. Eine geliehene Einsatz-Rolle (temp EL/Lage, Etappe 2) zählt mit, da das Alarmieren eine operative Führungsaufgabe ist. Die Permission-Matrix umfasst damit jetzt 40 atomare Rechte.
⚠️ Nach dem Update einmalig
/admin/schema-check.php→ „Reparieren" ausführen. Etappe 3 legt drei neue Spalten an der Alarmregel-Tabelle an (manual_address_mode,manual_strasse,manual_ort) sowie die Tabellealarm_trigger_throttlefür den Cooldown; das Rechtalarm.trigger_manualwird bei Lage und Einsatzleiter nachgerüstet. Bis dahin bleibt die Funktion still inaktiv (keine Fehler), es erscheint der Schema-Banner. -
Einsatz-Rollen — temporäre Rollen leihen (Etappe 2) — schließt #30 (Rollenwechsel bei Anmeldung). Eine neue Seite „🤝 Einsatz-Rollen" (Sidebar-Gruppe „Werkzeuge") erlaubt es Einsatzleiter und Admin, einem Benutzer befristet (max. 48 Stunden) die höhere Rolle Einsatzleiter oder Lage zu leihen — z. B. für eine mehrtägige Lage.
- Wirkt sofort ohne Neuanmeldung („Highlander"-Prinzip): Die geliehene Rolle kommt zur festen Rolle hinzu (Vereinigung der Rechte), das höhere Recht gewinnt. Nach Ablauf des gedeckelten Zeitpunkts läuft die Einsatz-Rolle automatisch aus.
- „Entfernen" je Benutzer und „Alle Einsatz-Rollen zurücksetzen" beenden sie sofort. Die betroffene Person sieht in der Seitenleiste bei ihrer Rolle den Zusatz „(temp)" (z. B. „Einsatzleiter (temp)").
- Sicherheits-Leitplanken: Administrator und Schwerpunkt- Dispo nehmen am Einsatz-Rollen-System nicht teil (weder als Geber noch als Empfänger). Man kann sich nicht selbst eine Einsatz-Rolle geben. Eine geliehene Rolle kann nicht weiterverliehen werden (das Recht wird gegen die Basis-Rolle geprüft — ein temporärer Einsatzleiter sieht die Einsatz-Rollen- Funktion nicht). Bekommt ein Dispo eine Einsatz-Rolle, entfällt für deren Dauer sein Eigentums-Filter (er sieht dann alle Einsätze/Schwerpunkte).
- Neues Recht im Rollen-Editor: „Einsatz-Rollen vergeben"
(
user.assign_temp_role, neue Gruppe „Einsatz-Rollen") — per Default beim Einsatzleiter, optional für die Lage; nicht vergebbar an Dispo/SP-Dispo/Gast. Die Permission-Matrix umfasst damit jetzt 39 atomare Rechte. Vergabe, Änderung und Rücknahme landen im Rollen-Audit-Log.
⚠️ Nach dem Update einmalig
/admin/schema-check.php→ „Reparieren" ausführen. Die Einsatz-Rollen legen vier neue Spalten an der Benutzer-Tabelle an (temp_role,temp_role_until,temp_role_by,temp_role_at). Bis dahin bleibt die Funktion still inaktiv (keine Fehler), es erscheint der Schema-Banner. -
Neuer Einsatz-Status-Lebenszyklus & Vier-Augen-Abschluss (Etappe 1) — schließt #3 (Status-Workflow) und #114 (Dispo sah keine Einsätze). Der Einsatz durchläuft jetzt fünf klar benannte Stufen: Neu → Disponent → In Bearbeitung → Erledigt → Abgeschlossen. Die alten Stufen „Status 3 (Anfahrt)", „Status 4 (vor Ort)" und „Abschluss beantragt" entfallen.
- Automatische Übergänge nehmen dir Klickarbeit ab (nur vorwärts): Wer einen Disponenten zuweist, hebt den Einsatz von „Neu" auf „Disponent"; das erste zugewiesene Einsatzmittel schaltet ihn auf „In Bearbeitung". Jeder Automatik-Sprung steht mit Begründung in der Historie.
- Neuer Button „✅ Einsatz erledigen" (ersetzt „Abschluss-Freigabe beantragen"): setzt den Status auf „Erledigt" und bietet ein optionales Abschluss-Kommentarfeld — mit Text wird ein normaler Kommentar gespeichert, ohne Text ein revisionsfester System-Kommentar.
- Vier-Augen-Prinzip beim Abschluss: Der finale Schritt auf
„Abgeschlossen" verlangt das Recht „Einsatz abschließen"
(
einsatz.abschluss, Default Lage/Einsatzleiter/Admin). Ein Dispo kann erledigen, aber nicht abschließen — die Sperre greift im Status-Dropdown und in der Bulk-Aktion. Lage/EL/Admin behalten das freie Status-Dropdown (auch rückwärts). - Übersicht für Disponenten: Die ETB-Übersicht zeigt einem Dispo (ohne das Recht „alle Einsätze sehen") beim ersten Aufruf nur die eigenen zugewiesenen Einsätze — mit sichtbarem Hinweis und „Alle anzeigen"-Link. Neuer Filter „👥 Anderen zugeordnet" ergänzt „Mir zugeordnet" und „Nicht zugeordnet".
- Einsatzmittel werden automatisch frei, sobald alle ihre Einsätze erledigt oder abgeschlossen sind (vorher endeten sie u. a. an den entfallenen Status 3/4).
⚠️ Nach dem Update einmalig
/admin/schema-check.php→ „Reparieren" ausführen. Die Umstellung migriert die Einsatz-Status in der Datenbank (Status 3/4 → „In Bearbeitung", „Abschluss beantragt" → „Erledigt") und legt neue Spalten an. Ohne diesen Schritt zeigt das ETB den Schema-Banner; bestehende Einsätze bleiben dabei erhalten. -
Wiederverwendbare UI-Bausteine (Grundlage, noch nicht flächig im Einsatz): eine Formularfeld-Komponente (
.form-field) mit zugehöriger Inline-Validierung (form-validate.js, opt-in überdata-validateam<form>— bestehende Formulare bleiben unberührt) sowie die Design- Bausteine Mono-Einsatznummer (.einsatznr-mono), Status-Akzentleiste (.status-accent), Filter-Chip (.toggle-chip), Identitäts-Akzent (.identity-accent) und eine Icon-Basisklasse (.icon). -
Icon-Bibliothek (
IconLibrary,src/IconLibrary.php): zentrales Inline-SVG-Set im Tabler-Stil (MIT, Single-File-Vendoring, kein Build). Löst künftig die verstreuten Emoji ab; rendert mitcurrentColorund passenden a11y-Attributen (dekorativaria-hidden, mit Labelrole="img").
Barrierefreiheit & UI-Politur
- Dialoge fangen den Tastatur-Fokus ein (#124): Solange ein Dialog (z. B. eine Sicherheitsabfrage) offen ist, bleibst Du beim Durchtabben innerhalb des Dialogs — der Fokus springt nicht mehr hinter das Fenster. Nach dem Schließen kehrt der Fokus auf das Element zurück, mit dem Du den Dialog geöffnet hast. Der Rest der Seite wird währenddessen für Screenreader stillgelegt, sodass nur noch der Dialog vorgelesen wird (WCAG 2.1.2 / 2.4.3 / 4.1.2).
- Größere Touch-Ziele (#124, #118): Die Buttons in Dialogen und die Status-Filter-Chips in der Einsatzliste haben jetzt eine ausreichende Mindesthöhe — leichter zu treffen, vor allem auf Tablet und Smartphone.
- Sichtbarer Wartezustand der Status-Auswahl (#118): Wenn Du in der Einsatzliste oder der Einsatz-Detailansicht einen Status über das Dropdown umstellst, zeigt das Auswahlfeld während des Speicherns einen abgeblendeten, gesperrten Zustand an — Du siehst, dass die Änderung läuft, und kannst nicht versehentlich doppelt klicken. Bisher gab es diese Optik nur in der Abschnitts-Ansicht.
- Schwerpunkt-Übersicht auf schmalen Bildschirmen (#116): Die Tabelle der aktiven Schwerpunkte wird auf schmalen Geräten jetzt horizontal scrollbar dargestellt, statt am rechten Rand abgeschnitten zu werden — die rechten Spalten sind damit wieder vollständig erreichbar.
- Einheitliche Begriffe und Aktions-Verben in der Oberfläche (#119):
Über die gesamte Oberfläche heißen gleiche Aktionen jetzt überall gleich —
Zuweisen (Einsatzmittel oder Einsatz an ein Ziel hängen), Zuordnen
(eine Person setzen, z. B. den Disponenten), Entfernen (eine Zuordnung
lösen) und Löschen (einen Datensatz endgültig vernichten). Das frühere
„Herausnehmen" entfällt zugunsten von „Entfernen"; ein an einen Einsatz
oder Schwerpunkt gehängtes Einsatzmittel ist nun durchgängig „zugewiesen"
(nicht mehr „zugeordnet"). Die durchgängige Du-Anrede wurde
vereinheitlicht (die letzte Sie-Stelle entfernt, „Dein/Deine/Deinem"
durchgehend groß), und alle sichtbaren Meldungen nutzen jetzt echte
Umlaute (z. B. „gelöscht" statt „geloescht"). Aus den Buttons sind die
⏳-Lade-Emoji verschwunden — der Lade-/Gesperrt-Zustand wird ohne Emoji
angezeigt. Die Einsatzmittel-Status-Bezeichnungen sind angeglichen:
„Nicht eingesetzt" (vorher „Nicht zugewiesen") und „Anfahrt" (vorher
„Auf Anfahrt"). Es ändert sich nur die Beschriftung, keine Funktion.
Als verbindliche interne Referenz für künftige UI-Texte ist dazu das
Glossar
docs/microcopy-glossar.mdneu hinzugekommen. - Einheitlichere Chip-Darstellung beim Schwerpunkt-Bearbeiten: Im Dialog Schwerpunkt bearbeiten sehen die Einsatzmittel im Pool jetzt genauso aus wie die zugewiesenen Einsatzmittel im Einsatz — eine grüne, entfernbare Pille statt der bisherigen grauen Darstellung. Auch die Trigger-Orte erscheinen als saubere Auswahl-Pille (blau hervorgehoben, wenn ausgewählt) statt mit roher Checkbox; die Bedienung per Tastatur und der sichtbare Fokusring bleiben erhalten. Das fügt sich stimmig zu den Einsatzmittel-Chips. Es ändert sich nur die Optik, keine Funktion.
- Aktiver Lagekarten-Filter im Dark-Mode jetzt rot statt blau: Die aktiven Umschalter „Filter" und „Einsatzmittel" auf der Lagekarte werden im dunklen Design jetzt rot hinterlegt — passend zur hellen Variante und zu den aktiven Status-Pillen, und mit ausreichendem Kontrast (Weiß auf Rot, WCAG AA).
- Besserer Dark-Mode-Kontrast (Voll-Review vor v4.0.0): Die Überschrift der Schwerpunkte-Übersicht und der Lagekarten-Umschalter (Pill-Hover) stellen sich im dunklen Design jetzt mit ausreichendem Kontrast dar — vorher war die grüne Überschrift bzw. der Hover auf der dunklen Pille schwer lesbar (WCAG 1.4.3).
- Mehr per Tastatur bedienbar (Voll-Review vor v4.0.0): Die Bild-Lightbox in der Einsatz-Detailansicht lässt sich jetzt komplett ohne Maus bedienen — ein Bild öffnest Du mit Enter / Leertaste, der ×-Knopf reagiert ebenfalls auf die Tastatur. Auch der Zuweisen-/Verschieben-Dialog der Einsatz-Übersicht fängt den Tastatur-Fokus jetzt ein (Tab bleibt im Dialog, Esc schließt, der Fokus kehrt danach zurück) — wie die übrigen Dialoge (WCAG 2.1.1 / 2.1.2 / 2.4.3). Zusätzlich hat das Koordinaten-Eingabefeld im Geocode-Werkzeug wieder einen sichtbaren Fokus-Indikator (WCAG 2.4.7).
- Einsatzmittel komplett per Tastatur zuweisen (Voll-Review vor v4.0.0, WCAG 2.1.1): Die Chips der EM-Seitenleiste erreichst Du jetzt mit Tab; Enter oder Leertaste weist das Einsatzmittel zu — bei genau einem sichtbaren Ziel direkt, bei mehreren öffnet sich der bekannte Auswahl-Dialog „… zuweisen", der den Fokus einfängt, sich mit Esc schließen lässt und den Fokus danach zum Chip zurückgibt. Das gilt überall, wo die EM-Seitenleiste erscheint: Einsatz-Übersicht, Einsatz-Detail, Abschnitt-Detail, Einsatz anlegen/bearbeiten und Schwerpunkt-Einstellungen. Auch der Schwerpunkt-Anlage-Wizard (Schritt 4, Einsatzmittel-Pool) ist inzwischen tastaturbedienbar (siehe #180 unter „Neu").
- Einheitliche Stärke-Lesart an den EM-Chips (Voll-Review vor v4.0.0): Die Stärke eines einzelnen Einsatzmittels (an Einsatz und Abschnitt) zeigt die Gesamtzahl jetzt wie die Summen-Pillen doppelt unterstrichen und erklärt die Positionen per Tooltip („Zug- und Verbandführer / Gruppenführer / Mannschaft / Gesamt"). Rein optisch, keine geänderte Bedienung.
- EM-Status in der Seitenleiste nicht mehr nur über Farbe (WCAG 1.4.1):
Jeder Einsatzmittel-Chip in der EM-Seitenleiste trägt seinen Status
jetzt zusätzlich als kurzen Text („frei", „im Einsatz", „entlassen",
„n. zugew.") — bisher war er nur am farbigen Punkt und im
Hover-Tooltip ablesbar. Damit ist die Frei-/Belegt-Unterscheidung auch
bei Farbfehlsichtigkeit, auf Touch (kein Hover) und für
Screenreader wahrnehmbar; der farbige Punkt bleibt als schnelle
Zusatz-Codierung erhalten (dekorativ,
aria-hidden). Rein additiv, kein Schema-Check nötig. - Bestätigungs-Dialoge im Marken-Rot statt Blau (Abschluss-Politur): Der zentrale Bestätigungs-/Abfrage-Dialog (Sicherheitsabfragen, Eingabe-Prompts) färbt seinen Bestätigen-Knopf jetzt im Marken-Rot der Anwendung statt im bisherigen Bootstrap-Blau — es war der letzte blaue Primär-Knopf der Oberfläche. Weißer Text auf dem Identity-Rot bleibt kontraststark (WCAG AA). Zugleich zieht der Dialog seine gesamte Optik (Box, Kopf, Rumpf, Fußzeile, Buttons, Eingabefeld) jetzt durchgängig aus den zentralen Design-Tokens — damit sitzt auch der Dark-Mode ohne Sonder-Overrides richtig. Rein optisch, keine geänderte Bedienung.
- Weitere Dialoge fangen den Tastatur-Fokus ein (Abschluss-Politur, WCAG 2.1.2 / 2.4.3): Auch der Abschnitte-bilden-Dialog und der Einsatzmittel-zuweisen-Dialog halten den Fokus beim Durchtabben jetzt im Fenster, statt ihn hinter das Overlay in den verdeckten Seiteninhalt wandern zu lassen — wie schon die übrigen Dialoge. Die zuvor mehrfach kopierte Fokus-Logik ist dafür zentralisiert (opt-in je Dialog); Dialoge mit eigener Fokus-Verwaltung bleiben unberührt.
- Vereinheitlichte Fokus-Ringe und einzelne Dark-Kontraste
(Abschluss-Politur): Sichtbare Fokus-Ringe reagieren jetzt konsistent auf
Tastatur-Fokus (
:focus-visible) und nutzen die Marken-Farbe, sodass ein Klick mit der Maus keinen dauerhaften Rahmen mehr stehen lässt. Einzelne Pillen (u. a. Status erledigt/entlassen, Rollen-Pillen Gast/off) im dunklen Design haben einen minimal helleren Text für AA-Kontrast (≥ 4.5:1). Rein optisch, kein Schema-Check nötig.
Geändert
-
Rechte:
einsatz.deleteist jetzt das echte Einsatz-Löschrecht, Kommentar-Moderation wandert nachcomment.delete— der Schlüsseleinsatz.deletetrug bislang das Label „Einsatz löschen", steuerte faktisch aber nur die Moderation fremder Einsatz-Kommentare. Mit dem neuen Löschen-Feature bedeuteteinsatz.deletejetzt tatsächlich „Einsatz löschen" (Entity). Die frühere Kommentar-Moderation läuft über den neuen Schlüsselcomment.delete(„Einsatz-Kommentare moderieren") weiter — das Verhalten der Moderation selbst bleibt unverändert. Der Rollen-Editor zeigt entsprechend beide Rechte getrennt. → einmaliger Schema-Check nach dem Update nötig: Er benennt die bestehendeneinsatz.delete-Zuordnungen aller Rollen einmalig aufcomment.deleteum (bewahrt so die bisherige Moderation) und setzteinsatz.deleteals neues Löschrecht für Administrator, Einsatzleiter und Lage. Die Umstellung ist über einen Marker gegen doppelte Ausführung abgesichert. -
Einheitliche Symbole auf dem Rückmelde-Dashboard (#178) — die Rückmelde-Status auf dem Dashboard (Komme, ESt, Später, Nicht, ELW raus, Abbruch, LG) und das Schema-Update-Warnsymbol nutzen jetzt einheitliche SVG-Symbole statt Emojis — je Status in seiner Statusfarbe, sowohl in den Kacheln als auch in den Listen-Badges. Rein optisch, keine Bedienungsänderung. Der orangefarbene Status („Später") wurde zugleich leicht abgedunkelt, damit der weiße Badge-Text den AA-Kontrast erreicht.
-
A11y-/Dark-Feinschliff (#177) — kleinere Politur an mehreren Stellen: größere Touch-Flächen an den Einsatzmittel-Entfernen-Buttons (×), vereinheitlichte Platzhalter in Auswahl-Feldern, ergänzte Screenreader-Beschriftungen und abgestimmte Dark-Mode-Farben.
-
Schwerpunkt-Stärke: dritte Gruppe „entlassen" (#165) — die Kräfte-Aufschlüsselung eines Schwerpunkts (Kräfte-Pill in der Übersicht und der Titelleiste, PDF-Export) weist aus dem Einsatz entlassene Einheiten jetzt getrennt aus: „N im Einsatz · M Reserve · K entlassen". Bisher zählten entlassene Einheiten unsichtbar in die Reserve. Die Gesamtzahl bleibt Pool-basiert und enthält alle drei Gruppen — Entlassene werden nur getrennt ausgewiesen, nicht abgezogen. Kein Schema-Check nötig.
-
Einheitliche Eingabefelder in den EM-Dialogen (Maintainer-Feedback) — die Textfelder im EM-Zuweisungs-Dialog und im neuen üÖrt-Anlage-Dialog folgen jetzt demselben Standard-Look wie die Einsatz-Formularfelder (gemeinsame Design-Tokens, Dark-Mode-korrekt) — vorher trugen sie teils noch hartkodierte helle Farben. Rein optisch, keine geänderte Bedienung.
-
Neue Abschluss-Semantik: „in Arbeit" blockiert, „geplant" nicht mehr (#162) — ein Einsatz lässt sich weder erledigen noch abschließen, solange Abschnitte in Arbeit sind (begonnen, aber nicht erledigt — z. B. „Im Aufbau", „Im Einsatz"). Neu dabei: Geplante (nie begonnene) Abschnitte blockieren nicht mehr, und die Sperre greift jetzt auch schon beim Erledigen (bisher nur beim Abschließen). Sie wirkt serverseitig überall — Status-Dropdown, Bulk-Aktion, Bearbeiten-Formular und Abschluss-Arbeitsplatz.
-
Ort ist Pflicht-Auswahl aus der Orts-Verwaltung (#173) — der feste Ort einer Alarm-Regel (Adress-Quelle „Feste Adresse"), der Ort im Dialog „Alarm auslösen" und der Leitstellen-Ort (Organisation & Branding) sind jetzt Dropdowns mit den aktiven Katalog-Orten statt Freitext — gespeichert wird immer die kanonische Katalog-Schreibweise (Freitext erzeugte bisher Orte außerhalb der Orts-Übersicht). Ohne gepflegte Orte ist die manuelle Alarm-Auslösung gesperrt (mit Hinweis zur Orts-Verwaltung), und der Regel-Modus „Feste Adresse" lässt sich nicht speichern. Alt-Werte außerhalb des Katalogs werden markiert angezeigt („— nicht mehr im Orts-Katalog") und lassen sich nicht erneut speichern; ein unveränderter Leitstellen-Alt-Wert blockiert das Speichern der übrigen Branding-Felder bewusst nicht.
-
Neue Standard-Bilder (BrunSoft) — Logo, Menü-Logo und Favicon haben jetzt neutrale Standard-Bilder (
brunsoft-logo.png,brunsoft-menu.png,brunsoft-favicon.png). Sie gelten, solange Deine Organisation unter Admin → Organisation & Branding keine eigenen hochlädt — eigene Uploads bleiben unverändert. Alte instanzspezifische Bilder wurden entfernt; bestehende Instanzen fallen automatisch auf die neuen Standardbilder zurück (kein Handgriff nötig). -
Mail-Parser behält das Stichwort-Präfix + Katalog-Abgleich (Stage 3): Der Parser für eingehende Alarm-Mails schnitt bei Alarm- und Unwetter-Stichworten bisher die ersten Zeichen (das Präfix, z. B.
SU-) ab — das volle Stichwort bleibt jetzt erhalten. Anschließend gleicht das ETB das mail-erzeugte Stichwort gegen den Stichwort-Katalog ab: Bei einem Treffer wird die Anzeige-Variante gespeichert und angezeigt (samt Katalog-Verknüpfungstichwort_katalog_id), ohne Treffer das volle Stichwort als Freitext. Dadurch kann sich das angezeigte Stichwort automatisch erzeugter Einsätze gegenüber früher ändern. Die Alarm-Regel-Prüfung läuft jetzt auf der Anzeige-Variante — die bestehende Wildcard-Logik (B3*) greift unverändert. -
Handbuch-Seite optisch überarbeitet (Hilfe/
/hilfe.php): Die in-App- Hilfe trägt jetzt über jedem Artikel eine „Kapitel-Plakette" — die Kapitelnummer (aus dem Datei-Präfix, z. B.16) in Mono-Schrift auf dem Feuerwehr-Rot-Identitätsakzent, darüber als Eyebrow die Gruppe (z. B. „Tagesbetrieb"). Das greift dasselbe Zahl-auf-Farbe-Motiv wie die Status-Kachel der App auf. Die Stylesheet-Farben sind vollständig auf die zentralen Design-Tokens umgestellt (0 hartkodierte Farben) — Hell und Dunkel stellen sich damit automatisch korrekt dar; das frühere Fremd-Blau (Hover/Aktiv-Markierung der Themenliste, Prev/Next) ist dem Identitätsakzent gewichen. Die Vor-/Zurück-Navigation am Seitenende nutzt jetzt SVG-Pfeile (statt Unicode-Pfeile), Übergänge respektierenprefers-reduced-motion, und der Aktiv-/Akzent-Ton wurde so aufgehellt, dass er auch im Dunklen Modus den 3:1-Kontrast (WCAG 1.4.11) erreicht. Rein optisch — Inhalte, Navigation und Bedienung bleiben gleich. -
Handbuch seiten-genau neu geschnitten (Etappe 7,
docs/handbuch/): Passend zur Kontext-Hilfe ist das Handbuch von rund 20 großen Kapiteln auf gut 50 seiten-genaue Themen umgestellt — ein Thema je Bildschirm (im Admin je Kachel). Die Themen sind in einer logischen Reihenfolge gruppiert (Einstieg → Betrieb & Installation → Konzepte → Einsätze → Schwerpunkte → Karten → Werkzeuge → Admin · Feuerwehr/Konfiguration/ Aktionen/Logs & Diagnose → FAQ & Glossar); FAQ und Glossar sind jetzt getrennte Themen. Jede Datei trägt ein Frontmatter (title/slug/groups/order/context), das Reihenfolge und Gruppe steuert — der Dateiname ist nicht mehr für die Sortierung zuständig. Inhaltlich derselbe Stoff, nur kleinteiliger auffindbar; betrifft nur die Dokumentation, an der Anwendung selbst ändert sich dadurch nichts. -
Rollen-Beschreibung präzisiert (Etappe 7, Handbuch): Die Rollen-Themen benennen die Rollen jetzt mit ihren sprechenden Namen und stellen klar, dass die Lage über dem Einsatzleiter steht. Reine Doku-Präzisierung.
-
Handbuch-Inhalt durchgesehen und aktualisiert (
docs/handbuch/): Ein Inhalts-Audit hat die Bedienungsanleitung auf den aktuellen Stand der Oberfläche gebracht. Neu ist ein eigenes Kapitel „Mobil, Tablet & App" (Gruppe „Einstieg") zum Tippen-statt-Ziehen der Einsatzmittel, zum einspaltigen Reflow schmaler Bildschirme und zur PWA-Installation. Außerdem entfernt: rund 67 veraltete Button-Symbole über 17 Seiten, weil die Oberfläche seit Etappe 6 durchgängig SVG-Icons statt Emoji nutzt (Callout-Marker ℹ️/⚠️/💡 sowie echte Telegram-/Status-Symbole bleiben erhalten) — sowie mehrere Verweise auf frühere, nie veröffentlichte Zwischenstände. Betrifft nur die Dokumentation; an der Anwendung ändert sich nichts. -
Deploy-Werkzeug räumt verwaiste Server-Dateien auf (
--prune): Das SFTP-Deploy (scripts/deploy-sftp.php) lud bisher nur hoch und ließ umbenannte oder gelöschte Dateien als Karteileichen auf dem Webspace zurück (z. B. eine alte Handbuch-Seite nach einer Umbenennung). Mit dem neuen Opt-in-Flag--pruneentfernt es nach dem Upload genau diese verwaisten Dateien. Secrets (config/.env*,.htpasswd), Build-Stempel und hochgeladene Runtime-Daten (public/branding/,public/uploads/) bleiben dabei immer unangetastet; gelöscht wird nur mit--yesbzw. Bestätigung, auf Prod nur vommain-Branch und nur bei sauberem Working-Tree. Reines Maintainer-Werkzeug — am ETB selbst ändert sich nichts. Details indocs/DEPLOYMENT.md. -
Einsatz-Rollen jetzt als Modal auf der Einsatz-Übersicht (Etappe 6): Die Vergabe temporärer Einsatz-Rollen ist keine eigene Sidebar-Seite mehr, sondern ein Modal, das über den Button „🤝 Einsatz-Rollen" auf der Einsatz-Übersicht (zwischen „Schwerpunkt erstellen" und „⚡ Alarm auslösen") aufgeht. Wer das Recht
user.assign_temp_rolenicht über seine Basis-Rolle hat, sieht den Button nicht (geliehene Rollen können nach wie vor nicht weiterverliehen werden); Berechtigungs-Prüfung und Mutation laufen unverändert über den abgesicherten Endpoint. Der alte Deep-Link/einsatz-rollen.phpleitet weiter auf die Übersicht und öffnet das Modal — Lesezeichen bleiben gültig. -
Sechs editierbare Telegram-Templates (Etappe 6): Der Template-Editor (
/admin/telegram-templates.php) deckt jetzt alle sechs Nachrichten- Arten ab — neben main, alarmierung und error auch heartbeat (Status-Ping), reset (ETB-Reset-Meldung) und selftest (Selbsttest-Ping). Jedes Template lässt sich einzeln bearbeiten, per Haken aktivieren/deaktivieren (sonst gilt der hartkodierte Standard-Text), auf Default zurücksetzen und mit Beispiel-Daten an den Debug-Chat testen. Diereset-Vorlage kennt die Blöcke{#ok}(✅) und{#fail}(❌), die das ETB je nach Ausgang des Resets rendert. -
Status- und Wichtigkeit-Symbole entfernt (Etappe 6): Abschnitts-Status, Schwerpunkt-Status und Wichtigkeit unterscheiden sich jetzt nur noch über Farbe + Label — es gibt kein Icon und keine Marker-Form mehr. In den Admin-Katalogen (
/admin/wichtigkeit.php,/admin/abschnitt-status.php) sind Icon und Karten-Marker-Form nicht mehr einstellbar (die DB-Spalten bleiben unangetastet, nur ohne UI). Die Lagekarte stellt Einsätze über eine einheitliche Status-Kachel dar, deren Farbe dem Einsatz-Status folgt — nicht mehr der Wichtigkeit-Form. -
Standard-Wert per Stern (★) in den Admin-Katalogen (Etappe 6): Den Standard-Wert (vorausgewählte Wichtigkeit bzw. Abschnitts-Status bei neuen Einträgen) legst du jetzt über einen klickbaren Stern (★) in der Spalte „Standard" fest; der aktive Standard ist mit einem gefüllten ★ markiert. Nur aktive Stufen sind als Standard wählbar.
-
Branding vereinfacht: „Eigenes Theme" entfernt (Etappe 6): Die frei konfigurierbare Marken-Farb- und -Schrift-Auswahl unter Admin → Organisation & Branding (vormals „Eigenes Theme" / Custom-Theme- und Font-Engine) ist entfallen. Geblieben sind Org-Name, Logo, Favicon, Menü-Logo und Leitstellen-Adresse sowie der normale Hell-/Dunkel-Umschalter. Farben und Schrift kommen jetzt einheitlich aus dem ausgelieferten Design (zentrale Design-Tokens), damit Hell- und Dunkel-Variante überall sauber lesbar bleiben. Bereits hinterlegte Theme-Werte werden ignoriert (keine Migration nötig); für die übrige Bedienung ändert sich nichts.
-
Durchgängige Icons statt Emoji (Etappe 6): Sidebar, Einsatz-Listen und -Detail, Lagekarte sowie rund 33 Admin- und Schwerpunkte-Seiten zeigen jetzt einheitliche Inline-SVG-Icons (Tabler-Stil, gerendert in
currentColormit passenden a11y-Attributen) statt der bisherigen Unicode-Emoji. Rein optisch — Beschriftungen, Tooltips und Abläufe bleiben gleich. -
PWA: Browser-Chrome folgt dem Theme (Etappe 6): Die
theme-color(Statusleisten-/Adressleisten-Farbe auf Mobilgeräten und im installierten PWA-Fenster) folgt jetzt dem aktiven Hell-/Dunkel-Theme und schaltet beim Umstellen mit um. -
Lagekarte: Dark-Mode-Feinschliff der Filterleiste (Etappe 6): Die Filter-/Ansichts-Leiste der Lagekarte ist jetzt token-basiert und stellt sich im Dunklen Modus korrekt dar (kein heller Streifen mehr); der Karte-hell/dunkel-Umschalter sitzt als Icon-Knopf an gewohnter Stelle.
-
CSS-/Token-Konsolidierung (Etappe 6, intern): Auflösung der zuvor in Etappe 0.5 angekündigten
theme.css-Duplikate, neue Tokens für die Status-Kachel (Hell + Dunkel) und für die Alarm-Regel-Chips (/admin/alarm-regeln.php), die damit von hartkodierten Farben auf Tokens umgestellt sind. Ohne sichtbare Wirkung auf die Bedienung. -
Entmandantisierung — neutrale Standard-Texte & interne Umbenennungen (Etappe 5): Alle fest auf die Referenz-Wehr zugeschnittenen Kennungen wurden entfernt, damit das ETB ohne Nacharbeit bei jeder Feuerwehr startet. Für die tägliche Bedienung ändert sich nichts — die betroffenen Werte waren intern oder werden ohnehin über „Organisation & Branding" und die Stammdaten je Instanz gepflegt.
- Neutrale Vorgaben: Branding-Standardtexte (z. B. „Freiwillige Feuerwehr" statt eines konkreten Wehr-Namens), leere Logo-/URL- Vorgaben sowie neutrale Platzhalter im Admin-Bereich. Deine bereits eingetragenen eigenen Werte bleiben unverändert.
- Interne Umbenennungen ohne sichtbare Wirkung: Der interne
Speicherwert der Einsatzmittel-Kategorie „eigene" heißt in der
Datenbank jetzt
eigene(vorher ein wehr-spezifisches Kürzel); im Einsatzmittel-Editor stand und steht weiterhin das Label „eigene". Auch der Name des Sitzungs-Cookies wurde neutralisiert (FFETB_SID). - Doku-Quellen vereinheitlicht: Die GitHub-Links in Handbuch, README, CONTRIBUTING und SECURITY zeigen jetzt einheitlich auf den aktuellen Projekt-Owner, und die Handbuch-Beispiele nennen neutrale Dummy-Orte statt eines realen Wehrgebiets.
⚠️ Nach dem Update einmalig
/admin/schema-check.php→ „Reparieren" ausführen. Die Entmandantisierung benennt den internen Speicherwert der Einsatzmittel-Kategorie um (DB-ENUM von einem wehr-spezifischen Kürzel aufeigene); der Schema-Check zieht bestehende Einsatzmittel verlustfrei und idempotent mit. Bis dahin zeigt das ETB den Schema-Banner.ℹ️ Einmaliger Logout beim Update: Weil der Sitzungs-Cookie umbenannt wurde (
FFETB_SID), werden mit dem Deploy alle aktiven Sitzungen einmalig beendet — alle Nutzer müssen sich einmal neu anmelden. Das ist bewusst so eingeplant; danach läuft alles normal weiter. -
Rollen-, Einsatz-Rollen- und Aktiv-Status-Änderungen wirken jetzt sofort (Etappe 2, #30): Der Anmelde-Status wird bei jedem Seitenaufruf frisch aus der Datenbank geprüft (statt nur aus der Sitzung). Ändert ein Admin die Rolle eines Benutzers oder vergibt/entzieht eine Einsatz-Rolle, greift das ohne Neuanmeldung beim nächsten Klick — vorher konnte das bis zu 12 Stunden dauern. Deaktivierte Konten werden jetzt sofort ausgeloggt (beim nächsten Seitenaufruf), statt erst nach Ablauf der Sitzung. Für die Bedienung ändert sich sonst nichts.
-
Bessere Tastatur- und Touch-Bedienbarkeit (Barrierefreiheit, WCAG 2.2 AA): Wer mit der Tastatur navigiert (Tab-Taste), sieht jetzt app-weit einen deutlich sichtbaren Fokus-Rahmen — vorher war er besonders im Dunklen Modus kaum zu erkennen. Das gilt auch für die Disponenten-Auswahl in den Einsatz-/Abschnitts-Zeilen, die zuvor gar keinen sichtbaren Fokus hatte. Auf Smartphone und Tablet sind Buttons, Filter- und Auswahl-Chips sowie Eingabefelder jetzt durchgängig mindestens 44 px hoch und damit fingerfreundlicher. Eingabefehler in Formularen werden zusätzlich für Screenreader angekündigt (
aria-invalid/role="alert"). Mit der Maus ändert sich nichts (der Fokus-Rahmen erscheint nur bei Tastatur-/Programm-Fokus). -
Erweiterte Design-Tokens (
tokens.css): zentrale Skalen für Abstände, Radien, Schatten und Schriftgrößen, eine zentrale Breakpoint-Referenz, ein Mono-Font-Token sowie ein dezenter, von der Status-/Alarm-Farbe getrennter Identitäts-Akzent (Feuerwehr-Rot, in Hell und Dunkel sichtbar). Die Light-Defaults der Admin-Rollen-Pills liegen jetzt ebenfalls zentral als Tokens vor (Auflösung der theme.css-Duplikate folgt in Etappe 6).
Behoben
-
Lagekarte: einheitliche Höhe der Topbar-Buttons bei schmaler Ansicht (#179) — die Umschalter Einsätze, Filter und Einsatzmittel in der Kopfleiste der Lagekarte hatten bei schmaler Breite unterschiedliche Höhen, weil ihr Text intern umbrach. Sie halten jetzt Symbol und Text einzeilig und brechen als ganzer Button in die nächste Zeile um — dadurch bleiben sie gleich hoch. Rein optisch, kein Schema-Check nötig.
-
Lagekarte-Filter „Nur offene" blendet jetzt auch erledigte Einsätze aus — bisher zeigte Nur offene noch Einsätze im Status Erledigt; nur Abgeschlossen wurde ausgeblendet. Jetzt zeigt Nur offene konsistent nur aktive Einsätze (Neu, Disponiert, In Bearbeitung) — Erledigt und Abgeschlossen sind beide ausgeblendet, passend zu Einsatzliste und Zählern. Kein Schema-Check nötig.
-
Kleine Nachbesserungen aus dem Abschluss-Review — kein Schema-Check nötig.
- Schwerpunkt anlegen: Orte, die bereits einem offenen Schwerpunkt zugeordnet sind, werden im Ort-Schritt jetzt ausgegraut mit „belegt"-Kennzeichnung gezeigt (statt kommentarlos zu fehlen) — so ist klar, warum ein Ort nicht wählbar ist.
- Abschnitts-Status: Zum Ändern eines Abschnitts-Status verlangt der Server jetzt konsistent das Recht „Abschnitts-Status setzen" (genau wie schon in der Oberfläche) statt des allgemeineren Einsatz-Bearbeiten-Rechts. Für die Standard-Rollen ändert sich nichts.
- Einsatzmittel am Abschnitt zuweisen: Das Zuweisen/Entfernen von
Einsatzmitteln an einem Abschnitt verlangt serverseitig jetzt konsistent
das Recht „EMs zu Abschnitt zuweisen" (
abschnitt.em_assign) — genau das Recht, an dem auch schon der EM-Editor in der Abschnittsansicht hängt. Vorher prüfte der Endpoint das allgemeinere Einsatz-Bearbeiten-Recht, wodurch Oberfläche und Server bei eigenen (Custom-)Rollen auseinander laufen konnten. Für die Standard-Rollen (die beide Rechte gemeinsam tragen) ändert sich nichts. - Schwerpunkt erledigen: Die Warnung „noch X Einsätze offen" am Erledigen-Knopf im Schwerpunkt-Banner nutzt jetzt den aktuellen Stand statt eines evtl. veralteten Werts vom Seitenaufbau.
-
Korrektheit & Politur (Nachzieher aus dem Voll-Review) — kleine Korrekturen ohne geänderte Bedienung; kein Schema-Check nötig.
- Abschluss-/Erledigt-Vermerk auch beim Formular-Speichern korrekt: Änderst du den Status eines Einsatzes über das Bearbeiten-Formular, werden die Vermerke „erledigt von/am" und „abgeschlossen von/am" jetzt genauso konsistent gesetzt bzw. wieder geleert wie über das Status-Dropdown — vorher konnte das Formular veraltete Stempel stehenlassen. Ein über das Formular ausgelöster Disponenten-Wechsel landet außerdem korrekt in der Historie.
- Alarm-Regeln: kein Doppel-Anlegen bei gleichzeitigem Auslösen. Beim manuellen Auslösen einer Alarm-Regel am Einsatz konnte ein Doppelklick oder ein zweiter Tab in seltenen Fällen die Folge-Einsätze/-Abschnitte doppelt anlegen. Der Server merkt sich die Auslösung jetzt vor dem Anlegen und überspringt parallele Zweitversuche; eine manuell ausgelöste Regel wird zudem zuverlässig protokolliert, sodass das Bestätigungs-Banner sie danach nicht erneut als offen anbietet.
- „Einsätze abschließen": schnellere Liste. Die Liste der erledigten Einsätze (Zähler und Sammel-Modal) lädt die Anzahl noch offener Abschnitte jetzt in einer Abfrage statt einzeln pro Zeile — spürbar flotter bei vielen Einsätzen und bei Live-Aktualisierungen.
- Deaktivierte Katalog-Stichworte zählen nicht als Auswahl: Beim Speichern eines Einsatzes wird eine übergebene Stichwort-Katalog-ID nur noch akzeptiert, wenn der Eintrag aktiv ist; ein deaktivierter Eintrag fällt sauber auf Freitext zurück.
- Erledigen-Dialog: Tastatur-Bedienung & Fokus (Barrierefreiheit, WCAG 2.1.2 / 2.4.3). Im Fenster „Einsatz erledigen" bleibt der Fokus jetzt im Dialog (Tab springt nicht mehr dahinter), und nach dem Schließen kehrt er auf den auslösenden Knopf zurück.
- Größere Tipp-Flächen auf Touch-Geräten: Das Status-Auswahlfeld und die Einsatzmittel-Chips sind jetzt mindestens 44 px hoch und damit auf dem Smartphone besser zu treffen.
- Auto-Aktualisierung pausiert bei offenem Dialog: Die automatische Listen-Aktualisierung hält jetzt an, solange ein Dialog (z. B. „Erledigen") offen ist, und reißt ihn nicht mehr unter den Händen weg.
- Dark-Mode-Lesbarkeit nachgezogen: Mehrere Flächen, die im dunklen Erscheinungsbild noch hellgrau hinterlegt waren (gesperrtes Disponenten-Feld, CSV-Status-Markierungen im Stichwort-Katalog, Hinweis-Einblendungen, aufgeklappte Schwerpunkt-Unterzeilen sowie die graue „vorhanden/—"-Pille), nutzen jetzt die Theme-Farben und sind im Dunkelmodus sauber lesbar.
-
SMTP („Passwort vergessen") jetzt im Setup-Wizard und unter Admin → Einstellungen sichtbar — der ausgehende Mailversand ließ sich bisher nur per Hand in
config/.enveintragen und tauchte nirgends in der Oberfläche auf; nach einer Frischinstallation fehlte er im Wizard komplett, sodass „Passwort vergessen" tot war und sich der Fehler nicht diagnostizieren ließ. Jetzt:- Der Setup-Wizard fragt in Schritt 3 (unter dem Alarmpush-Postfach)
optional die SMTP-Felder ab — Host, Port, Verschlüsselung (
tls/ssl/none), Benutzer, Passwort, Absender und Absender-Name — und schreibt sie nachconfig/.env; die Zusammenfassung (Schritt 7) zeigt sie an (Passwort nie im Klartext). Leerer Host = Versand bewusst aus. - Admin → Einstellungen (
/admin/config.php) zeigt den SMTP-Block jetzt als eigene Sektion (read-only, Passwort maskiert), sodass Du auf einen Blick siehst, was hinterlegt ist. Geändert wird weiter über den Wizard bzw.config/.env. - Als Merkhilfe: Port
587= STARTTLS (tls), Port465= implizites SSL (ssl); der Wizard warnt, wenn Port und Verschlüsselung nicht zusammenpassen. - Damit ist „Passwort vergessen" ohne
.env-Handarbeit konfigurierbar. Kein Schema-Check nötig.
- Der Setup-Wizard fragt in Schritt 3 (unter dem Alarmpush-Postfach)
optional die SMTP-Felder ab — Host, Port, Verschlüsselung (
-
.env-Vorlage entrümpelt: Der nicht mehr gelesene EintragALARMPUSH_BASE_URList ausconfig/.env.exampleentfernt — die App-Basis-URL (z. B. für Einsatz-Links in Telegram) kommt aus dem DB-Settingorg_url(Setup-Wizard Schritt 1 bzw. Admin → Organisation & Branding). -
„Einsätze abschließen" lässt den Komfort/Kompakt-Schalter in Ruhe: Der eigenständige Knopf teilt sich für die Optik die
.lvt-btn-Klasse mit dem Komfort/Kompakt-Umschalter und wurde dadurch von dessen JavaScript miterfasst — ein Klick entfernte die aktive (rote) Markierung des Umschalters. Die Umschalt-Logik greift jetzt nur noch die echten Toggle-Buttons (mitdata-view). -
Geocodierung beim Bearbeiten folgt der Adressänderung: Wurde bei einem bestehenden Einsatz die Straße/Adresse geändert und gespeichert, blieb die alte Geocodierung (Lagekarte-Marker) stehen — die automatische Geocodierung brach ab, weil das Formular die alten Koordinaten mittrug. Jetzt werden bei geänderter Adresse die alten Koordinaten verworfen und neu geocodiert; selbst eingetragene Koordinaten behalten Vorrang. Liefert die Neu-Geocodierung keinen Treffer (Dienst nicht erreichbar oder Adresse unbekannt), bleiben die bisherigen Koordinaten erhalten, statt den Marker stumm zu verlieren.
-
Schwerpunkt-Personalstärke aktualisiert sich live: Die Einsatzkräfte-Summe in der Schwerpunkt-Titelleiste aktualisiert sich jetzt automatisch beim Hinzufügen/Entfernen von Einsatzmitteln, Ändern der Einsatzstärke und bei Status-/Abschluss-Wechseln — vorher war ein Browser-Reload nötig.
-
Standard-Stern in den Status-Stammdaten korrekt ausgerichtet: In den Katalog-Seiten (Wichtigkeit, Abschnitts-/Schwerpunkt-Status) saß der gold markierte Standard-Stern etwas weiter links als die klickbaren Sterne der übrigen Zeilen — der markierte Stern ist ein
<span>ohne Innenabstand, die klickbaren ein<button>mit Padding. Der Span bekommt jetzt dieselbe Box (display: inline-block+ gleiches Padding), sodass der gelbe Stern exakt mittig über den anderen sitzt. -
ETB-Reset meldet jetzt echte Datenbank-Fehler (Etappe 6): Der ETB-Reset wertete bisher jeden Durchlauf als „erfolgreich" und schickte den grünen Haken per Telegram — selbst wenn einzelne
DELETE-Operationen an einem echten Datenbank-Fehler (Lock-Timeout, Fremdschlüssel o. ä.) scheiterten und Daten gar nicht gelöscht wurden. Jetzt zählt nur eine fehlende Tabelle als unkritisch (übersprungen); jeder andere Fehler setzt die Reset-Meldung auf die ❌-Variante und wird je Tabelle im Detail ausgewiesen. Betrifft Anzeige im Admin und die Telegram-reset-Nachricht. -
Detail-Mini-Karte: Theme-Leak behoben (Etappe 6): Die Mini-Karte der Einsatzstelle (Einsatz-Detail) und der Abschnitts-Detailseite folgt jetzt zuverlässig dem aktiven App-Erscheinungsbild (hell/dunkel). Der frühere eigene Hell/Dunkel-Umschalter dieser kleinen Karten ist entfernt — er konnte dazu führen, dass eine Karte im falschen Modus „hängen blieb". Der manuelle Karten-Umschalter wirkt bewusst nur noch auf Lagekarte und Hydrantenplan (die Vollkarten).
-
„Auch SP-Einsätze anzeigen" bleibt beim Filtern erhalten (Etappe 6): Hattest du in der Einsatz-Übersicht die freien Einsätze um die Schwerpunkt-Einsätze erweitert („Auch SP-Einsätze in Liste anzeigen") und danach einen Filter gesetzt (Status, Wichtigkeit, Suche, Disponent), sprang die Liste fälschlich zurück auf „nur freie Einsätze". Der Schalter (sowie eine aktive Sortierung und der Schwerpunkt-Kontext) wird jetzt über das Filter-Formular mitgeführt und bleibt erhalten.
-
Lesbare Textfarbe auf frei gewählten Status-/Wichtigkeit-Farben (Barrierefreiheit, WCAG 1.4.3, Etappe 6): Die Status- und Wichtigkeit-Pillen sowie die Abschnitts-Status-Kachel zeigten ihren Text bisher immer weiß. Auf mittelhellen Farben — etwa Grün (
#229954), Orange (#e98011) oder Gelb (#f1c40f) — unterschritt das die geforderten 4,5:1 Kontrast und war schlecht lesbar. Die Textfarbe (Schwarz oder Weiß) wird jetzt automatisch anhand der Helligkeit der hinterlegten Farbe gewählt und hält den AA-Kontrast auf jeder gültigen Farbe ein. Betroffen sind die Einsatz-Liste (Wichtigkeit-, Schwerpunkt-Status-, Abschnitts-Status-Pille und die Wichtigkeit-Filter-Chips), die Einsatz-Detailseite (Wichtigkeit-Pille im Kopf + Abschnitts-Status- Kachel), die Abschnitts-Detailseite, die Schwerpunkt-Liste, -Bearbeitung und -Historie, die Admin-Kataloge Wichtigkeit / Abschnitts-Status / Schwerpunkt-Status (Vorschau-Pillen samt „★ Standard"-Badge), PDF-Export und Druckansicht sowie die Kartenbeschriftungen: die Schwerpunkt-Marker der Lagekarte (grün = aktiv, gelb = pausiert; Weiß auf Gelb war zuvor nur ~1,6:1) und die farbigen Hydranten-Größen-Chips in den Karten-Popups (Hydrantenplan, Admin-Hydranten-Karte und Einsatz-Detailansicht) sowie die interaktiven Status-Dropdowns (das Status-<select>der Abschnitts- Detailseite und der Schwerpunkt-Übersicht) — dort wird die lesbare Textfarbe sowohl beim Laden als auch sofort beim Statuswechsel (ohne Neuladen) gewählt. Karten- und Server-Beschriftung nutzen dieselbe Kontrast-Logik, sodass eine Farbe überall dieselbe Textfarbe erhält. Für Admins heißt das: Beim Festlegen einer Status- oder Wichtigkeit-Farbe musst du nicht mehr selbst auf den Textkontrast achten — die Lesbarkeit stellt sich automatisch ein. Rein optisch, keine geänderte Bedienung, kein Schema-Check nötig. -
Abschnitt eines abgeschlossenen Einsatzes lässt sich nicht mehr ändern (Voll-Review vor v4.0.0): Solange ein Einsatz abgeschlossen ist, weist das ETB einen Status-Wechsel seiner Abschnitte jetzt ab — sonst hätte ein „abgeschlossener" Einsatz wieder einen offenen Abschnitt haben können (genau der Zustand, den die Abschluss-Sperre verhindert). Wer einen Abschnitt ändern will, muss den Einsatz erst wieder öffnen (Recht „Wiedereröffnen",
einsatz.reopen); die Meldung sagt das auch so. Kein Schema-Check nötig. -
Einsatzmittel in den Schwerpunkt-Pool hinzufügen ist jetzt atomar (Voll-Review vor v4.0.0): Beim Hinzufügen eines Einsatzmittels zum Schwerpunkt-Pool laufen das Herauslösen aus freien Einsätzen und der Pool-Eintrag jetzt in einem Schritt. Bricht etwas mitten dabei ab, wird alles zurückgerollt — vorher konnte ein verwaister Zustand entstehen (Einsatzmittel aus den Einsätzen entfernt, aber nicht im Pool gelandet). Kein Schema-Check nötig.
-
Abschnitts-Disponent: „– nicht zugewiesen –" wählbar, kein stilles Umspringen mehr (#167, Voll-Review vor v4.0.0): Das Disponenten-Dropdown der Abschnitts-Detailseite zeigte ohne zugewiesenen Disponenten fälschlich den ersten Eintrag der Liste an — und schon eine Berührung des Feldes speicherte diesen still. Jetzt steht „– nicht zugewiesen –" als erster Eintrag im Dropdown und ist korrekt vorausgewählt, wenn kein Disponent zugewiesen ist; über diesen Eintrag lässt sich eine bestehende Zuweisung auch wieder entfernen. Hängt der Mutter-Einsatz an einem Schwerpunkt, zeigt die Detailseite den Disponenten jetzt nur lesend mit Schloss-Symbol (er folgt zwangsweise dem Schwerpunkt-Disponenten) — vorher stand dort ein scheinbar editierbares Dropdown, dessen Änderungen kommentarlos verworfen wurden. Kein Schema-Check nötig.
-
Einsatzkräfte-Summen: Gesamtzahl immer aus den drei Positionen (#165, Voll-Review vor v4.0.0): Alle Stärke-Summen — die Zeile „Einsatzkräfte" im Einsatz-Detail, die Gesamt-Einsatzstärke in der Titelzeile der Einsatz-Übersicht und die Kräfte-Anzeige der Schwerpunkte (Titelleiste und Übersicht) — leiten die Gesamtzahl (letzte Position) jetzt immer aus A+B+C ab, genau wie die Eingabe beim Zuweisen normalisiert wird. Vorher konnten inkonsistent gespeicherte Alt-Werte (Gesamt ≠ Summe der drei Positionen) die angezeigten Summen verfälschen. Der Schema-Check bereinigt solche Alt-Werte zusätzlich einmalig in der Datenbank (Normalisierung auf das Schema A/B/C/S) → einmaliger Schema-Check nach dem Update empfohlen.
-
Internes Aufräumen vor v4.0.0: toter Code entfernt (u. a. eine ungenutzte Diagnose-Seite und nicht mehr verdrahtete Service-Bausteine), doppelte CSS-Farbwerte zu zentralen Design-Tokens zusammengeführt. Ohne sichtbare Wirkung auf die Bedienung.
Sicherheit
-
Lagekarte respektiert den Disponenten-Scope — ein auf seine eigenen Einsätze beschränkter Disponent (Rolle Dispo ohne das Recht „Alle Einsätze sehen",
einsatz.view_all) sah auf der Lagekarte bisher die Marker und Adressen aller Einsätze — also genau die Daten, die ihm die Einsatz-Übersicht vorenthält. Die Karte wendet jetzt denselben Eigentums-Filter an wie die Liste (eigene + zugewiesene Einsätze) und zeigt beide Ansichten damit im selben Scope. Der Schwerpunkt-Dispo-Scope wird zusätzlich wie bisher am Endpoint erzwungen; bewusst fail-safe gehalten (die Karte kann höchstens strenger filtern als die Liste, nie durchlässiger). Einsatzleiter, Lage und Admin sehen unverändert alle Einsätze. Kein Schema-Check nötig. -
Link-Icon-URLs auf http(s):// beschränkt (#177) — in der Link-Verwaltung akzeptiert das ETB als Icon-URL jetzt ausschließlich
http://- oderhttps://-Adressen (wie schon bei der Link-URL). Andere Schemata (z. B.javascript:oderdata:) werden beim Speichern verworfen und beim Anzeigen defensiv herausgefiltert — auch für Alt-Daten, die vor dieser Prüfung gespeichert wurden. Das schließt einen möglichen XSS-Vektor im<img src>der Linksammlung. Kein Schema-Check nötig. -
Abgeschlossener Einsatz auch serverseitig komplett eingefroren (#162) — der Freeze eines abgeschlossenen Einsatzes war bei Kommentaren und der Einsatzmittel-Zuordnung bisher teils nur eine UI-Sperre (verstecktes Formular). Jetzt weisen die Endpoints Kommentare und EM-Zuordnungen am Einsatz und an seinen Abschnitten serverseitig ab, und die Abschnittsseite zeigt die Sperre auch in der Oberfläche — relevant, seit geplante Abschnitte den Abschluss nicht mehr blockieren (ein nie begonnener Abschnitt kann jetzt an einem abgeschlossenen Einsatz hängen). Ausnahme wie gehabt: das Recht „Einsatz wiedereröffnen" (
einsatz.reopen, Default Admin + Einsatzleiter). Kein Schema-Check nötig. -
Review-Härtung (Nachzieher aus dem Voll-Review) — gezielte Absicherungen ohne neue Bedienung; kein Schema-Check nötig.
- Abschließen über das Bearbeiten-Formular respektiert das
Vier-Augen-Prinzip: Setzt jemand einen Einsatz im Bearbeiten-
Formular auf „Abgeschlossen", greifen jetzt dieselben Sperren
wie beim Status-Dropdown — das Recht „Einsatz abschließen"
(
einsatz.abschluss) und die Sperre „erst, wenn alle Abschnitte erledigt sind". Wer das Recht nicht hat (z. B. Disponent), bekommt die Stufe „Abgeschlossen" im Formular gar nicht mehr angeboten — wie schon zuvor im Status- und Bulk-Dropdown. (Ein bereits abgeschlossener Einsatz zeigt seinen Status weiterhin an.) - Schwerpunkt-Dispo bleibt strikt auf die eigenen Schwerpunkte begrenzt: Die mutierenden Schwerpunkt- und Abschnitts-Endpoints (Schwerpunkt bearbeiten, EM zum Pool hinzufügen/entfernen, Einsatz zuweisen/herauslösen/verschieben sowie Abschnitt löschen) prüfen den SP-Dispo-Scope jetzt durchgängig serverseitig — beim Verschieben sowohl für den Quell- als auch den Ziel-Schwerpunkt. Aktionen außerhalb der eigenen Schwerpunkte werden mit einer klaren Meldung abgewiesen. (Der SP-Dispo-Scope ist Code-Logik und greift immer — unabhängig davon, welche Häkchen ein Admin gesetzt hat.)
- Schwerpunkt-/Abschnitts-Vollrechte nur noch in Führungshand: Die
Rechte Schwerpunkt bearbeiten / zuweisen / löschen / schließen
(
schwerpunkt.edit,…assign_einsatz,…delete,…close) und Abschnitt löschen (abschnitt.delete) erscheinen im Rollen-Editor jetzt nur noch bei Einsatzleiter und Lage (Admin über den Failsafe). Für Dispo, Schwerpunkt-Dispo und Gast tauchen sie gar nicht erst auf, sie lassen sich diesen Rollen also auch nicht versehentlich zuteilen. - Telegram-Vorschau: HTML-Attribute härter gefiltert: Die
Server-Vorschau der Telegram-Nachricht ließ bei den erlaubten
Formatierungs-Tags bisher beliebige Attribute durch. Sie entfernt jetzt
alle Attribute der Formatierungs-Tags und lässt bei Links nur ein
hrefmit sicherem Schema (http/https/tg/mailto) stehen — wie es der Telegram-HTML-Modus ohnehin verlangt.
- Abschließen über das Bearbeiten-Formular respektiert das
Vier-Augen-Prinzip: Setzt jemand einen Einsatz im Bearbeiten-
Formular auf „Abgeschlossen", greifen jetzt dieselben Sperren
wie beim Status-Dropdown — das Recht „Einsatz abschließen"
(
-
Schwerpunkt schließen / archivieren nur noch für Lage, EL und Admin — der Status-Wechsel eines Schwerpunkts auf „geschlossen" oder „archiviert" verlangt jetzt fest das Recht „Schwerpunkt schließen / archivieren" (
schwerpunkt.close, Default: Lage, Einsatzleiter, Admin). Vorher konnte der Wechsel über das breitereschwerpunkt.edit-Recht des Endpoints laufen;SchwerpunktServiceerzwingt dasschwerpunkt.close-Recht nun serverseitig (defense-in-depth), unabhängig vom Endpoint. Damit ist der Abschluss eines Schwerpunkts ein Vier-Augen-Schritt wie der Einsatz-Abschluss (einsatz.abschluss). Die bestehende Sperre — „geschlossen" erst, wenn alle Einsätze des Schwerpunkts abgeschlossen sind — bleibt unverändert. In den Schwerpunkt-Oberflächen sind die Aktionen „Schließen"/„Archivieren" für Nutzer ohne dieses Recht jetzt ausgegraut bzw. nicht wählbar (statt erst beim Klick serverseitig abgewiesen zu werden). Kein Schema-Check nötig. -
CSRF-Schutz für die JSON-API (Header-Token, Etappe 0.7): Alle mutierenden AJAX-/JSON-Aktionen (
public/api/*— z. B. Kommentar anlegen, Status ändern, Einsatzmittel zuweisen, Schwerpunkt/Abschnitt bearbeiten) verlangen jetzt zusätzlich einX-CSRF-Tokenim Request-Header. Ein zentralerfetch-Wrapper (etb-common.js) hängt dieses Token automatisch an jeden mutierenden, gleich-stammenden (same-origin) Request an; serverseitig erzwingt esCsrf::checkHeader()(Vergleich mithash_equals). Das ergänzt die bereits bestehendeSameSite=Lax-Absicherung des Session-Cookies als zweite Verteidigungslinie gegen Cross-Site-Request-Forgery. Für Dich ändert sich an der Bedienung nichts — alle Aktionen laufen wie bisher.ℹ️ Nach dem Update einmal neu laden: Hat der Browser noch die alte JavaScript-Version zwischengespeichert, kann eine AJAX-Aktion kurz mit dem Hinweis „Sicherheits-Token … bitte die Seite neu laden" abbrechen. Ein einmaliges Neuladen der Seite (Strg+F5) behebt das.
-
Stichwort-Katalog: Änderungen mit auslösendem Benutzer protokolliert — jede Mutation am Stichwort-Katalog (Stichwort anlegen / ändern / löschen, CSV-Import, Änderung der Ausblend-Präfixe) wird jetzt nachvollziehbar mit dem auslösenden Benutzer im Anwendungs-Protokoll festgehalten. Für Dich ändert sich an der Bedienung nichts; kein Schema-Check nötig.
-
Härtung vor v4.0.0 (Voll-Review) — gezielte Absicherungen ohne neue Bedienung; kein Schema-Check nötig.
- Gehärtete Ausgabe-Codierung gegen XSS: Die Bestätigungs- und Fehler-Meldungen beim Anlegen eines Schwerpunkts geben Name und eventuelle Konflikt-Texte jetzt maskiert aus, statt sie roh in die Seite zu schreiben. Ebenso betten die Karten-Seiten (Lagekarte-/ Hydrantenplan-Daten) ihre Daten jetzt mit härteren Maskierungs-Schaltern ein, sodass Inhalte aus der Datenbank nicht als aktives Markup wirken können. Sichtbar ändert sich nichts.
- Zusätzlicher Zugriffs-Scope beim Anhängen an Kommentare: Wer eine auf eigene Einsätze beschränkte Rolle (Disponent / Schwerpunkt-Dispo) hat, kann an einen Kommentar (Einsatz oder Abschnitt) nur dann noch eine Datei anhängen, wenn der zugehörige Einsatz im eigenen Scope liegt — derselbe Schutz, der schon beim Bearbeiten/Löschen von Kommentaren greift.
3.0.1 — 2026-06-15
Neu
- Neues Recht „Als Disponent arbeiten" (
dispo.act_as): Im Rollen-Editor (/admin/rollen.php, Gruppe „Einsätze") gibt es ein neues, administrierbares Recht. Es steuert, wer in den Disponenten- Auswahllisten (Einsatz, Abschnitt, Schwerpunkt) erscheint und als Disponent zugewiesen werden kann. Der Default ist unverändert: nur die Rolle „Dispo" hat das Recht — und zwar fest (das Häkchen ist gesperrt/🔒, kann ihr also nicht entzogen werden); im Schwerpunkt-Kontext kommt wie bisher der Schwerpunkt-Dispo dazu. Neu zuschaltbar: Der Admin kann das Recht jetzt zusätzlich an „Lage" und „Einsatzleiter" vergeben — diese Rollen tauchen dann ebenfalls in den Disponenten-Listen auf. Administratoren erscheinen über den Admin-Failsafe ebenfalls in den Listen (sie haben ohnehin jedes Recht). Bewusst ausgeschlossen bleiben „Schwerpunkt-Dispo" (bleibt auf seine Schwerpunkte beschränkt — das Häkchen wird für diese Rolle gar nicht angezeigt) und Gast. Alle Disponenten-Dropdowns zeigen die Auswahl jetzt einheitlich im Format „Name (Rolle)". Bestands-Installationen ziehen das Recht beim nächsten/admin/schema-check.php→ „Reparieren" für „Dispo" nach; dank der Festschreibung wirkt es aber sofort, auch ohne Schema-Lauf.
Geändert
- Administratoren erscheinen jetzt ebenfalls in den Disponenten-
Auswahllisten (Einsatz, Abschnitt, Schwerpunkt): Da ein Admin per
Admin-Failsafe jedes Recht hat, gilt das auch für „Als Disponent
arbeiten" (
dispo.act_as). Damit lässt sich ein Admin wie ein Dispo zuweisen. (Korrigiert das zuvor dokumentierte Verhalten, wonach Admins bewusst nicht in den Listen standen.) Schwerpunkt-Dispo und Gast bleiben weiterhin ausgeschlossen. - EM-Seitenleiste der ETB-Übersicht: Live-Update bei Status-Änderung:
Änderst du in der Einsatz-Übersicht den Status eines Einsatzes über das
Status-Dropdown der Zeile, ziehen die zugeordneten Einsatzmittel in der
Seitenleiste jetzt sofort nach (ohne Reload): Sie wechseln passend
zwischen „frei" und „im Einsatz", die zugeordnete laufende Nummer
(
#007) kommt hinzu bzw. fällt weg. Das ergänzt den bereits bestehenden Live-Update beim Zuweisen per Drag&Drop. - SP-Pool-Einsatzmittel bleiben in der ETB-Übersicht ausgeblendet: In der normalen Einsatz-Übersicht werden Einsatzmittel, die einem aktiven Schwerpunkt-Pool angehören, weiterhin ausgeblendet — sie sind dem Schwerpunkt vorbehalten und stehen anderen Einsätzen nicht zur Verfügung, sollen also nicht zur Doppel-Zuweisung verleiten. Sichtbar bleiben diese EM innerhalb des jeweiligen Schwerpunkttagebuchs, wo die Seitenleiste auf den Pool gefiltert ist und als Pool-Picker dient. (Nimmt die kurzzeitige Änderung zurück, die SP-Pool-EM auch im ETB-Modus einblendete.)
- Einsatz-Übersicht: zugeordnete Einsatzmittel jetzt auch auf dem Smartphone sichtbar: Auf schmalen Bildschirmen ist die eigene Einsatzmittel-Spalte weiterhin ausgeblendet. Damit die zugeordneten Einsatzmittel eines Einsatzes mobil nicht ganz fehlen, erscheinen sie dort jetzt als kompakte Chip-Zeile direkt unter dem Stichwort der Einsatz-Zeile. Am Desktop bleibt es unverändert bei der eigenen Spalte.
- Lagekarte: Einsatznummer im Format
#007: Marker-Tooltip und Marker- Popup zeigten die Einsatznummer bisher roh bzw. siebenstellig. Sie steht jetzt als unsere laufende Nummer im Format#007— konsistent mit der Anzeige im restlichen ETB. Ebenso angeglichen ist die Einsatz-Geocoding- Admin (/geocode-admin.php), wo Liste und Status-Meldungen die laufende Nummer nun im#007-Format ausgeben. - Disponent-Anzeige einheitlich „Name (Rolle)": Wo der Disponent eines Einsatzes nur lesend angezeigt wird (gesperrtes Feld, z. B. bei einem schwerpunkt-gekoppelten oder abgeschlossenen Einsatz), erscheint jetzt ebenfalls das Format „Name (Rolle)" wie in den Auswahllisten — statt nur des Namens.
Behoben
- Neutrale Links, Buttons und Kacheln bleiben nach Klick neutral
(app-weit): Viele Elemente, die technisch Links sind — Menü- und
Admin-Kacheln, Buttons (
.btn/.btn-link), die Linksammlung (/links.php), die Hilfe-Navigation (Inhaltsverzeichnis + Vor/Zurück), Sortier-Spaltenköpfe in den Tabellen, die Telegram-Vorlagen-Reiter und die Karten-Buttons (TIM/Hydrant) — färbten sich nach einem Klick oder beim Hovern über die globale Link-Farbe blau (inkl.:visited). Sie bleiben jetzt in allen Zuständen neutral; nur der jeweils gewollte Hover (Hintergrund, Rahmen, Schatten) wirkt noch. Aktive/primäre Varianten (z. B. ein aktiver Reiter oder ein „primary"-Button) behalten unverändert ihre eigene Farbe. - Einsatzmittel-Sidebar: laufende Nummer statt Leitstellen-Nummer:
Unter einem zugeordneten Einsatzmittel zeigte die EM-Sidebar (Einsatz-
Übersicht, Einsatz-Detail und Schwerpunkt) fälschlich die
Leitstellen-Einsatznummer an. Jetzt steht dort immer unsere
laufende Nummer im Format
#007— konsistent mit dem Rest der Anwendung. Das gilt auch für den Live-Update nach Drag&Drop, die Einsatzauswahl beim Anlegen eines Schwerpunkts und die Kaskaden-Bestätigungsdialoge beim Umhängen belegter Einsatzmittel. Die Leitstellen-Nummer dient weiterhin nur intern der Duplikaterkennung eingehender Alarm-Mails. - Frisch alarmierte Einsatzmittel werden als „im Einsatz" angezeigt: Ein Einsatz startet im Status „neu" (egal ob aus Alarm-Mail oder manuell angelegt) und hat seine Einsatzmittel damit bereits draußen. Bisher galten EM an einem „neu"-Einsatz in der Sidebar trotzdem als frei (ohne Nummer) — besonders störend auf Smartphone/Tablet, wo die Einsatzmittel-Tabellenspalte ausgeblendet ist und nur die Sidebar bleibt. Jetzt zählt „neu" als „im Einsatz": solche EM erscheinen als belegt mit Nummer, und zwar identisch beim ersten Laden wie nach dem Live-Update per Drag&Drop. Auf der Lagekarte bzw. im Einsatzmittel-Panel zählen „neu"-EM zur Disp.-Stufe. Die Status erledigt, Abschluss beantragt und abgeschlossen gelten unverändert als frei (Nachlauf).
- Dark-Mode: zwei hell leuchtende Pillen abgedunkelt: Die
Zähler-/Quellen-Pillen in der EM-Gruppen-Verwaltung
(
/admin/em-gruppen.php) und im Geocode-Cache (/admin/geocode-cache.php) hatten fest hinterlegte Hellblau-Töne und leuchteten dadurch im Dunklen Modus grell. Sie nutzen jetzt die zentralen Design-Tokens und schalten im Dark-Mode korrekt mit um. - Zugewiesener, aber nicht mehr berechtigter Disponent verschwindet
nicht still: Verliert ein bereits einem Einsatz oder Abschnitt
zugewiesener Disponent nachträglich seine Berechtigung (inaktiv gesetzt
oder das Recht „Als Disponent arbeiten" (
dispo.act_as) entzogen), fiel er bisher kommentarlos aus dem Auswahl-Dropdown — beim nächsten Speichern wäre die Zuordnung damit unbemerkt verloren gegangen. Jetzt bleibt er als selektierte Option „Name (Rolle) — nicht mehr verfügbar" sichtbar (im Bearbeiten-Formular und in der Inline-Auswahl von Einsatz und Abschnitt), sodass die bestehende Zuordnung erhalten bleibt, bis sie bewusst geändert wird. - Dark-Mode: Setup-Wizard (installiert) und Geocode-Filter lesbar: Ruft man den Setup-Wizard aus dem installierten Admin-Menü auf, wurden mehrere Flächen (die Tabellen-Anlage-Liste in Schritt 2, die Zusammenfassungs- Blöcke, die Schalter-Box und die Buttons) noch mit festen hellen Farben gezeichnet — im Dunklen Modus schwer lesbar. Sie nutzen jetzt die zentralen Design-Tokens und dunkeln korrekt mit (die Erstinstallation bleibt bewusst hell, da dort noch kein Theme existiert). Außerdem waren im Geocode-Admin die Filter-Schaltflächen („Alle / Nicht geocodiert / Geocodiert") im Dark-Mode schwarz und kaum lesbar — sie sind jetzt hell.
3.0.0 — 2026-06-14
Neu
- Versionsanzeige in der Seitenleiste: Ganz unten im Menü (unter den
Buttons Abmelden / Theme / Einklappen) steht jetzt dezent die laufende
Programmversion, z. B. „Version 2.4.0-58-a1b2c3d" — die
Release-Version plus Build-Nummer (Anzahl der Commits seit dem letzten
Release) und Commit-Kürzel. Direkt auf einem Release-Tag steht sie
sauber als „Version 3.0.0". Per Maus-Tooltip gibt es Build-Zeitpunkt und Instanz
(TEST/PROD). Die Angabe wird bei jedem Deploy automatisch aus dem
Git-Stand erzeugt — so sieht man auf TEST und PROD sofort, welcher Stand
läuft, und kann beide vergleichen. Sobald ein neuer Release-Tag (z. B.
v3.0.0) gesetzt ist, zeigt sie automatisch „Version 3.0.0". Im eingeklappten Menü wird die Zeile ausgeblendet; zusätzlich steht die Version dezent auf der Login-Seite (TEST/PROD-Vergleich schon vor der Anmeldung). - PDF-Export: Einsatzmittel-Übersicht mit Stärke & Kontakt (#32): Am Ende des Einsatz-Berichts steht jetzt eine Übersichts-Tabelle der eingesetzten Einsatzmittel mit ihrer Stärke (Zug- und Verbandführer / Gruppenführer / Mannschaft / Gesamt) und ihrem Kontakt (hinterlegte Erreichbarkeit bzw. Funkrufname), abgeschlossen durch eine Gesamtstärke-Summenzeile. Die Tabelle erscheint nur, wenn mindestens ein Einsatzmittel eine Stärke oder einen Kontakt hinterlegt hat. Im Kopf des Berichts bleiben die Einsatzmittel bewusst eine reine Namensliste.
- Passwort vergessen — Selbsthilfe per E-Mail-Link (#39): Die
Login-Seite hat jetzt einen Link „Passwort vergessen?". Du gibst
Deinen Benutzernamen oder Deine hinterlegte E-Mail-Adresse ein und
bekommst einen einmalig verwendbaren Link an diese Adresse, über
den Du (mit Wiederholung) ein neues Passwort vergibst. Der Link ist
30 Minuten gültig; mit dem ersten erfolgreichen Setzen werden alle
weiteren offenen Links des Kontos entwertet. Aus Sicherheitsgründen
funktioniert das nur für Konten mit hinterlegter E-Mail-Adresse —
Konten ohne E-Mail bekommen den Hinweis, sich an einen Admin zu
wenden (der die Adresse in der Benutzerverwaltung nachträgt oder das
Passwort direkt zurücksetzt). Es gibt keine Selbstregistrierung.
Die Rückmeldung der Seite ist bewusst neutral (Anti-Enumeration), und
ein Rate-Limit bremst Missbrauch.
- Betreiber-Hinweis — neuer SMTP-Mailversand: Für die Reset-Mail
bringt das ETB jetzt ausgehenden Mailversand per SMTP mit,
getrennt vom IMAP-Postfach (das nur Alarm-Mails liest). In
config/.envkommen dafür die KeysSMTP_HOST,SMTP_PORT,SMTP_SECURITY(tls/ssl/none),SMTP_USER,SMTP_PASS,SMTP_FROMundSMTP_FROM_NAMEhinzu (Vorlage inconfig/.env.example). Ist kein SMTP konfiguriert, bleibt die „Passwort vergessen"-Funktion inaktiv und zeigt statt eines Versands einen Admin-Hinweis. Nach dem Update einmal/admin/schema-check.phpausführen — es gibt eine neue Tabellepw_reset(sonst erscheint der Schema-Hinweis-Banner).
- Betreiber-Hinweis — neuer SMTP-Mailversand: Für die Reset-Mail
bringt das ETB jetzt ausgehenden Mailversand per SMTP mit,
getrennt vom IMAP-Postfach (das nur Alarm-Mails liest). In
- Menü-Logo für die Seitenleiste: Unter Organisation & Branding
(
/admin/branding.php) lässt sich jetzt ein separates Logo für die dunkle/eingefärbte Seitenleiste hochladen — getrennt vom bestehenden (Login-)Logo. Empfohlen wird ein möglichst quadratisches PNG mit Transparenz, mindestens 256 px; es wird auf eine feste Fläche zentriert eingepasst. Ist kein Menü-Logo gesetzt, fällt die Seitenleiste wie bisher auf das Login-Logo zurück. - Logo, Menü-Logo und Favicon wieder entfernbar (#88): Unter
Organisation & Branding (
/admin/branding.php) gibt es jetzt pro Bild eine Checkbox „… entfernen (auf Standard zurücksetzen)". Damit lässt sich ein hochgeladenes Bild wieder löschen und auf den Standard zurücksetzen (Menü-Logo zurück auf das Login-Logo) — vorher war nur Ersetzen möglich. Kommt im selben Vorgang ein neuer Upload fürs gleiche Bild, gewinnt der Upload. - Eigenes Erscheinungsbild (Theme) pro Organisation: Neuer Bereich Erscheinungsbild in Organisation & Branding mit der Wahl zwischen dem ausgelieferten Standard-Theme (Hell/Dunkel) und einem eigenen Theme. Beim eigenen Theme sind Primärfarbe (Akzent: Buttons/Links/aktive Elemente), Sekundärfarbe (aktiver Marker in der Seitenleiste), Seitenleisten-Hintergrund, Seitenleisten-Text und die Schriftart (aus einer kuratierten, lokal ausgelieferten Auswahl — kein externes Laden) einstellbar. Der Hell-/Dunkel-Umschalter bleibt in beiden Modi aktiv: Das eigene Theme legt nur eine Marken-Ebene über die Hell-/Dunkel-Basis, Grundflächen und Status-Farben bleiben hell-/dunkel-gesteuert. Ungesetzte Werte bleiben auf dem Standard.
- Mobile Bedienung (Off-Canvas-Menü): Auf schmalen Bildschirmen (Smartphone, kleines Tablet) wird die Hauptnavigation zu einem ausklappbaren Menü. Oben links öffnet das Menü-Symbol (☰) die Seitenleiste als Schublade über einem abgedunkelten Hintergrund; ein Tippen auf den abgedunkelten Bereich schließt sie wieder. Zusätzlich werden Formulare einspaltig, Touch-Ziele (Schaltflächen, Chips) größer und breite Admin-Tabellen seitlich scrollbar statt abgeschnitten.
- Als App installierbar (PWA): Das ETB bringt jetzt ein Web-App-
Manifest und einen Service-Worker mit und lässt sich über den Browser
(„Zum Startbildschirm hinzufügen") als App-ähnliche Verknüpfung mit
eigenem Icon im Vollbild installieren. Am iPhone/iPad (Safari)
funktioniert „Zum Home-Bildschirm" jetzt auch ohne HTTPS (über
Apple-eigene Meta-Tags, ohne Service-Worker); die Android-Chrome-
Vollinstallation und der Service-Worker brauchen weiterhin HTTPS
(auf der unverschlüsselten Test-Instanz bleibt der SW inaktiv). Als
App-Icon und -Titel dienen am iPhone das (Login-)Logo und der
konfigurierte App-Titel. Es werden bewusst keine Einsatzdaten
offline zwischengespeichert (das ETB braucht stets aktuelle Daten,
Strategie „Network-first") — nur statische Programm-Assets (Design,
Symbole) werden gecacht und laden dadurch schneller; HTML-Seiten und
/api/nie. Die Browser-/App-Leistenfarbe (theme-color) folgt der (ggf. eigenen) Seitenleisten-Farbe.
Geändert
- Passwort-Reset beendet bestehende Sessions des Kontos
(#96, Sicherheit): Wird das Passwort eines Kontos zurückgesetzt —
über den „Passwort vergessen"-E-Mail-Link (#39) oder durch einen
Admin-Reset in der Benutzerverwaltung — werden ab jetzt alle
laufenden Sessions dieses Kontos beim nächsten Request serverseitig
beendet; danach ist ein erneutes Anmelden nötig. So lässt sich ein
Eindringling, der bereits eine offene Sitzung hat, durch das Setzen
eines neuen Passworts wirklich aussperren. Setzt ein Admin sein
eigenes Passwort zurück, loggt ihn das selbst aus (gewollt) — beim
normalen „Passwort vergessen"-Flow ist das folgenlos, da man dabei
ohnehin nicht angemeldet ist. Bestehende Sitzungen werden durch das
Update nicht schlagartig beendet; die Sperre greift erst, wenn
nach dem Update ein Passwort geändert wird. Nach dem Update einmal
/admin/schema-check.phpausführen — es gibt eine neue Spalteusers.password_changed_at(sonst erscheint der Schema-Hinweis-Banner und die Invalidierung bleibt still inaktiv). - Schwerpunkt-Stärke getrennt nach „im Einsatz" und „Reserve" (#34): Die Einsatzkräfte-Pill eines Schwerpunkts weist die Personalstärke jetzt aufgeschlüsselt aus — „im Einsatz" sind die Einsatzmittel an einem aktiven Einsatz des Schwerpunkts (Status neu, in Dispo, Status 3, Status 4), „Reserve" die Pool-Einsatzmittel ohne aktiven Einsatz; „Gesamt" zählt beide zusammen, jedes Fahrzeug nur einmal. Ein beendeter Einsatz zählt nicht mehr als „im Einsatz": Sobald ein Einsatz erledigt, Abschluss beantragt oder abgeschlossen ist, fallen seine Einsatzmittel in die Reserve (vorher zählten alle nicht-abgeschlossenen Einsätze als „im Einsatz", auch bereits erledigte). Die Reserve-Stärke ist die zuletzt bekannte Anzahl aus der Einsatz-Historie des Fahrzeugs (ein EM ohne jede Einsatz-Historie zählt 0). Reine Pool-EMs fließen ebenfalls in die Reserve ein. Die Aufschlüsselung erscheint im Schwerpunkt-Banner, in der ETB-Übersicht, der Schwerpunkt-Übersicht, der SP-Historie und im PDF-Export.
- Theme-Engine eingeführt; Erscheinungsbild jetzt
org-konfigurierbar (Refactoring-Scheibe T3): Marken-Farben und
-Schrift laufen über zentrale Design-Tokens, sodass ein eigenes Theme
als Override-Ebene greift. Im Zuge dessen wurden in Seitenkopf,
Toolbar und Schema-Bannern verbliebene hartkodierte Farben auf
Tokens umgestellt und der Basis-Font-Stack als Token (
--font-base) zentralisiert — ohne sichtbare Änderung am Standard-Aussehen. - Klareres Symbol für „Einsatz übernehmen/verschieben" (#33): In der Schwerpunkt-Einsatzliste trägt die Aktion zum Übernehmen, Verschieben oder Herausnehmen eines Einsatzes jetzt einen grünen Haken (✅) statt des bisherigen Wiederhol-Symbols (🔄); der Tooltip nennt zusätzlich „Übernehmen".
- Einsatzmittel-Stärke im Schema A/B/C/S, Gesamt rechnet das ETB:
Beim Speichern der Personalstärke eines Einsatzmittels wird
die Eingabe jetzt auf das Format A/B/C/S (Zug- und Verbandführer /
Gruppenführer / Mannschaft / Gesamt) normalisiert und die
Gesamtzahl S automatisch als A + B + C gesetzt. Eine falsch oder
gar nicht eingetippte Gesamtzahl wird damit korrigiert bzw. ergänzt
(
1/0/5/7und1/0/5ergeben beide1/0/5/6); eine leere Eingabe bleibt leer (die Stärke ist optional). So sind alle Stärke-Werte einheitlich vierstellig und in sich stimmig — Grundlage für die korrekte Aufsummierung in den Personal-Pills und im PDF-Export. - Lagekarte: Modus „Taktisch" entfernt: Die Lagekarte bietet jetzt nur noch die Ansichten 📍 Status und 🔥 Dichte (Heatmap). Der bisherige Modus Taktisch mit großen taktischen Zeichen pro Einsatzmittel (und der zugehörige Filter) ist entfallen — die taktischen Symbole überdeckten benachbarte Marker und brachten in der Praxis keinen Mehrwert gegenüber der Status-Ansicht.
- Setup-Wizard: Schritt-Navigation links statt oben: Die sieben Setup-Schritte stehen jetzt als senkrechte Liste links neben dem Eingabe-Bereich (vorher eine waagerechte Pill-Leiste oben). Auf schmalen Bildschirmen klappt die Schrittliste über den Inhalt. Die Inhalte der Schritte sind unverändert.
- Hauptmenü in Gruppen gegliedert: Die Einträge der Seitenleiste sind jetzt in die Gruppen Lage (Einsätze, Schwerpunkte, Lagekarte, Einsatzmittel), Werkzeuge (Rückmeldungen, Linksammlung, Hydrantenplan, Geocodes) und System (Hilfe, Administration) unterteilt — jede mit leiser Überschrift. Leere Gruppen (alle Einträge per Rolle ausgeblendet) erzeugen keine Überschrift; im eingeklappten Menü schrumpfen die Überschriften zu Trennlinien. Die Einträge selbst und ihre Berechtigungen bleiben unverändert.
Behoben
-
PDF-Export immer im Hellmodus: Der Druck-/PDF-Export erzwingt jetzt ausdrücklich helle Darstellung (
color-scheme: light, Sonderfall wie die Login-Seite). Auf Geräten mit aktivem (Browser-)Dunkelmodus wurde die Export-Seite sonst automatisch abgedunkelt — beim Druck ist der Hintergrund aber immer weiß, sodass hell eingefärbte Inhalte unlesbar waren. -
Hauptmenü-Links behalten nach dem Klick ihre Farbe: Mit der globalen Link-Farbe (für die Dark-Mode-Lesbarkeit) hatten besuchte Menüpunkte die Verweis-Farbe angenommen. Die Seitenleisten-Einträge bleiben jetzt unabhängig vom Besucht-Status in ihrer normalen Farbe (Sonderfall), Hover und aktiver Eintrag wie gehabt.
-
Einsatzmittel per Touch zuweisen (Handy/Tablet): Auf Touch-Geräten ließ sich ein EM bisher nicht zuverlässig per Drag&Drop zuordnen (je nach Browser startete stattdessen das Kontextmenü). Ein langer Druck auf einen EM-Chip startet jetzt das Ziehen; ein Vorschau-Bild folgt dem Finger, die Seite scrollt an den Rändern automatisch (damit auch ein weiter oben liegendes Einsatz-/EM-Feld erreichbar ist), und beim Loslassen wird das Feld darunter getroffen. Kurzes Wischen scrollt wie gewohnt, kurzes Tippen bleibt ein Klick.
-
Bild-Anhänge: Galerie-Navigation in der Großansicht: Klickt man ein an einen Kommentar angehängtes Bild an, lässt sich jetzt per Pfeil-Buttons, Pfeiltasten (←/→) oder Bildzähler durch alle Bilder desselben Kommentars blättern — vorher zeigte die Großansicht nur das eine angeklickte Bild, und man musste sie schließen und das nächste Vorschaubild einzeln öffnen. Gilt für Einsatz- und Abschnitts-Kommentare.
-
PDF-Export: große/viele Kommentarbilder werden sauber dargestellt: Bei mehreren oder hochauflösenden Fotos in einem Kommentar wurden Bilder am Seitenumbruch zerschnitten oder es entstanden große Leerräume. Ursache war ein „nicht umbrechen"-Zwang auf dem gesamten Kommentar-/Anhang-Block, der höher als eine Seite werden kann. Jetzt darf der Block über Seiten umbrechen, nur das einzelne Bild bleibt unzertrennlich, und Bilder werden kompakter eingebettet (mehrere pro Seite) — so bleibt jedes Foto vollständig und der Bericht lesbar.
-
Hinweis beim Anlegen, wenn noch keine Orte angelegt sind (#59): Der Ort ist beim Einsatz-Anlegen ein Pflichtfeld aus den Stammdaten. Gab es noch gar keine Orte (frische Installation), schlug das Speichern wortlos an der Pflichtfeld-Prüfung fehl. Jetzt erscheint am Ort-Feld ein Hinweis mit Link zur Orte-Stammdatenseite (Admin → Stammdaten → Orte).
-
Doppelte Einsätze durch Doppelklick verhindert (#81): Beim Anlegen eines Einsatzes wird der „Anlegen"-Button nach dem ersten Absenden gesperrt („⏳ … wird gespeichert"), sodass ein zweiter Klick oder ein Doppelklick keinen zweiten Einsatz mehr erzeugt.
-
Einsatzmittel aus der ETB-Liste entfernen fragt jetzt nach (#71): Ist ein Einsatzmittel noch in Abschnitten des Einsatzes zugewiesen, zeigte das Entfernen über den EM-Chip in der Einsatzliste nur eine wirkungslose Meldung. Jetzt kommt — wie auf der Detailseite — ein echter Bestätigungs-Dialog („Trotzdem entfernen"); erst nach Bestätigung wird das Einsatzmittel auch aus den Abschnitten gelöst.
-
Kommentar-Bearbeitungs-Marker zeigte Platzhalter wörtlich an (#73): Bei einem bearbeiteten Kommentar ohne angegebene Begründung erschien der interne Platzhalter „(ohne Begründung)" im Verlauf. Dieser Text wird — wie beim Löschen — nicht mehr angezeigt.
-
Echte Umlaute in Katalog- und Hinweistexten (#69): An mehreren Stellen (z. B. „gelöscht", „Einsätzen") standen noch ASCII-Ersatzschreibweisen; sie zeigen jetzt korrekte Umlaute.
-
Einsatzmittel aus abgeschlossenen Einsätzen lassen sich wieder einem Schwerpunkt zuordnen (#35): Ein Fahrzeug, das noch (historisch) in einem abgeschlossenen Einsatz hängt, ließ sich im Schwerpunktmenü nicht in den Pool aufnehmen — und die Pool-Aufnahme hätte den Eintrag sogar lautlos aus dem abgeschlossenen Einsatz gelöscht (Revisionsbruch). Die Pool-Aufnahme klammert abgeschlossene Einsätze jetzt aus: Sie gelingt, der historische Eintrag im abgeschlossenen Einsatz bleibt unverändert erhalten. Im selben Zuge ist auch das „Schwerpunkt-mit-EM-Auswahl zuweisen" gegen abgeschlossene Einsätze abgesichert (es hätte sonst beim Abwählen von Einsatzmitteln deren Historie im abgeschlossenen Einsatz verändert).
-
Kleinere UI-Korrekturen (Refactoring-Scheibe S5, Befunde der Test-Durchläufe): Das Haus-Symbol in den Einsatzmittel-Kacheln „Entlassen"/„Nicht eingesetzt" war unsichtbar (#66) und ist wieder da; im Schwerpunkt-Wizard sind die Auswahlkarten „Bestimmte Ortsteile"/„Einzelne Einsätze" und die ausgewählten Orts-Chips im Dark-Mode jetzt lesbar (#65); der Erstinstallations-Hinweis unterscheidet jetzt „Datenbank leer" von „noch kein Benutzer" (#60); die System-Status-Texte sprechen statt vom installationsspezifischen „Homey-Flow" neutral von der „Alarmverarbeitung" (#61); der Adress-Platzhalter im Wizard ist als Beispiel gekennzeichnet (#58).
-
Erstinstallation steckte nach dem Tabellen-Schritt fest (Tester-Blocker): Sobald Wizard-Schritt 2 die Tabellen angelegt hatte, galt die Installation nicht mehr als „frisch" und der Wizard verlangte einen Login — den ersten Admin legt aber erst der Abschluss-Schritt an. Wizard und Auto-Weiterleitung bleiben jetzt im Erstinstallations-Modus, solange noch kein einziger Benutzer existiert (bewusst nicht „kein aktiver Admin" — eine laufende Installation mit deaktivierten Admins darf den Wizard nicht öffnen).
-
Orte-Verwaltung auf Neuinstallationen defekt (Tester-Blocker): Der Tabellen-Bauplan der
orte-Tabelle kannte die Spaltengeolat/geolngnicht, die die Orte-Verwaltung fest erwartet — „Interner Fehler" beim Anlegen, und ohne Ort ließ sich kein Einsatz erfassen. Bauplan ergänzt; der Schema-Check erkennt jetzt auch komplett fehlende Spalten und ergänzt sie per Reparieren-Knopf (neuer Migrations-Mechanismus, hilft auch künftigen Fällen). -
Erstinstallations-Wizard immer hell: Im Frisch-Modus lädt der Wizard kein zentrales Stylesheet (Datenbank existiert noch nicht) — die Farbvariablen waren undefiniert und die Seite sah kaputt aus. Der Wizard definiert die hellen Farben jetzt lokal (wie die Login-Seite: kein Dark-Mode vor dem ersten Login).
-
Doku/Pfad-Korrektur Branding-Verzeichnis (#85): Handbuch, README und Deploy-/Backup-Hinweise nannten für hochgeladenes Logo/Favicon noch den alten Pfad
storage/branding/. Tatsächlich liegen die Dateien inpublic/branding/— überall korrigiert (kein Verhalten geändert, reine Doku-/Pfad-Richtigstellung). -
Dark-Mode-Anzeige an mehreren Stellen korrigiert: In verschiedenen Admin- und Wizard-Seiten waren noch helle Farben fest verdrahtet, sodass Flächen, Eingabefelder und Hinweis-Boxen im Dark-Mode falsch (zu hell) dargestellt wurden. Betroffen waren u. a. der Logo-/Favicon-Upload unter Organisation & Branding (Vorschau-Box, Datei- und Farbfelder, Schrift-Auswahl), die Schwerpunkt-Anlage (Wizard-Schritt-Marken, Auswahl-Tabellen, Buttons), der Setup-Wizard sowie diverse Toast-Meldungen, Eingabefelder und Tabellen quer durch den Admin-Bereich. Alle betroffenen Stellen nutzen jetzt die zentralen Design-Tokens und folgen damit korrekt dem hellen wie dem dunklen Theme.
-
Dark-Mode-Feinschliff nach dem Abnahme-Klick-Test: Vier weitere Stellen, die im dunklen Theme schlecht lesbar waren, sind korrigiert: gelöschte Kommentare behielten ihre helle Schraffur; Verweise/ Links nutzten das Browser-Standardblau bzw. -lila (jetzt ein theme-eigener, gut lesbarer Link-Ton); die Filter in der Geocode-Übersicht zeigten schwarzen statt hellen Text; und die Buttons im Webhook-Status hatten schwarze statt helle Beschriftung. Auch das Gelöscht-Banner und die Fehler-Toasts auf der Einsatz-Seite folgen jetzt dem Theme. Zusätzlich nutzten einige Admin- und Bearbeiten-Seiten (Abschnitt bearbeiten, Hydrantenplan, Admin-Übersicht, PDF-Export) ein fest verdrahtetes Fehler-Rot, das im Dark-Mode zu dunkel wirkte — auch diese folgen jetzt dem adaptiven Token.
-
Einsatzmittel-Stärke: Anzeige direkt nach dem Zuweisen korrekt: Beim Zuweisen eines Einsatzmittels zeigt der Chip jetzt sofort die vom ETB geprüfte Stärke im Schema A/B/C/S (mit automatisch berechnetem Gesamtwert S) — vorher stand kurzzeitig der unkorrigierte Eingabewert da, bis die Seite neu geladen wurde.
Behoben (Sicherheit)
-
Einsatzmittel-Vorbelegung: Kontaktdaten scope-begrenzt: Beim Zuweisen eines Einsatzmittels lädt der Dialog die zuletzt erfasste Stärke und den Kontakt als Vorbelegung. Diese Vorbelegung wird jetzt auf den eigenen Sichtbarkeitsbereich begrenzt: Disponenten (ohne „alle Einsätze sehen") und Schwerpunkt-Disponenten erhalten nur noch Werte aus Einsätzen ihres eigenen Scopes. Vorher konnte über die Vorbelegung der zuletzt gespeicherte Kontakt (z. B. eine Telefonnummer) eines Einsatzmittels aus einem fremden Einsatz bzw. Schwerpunkt sichtbar werden.
-
CSRF-Schutz für alle Admin- und Bearbeiten-Formulare: Sämtliche formularbasierten Schreibaktionen (Benutzer-, Branding-, Konfigurations- und Stammdaten-Verwaltung, Schwerpunkt- sowie Einsatz-/Abschnitt- Bearbeitung u. a.) verlangen jetzt zusätzlich zum bestehenden SameSite=Lax-Cookie ein sitzungsgebundenes CSRF-Token. Fehlt es oder ist es ungültig, wird die Aktion mit einem Hinweis abgewiesen (Defense-in-depth). Die AJAX-Endpoints und der Setup-Wizard nutzen weiterhin ihre eigenen Token-Mechanismen.
-
Hydranten-Daten respektieren die Berechtigung auch im Endpoint: Der GeoJSON-Abruf prüft jetzt
hydranten.view(vorher nur „eingeloggt") — einer Rolle ohne Hydranten-Recht werden die Daten auch über die API nicht mehr geliefert. -
Schwerpunkt-Disponent: Eignung wird serverseitig geprüft: Beim Setzen des SP-Disponenten akzeptiert der Server nur noch aktive Disponenten bzw. SP-Disponenten (identisch zum Auswahlmenü), nicht mehr beliebige Benutzer-IDs.
-
Kommentar-Moderation an den eigenen Bereich gebunden: Bearbeiten und Löschen von Kommentaren und Anhängen prüfen jetzt zusätzlich den Einsatz-Scope, sodass disponierende Rollen nur im eigenen Zuständigkeitsbereich moderieren können.
-
Setup-Wizard gegen CSRF gehärtet (#62): Die beiden schreibenden Schritte des Wizards — Tabellen anlegen (Schritt 2) und Speichern (Schritt 7) — liefen bisher per GET und ohne Token, ließen sich also durch einen vorbereiteten Link oder ein eingebettetes Bild von außen auslösen (heikel, weil der Wizard bei der Erstinstallation ohne Login erreichbar ist). Beide Aktionen verlangen jetzt POST und ein sitzungsgebundenes Token (
X-CSRF-Token); ein einfacher GET-Aufruf wird mit 405, ein fehlendes/falsches Token mit 403 abgewiesen. Für Dich ändert sich an der Bedienung nichts — Du klickst dieselben Schaltflächen. Außerdem überschreibt „Speichern" eine bereits funktionierende.envnicht mehr mit leeren Datenbank-Zugangsdaten (Existenz-Prüfung mit Rückfall auf die bestehende Konfiguration; fehlen die Werte ganz, bricht der Schritt mit einem Hinweis ab, statt die Verbindung zu zerschießen). -
Scope-Lücken geschlossen (Befunde des Security-Voll-Sweeps):
api/abschnitt-update.phpundapi/geocode-admin.phpprüften den Dispo-/SP-Dispo-Scope nicht — gescope-te Rollen konnten Stammdaten bzw. Geokoordinaten fremder Einsätze ändern. Beide Endpoints erzwingen jetzt das Scope-Muster ihrer Geschwister-Endpoints; Geocode-Bulk-Aktionen sind Lage/EL/Admin vorbehalten. -
Lagekarten-API (
api/mapdata.php) verlangt jetztlagekarte.viewund filtert die Einsatz-Marker für SP-Dispos auf deren eigene Schwerpunkte (vorher sahen sie alle Einsätze). -
Geocode-Verwaltung hinter
admin.access(Folge-Befund der Nach-Abnahme): Seite und API lieferten per GET jedem eingeloggten Benutzer die Adressliste samt Koordinaten ALLER Einsätze — der Sidebar-Eintrag war zwar Admin-gegated, das Backend aber nicht. Beide verlangen jetzt dieselbe Permission wie der Menüpunkt. -
Login-Brute-Force-Bremse (#50): Nach 5 Fehlversuchen pro Konto+IP steigt die Pflicht-Wartezeit zwischen Login-Versuchen exponentiell (2 s → max. 60 s). Bewusst keine harte Sperre — im Einsatz darf sich niemand aussperren, und im Gerätehaus teilen sich alle eine IP. Der Zähler-Schlüssel faltet Groß-/Kleinschreibung und Akzente identisch zur DB-Collation, damit die Bremse nicht über Schreibvarianten (
ädmin,ADMÍN) umgangen werden kann. Einträge leben max. 24 h (Datenschutz); neue Tabellelogin_throttle(Schema-Check nach Update ausführen). -
Keine internen Fehlertexte mehr im Browser (#51): Alle Endpoints und Admin-Seiten maskieren unerwartete Exceptions jetzt mit einer generischen Meldung (Details nur im Log-Dashboard); bewusste Validierungsmeldungen („Name fehlt", „bereits im Einsatz") bleiben über die neue
UserFacingExceptionerhalten. Zusätzlich erzwingt der Bootstrapdisplay_errors=0für alle Web-Requests (pluspublic/.user.inials Absicherung auf Hoster-Ebene), unabhängig von der php.ini des Hosters. -
EM-Entlassen-Toggle abgesichert (#52): Entlassen/Reaktivieren verlangt jetzt die EM-Dispositions-Permission
em.assign(vorher reichte das breitereeinsatz.edit), und SP-Disponenten können nur noch Einsatzmittel aus den Pools ihrer eigenen Schwerpunkte umschalten. Karten ohne Berechtigung sind nicht mehr klickbar.
Neu
- Test-Instanz-Override — der Config-Loader akzeptiert die
Umgebungsvariable
ETB_ENV_FILEund lädt damit eine alternative.env(z. B.config/.env.testmit eigenem Tabellen-Präfix). Grundlage für eigenständige QA-Klick-Tests gegen isoliertetest_*-Tabellen, ohne Produktivdaten anzufassen (siehedocs/DEPLOYMENT.md).
Geändert
- Intern: Kommentar-/Anhang-/Audit-Services konsolidiert
(Refactoring-Scheibe S7): Die je drei fast identischen Services für
Einsatz, Abschnitt und Schwerpunkt teilen sich ihre Logik jetzt in
gemeinsamen Basisklassen (
KommentarServiceBase,AnhangServiceBase,AuditServiceBase); die bisherigen Klassen bleiben als dünne Erben bestehen (kein Aufrufer geändert). −494 Zeilen (−33 %), 21 neue Unit-Tests sichern die revisionsfesten System-Kommentare und die Upload-MIME-Whitelist ab. Verhalten unverändert. - Intern: Schwerpunkt-SQL in die Services verlagert (Refactoring- Scheibe S6): Direkte Datenbank-Abfragen aus den Schwerpunkt-Seiten und -Endpoints (Wizard, Bearbeiten, Historie, EM-Pool, Einsatz- Zuweisung-mit-EM) liegen jetzt als benannte Methoden in den zuständigen Services; die mehrschrittige „Einsatz mit EM-Auswahl zuweisen"-Operation ist als eine transaktionssichere Service-Methode gekapselt (inkl. Audit + revisionsfester System-Kommentare). Kein Verhaltensunterschied.
- UI-Vereinheitlichung (Quick-Wins aus dem Code-Audit): Die
Abschnitts-Bearbeiten-Seite, der Admin-Index, das Log-Dashboard
und der System-Status nutzen jetzt die zentrale Seiten-Toolbar
(Breadcrumbs + Aktionen) statt handgebautem Markup; der
Lagekarten-Kopf verwendet Design-Tokens statt hartkodierter
Farben — damit zeigt die Fehlermeldung im Dark-Mode wieder rot
statt grau. Intern:
app-config.js.phpliefert die JS-Konfiguration nur noch an eingeloggte Benutzer,SchemaProviderbindet den letzten interpolierten Query-Parameter sauber. - Intern: Abschnitts-Detailseite entschlackt (Refactoring-Scheibe
S4c):
einsaetze/abschnitt-view.phpgibt ihr Inline-CSS und -JS an die geteilteassets/css/einsaetze.css(neue Sektion „abschnitt-view.php"; mit view.php zeichengleiche Blöcke werden nicht dupliziert) und das neueassets/js/abschnitt-view.jsab (−893 Zeilen in der Seite); die 3 PHP-Interpolationen wandern inwindow.ABSCHNITT_VIEW_CONFIG. Intheme.cssentfallen fünf Dark-Overrides, die der Token-Switch jetzt 1:1 reproduziert (.em-pill-ro,.comments-empty,.comment-text,.comment-deleted-info,.att-meta). Beifang:lagekarte.jsüberschreibt nicht mehr das globaleescapeHtmlausetb-common.js. Optik im Light-Mode unverändert; im Dark-Mode folgen die Eingabefelder der Abschnitts-Seite (Disponenten-Auswahl, Kommentar-Felder) jetzt dem dunklen Schema statt wie bisher weiß zu bleiben — die letzte Inkonsistenz, mit der die Seite damit zu den Einsatz-Seiten aufschließt. - Intern: Einsatz-Detailseite entschlackt (Refactoring-Scheibe S4b):
einsaetze/view.phpgibt ihr Inline-CSS und -JS an die geteilteassets/css/einsaetze.css(neue Sektion „view.php") und das neueassets/js/einsaetze-view.jsab (−1.825 Zeilen in der Seite); die 10 PHP-Interpolationen wandern inwindow.EINSAETZE_VIEW_CONFIG. Seiten-exklusive Regeln sind per:where(body.einsatz-…)-Marker gescopt (Spezifität 0 — Kaskade unverändert). Optik und Verhalten in beiden Themes unverändert. - Intern: ETB-Übersicht entschlackt (Refactoring-Scheibe S4a):
Die größte Seite (
einsaetze/index.php) gibt ihr Inline-CSS und -JS anassets/css/einsaetze.cssundassets/js/einsaetze-index.jsab (−1.221 Zeilen in der Seite); 31 neue Design-Tokens ersetzen Hex-Farben, obsolet gewordene Dark-Overrides wurden entfernt. Optik und Verhalten unverändert. - Intern: gemeinsame Basisklasse für die Katalog-Services
(Refactoring-Scheibe S3): Abschnitts-Status, Schwerpunkt-Status und
Wichtigkeit teilen sich ihre CRUD-/Fallback-/Default-Logik jetzt in
KeyedCatalogService(−209 Zeilen, −26 %); 19 neue Unit-Tests sichern Normalisierung, Fallback- und Default-Key-Logik ab. Verhalten und Fehlertexte unverändert. - Schema-Check zählt ehrlich (#57): Nach einer Reparatur meldet
/admin/schema-check.phpnur noch tatsächlich neu angelegte Tabellen („Nichts zu tun — Schema war bereits aktuell." statt „39 Tabellen angelegt"). - Intern: CSS-Komponenten ausgebaut (Refactoring-Scheibe S2):
Wiederkehrende Muster (schwebende Toasts, Spinner, Status-Banner,
Sekundär-Buttons, Orts-Chips, Tabellen) leben jetzt zentral in
components.css; die EM-Statusfarben sind benannte Design-Tokens. Sechs Seiten (Einsatzmittel, Geocodes, Schwerpunkte-Übersicht/ Wizard/Bearbeiten, Hydrantenplan) verloren ihre Inline-Duplikate. Optik unverändert (Dark-Mode: drei Detailfarben folgen jetzt den Tokens und passen damit erstmals zum restlichen Dark-Schema). - Intern: gemeinsame JS-Bausteine (Refactoring-Scheibe S1):
escapeHtml/cssEsc/postJsonund das EM-Drag&Drop-Verhalten leben jetzt zentral inassets/js/etb-common.jsbzw.em-dnd.jsstatt fünf- bis sechsfach kopiert in den Seiten (rund 650 Zeilen Inline-JS entfernt, netto −226). Keine Verhaltensänderung; Nebeneffekt: Sonderzeichen wie Anführungszeichen werden überall einheitlich (und im Schwerpunkt-Wizard erstmals korrekt) escaped.
2.4.0 — 2026-05-29
Fokus: Schwerpunkt-Dispo-Kopplung, Folge-Abschnitte, Übersichtlichkeit
Großes Funktions-Release: Einsatz- und Abschnitts-Disponenten folgen im Schwerpunkt automatisch dem SP-Dispo, Alarm-Regeln können nun auch Folge-Abschnitte anlegen und den Auto-Reset gezielt stoppen, Einsatzmittel werden nach Gruppen strukturiert dargestellt, und es gibt administrierbare Standard-Werte. Dazu Beamer-Tauglichkeit der Lagekarte und diverse Politur.
Neu
- SP-Dispo-Kopplung — solange ein Einsatz einem Schwerpunkt angehört, folgt sein Disponent (und der seiner Abschnitte) automatisch dem Schwerpunkt-Disponenten; das Dispo-Feld ist dann gesperrt (readonly + Hinweis). Herauslösen per Modal-Dialog mit Wahl eines übernehmenden Disponenten; Neuanlage im SP-Kontext wird dem SP zugewiesen; ein Wechsel des SP-Dispos propagiert auf alle zugeordneten Einsätze/Abschnitte.
- Alarm-Regeln: Folge-Abschnitte — eine Regel ist nun entweder vom Typ Folge-Einsätze oder Folge-Abschnitte (exklusiv). Abschnitt- Regeln legen beim Greifen Abschnitte am ausgelösten Einsatz an.
- Alarm-Regeln: Auto-Reset-Stopp pro Regel — eigene Checkbox je Regel (statt fest verdrahtet). Mehrere Regeln mit gleichem/ähnlichem Trigger feuern jetzt alle ihre Aktion.
- Standard-Werte in der Administration — pro Liste ein Default für Wichtigkeit und Abschnitts-Status (★), der in den Dropdowns/bei der Anlage vorausgewählt wird. Neuer Abschnitts-Status „geplant" (dunkelgrau, ⏳) als Voreinstellung.
- Personalstärke-Anzeige — je Einsatz unter dem Stichwort sowie die Gesamt-Einsatzstärke in der Titelzeile der Übersicht (dedupliziert pro EM, ohne abgeschlossene Einsätze), inkl. Schwerpunkt-/Einsatz- Zähler im Lagekarten-Stil.
- Einsatzmittel nach Gruppen — Übersichtsseite und Lagekarten-Panel gruppieren EMs nach EM-Gruppe (üÖrt-Block am Ende), alphabetisch innerhalb der Gruppe.
- Lagekarte: Filter-Leiste ein-/ausblendbar („🎛️ Filter") — zusammen mit eingeklapptem Menü eine große Beamer-Ansicht.
- Geocode-Cache-Verwaltung — neue Admin-Unterseite
(
/admin/geocode-cache.php): alle gecacheten Geocodes mit Löschen je Zeile + „Alle löschen". Der Cache bleibt beim Reset erhalten. - Rufgruppe-Spalte in der Abschnitts-Tabelle der Einsatz-Detailseite.
Geändert
- Personalstärke-Format überall korrigiert auf „Zug- und Verbandführer / Gruppenführer / Mannschaft / Gesamt".
- Abschnitts-Disponent ist optional („– nicht zugewiesen –");
einsatz_abschnitt.assigned_dispo_user_idwurde nullable. - EM-Auswahl im Schwerpunkt-Kontext einheitlich — Übersicht, Einsatz-Detail und Bearbeiten zeigen denselben flachen Pool-Picker.
- üÖrt-Anlage durchgängig per App-Dialog (kein Browser-
prompt()mehr), inkl. Format-Hinweis „Ort FzArt" (z. B. „FFW DLK"). Auch das Löschen von Kommentaren nutzt jetzt den App-Dialog. - Aktive Toggle-Buttons der Lagekarte sind farbig hinterlegt (Light + Dark).
Behoben
- Horizontaler Verschiebebalken auf Lagekarte, Einsatzmittel und Hilfe
(fehlendes
box-sizing: border-box). - Bulk-Dispo-Wechsel überspringt SP-gebundene Einsätze sauber, statt einen Fehler zu werfen.
- Aufräumen: doppelte Schema-Migration entfernt, toter Code
(
findActiveByStichwort) entfernt.
Datenbank / Migration
- Neue Tabelle
alarm_rule_followup_abschnitt; neue Spaltenalarm_rule.action_type+alarm_rule.stop_auto_reset;einsatz_abschnitt.assigned_dispo_user_idnullable; Abschnitts-Status „geplant" + Default-Settings. Nachziehbar über Admin → Schema-Check bzw.php scripts/migrate.php. Optional einmaligphp scripts/migrate-sp-dispo-kopplung.php(koppelt Bestands-Einsätze an den SP-Dispo).
2.3.0 — 2026-05-28
Fokus: Dark-Mode, UI-Politur & CSS-Zentralisierung
Schwerpunkt dieses Releases ist ein app-weiter Dark-Mode, eine einklappbare Sidebar und die Zusammenführung des bis dahin in ~38 Seiten duplizierten CSS in zentrale Token- und Komponenten-Dateien (Trennung von Design und Funktionalität). Dazu kommen diverse Politur-Arbeiten im Admin-Bereich und ein paar funktionale Fixes.
Neu
- Dunkler Modus — app-weiter Dark-Mode über den 🌙/☀️-Knopf neben
„Abmelden". Initial via
prefers-color-scheme, danach inlocalStoragegemerkt; FOUC-frei (Sync-Script im<head>). - Einklappbare Sidebar (« / ») — reduziert die Navigation auf reine Icons; im eingeklappten Zustand erscheint das Favicon statt Logo. Zustand persistent.
- Karten-Hell/Dunkel-Toggle — Lagekarte, Hydrantenplan und die Einsatz-Detail-Karte lassen sich per 🌙/🌞 unabhängig vom App-Theme hell/dunkel schalten (Leaflet-Tiles via Invert-Filter).
- Einklappbare Filterleiste in der Einsatz-Übersicht; Suchfeld rückt neben den Disponent-Filter, mit „Suchen" + „Zurücksetzen".
- Zentrale Design-Tokens — neue
tokens.css(alle Farben Light + Dark, eine Quelle) +components.css(wiederverwendbare Bausteine).
Geändert
- Admin — einheitliche Breadcrumb-Leisten auf allen Seiten; Admin-Kacheln in vier Kategorien neu sortiert (Feuerwehr, Konfiguration, Aktionen, Logs & Diagnose). Einstellungen mit zentriertem Content-Container.
- EM-Kategorie „FFWAC" wird benutzersichtbar als „eigene" angezeigt (DB-Wert intern unverändert).
- Einsatz-Bearbeitung respektiert jetzt den Schwerpunkt-Pool bei der EM-Auswahl; EM-Gruppen-Summen zählen nur tatsächlich verfügbare EMs.
- Schwerpunkt-Kontext bleibt bei Reset-/Neuanlage-/Toolbar-Links erhalten.
- Hilfe/Handbuch + alle Modals (Confirm/Alert, „Abschnitte bilden", EM-Dialog u.a.) sind im Dark-Mode sauber dargestellt; Handbuch um die neuen Funktionen ergänzt.
Behoben
- Farb-Leak in der Einstellungen-Settings-Nav (DB-Einträge erschienen hellgrau).
- Null-Guard für den Alarmpush-Button auf der Admin-Startseite.
2.2.0 — 2026-05-27
Fokus: Bug-Fixing + Alarm-Regeln
Schwerpunkt dieses Releases waren ein langes Audit-Bündel von SP-Dispo- Bugs, ein generischer Schema-Reparatur-Mechanismus für veraltete DB-Definitionen und eine neue Feature-Funktion für Multi-Alarm- Regelwerke (UW-ERSTALARM → automatische Grundschutz- und Bereitstellungs- Einsätze).
Neu
- Alarm-Regeln (
/admin/alarm-regeln.php) — neues Multi-Alarm- Regelwerk. Pro Regel ein Trigger-Stichwort (z. B.UW-ERSTALARM) und beliebig viele Folge-Einsatz-Templates (Stichwort, Wichtigkeit, LGs, Sachverhalt mit Platzhaltern). Eine Trigger-Mail erzeugt automatisch den Haupteinsatz plus alle konfigurierten Folge-Einsätze (Adresse/Geo geerbt). Default-Regel UW-ERSTALARM (Grundschutz + Bereitstellung) wird mit-geseedet. Bei aktiver Multi-Alarm-Regel wird der morgendliche ETB-Reset deaktiviert, damit die Großlage nicht weggespült wird. - Wichtigkeit „Bereitstellung" (gelb, niedriger als „Normal") als neue Stammdaten-Stufe für Vorhalte-Einsätze.
- Unwettermail Multi-Einsatz-Parsing — eine Unwettermail mit n
Einsatz-Blöcken (Tabellen-Format) erzeugt jetzt n eigenständige
Einsätze statt nur einen mit den Werten des letzten Tabellen-
Eintrags. Block-Trigger ist der Marker
ALARMDEPESCHE >>. - Pro-Page Feature-Tabellen-Banner (
MainNavSidebar::featureBanner()). Bestimmte Admin-Pages (/admin/alarm-regeln.php,/admin/rollen.php,/admin/abschnitt-status.php,/admin/schwerpunkt-status.php) prüfen pro Request frisch (kein Cache), ob ihre Feature-Tabellen vorhanden sind, und zeigen sonst einen prominenten Hinweis-Banner mit Direkt-Link zum Schema-Check. - Schema-Check erweitert —
applyColumnMigrations()undseedMissingDefaults()ergänzen den vorhandenen Tabellen-Anlage- Pfad. Erkennt veraltete ENUM-Spalten (z. B.users.roleohnesp_dispo,einsaetze.wichtigkeitohnebereitstellung) und fehlende Default-Daten, alles per Knopfdruck reparierbar. - Spalten-Migrations-Pipeline in
SchemaProvider::columnMigrations()— generisches Muster für künftige Drift-Fälle (Liste von{table, column, detect, targetType, issue}). - Handbuch: neues Topic Alarm-Regeln und FAQ-Einträge zu Multi-Alarm-Verarbeitung + Schema-Migrationen.
Geändert
- System-Status „Verarbeitete Alarme" zeigt jetzt die echte
Anzahl aus der
einsaetze-Tabelle (gesamt seit ETB-Reset + 24-h- Counter) statt nur den letzten Cron-Lauf (war typisch 0). - Heartbeat-Mail „Verarbeitete Alarme" entsprechend angepasst —
Quelle ist jetzt die
einsaetze-Tabelle statt veralteter Mantis- Aera-Log-Pattern. Plus neuer Block „Seit letztem ETB-Reset: 🚒 Einsätze gesamt: N". - SP-Dispo-Dropdown-Trennung: Einsatz- und Abschnitts-Disponent-
Dropdowns enthalten jetzt nur klassische Dispos (
User::canBeEinsatzDispo()), Schwerpunkt-Disponent-Dropdowns enthalten beide Rollen (isAnyDispo()). Filter-Dropdowns (ETB-Übersicht, PDF-Export) zeigen weiterhin beide. - Konsistenter Display-Name „Schwerpunkt-Dispo" über alle Dropdowns, Pills und Modal-JS (statt teilweise „SP-Dispo" als Kurzform).
- Pill-Farbe für
sp_dispoin/admin/users.phpergänzt (war vorher grau wie „Gast", was wie „Rolle nicht übernommen" aussah). - Admin-Index: Kachel „Schema-Check" von Konfiguration nach Aktionen verschoben — semantisch eine Repair-Aktion, keine Einstellung.
Behoben
- Schwerpunkt-Dispo-Rolle ließ sich nicht speichern — Ursache war
ein ENUM auf
users.roleaus dem alten Migrations-SQL (kanntesp_disponicht). Schema-Migration zieht jetzt automatisch auf VARCHAR(32) um, wenn der Reparatur-Knopf geklickt wird. - SP-Marker-Info-Leak auf der Hauptkarte (
/api/mapdata.php) — SP-Dispo sah dort alle aktiven SP-Marker. Jetzt nur die eigenen, analog zuSchwerpunktService::listForUser. - System-Kommentar-Schutz im Service-Layer für alle drei Kommentar-
Services (Einsatz, Abschnitt, Schwerpunkt).
canEdit()schützte nur die UI; ein direkteredit()-Aufruf auf einen System-Kommentar (author_user_id = NULL) wäre durchgegangen. - Hilfe-Topic-Links wurden vom Markdown-Renderer als relative URLs
generiert (z. B.
01-installation), führten in der in-App-Hilfe ins Leere. NeuerHelpService::rewriteTopicLinks()schreibt sie auf/hilfe.php?topic=<slug>um. - Handbuch-Pfade korrigiert:
/admin/geocode-admin.php→/geocode-admin.php(Datei lag schon immer unter/, nicht unter/admin/). - Setting-Doku
auto_delete_sp_dispo_on_close→sp_dispo_delete_on_reset(das Setting existiert tatsächlich, hat aber andere Semantik — greift beim ETB-Reset, nicht beim SP-Close).
Sicherheit / Härtung
- Konsolidierungs-Schlüssel im AlarmProcessor für Unwetter-Blöcke
angepasst: ein eindeutiger Schlüssel pro Block (
UW:<ts>:<idx>:<strasse>|<ort>) verhindert, dass mehrere Blöcke mit identischem Stichwort + Timestamp zu einer Gruppe konsolidiert werden.
Migration / Upgrade-Hinweise
/admin/schema-check.phpöffnen → „Reparieren" — legt fehlende Tabellen (alarm_rule,alarm_rule_followup), Indizes, veraltete Spalten-Migrationen und fehlende Defaults (Wichtigkeitbereitstellung, UW-ERSTALARM-Regel) in einem Rutsch an.- Falls SP-Dispo-User mit jetzt leerer Rolle existieren (durch die
alte ENUM-Sperre): unter
/admin/users.phpeinmal bearbeiten, Rolle nochmal setzen. - Auf
/admin/alarm-regeln.phpprüfen, dass die UW-ERSTALARM-Regel da ist. LG-Felder der Folge-Einsätze bleiben absichtlich leer — wachen-spezifisch eintragen. - Komplett additiv ansonsten — kein Code-Update nötig, keine Bestandsdaten betroffen.
2.1.0 — 2026-05-26
Handbuch — In-App-Hilfe + GitHub-Wiki
Das ETB hatte bisher keine zusammenhängende Bedienungsanleitung. Diese Version liefert ein vollständiges Handbuch mit 20 Topics (~50 Seiten), zugänglich auf zwei Wegen — und beide aus derselben Quelle gespeist.
Neu
- In-App-Hilfe über den neuen Sidebar-Eintrag „📖 Hilfe"
(
/hilfe.php) — für alle eingeloggten User sichtbar, Gast inkl. - 20 Markdown-Topics unter
docs/handbuch/, gruppiert nach Einstieg, Tagesbetrieb, Rollen & Berechtigungen, Admin-Bereich, Betrieb und Referenz. - TOC-Layout mit linker Themen-Spalte und rechter Content-Spalte, inkl. Vorheriges/Nächstes-Navigation am Ende jedes Topics.
- Branding-Platzhalter (
Freiwillige Feuerwehr Wachtberg,FFW Wachtberg,http://einsatz.ffwachtberg.de,Einsatztagebuch) werden ausBrandingServiceersetzt — White-Label-tauglich. - GitHub-Wiki-Sync via
scripts/wiki-sync.ps1: PowerShell-Skript klont das Wiki-Repo, spiegelt die Markdown-Dateien, transformiert interne Links ins Wiki-Format und pusht. HelpServiceliest die Topics, parst Front-Matter (erste H1 = Titel, Dateinamens-Prefix = Sortier-Order und Gruppen-Bucket), rendert via Parsedown.- Parsedown als Single-File-Lib unter
src/lib/Parsedown.php(MIT-Lizenz, kein Composer nötig).
Topics im Überblick
| Gruppe | Topics |
|---|---|
| Einstieg | Übersicht, Installation, Setup-Wizard |
| Tagesbetrieb | Einsätze, Abschnitte, Schwerpunkte, Lagekarte, Einsatzmittel, Hydrantenplan |
| Rollen & Berechtigungen | Die 6 Rollen, Permission-Matrix administrieren |
| Admin-Bereich | Admin-Übersicht, Konfiguration, Stammdaten, Telegram, Diagnose |
| Betrieb | Cron & Mail-Verarbeitung, Backup & Updates |
| Referenz | FAQ (~30 Q&A), Glossar |
Migration / Upgrade-Hinweise
- Komplett additiv — kein DB-Schema-Update, keine Konfigwerte- Migration. Pull + Reload, fertig.
- Der Sidebar-Eintrag „📖 Hilfe" erscheint automatisch für alle eingeloggten User.
- Master-Quelle für die Inhalte sind die Markdown-Dateien im Repo.
Für das GitHub-Wiki führst du nach jedem Inhalts-Update einmalig
pwsh scripts/wiki-sync.ps1aus (manuell, keine Auto-Sync per GitHub-Action). - Bei privaten Repos kommt der Wiki-Sync später dran, sobald das Repo public ist — die In-App-Hilfe funktioniert unabhängig davon sofort.
2.0.0 — 2026-05-26
Rollen-/Permission-Architektur — administrierbare Berechtigungen
Die Berechtigungen sind nicht mehr hartcodiert in User::can(), sondern
werden über eine DB-gestützte Häkchen-Matrix pro Rolle gepflegt. Die
6 Rollen (admin, lage, einsatzleiter, dispo, sp_dispo, gast)
bleiben fix; ihre Permissions sind über /admin/rollen.php administrierbar.
PermissionCatalog (36 atomare Permissions, 7 Gruppen)
↓
PermissionService (DB-Lookup, Per-Request-Cache)
↓
User::can('permission_key') → bool
Neu
- PermissionCatalog mit 36 atomaren Permission-Keys in 7 Gruppen (einsatz, abschnitt, schwerpunkt, em, anhang, admin, karten).
- Admin-UI
/admin/rollen.phpals Häkchen-Matrix mit Scope-Banner, „Reset auf Default"-Button und Audit-Log pro Änderung. - 3-Layer-Failsafe:
ROLE_ADMINbekommt inuserCan()immertrue— verhindert Selbst-Aussperren auch bei kaputter DB.- Locked-Permissions (z. B.
schwerpunkt.viewfürsp_dispo) können weder via UI noch via API abgewählt werden. - ROLE_SPECIFIC_PERMS (z. B.
einsatz.view_all) sind nur bei der jeweiligen Rolle sichtbar — andere Rollen sehen die Option gar nicht und können sie nicht versehentlich setzen.
- RoleAuditService loggt jede Permission-Änderung mit Diff + ausführender User-ID.
- Schema-Auto-Migration: Neue Seite
/admin/schema-check.phpzeigt fehlende Tabellen + Indizes und legt sie auf Knopfdruck an. Schema-Banner in der Sidebar (rollen-abhängig sichtbar) warnt proaktiv bei inkonsistentem DB-Stand. - SetupStatus::missingTables() mit 1 h Session-Cache verhindert Bounce auf jeder Seite.
Modal-Dialog-Library
Dialog.confirm/alert/prompt-API mitinfo/warn/danger- Severities, globalem Background-Klick-Schließen, ESC-Handling und Auto-Wiring viadata-confirm-Attributen.- Ersetzt alle ~40 nativen
confirm()/alert()-Aufrufe in der gesamten App — konsistentes Design, kein Browser-Modal mehr.
Schwerpunkt-Historie
- Neue Seite
/schwerpunkte/history.phpmit Stammdaten, EM-Pool-Snapshot, Einsatzliste und chronologischer Audit-Liste. - „🕓 Historie"-Button im SP-Banner zwischen Edit und Export.
- Auto-Logging in
EinsatzMittelAssignmentServicefürem_add/em_remove/anzahl_change/kontakt_change— jede EM-Mutation im SP-Kontext landet im SP-Audit (via Setter- Injection, damit keine zyklische Service-Abhängigkeit entsteht). - PDF-Export mit SP-Cover (Stammdaten + komplette Audit-Tabelle)
wenn
?schwerpunkt=<id>mitgegeben wird.
Lagekarte-Verbesserungen
- Einsatznummer als permanenter Leaflet-Tooltip im
tooltipPane(z-Index 650, also über allen Markern). Vorher konnten taktische 96×96-Symbole, Fahrzeug-Icons und SP-Pills die Einsatznummer überdecken — der Tooltip rendert jetzt strukturell darüber. - Tooltip-Background in Wichtigkeits-Farbe, Textfarbe via
YIQ-Lesbarkeits-Formel (weiß auf dunklem, schwarz auf hellem
Hintergrund). Tooltip-Offset
[0, 8]— nah am Marker. - Cluster on/off Toggle in der Topbar, persistiert in
localStorage. Klick wechselt zwischenL.markerClusterGroupundL.layerGroupohne Page-Reload. - Heatmap-Gradient warm (`#ffeb99 → #ffcc33 → #ff9933 →
ff5500 → #cc0000
,minOpacity: 0.45`). Der Leaflet-Defaultgrün→blau→gelb war auf OSM-Wald-/Wasser-Tiles praktisch unsichtbar. SP-Heatmap nutzt jetzt denselben warmen Gradient für visuelle Konsistenz.
Geändert
- System-Kommentare (Autor
NULL) sind in allen drei Kommentar-Services (Einsatz, Abschnitt, Schwerpunkt) jetzt revisionsfest — der explizite Null-Check blockiert das Editieren komplett, auch für Admins. - SP-Personal-Aggregation deduplizieren: Ein EM, das mehreren
Einsätzen eines Schwerpunkts zugewiesen ist, wird im
SP-Personal-Pill jetzt nur einmal gezählt (per
em_name, höchste Personenzahl gewinnt) — vorher wurde es pro Zuweisung mehrfach addiert. - SP-Edit-Page: Disponent-Dropdown unterscheidet jetzt
Name (Dispo)vs.Name (SP-Dispo). Neuer Button „+ SP-Dispo anlegen" öffnet ein Inline-Modal mit hartcodierter Rollenzuweisung server-seitig. - Einsatzmittel-Sidebar auf der Einsatz-Detail-Page filtert jetzt korrekt auf den SP-Pool, wenn der Einsatz einem Schwerpunkt zugewiesen ist. EMs außerhalb des Pools sind ausgeblendet, damit das EM-Management mit der SP-Logik konsistent bleibt.
- N+1-Fix in der ETB-Übersicht: neuer Bulk-Lookup
forAbschnitte()ersetzt die per-Abschnitt-Schleife mit einer einzigen Query.
Behoben
- 500er auf
/admin/rollen.phpbei fehlenden DB-Tabellen: Defensivestry/catchinPermissionService::getAllRoles()und automatische Migration viaSchemaProvider::createAll()beim ersten Aufruf. - SP-Banner fehlte auf der SP-Historie-Page — jetzt im SP-Kontext sichtbar (Header-Streifen wie auf allen anderen SP-Sub-Pages).
Intern (Refactoring)
- ~50 hartcodierte Rollen-Checks (
$me->role === ROLE_X/in_array($me->role, […])) durch Permission-Checks ersetzt. dispoScopeApplies($me)-Helper imbootstrap.php: respektiert die neueeinsatz.view_all-Permission als Scope-Override für Dispo-User (im Standardfall greift der Eigentums-Filter; mitview_allsieht der Dispo alle Einsätze).- Scope-Filter bleiben Code-Logik: Dispo-Eigentums-Filter und SP-Scope sind NICHT permission-konfigurierbar (Sicherheits- Sweetspot — kein Häkchen kann die Schwerpunkt-Beschränkung des SP-Dispo aufheben).
- Neue Service-Klassen:
PermissionCatalog,PermissionService,RoleAuditService. - 3 neue Tabellen via
SchemaProvider:roles,role_permissions,role_audit(mit Composite-Soft-Delete- Indizes für die bestehenden Tabellen).
Migration / Upgrade-Hinweise
- Die neuen Tabellen werden beim ersten Aufruf einer beliebigen
Admin-Seite automatisch angelegt. Falls die Auto-Migration nicht
greift:
/admin/schema-check.phpöffnen und „Jetzt anlegen" klicken. - Die Default-Permission-Belegung pro Rolle entspricht dem alten hartcodierten Mapping — bestehendes Verhalten bleibt erhalten.
- Admin kann nach dem Upgrade unter
/admin/rollen.phpeinzelne Permissions umkonfigurieren. „Reset auf Default" stellt jederzeit den Auslieferungsstand wieder her. - Empfohlene Prüfschritte: Als Admin einloggen, einmal jede Rolle durchklicken (oder Test-User mit der Rolle erstellen), prüfen, dass Permissions wie gewohnt greifen.
1.5.0 — 2026-05-25
Schwerpunkte — Großlagen-Gruppierung mehrerer Einsätze
Neue Strukturebene über den Einsätzen für die Koordination von Großlagen (Unwetter, Flächenbrand, Großübung). Ein Schwerpunkt bündelt mehrere Einsätze unter einem dedizierten Disponenten mit eigenem EM-Pool, eigener Lagekarte und eigenem „Schwerpunkttagebuch"-Modus.
Schwerpunkt (n) ← NEU
└── Einsatz (1..n)
└── Abschnitt (0..n)
Neu
- Schwerpunkt-Wizard (
/schwerpunkte/new.php) mit 4 Schritten: Stammdaten + Disponent (mit Inline-User-Anlage), Modus-Auswahl (Orte vs. konkrete Einsätze), Einsatz-Auswahl mit Konflikt-Markierung, Einsatzmittel-Pool (vorbefüllt aus den schon zugewiesenen EMs). - Schwerpunkt-Übersicht (
/schwerpunkte/index.php) mit Filterung nach Status (aktiv/pausiert/geschlossen/archiviert). - Schwerpunkt-Tabelle im Haupt-ETB oberhalb der Einsatz-Liste mit 3-stufiger Expansion: Schwerpunkt → Einsatz → Abschnitt.
- Schwerpunkttagebuch-Modus via
?schwerpunkt=<id>— alle Sub-Pages (Einsatzliste, Lagekarte, Einsatzmittel, Hydrantenplan, Links, Geocode-Admin) filtern auf den jeweiligen Schwerpunkt; die Sidebar wechselt in den SP-Modus mit Banner und „← Zurück zum ETB". - Einsatzmittel-Pool als n:m-Beziehung pro Schwerpunkt. Entfernen eines EMs aus dem Pool kaskadiert in alle SP-Einsätze und ihre Abschnitte und schreibt einen System-Kommentar in jeden betroffenen Einsatz — alles transaktional.
- Automatische Einsatz-Zuweisung an Schwerpunkte: Neue Einsätze (auch via Mail-Parser) werden anhand ihres Orts dem passenden aktiven Schwerpunkt im Modus „Orte" zugewiesen.
- Status-Lifecycle:
aktiv→pausiert(Auto-Zuweisung aus) →geschlossen(mit Sperre solange offene Einsätze enthalten sind) →archiviert(aus Listen verborgen). - Personal-Aggregation pro Schwerpunkt: „GF/TF/EK/Gesamt"-Summen über alle EM-Zuweisungen im Schwerpunkt, mit Doppel-Unterstreichung der Gesamt-Zahl in ETB-Übersicht, SP-Liste und SP-Banner.
- Lagekarte im SP-Modus: SP-Einsätze werden standardmäßig als Dichte-Visualisierung (Heatmap) statt als N einzelne Marker gerendert, mit Toggle „Alle Einsätze anzeigen" / „SP-Marker aus" und Auto-Fit auf die SP-Bounding-Box.
- Schwerpunkt-Marker auf der Hauptlagekarte für eine schnelle Übersicht aller aktiven Schwerpunkte.
- PDF-Export pro Schwerpunkt (
/schwerpunkte/export.php) und „Alle-mit-SP-Gruppen"-Modus im Admin-PDF-Export. - Bulk-Zuweisung zu Schwerpunkten direkt aus der ETB-Übersicht (Mehrfach-Auswahl + Aktionsbar).
- Drag&Drop von EMs aus der Sidebar direkt auf einen Schwerpunkt in der ETB-Übersicht — fügt das EM dem Pool hinzu.
Neue Rolle: SP_DISPO (Schwerpunkt-Disponent)
- Eigene Rolle für Disponenten, die nur Einsätze und Abschnitte aus „ihren" Schwerpunkten sehen und bearbeiten dürfen.
- Zentrale Scope-Prüfung via
spDispoCanAccessEinsatz()insrc/bootstrap.php, durchgehend an 13 API-Endpoints angebunden. - Disponenten-Dropdowns (Reassign-Selects, Bulk-Editor) berücksichtigen
die neue Rolle via
User::isAnyDispo().
Geändert
- Einsatz-Reset (
EinsatzResetService): löscht jetzt auch alle Schwerpunkte und ihre Tabellen mit (Abschnitte und Einsätze waren bereits abgedeckt). - Sidebar (
MainNavSidebar) zeigt das „Schwerpunkte"-Item nur, wenn aktive Schwerpunkte existieren — sonst bleibt sie aufgeräumt. - EM-Sidebar im SP-Modus: zeigt nur EMs aus dem Pool des aktiven Schwerpunkts, flach (ohne üÖrt-Sentinel-Gruppe).
- Einsatz-Detail-Page: neuer Button „Schwerpunkt zuweisen" mit Modal, das auch die EM-Zuordnung zum Pool mitanbieten kann.
- Lagekarte-Popup: Einsatz-Links erhalten den
?schwerpunkt=<id>- Parameter, wenn der Klick aus dem SP-Tagebuch kam.
Behoben
- Anhang-Download für Abschnitts-Kommentare: Der Endpoint
/api/anhang-download.phpkannte denkind=abschnitt-Parameter nicht und suchte immer in der Einsatz-Anhang-Tabelle — Downloads von Abschnitts-Anhängen schlugen still fehl. Jetzt zweigleisig mit getrennten MIME-Whitelists und Permission-Checks pro Variante. - Status-Blacklist im Bulk-Editor (
/api/einsatz-bulk.php): Die Sperre für „Abschluss beantragen"/„Abgeschlossen" griff nur für DISPO, nicht für SP_DISPO. - Erledigt-Sperre an Abschnitten (
abschnitt-em-assign.php,abschnitt-comment.php): griff nur für DISPO — SP_DISPO konnte weiter editieren. - 7 Dispo-Dropdown-Filter blendeten SP_DISPO aus und konnten ihm keine Einsätze/Abschnitte als Dispo zuweisen.
- Nested-Transaction-Bug in
SchwerpunktService::setOrte()undSchwerpunktEmService::unassign(): führten bei verschachtelten Aufrufen zu PDO-Fehlern.
Sicherheit
- Session-Cookie:
SameSite=Laxexplizit dokumentiert als CSRF-Schutz für die JSON-AJAX-Endpoints. Cross-Site-POSTs werden vom Browser blockiert (Auth-Cookie geht nicht mit); GET-Top-Level- Navigationen aus externen Quellen (Telegram-Push-Links) funktionieren weiter.
Intern (Refactoring)
buildUrl()auseinsaetze/index.phpundadmin/export.phpin zentralen Helper insrc/bootstrap.phpausgelagert.SchwerpunktService::sumAnzahlStrings()alspublic static— beseitigt das Personal-Aggregat-Code-Duplikat zwischenview.phpund dem Service.- Neue Service-Klassen:
SchwerpunktService,SchwerpunktStatusService,SchwerpunktEinsatzAssignmentService,SchwerpunktEmService,SchwerpunktKommentarService,SchwerpunktAnhangService,SchwerpunktAuditService. - 8 neue Tabellen via
SchemaProvider(keine separaten SQL-Migrationen):schwerpunkte,schwerpunkt_status,einsatz_schwerpunkt,schwerpunkt_einsatzmittel,schwerpunkt_ort,schwerpunkt_kommentar,schwerpunkt_anhang,schwerpunkt_audit.
Migration / Upgrade-Hinweise
- Die neuen Tabellen werden beim nächsten Aufruf automatisch via
SchemaProvider::createAll()angelegt — kein manueller SQL-Schritt nötig. - Bestehende Einsätze, Abschnitte, User und Konfiguration bleiben unverändert. Das Feature ist additiv: Wer keine Schwerpunkte anlegt, sieht das Verhalten wie in v1.0.0.
- Die neue Rolle
SP_DISPOist optional. Bestehende Dispo-User behalten ihre Rolle. - Empfohlene Prüfschritte nach dem Upgrade: einmal als Admin einloggen, einen Schwerpunkt anlegen (Wizard), einen Einsatz zuweisen, EM-Pool testen.
1.0.0 — 2026-05-23
Erste produktiv eingesetzte Version des Einsatztagebuchs.
Funktionsumfang
- Einsatz-Verwaltung: Mail-Parser für eingehende Alarm-Mails, Detailseite mit Kommentaren + Anhängen + Audit-Historie, Status- Lebenszyklus (offen → in Bearbeitung → Abschluss beantragt → abgeschlossen), PDF-Export.
- Abschnitte: Größere Einsätze in operative Abschnitte unterteilen, jeder mit eigenem Leiter, Funk-Rufgruppe, Disponent, Status; n:m EM-Zuweisung; Abschluss-Sperre auf Einsatz-Ebene.
- Karten & Geo: Lagekarte (Leaflet/OSM), Hydrantenplan mit Foto-Upload, Geocoding-Service mit DB-Cache.
- Telegram-Alarmierung: Push in mehrere Chats, IuK-Sondernachricht, Antwort-Webhook landet als Kommentar.
- Rollen:
admin,lage,einsatzleiter,dispo,gastmit Dispo-Restriction (Disponent sieht nur eigene/zugewiesene Einsätze). - Setup-Wizard für die Erst-Konfiguration; Branding-Assets, Geocoding-Suffix, Karten-Center konfigurierbar.
- Mehrmandanten-Fähigkeit via Tabellen-Präfix pro Instanz.
Vollständige Beschreibung im GitHub-Release v1.0.0.