Atemschutzueberwachung nach FwDV 7 ergaenzen
Phase 5: das sicherheitsrelevanteste Modul des Projekts. Ueber jeder Ansicht steht dauerhaft, dass die analoge Atemschutzueberwachung fuehrend bleibt — abschaltbar nur zusammen mit der Fundstelle einer Freigabe des Kommandanten. Es gibt keinen Timer. In der Datenbank stehen Zeitstempel; wie lange ein Trupp unter Atemschutz ist, rechnet jede Ansicht bei jedem Bild neu aus. Damit ist die Anforderung "uebersteht Neuladen und Verbindungsabbruch" keine Funktion, die gelingen muss, sondern eine Eigenschaft, die sich nicht verlieren laesst. Server und Browser rechnen mit denselben Funktionen. Der Rueckzugsdruck folgt dem doppelten Anmarschverbrauch: was der Weg hinein gekostet hat, kostet der Weg zurueck noch einmal. Bis der Trupp das Einsatzziel meldet, greift die Zwei-Drittel-Regel — sie liegt hoeher und ist damit die vorsichtigere Annahme. Das Protokoll ist doppelt gesichert: entzogene Rechte und ein Trigger auf druckmessung und atemschutz_ereignis. Ein Fehler wird durch einen neuen Eintrag richtiggestellt, nicht durch Aendern. Verteilt wird ueber Server-Sent Events statt Socket.IO — es geht nur in eine Richtung, und so bleibt das Deployment bei "next start". Behoben: ein abgerissener Ereignisstrom meldete sich nicht. Die Anzeige haette weiter "Verbunden" behauptet, waehrend der Draht tot war. Jetzt gilt Stille von acht Sekunden als Abriss. Dazu zwei Altlasten: der Navigationseintrag "Protokoll" fuehrte ins Leere, und die Startseite stand noch auf Phase 1. 68 neue Tests (51 Unit, 17 gegen eine echte Datenbank, 8 E2E je Browser). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
b2b31ed00a
commit
4e2daaafd4
@@ -28,7 +28,7 @@ Anmelden mit `SEED_ADMIN_EMAIL` und `SEED_ADMIN_PASSWORT` aus der `.env`
|
||||
| Phase 2 — Wartung und Prüfung | fertig |
|
||||
| Phase 3 — Einsätze und Übungen | fertig |
|
||||
| Phase 4 — Kiosk-PWA im Gerätehaus | fertig |
|
||||
| Phase 5 — Atemschutz (FwDV 7) | offen |
|
||||
| Phase 5 — Atemschutz (FwDV 7) | fertig |
|
||||
| Phase 6 — Kartenmodule | offen |
|
||||
| Phase 7 — Benachrichtigungen und Termine | offen |
|
||||
| Phase 8 — Lokale KI | offen |
|
||||
@@ -529,6 +529,141 @@ Kiosk-Browser des Tablets wird daraus eine Vollbildanwendung ohne Adresszeile.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 — Atemschutz nach FwDV 7
|
||||
|
||||
Das sicherheitsrelevanteste Modul des Projekts. Über jeder Ansicht steht
|
||||
deshalb dauerhaft:
|
||||
|
||||
> **Ergänzendes System — die analoge Atemschutzüberwachung bleibt führend.**
|
||||
|
||||
Der Hinweis lässt sich abschalten, aber nur zusammen mit einer Fundstelle:
|
||||
`ATEMSCHUTZ_HINWEIS=false` wirkt erst, wenn unter `ATEMSCHUTZ_FREIGABE` steht,
|
||||
worauf sich die Freigabe stützt — etwa „Kommandantenbeschluss vom 12.03.2026".
|
||||
Fehlt sie, bleibt der Hinweis stehen. Eine Freigabe ohne Beschluss ist keine.
|
||||
|
||||
### Die Zeit gehört dem Server
|
||||
|
||||
Das ist die eine Entscheidung, aus der alles Weitere folgt. **Nirgends wird
|
||||
eine Restzeit heruntergezählt.** In der Datenbank stehen Zeitstempel; wie lange
|
||||
ein Trupp drin ist, rechnet jede Ansicht bei jedem Bild neu aus dem
|
||||
Einstiegszeitpunkt und der aktuellen Uhr.
|
||||
|
||||
Daraus ergibt sich von selbst, was Phase-5.md als wichtigste Anforderung nennt:
|
||||
|
||||
| Was passiert | Was die Anzeige macht |
|
||||
|---|---|
|
||||
| Browser neu laden | Zeigt dieselbe Zeit weiter — es gab nichts zu verlieren |
|
||||
| Zweiter Bildschirm daneben | Zeigt dieselbe Zeit, ohne Abgleich |
|
||||
| Verbindung bricht ab | Die Uhr läuft weiter, und der Abriss steht sichtbar da |
|
||||
| Server neu gestartet | Nach der ersten Antwort ist alles wieder da |
|
||||
|
||||
Server und Browser rechnen mit **denselben** Funktionen
|
||||
(`src/lib/atemschutz/berechnung.ts`). Was das Tablet anzeigt, weist das
|
||||
Protokoll später genauso aus.
|
||||
|
||||
### Rückzugsdruck
|
||||
|
||||
Gerechnet wird nach dem **doppelten Anmarschverbrauch**: was der Weg hinein an
|
||||
Luft gekostet hat, kostet der Weg zurück noch einmal.
|
||||
|
||||
```
|
||||
Rückzug = 2 × (Eingangsdruck − Druck am Einsatzziel) + Warndruck + Zuschlag
|
||||
```
|
||||
|
||||
Dafür meldet der Trupp beim Erreichen des Einsatzziels einmal seinen Druck.
|
||||
Solange das nicht geschehen ist, greift die **Zwei-Drittel-Regel** — sie liegt
|
||||
in aller Regel höher und ist damit die vorsichtigere Annahme; die Karte sagt
|
||||
dann „vorläufig" dazu.
|
||||
|
||||
Maßgeblich ist immer der ungünstigste Wert im Trupp: der Trupp geht gemeinsam
|
||||
zurück, also zählt, wer am wenigsten Luft hat.
|
||||
|
||||
Die Ampel steht schon zehn Prozent über der Grenze auf Gelb — der Trupp soll
|
||||
losgehen, bevor der Wert erreicht ist, nicht wenn er erreicht ist. Farbe **und**
|
||||
Text, wie überall in FLORIAN.
|
||||
|
||||
### Der Weg durch eine Überwachung
|
||||
|
||||
1. **Eröffnen** — Bezeichnung genügt. Die Zuordnung zu einem Einsatz lässt sich
|
||||
nachtragen; im Ernstfall wird zuerst überwacht.
|
||||
2. **Trupp anlegen** — zwei oder drei Personen, für jede der Eingangsdruck, eine
|
||||
davon Truppführer. Daneben steht, ob die Person nach FwDV 7 einsetzbar ist.
|
||||
**Gesperrt wird nichts:** im Einsatz entscheidet der Einheitsführer, und ein
|
||||
Programm, das ihm im entscheidenden Moment eine Person verweigert, wird
|
||||
umgangen — dann steht am Ende gar nichts im Protokoll.
|
||||
3. **Einstieg** — ab hier läuft die Uhr.
|
||||
4. **Druckabfrage** — für den ganzen Trupp in einer Zeile. Nach
|
||||
`ATEMSCHUTZ_ABFRAGE_INTERVALL` Sekunden ohne Meldung wird erinnert; gerechnet
|
||||
ab der letzten Meldung, nicht ab dem Einstieg.
|
||||
5. **Rückweg und heraus** — beim Herauskommen die Ausgangsdrücke.
|
||||
6. **Beenden** — geht erst, wenn alle Trupps als draußen gemeldet sind. Eine
|
||||
beendete Überwachung mit einem Trupp, der noch drin steht, wäre die
|
||||
gefährlichste Zeile im ganzen Protokoll.
|
||||
|
||||
Dazu jederzeit: **Rückzug anordnen**, **Mayday** (aufzuheben, nicht
|
||||
wegzuklicken) und Notizen ins Protokoll.
|
||||
|
||||
### Der Ereignisstrom
|
||||
|
||||
Änderungen kommen über **Server-Sent Events** unter `/api/atemschutz/strom` —
|
||||
kein WebSocket, kein eigener Node-Server, `next start` bleibt wie es ist. Der
|
||||
Strom meldet nur „es hat sich etwas geändert"; die Ansicht holt daraufhin den
|
||||
Stand. Geschrieben wird wie überall über tRPC.
|
||||
|
||||
Zwei Dinge machen ihn belastbar:
|
||||
|
||||
- **Er verbindet sich selbst neu.** `EventSource` bringt das mit.
|
||||
- **Stille gilt als Abriss.** Der Server schickt alle zwei Sekunden ein
|
||||
Lebenszeichen; bleibt es acht Sekunden aus, steht die Verbindung sichtbar auf
|
||||
„unterbrochen" — auch wenn der Browser keinen Fehler meldet. Dieser Fall ist
|
||||
real: wird das Netz gekappt, während der Strom offen ist, schweigt
|
||||
`EventSource` einfach.
|
||||
|
||||
Fällt der Strom ganz aus, bleibt die Ansicht bedienbar — sie fragt zusätzlich im
|
||||
festen Takt nach. Der Strom macht sie schneller, nicht erst funktionsfähig.
|
||||
|
||||
### Das Protokoll
|
||||
|
||||
Ein PDF mit Rahmen, Trupps und dem Verlauf — Ereignisse und Druckmessungen in
|
||||
**einer** Zeitachse, damit niemand zwei Spalten gleichzeitig lesen muss. Es
|
||||
entsteht beim Beenden im Hintergrundprozess und, falls das nicht geklappt hat,
|
||||
beim Abruf unter `/api/atemschutz/protokoll?id=…`.
|
||||
|
||||
Im Kopf steht, ob die digitale Überwachung freigegeben war. Wer das Blatt
|
||||
später in der Hand hält, soll wissen, was er da hat.
|
||||
|
||||
Verändern lässt sich nichts: `druckmessung` und `atemschutz_ereignis` sind für
|
||||
den Anwendungszugang gegen `UPDATE` und `DELETE` gesperrt, und zusätzlich sitzt
|
||||
auf beiden ein Trigger. Ein Fehler wird durch einen neuen Eintrag
|
||||
richtiggestellt.
|
||||
|
||||
### Wer darf unter Atemschutz?
|
||||
|
||||
Drei Nachweise, die gleichzeitig gelten müssen:
|
||||
|
||||
| Nachweis | Frist |
|
||||
|---|---|
|
||||
| **G26.3** | nach Alter: bis 50 Jahre drei Jahre, danach eines |
|
||||
| **Belastungsübung** | jährlich (Übungsstrecke) |
|
||||
| **Einsatzübung unter Atemschutz** | jährlich — ein echter Einsatz zählt |
|
||||
|
||||
Dazu die Qualifikation als Atemschutzgeräteträger aus Phase 1. Die Übersicht
|
||||
zeigt eine Ampel **mit Klartext**, was fehlt: eine rote Ampel ohne Begründung
|
||||
hilft am Fahrzeug niemandem. Auf der Startseite steht die Zahl, nach der im
|
||||
Einsatz als Erstes gefragt wird — wie viele Träger heute einsetzbar sind.
|
||||
|
||||
### Zusätzliche Umgebungsvariablen
|
||||
|
||||
| Variable | Vorgabe | Bedeutung |
|
||||
|---|---|---|
|
||||
| `ATEMSCHUTZ_HINWEIS` | `true` | Sicherheitshinweis über jeder Ansicht |
|
||||
| `ATEMSCHUTZ_FREIGABE` | — | Fundstelle der Freigabe; ohne sie bleibt der Hinweis |
|
||||
| `ATEMSCHUTZ_ABFRAGE_INTERVALL` | `600` | Abstand der Druckabfrage in Sekunden |
|
||||
| `ATEMSCHUTZ_WARNDRUCK` | `55` | Ansprechdruck der Warneinrichtung in bar |
|
||||
| `ATEMSCHUTZ_ZUSCHLAG` | `10` | Sicherheitszuschlag auf den Rückzugsdruck |
|
||||
|
||||
---
|
||||
|
||||
## Befehle
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user