Phase 2: Wartungs- und Pruefmanagement

Wartungsvorlagen mit Checklisten, Prueftermine aus einem naechtlichen Lauf,
Prueffristen-Dashboard, Pruefwizard mit Foto und Unterschrift, unveraenderliche
Protokolle als PDF, Maengel-Workflow, Rueckrufe und Lebensdauerueberwachung.

Elf neue Tabellen, alle mit organisationId und Row Level Security. Die
Unveraenderbarkeit abgeschlossener Protokolle setzt ein Datenbanktrigger
durch, nicht der Anwendungscode: eine Korrektur erzeugt eine neue Pruefung
mit Verweis auf die alte, beide bleiben lesbar.

79 neue Tests (47 Unit, 10 gegen eine echte Datenbank, 22 E2E).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Florian Wilde
2026-09-03 12:07:11 +02:00
co-authored by Claude Opus 5
parent 7f866ac35c
commit e503aafc18
97 changed files with 13367 additions and 133 deletions
+228 -9
View File
@@ -1,10 +1,10 @@
# Anleitung
Bedienung von FLORIAN, Stand Phase 1 (Version 0.2.0). Die Bilder zeigen die
Bedienung von FLORIAN, Stand Phase 2 (Version 0.3.0). Die Bilder zeigen die
Beispielwehr aus dem Seed und werden mit `npm run screenshots` neu erzeugt.
> Prüfungen, Einsätze, Atemschutz und die Kiosk-Oberfläche kommen in den
> folgenden Phasen dazu. Siehe [ROADMAP.md](ROADMAP.md).
> Einsätze, Atemschutz und die Kiosk-Oberfläche kommen in den folgenden Phasen
> dazu. Siehe [ROADMAP.md](ROADMAP.md).
---
@@ -70,7 +70,7 @@ derselben Installation hat, ist nicht sichtbar und nicht abfragbar.
### Die Seitenleiste
Links stehen alle Module. Was noch nicht existiert, ist ausgegraut und trägt
rechts sein Phasenkürzel — `P2` heißt „kommt in Phase 2".
rechts sein Phasenkürzel — `P3` heißt „kommt in Phase 3".
Was jemand überhaupt sieht, hängt an seinen Rechten. Ein einfaches Mitglied
sieht die Mitgliederliste, aber nicht das Protokoll. Wichtig zum Verständnis:
@@ -366,7 +366,226 @@ Zum Schluss steht da, wie viele Datensätze angelegt, aktualisiert und
---
## 11. Rollen und was sie dürfen
---
## 11. Prüfungen und Fristen
![Fristen-Dashboard](screenshots/11-fristen-light.png)
Die Seite, die der Gerätewart morgens aufmacht. Sie beantwortet eine Frage:
**was ist zu tun.**
Ganz oben stehen vier Zahlen, nach Dringlichkeit geordnet:
| Topf | Bedeutung |
|---|---|
| **überfällig** | hätte längst geprüft sein müssen |
| **diese Woche** | in den nächsten sieben Tagen |
| **diesen Monat** | in den nächsten 30 Tagen |
| **nächste 90 Tage** | mittelfristig zu planen |
Jede Zahl ist gleichzeitig ein Filter: ein Klick, und die Liste darunter zeigt
nur noch diesen Zeitraum. Nochmal klicken hebt den Filter wieder auf.
„Überfällig" wird jeden Tag neu gerechnet und nicht gespeichert. Ein Termin,
der heute Nacht fällig geworden ist, steht morgen früh im richtigen Topf, ohne
dass jemand etwas anstoßen muss.
### Verteilung
Darunter steht, **wo** die offenen Termine hängen — wahlweise nach Fahrzeug,
Standort, Gerätetyp oder Zuständigem. Wer einen Prüftag ansetzt, arbeitet ein
Fahrzeug ab und keine alphabetische Liste; deshalb ist Fahrzeug die Vorgabe.
### Termine zuweisen
In der Terminliste lassen sich mehrere Zeilen ankreuzen und in einem Zug jemandem
zuweisen. Der Zuständige bekommt die Erinnerungen; ist niemand zuständig, gehen
sie an die Gerätewarte der Wehr.
### Erinnerungen
Nachts um 3:45 Uhr verschickt FLORIAN eine **Sammelnachricht je Empfänger** —
nicht eine Mail je Gerät. Erinnert wird bei 30 Tagen (oder der Vorwarnzeit der
Vorlage), bei 7 Tagen, am Fälligkeitstag und einmal, wenn ein Termin überfällig
geworden ist. Jede Stufe genau einmal.
Solange `MAIL_ENABLED=false` steht, landen die Nachrichten im Protokoll statt
im Postfach.
---
## 12. Wartungsvorlagen
![Wartungsvorlagen](screenshots/12-vorlagen-light.png)
Eine Wartungsvorlage sagt, **was** an einem Gerätetyp **in welchem Takt**
geprüft wird. Sie ist die Regel; der Termin ist ihre Anwendung auf ein einzelnes
Gerät.
**Ohne Vorlage gibt es keine Termine.** Das ist die erste Seite, die eine Wehr
in diesem Modul ausfüllt.
| Angabe | Wofür |
|---|---|
| **Gerätetyp** | für welche Bauart die Vorlage gilt. Ohne Gerätetyp plant der nächtliche Lauf nichts. |
| **Intervall in Monaten** | zählt ab der letzten durchgeführten Prüfung |
| **Vorwarnzeit in Tagen** | wann die erste Erinnerung rausgeht |
| **Prüfvorschrift** | steht später im Protokoll und in der Fußzeile des PDF |
| **Übliche Dauer** | Erfahrungswert für die Planung eines Prüftags |
### Die Checkliste
![Checkliste einer Vorlage](screenshots/17-checkliste-light.png)
Jeder Punkt hat eine von vier Antwortarten:
| Art | Wann |
|---|---|
| **Ja / Nein** | Sichtprüfungen: „ohne Risse", „Kennzeichnung lesbar" |
| **Messwert** | alles Gemessene, mit zulässigem Bereich und Einheit |
| **Text** | Befunde, die sich nicht ankreuzen lassen |
| **Foto** | wenn der Zustand belegt werden soll |
Bei einem Messwert entscheidet der zulässige Bereich, ob der Punkt in Ordnung
ist. Gerechnet wird das auf dem Server, nicht im Browser.
**Pflichtpunkt heißt: davon hängt die Einsatzbereitschaft ab.** Ein
Pflichtpunkt, der durchfällt, bedeutet „nicht bestanden" und sperrt das Gerät.
Ein Kann-Punkt, der durchfällt, bedeutet „bestanden mit Mängeln". Wer einen
Punkt als Pflicht anlegt, trifft also eine fachliche Entscheidung.
Die Reihenfolge zählt: der Prüfwizard arbeitet die Punkte genau so ab, wie sie
hier stehen. Umsortiert wird mit den Pfeiltasten — das geht auch mit Handschuhen
und mit der Tastatur.
---
## 13. Eine Prüfung durchführen
Gestartet wird sie entweder im Fristen-Dashboard über **Prüfen** oder auf der
Gerätedetailseite über **Prüfung durchführen**. Wer das Gerät am Regal
gescannt hat, ist schon auf der richtigen Seite.
Der Wizard zeigt **einen Prüfpunkt je Bildschirm**. Oben läuft die Zeit mit;
sie landet im Protokoll und gehört zum Nachweis, wie gründlich geprüft wurde.
Zu jedem Punkt lassen sich zusätzlich ein Foto und eine Bemerkung erfassen.
Auf dem Tablet öffnet der Fotoknopf unmittelbar die Kamera.
**Jede Antwort geht sofort zum Server.** Wenn im Gerätehaus das WLAN wegbricht,
ist höchstens die letzte Antwort verloren. Beim erneuten Öffnen wird der
angefangene Durchgang fortgesetzt — es entsteht keine zweite halbe Prüfung.
### Der Abschluss
Am Ende steht:
1. **Ergebnis** — vorgeschlagen wird, was sich aus den Antworten ergibt.
Übersteuern darf der Prüfer; er trägt die Verantwortung, nicht die Software.
2. **Mängel** — aus den beanstandeten Punkten vorgeschlagen, frei ergänzbar.
Ein kritischer Mangel sperrt das Gerät.
3. **Unterschrift** — auf dem Zeichenfeld, mit Finger, Stift oder Maus. Ohne
Unterschrift lässt sich nicht abschließen: ein Protokoll ohne Unterschrift
ist kein Nachweis.
Wurde die Prüfung **extern** durch eine Fachfirma gemacht, lassen sich hier
Firma, Kosten und das Fremdprotokoll als PDF anhängen.
Mit dem Abschluss passiert alles auf einmal: die Prüfung wird festgeschrieben,
der Termin gilt als erledigt, der nächste wird geplant, der Gerätestatus zieht
nach, und das PDF entsteht im Hintergrund.
---
## 14. Prüfprotokolle
![Prüfprotokoll](screenshots/18-pruefprotokoll-light.png)
Jedes abgeschlossene Protokoll bekommt eine laufende Nummer im Format
`JJJJ-NNNN` — das ist die Nummer, die man bei einer Rückfrage der Unfallkasse
nennt.
Über **Protokoll als PDF** kommt die Fassung zum Ausdrucken oder Weiterreichen:
Kopf mit Wehr, Gerät und Prüfer-Kennung, die Checkliste mit Soll, Ist und
Befund, die Fotos, die Unterschriften und eine Fußzeile mit Prüfvorschrift und
Prüfdatum. Alles ist im PDF eingebettet — es lädt nichts nach und sieht in zehn
Jahren noch genauso aus.
### Ein Protokoll lässt sich nicht ändern
Das ist keine Bequemlichkeitsfrage, sondern der Kern der Sache: ein Nachweis,
den man nachträglich ändern kann, ist keiner. FLORIAN verhindert das in der
Datenbank, nicht bloß in der Oberfläche.
Wenn etwas falsch ist, legt **Korrektur anlegen** eine neue Prüfung an — mit den
bisherigen Antworten vorbelegt und einem Verweis auf das alte Protokoll. Sobald
sie abgeschlossen ist, gilt das alte als „ersetzt". **Beide bleiben lesbar**,
und im Korrekturprotokoll steht, warum korrigiert wurde.
---
## 15. Mängel
![Mängel](screenshots/13-maengel-light.png)
Der Weg ist immer derselbe:
```
gemeldet → zugewiesen → in Arbeit → behoben
```
**Melden darf jedes Mitglied.** Der Riss im Schlauch fällt dem auf, der ihn in
der Hand hat, nicht dem Gerätewart am Schreibtisch. Zum Melden gehören das
Gerät, eine Beschreibung, eine Dringlichkeit und auf Wunsch ein Foto.
Ein Mangel der Stufe **kritisch** sperrt das Gerät sofort. Beim Beheben wird
die Sperre wieder aufgehoben — aber nur, wenn kein anderer offener Mangel
dasselbe Gerät sperrt. Ein behobener Kratzer gibt kein Gerät frei, das wegen
eines Risses gesperrt ist.
Eine Fehlmeldung wird **verworfen**, nicht gelöscht: dass gemeldet wurde und
was, bleibt nachvollziehbar.
---
## 16. Rückrufe
![Rückrufe](screenshots/14-rueckrufe-light.png)
Kommt ein Sicherheitshinweis des Herstellers, wird er hier erfasst — mit der
betroffenen Bauart, wahlweise eingegrenzt über Modell, Seriennummernbereich und
Herstellungszeitraum.
FLORIAN sucht dann im Bestand nach passenden Geräten und zeigt sie als
**Vorschlag**. Zugeordnet wird nur, was der Gerätewart bestätigt — eine
Chargenangabe des Herstellers passt selten eins zu eins auf die eigenen
Seriennummern.
Zugeordnete Geräte lassen sich in einem Zug sperren. Je Gerät wird
fortgeschrieben, wie es steht: offen, nicht betroffen, Maßnahme läuft, erledigt.
Mit „erledigt" fällt die Sperre wieder — sofern kein Mangel dasselbe Gerät
sperrt. Abschließen lässt sich der Rückruf erst, wenn zu jedem betroffenen Gerät
ein Ergebnis steht.
---
## 17. Lebensdauer
![Lebensdauer](screenshots/15-lebensdauer-light.png)
Helme, Seile, Schutzkleidung und Pressluftatmer sind ab einem Stichtag nicht
mehr zugelassen — unabhängig davon, wie gut sie aussehen. Diese Seite zeigt,
was abgelaufen ist und was in den nächsten Monaten abläuft.
Ein Gerät mit abgelaufener Nutzungsdauer wird nachts automatisch **gesperrt**.
**Ausgesondert** wird es von einem Menschen: das entscheidet, wer weiß, ob
Ersatz da ist. Der Knopf dazu steht in der Zeile.
Voraussetzung ist, dass am Gerätetyp eine Lebensdauer hinterlegt ist
(Kapitel 5).
## 18. Rollen und was sie dürfen
Neun Rollen, jede mit einem festen Satz Rechte. Die Zuordnung steht zentral in
`src/lib/authz.ts` und wird beim Seed in die Datenbank gespiegelt — eine Wehr
@@ -395,7 +614,7 @@ Das Terminal selbst ist nur die Tür.
---
## 12. Anmeldung über authentik einrichten
## 19. Anmeldung über authentik einrichten
authentik läuft **getrennt** von FLORIAN und ist nicht Teil dieses Stacks.
@@ -448,7 +667,7 @@ ganze Wehr aus.
---
## 13. Terminal-Anmeldung im Gerätehaus
## 20. Terminal-Anmeldung im Gerätehaus
Die Oberfläche dazu kommt in Phase 4; der Anmeldeweg steht bereits.
@@ -470,7 +689,7 @@ Huber), PIN `471203`.
---
## 14. Was protokolliert wird
## 21. Was protokolliert wird
Jede schreibende Änderung erzeugt einen Eintrag mit Zeitpunkt, Person,
betroffenem Datensatz und den geänderten Feldern im Vorher-Nachher-Vergleich.
@@ -495,7 +714,7 @@ jeweiligen Detailseite sichtbar.
---
## 15. Wenn etwas nicht geht
## 22. Wenn etwas nicht geht
| Beobachtung | Wahrscheinliche Ursache | Was hilft |
|---|---|---|
+25 -2
View File
@@ -32,7 +32,7 @@ Faktoren, die in die Schätzung eingehen:
|---|---|---:|---:|---:|
| 0 | Fundament | 12–16 PT | — | **1:00 h** |
| 1 | Stammdaten | 10–14 PT | 2,5–3,5 h | **2:05 h** |
| 2 | Wartung und Prüfung | 18–24 PT | 4,5–6 h | offen |
| 2 | Wartung und Prüfung | 18–24 PT | 4,5–6 h | **2:25 h** |
| 3 | Einsätze und Übungen | 12–16 PT | 3–4 h | offen |
| 4 | Kiosk-PWA mit Offline | 16–22 PT | 4–5,5 h | offen |
| 5 | Atemschutz (FwDV 7) | 14–18 PT | 3,5–4,5 h | offen |
@@ -105,7 +105,7 @@ Datumsfelder, die sich in Chromium nicht automatisiert füllen lassen.
## Phase 2 — Wartung und Prüfung
**Vergleichsaufwand: 18–24 PT** — die aufwendigste Phase
**Vergleichsaufwand: 18–24 PT** · **Tatsächlich: 2:25 h Sitzungszeit** — die aufwendigste Phase
| Baustein | PT |
|---|---:|
@@ -124,6 +124,29 @@ der Unfallkasse. Das heißt aber auch, dass jeder Fehler teuer ist. Die
Unveränderlichkeit abgeschlossener Protokolle ist der Kern — und der Grund,
warum der Audit-Log schon in Phase 0 append-only ist.
**Rückblick.** Deutlich unter der geschätzten Sitzungszeit, und das aus einem
Grund, der sich benennen lässt: die Fristenrechnung aus Phase 1 war schon da
und musste nur exportiert werden. Wäre sie hier entstanden — samt der
Zeitzonen-Falle, über die Phase 1 gestolpert ist —, sähe die Zahl anders aus.
Teurer als gedacht war das, was zwischen den Bausteinen liegt. Drei Beispiele:
- Die Reihenfolge beim Abschluss einer Prüfung ist nicht beliebig.
Unterschriften und Mängel müssen vor dem Statuswechsel entstehen, denn danach
lässt die Datenbank am Protokoll nichts mehr zu. Derselbe Stolperstein traf
auch den Seed, der die Beispielprüfung zunächst fertig anlegen wollte.
- Die Protokollnummer muss unter einer Sperre vergeben werden. Aufgefallen ist
das erst, weil die E2E-Tests Desktop und Tablet gleichzeitig prüfen ließen —
zwei Prüfer, die im selben Moment abschließen, sind im Gerätehaus kein
konstruierter Fall.
- Das PDF entsteht zwischen zwei Datenbanktransaktionen, nicht in einer. Fotos
aus MinIO holen und Gotenberg rendern lassen dauert länger, als eine offene
Transaktion warten darf.
Billiger als angesetzt war das Unterschriftenfeld: Pointer-Events decken Finger,
Stift und Maus in einem ab, und mehr als Skalierung auf die Pixeldichte und
`touch-action: none` braucht es nicht.
## Phase 3 — Einsätze und Übungen
**Vergleichsaufwand: 12–16 PT**
+108 -1
View File
@@ -13,7 +13,114 @@ Die aufgewendete Zeit wandert nach jedem Abschnitt in die Spalte
| Phase 0 — Fundament | 1:00 h | 1 | 03.09.2026 |
| Phase 1 — Stammdaten | 1:15 h | 1 | 03.09.2026 |
| Phase 1 — Nachtrag Geräteformular | 0:50 h | 1 | 03.09.2026 |
| **Summe** | **3:05 h** | **3** | |
| Phase 2 — Wartung und Prüfung | 2:25 h | 1 | 03.09.2026 |
| **Summe** | **5:30 h** | **4** | |
---
## 2026-09-03 · Phase 2 — Wartungs- und Prüfmanagement
**09:55 – 12:20 · 2:25 h · Version 0.3.0**
### Was entstanden ist
Das Modul, wegen dem eine Wehr so ein Programm überhaupt einführt. Ab hier
ersetzt FLORIAN den Ordner mit den Prüfnachweisen.
**Datenmodell.** Elf neue Tabellen: Wartungsvorlage und Checklistenpunkt als
Regel, Wartungstermin als deren Anwendung auf ein einzelnes Gerät, Prüfung mit
Einzelergebnissen und Unterschriften als Nachweis, dazu Mangel, Rückruf mit
betroffener Bauart und je Gerät ein Bearbeitungsstand, und schließlich
Erinnerung als Nachweis und Sperre gegen Doppelversand in einem.
**Fristen-Dashboard.** Vier Töpfe nach Dringlichkeit, jede Zahl gleichzeitig
ein Filter, darunter die Verteilung nach Fahrzeug, Standort, Gerätetyp oder
Zuständigem. Daneben die Lebensdauerüberwachung mit Aussonderungsvorschlag.
**Prüfwizard.** Ein Punkt je Bildschirm, Foto aus der Kamera, Zeiterfassung im
Hintergrund, Unterschrift auf einem Zeichenfeld. Jede Antwort geht sofort zum
Server; ein abgebrochener Durchgang wird beim nächsten Öffnen fortgesetzt.
**Protokoll.** Der Worker rendert über Gotenberg ein PDF mit Kopf, Checkliste,
eingebetteten Fotos und Unterschriften und legt es in MinIO ab. Laufende
Nummer je Wehr und Jahr.
**Nächtlicher Lauf.** Termine planen, Gerätestatus nachziehen, erinnern bei
T-30, T-7, T-0 und einmal bei Überfälligkeit — als Sammelnachricht je
Empfänger.
### Entscheidungen
**Die Unveränderbarkeit sitzt in der Datenbank, nicht im Code.** Ein Trigger
weist jede Änderung an einer abgeschlossenen Prüfung ab, auch für den
Eigentümer-Zugang. Zulässig bleiben drei Dinge, die das Protokoll ergänzen
statt es zu verfälschen: der Wechsel auf „ersetzt", das Nachtragen des PDF,
solange keines hinterlegt ist, und `geaendertAm`. Dasselbe gilt für die
Bestandteile — sonst ließe sich ein festgeschriebenes Protokoll über den Umweg
der Einzelergebnisse verändern.
Der Grund ist derselbe wie beim Audit-Log in Phase 0: ein vergessener
Zustandscheck in einem Router reicht sonst, um den Nachweis wertlos zu machen.
**„Überfällig" wird gerechnet, nicht gespeichert.** Ein gespeicherter Zustand
läuft der Uhr hinterher — ein Termin, der heute Nacht fällig geworden ist,
stünde bis zum nächsten Lauf als „offen" da. Aus demselben Grund kennt
`WartungsterminStatus` nur offen, erledigt und entfallen.
**Pflichtpunkt heißt: davon hängt die Einsatzbereitschaft ab.** Ein
beanstandeter Pflichtpunkt bedeutet „nicht bestanden" und sperrt das Gerät, ein
beanstandeter Kann-Punkt „bestanden mit Mängeln". Damit ist das Ergebnis eine
fachliche Aussage und keine Zählübung. Übersteuern darf der Prüfer trotzdem —
er trägt die Verantwortung, nicht die Software.
**Bestanden hebt eine bestehende Sperre nicht auf.** Wer ein Gerät gesperrt
hat, hatte einen Grund, und der kann außerhalb dieser Prüfung liegen. Von
selbst löst sich nur „Prüfung fällig".
**Melden darf jedes Mitglied.** Der Mangel fällt dem auf, der das Gerät
benutzt. Eine Hürde beim Melden führt dazu, dass gar nicht gemeldet wird — und
ein nicht gemeldeter Riss im Schlauch ist gefährlicher als eine Fehlmeldung,
die jemand wieder verwirft.
**Die Rückrufsuche ist ein Vorschlag.** Seriennummern werden als Text
verglichen; das stimmt bei gleicher Stellenzahl und sonst nicht immer. Eine
automatische Sperre auf dieser Grundlage wäre gefährlicher als hilfreich.
### Wo es gehakt hat
| Problem | Ursache | Lösung |
|---|---|---|
| Prisma wollte die Suchindizes aus Phase 1 löschen | gin_trgm- und gist-Indizes kennt das Schema nicht | die `DROP INDEX`-Zeilen aus der erzeugten Migration entfernt, mit Kommentar für den nächsten, der sie neu erzeugt |
| Der Seed brach beim Beispielprotokoll ab | er legte die Prüfung fertig an, und der Trigger verbot die Ergebnisse dazu | erst Entwurf, dann abschließen — genau wie im Wizard |
| Zwei gleichzeitig abgeschlossene Prüfungen zogen dieselbe Protokollnummer | die Nummer kam aus einer Zählung ohne Sperre | Transaktionssperre je Wehr und Jahr, Nummer aus dem Höchstwert statt aus der Anzahl |
| Der Worker startete außerhalb des Containers nicht | `.env` wurde nicht geladen, und `server-only` wirft unter Node | `dotenv/config` und `--conditions=react-server` in beiden Startbefehlen |
| Der Wizard-Test klickte ins Leere | die Mauskoordinaten beziehen sich auf das Fenster, das Zeichenfeld lag darunter | vor dem Zeichnen ins Bild holen |
| Zwei E2E-Projekte teilten sich denselben Prüfentwurf | Desktop und Tablet laufen parallel unter demselben Benutzer | je Projekt ein eigenes Gerät |
### Abweichung von der Vorgabe
**Keine.** Alle elf Tabellen tragen `organisationId` und stehen unter Row Level
Security, jede schreibende Operation protokolliert, gelöscht wird weich.
Eine Ergänzung zur Regel „Prüfdaten werden nie hart gelöscht": ein
**Prüfentwurf** darf verschwinden. Er ist noch kein Nachweis, sondern ein
abgebrochener Vorgang; ihn aufzuheben würde die Liste der offenen Prüfungen
zumüllen. Ab dem Abschluss greift die Sperre.
### Was aufgefallen ist
Der Navigationseintrag „Protokoll" (`/protokoll`) zeigt seit Phase 1 auf eine
Seite, die es nicht gibt. Das Audit-Log ist über tRPC abrufbar, hat aber keine
Ansicht. Gehört in ein eigenes Issue.
### Nachweise
- `npm run typecheck` — ohne Ausgabe
- `npm run test` — 161 Tests grün, davon 18 gegen eine echte Datenbank
- `npm run test:e2e` — 71 Tests grün, 2 begründet übersprungen (Desktop und Tablet)
- `npm run build` — 30 Routen
- `docker compose up -d` — Postgres, Redis, MinIO, Gotenberg gesund; Worker
richtet die Zeitpläne ein und erzeugt die Protokoll-PDFs in gut einer Sekunde
---
+17 -9
View File
@@ -11,7 +11,7 @@ Versionszuordnung: [VERSIONIERUNG.md](VERSIONIERUNG.md).
```
Phase 0 ████████████████████ fertig 0.1.0
Phase 1 ████████████████████ fertig 0.2.0
Phase 2 ░░░░░░░░░░░░░░░░░░░░ offen 0.3.0
Phase 2 ████████████████████ fertig 0.3.0
Phase 3 ░░░░░░░░░░░░░░░░░░░░ offen 0.4.0
Phase 4 ░░░░░░░░░░░░░░░░░░░░ offen 0.5.0
Phase 5 ░░░░░░░░░░░░░░░░░░░░ offen 0.6.0
@@ -59,23 +59,31 @@ Die Wehr trägt ein, was sie hat.
**Danach kann die Wehr:** ihren Bestand vollständig führen und jedes Gerät per
QR-Code am Regal wiederfinden.
## Phase 2 — Wartung und Prüfung · als Nächstes
## Phase 2 — Wartung und Prüfung · fertig
Das wichtigste Modul. Ab hier ersetzt FLORIAN den Ordner.
- Wartungsvorlagen mit Checklisten, Intervall und Vorwarnzeit
- Fristen-Dashboard: überfällig / diese Woche / diesen Monat / nächste 90 Tage
- Nächtlicher Job erzeugt Termine, setzt Status, erinnert bei T-30, T-7 und T-0
- Prüfungs-Wizard mit Foto je Checklistenpunkt, Zeiterfassung und Unterschrift
- PDF-Prüfprotokoll über Gotenberg, unveränderlich in MinIO
- Fristen-Dashboard: überfällig / diese Woche / diesen Monat / nächste 90 Tage,
gebündelt nach Fahrzeug, Standort, Gerätetyp oder Zuständigem
- Nächtlicher Lauf erzeugt Termine, zieht den Gerätestatus nach und erinnert bei
T-30, T-7, T-0 und einmal bei Überfälligkeit
- Prüfwizard mit Foto je Checklistenpunkt, Zeiterfassung und Unterschrift auf
dem Zeichenfeld
- PDF-Prüfprotokoll über Gotenberg, unveränderlich in MinIO — die Sperre setzt
ein Datenbanktrigger durch, nicht der Anwendungscode
- Korrekturen erzeugen ein neues Protokoll mit Verweis auf das alte
- Lebensdauerüberwachung mit Aussonderungsvorschlag
- Rückrufe markieren betroffene Geräte automatisch
- Mängel-Workflow: melden → zugewiesen → in Arbeit → behoben
- Rückrufe suchen betroffene Geräte über Bauart, Modell, Seriennummernbereich
und Herstellungszeitraum
- Mängel-Workflow: melden → zugewiesen → in Arbeit → behoben, mit
Gerätesperre bei kritischen Mängeln
- Externe Wartung: Fachfirma, Kosten und Fremdprotokoll als PDF
**Danach kann die Wehr:** einen DGUV-Nachweis führen, der einer Prüfung durch
die Unfallkasse standhält.
## Phase 3 — Einsätze und Übungen
## Phase 3 — Einsätze und Übungen · als Nächstes
- Einsatz mit allen Zeitstempeln: alarmiert, ausgerückt, eingetroffen,
Einsatzende, eingerückt, einsatzbereit
Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 KiB

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 KiB

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

After

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 KiB

After

Width:  |  Height:  |  Size: 409 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 KiB

After

Width:  |  Height:  |  Size: 419 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 727 KiB

After

Width:  |  Height:  |  Size: 728 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 746 KiB

After

Width:  |  Height:  |  Size: 751 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 KiB

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 KiB

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 962 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB