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:
co-authored by
Claude Opus 5
parent
7f866ac35c
commit
e503aafc18
@@ -25,7 +25,7 @@ Anmelden mit `SEED_ADMIN_EMAIL` und `SEED_ADMIN_PASSWORT` aus der `.env`
|
||||
|---|---|
|
||||
| Phase 0 — Fundament | fertig |
|
||||
| Phase 1 — Stammdaten | fertig |
|
||||
| Phase 2 — Wartung und Prüfung | offen |
|
||||
| Phase 2 — Wartung und Prüfung | fertig |
|
||||
| Phase 3 — Einsätze und Übungen | offen |
|
||||
| Phase 4 — Kiosk-PWA | offen |
|
||||
| Phase 5 — Atemschutz (FwDV 7) | offen |
|
||||
@@ -152,6 +152,133 @@ ausschließlich über [`src/lib/storage.ts`](src/lib/storage.ts). Objektschlüss
|
||||
Downloads laufen über presignte Links mit begrenzter Gültigkeit
|
||||
(`S3_URL_TTL`, Vorgabe 15 Minuten).
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Wartung und Prüfung
|
||||
|
||||
Das Modul, wegen dem eine Wehr so ein Programm überhaupt einführt: Prüffristen
|
||||
im Blick behalten und im Streitfall nachweisen können, dass geprüft wurde.
|
||||
|
||||
### Der Weg durch das Modul
|
||||
|
||||
```
|
||||
Wartungsvorlage was an einem Gerätetyp in welchem Takt geprüft wird
|
||||
└─ Checklistenpunkt die einzelne Frage: ja/nein, Messwert, Text, Foto
|
||||
↓ nächtlicher Lauf
|
||||
Wartungstermin ein fälliger Termin an einem konkreten Gerät
|
||||
↓ Prüfwizard
|
||||
Pruefung durchgeführte Prüfung, unterschrieben, festgeschrieben
|
||||
├─ Pruefergebnis je Checklistenpunkt eine Antwort
|
||||
├─ Signatur Unterschrift aus dem Zeichenfeld, PNG in MinIO
|
||||
└─ Mangel was aufgefallen ist und behoben werden muss
|
||||
```
|
||||
|
||||
Ohne Vorlage gibt es keine Termine, ohne Termine kein Fristen-Dashboard. Die
|
||||
erste Seite, die eine Wehr in Phase 2 ausfüllt, ist deshalb
|
||||
`/pruefungen/vorlagen`.
|
||||
|
||||
### Das Protokoll ist unveränderbar
|
||||
|
||||
Ein abgeschlossenes Prüfprotokoll ist der Nachweis gegenüber der Unfallkasse.
|
||||
Wäre es nachträglich änderbar, wäre es als Nachweis wertlos. Die Sperre sitzt
|
||||
deshalb in der Datenbank (Trigger `pruefung_unveraenderlich`, Migration
|
||||
`20260903000300_wartung_rls`) und nicht nur im Anwendungscode — ein vergessener
|
||||
Zustandscheck in einem Router würde sonst reichen, um sie auszuhebeln.
|
||||
|
||||
Nach dem Abschluss sind genau drei Änderungen zulässig, und alle drei ergänzen
|
||||
das Protokoll, statt es zu verfälschen:
|
||||
|
||||
| Änderung | Warum |
|
||||
|---|---|
|
||||
| `ABGESCHLOSSEN` → `ERSETZT` | eine Korrekturprüfung ist nachgefolgt |
|
||||
| `protokollDateiId`, solange leer | das PDF entsteht im Hintergrund und wird nachgetragen |
|
||||
| `geaendertAm` | setzt Prisma bei jedem Schreibvorgang mit |
|
||||
|
||||
Dasselbe gilt für die Bestandteile: an einem abgeschlossenen Protokoll lassen
|
||||
sich weder Einzelergebnisse ändern noch Unterschriften nachtragen. **Korrekturen
|
||||
erzeugen eine neue Prüfung** mit Verweis auf die alte; beide bleiben lesbar.
|
||||
|
||||
Gelöscht wird ein Protokoll nie — außer im ausdrücklich gekennzeichneten
|
||||
Aufbewahrungslauf, demselben Schalter wie beim Audit-Log
|
||||
(`SET LOCAL app.audit_bereinigung = 'an'`).
|
||||
|
||||
### Der nächtliche Lauf
|
||||
|
||||
Der Worker trägt sich beim Start je Wehr zwei wiederkehrende Aufträge ein:
|
||||
|
||||
| Auftrag | Vorgabe | Was er tut |
|
||||
|---|---|---|
|
||||
| `fristen.pruefen` | 03:15 Uhr | Termine aus den Vorlagen planen, Frist und Status an jedem Gerät nachziehen |
|
||||
| `erinnerung.senden` | 03:45 Uhr | Vorwarnungen zu offenen Terminen verschicken |
|
||||
|
||||
Beide sind wiederholbar: doppelte Termine verhindert die Eindeutigkeit über
|
||||
Gerät, Vorlage und Fälligkeitstag, doppelte Mails ein Erinnerungseintrag je
|
||||
Termin und Stufe. Erinnert wird bei T-30 (bzw. der Vorwarnzeit der Vorlage),
|
||||
T-7, T-0 und einmal bei Überfälligkeit — als **eine** Sammelnachricht je
|
||||
Empfänger, nicht als eine Mail je Gerät.
|
||||
|
||||
„Überfällig" ist bewusst kein gespeicherter Zustand, sondern wird aus dem
|
||||
Fälligkeitsdatum und dem heutigen Tag gerechnet. Gespeicherte Zustände laufen
|
||||
der Uhr hinterher; berechnete nicht.
|
||||
|
||||
### Prüfwizard
|
||||
|
||||
Zugeschnitten auf das Tablet im Gerätehaus: ein Prüfpunkt je Bildschirm, große
|
||||
Schaltflächen, Foto direkt aus der Kamera, Unterschrift auf einem Zeichenfeld,
|
||||
das Finger, Stift und Maus gleichermaßen versteht.
|
||||
|
||||
Jede Antwort geht sofort zum Server. Bricht das WLAN weg, ist höchstens die
|
||||
letzte Antwort verloren, nicht die ganze Prüfung — beim erneuten Öffnen wird der
|
||||
Entwurf fortgesetzt.
|
||||
|
||||
Die Bewertung rechnet der Server, nicht der Browser
|
||||
([`src/lib/wartung/bewertung.ts`](src/lib/wartung/bewertung.ts)):
|
||||
|
||||
- ein Messwert außerhalb des zulässigen Bereichs gilt als beanstandet,
|
||||
- ein beanstandeter **Pflichtpunkt** bedeutet „nicht bestanden" und sperrt das
|
||||
Gerät,
|
||||
- ein beanstandeter Kann-Punkt bedeutet „bestanden mit Mängeln".
|
||||
|
||||
Das Ergebnis ist ein Vorschlag; die Entscheidung trifft der Prüfer, denn er
|
||||
trägt die Verantwortung.
|
||||
|
||||
### Prüfprotokoll als PDF
|
||||
|
||||
Erzeugt der Worker über Gotenberg
|
||||
([`src/lib/wartung/protokoll.ts`](src/lib/wartung/protokoll.ts)) und legt es in
|
||||
MinIO ab. Kopf mit Wehr, Gerät und Prüfer-Kennung, die Checkliste mit Soll, Ist
|
||||
und Befund, eingebettete Fotos und Unterschriften, Fußzeile mit Prüfvorschrift,
|
||||
Prüfdatum und Seitenzahl.
|
||||
|
||||
Alles ist eingebettet — keine externen Schriften, keine nachgeladenen Bilder.
|
||||
Ein Protokoll muss in zehn Jahren noch genauso aussehen wie heute.
|
||||
|
||||
Die laufende Protokollnummer (`JJJJ-NNNN`) wird je Wehr und Jahr unter einer
|
||||
Transaktionssperre vergeben; zwei gleichzeitig abschließende Prüfer bekommen
|
||||
verschiedene Nummern.
|
||||
|
||||
### Mängel und Rückrufe
|
||||
|
||||
Der Mängelweg ist immer derselbe: melden → zugewiesen → in Arbeit → behoben.
|
||||
**Melden darf jedes Mitglied** — der Mangel fällt dem auf, der das Gerät
|
||||
benutzt, nicht dem Gerätewart am Schreibtisch. Ein kritischer Mangel sperrt das
|
||||
Gerät sofort; beim Beheben wird die Sperre wieder aufgehoben, aber nur, wenn
|
||||
kein anderer offener Mangel dasselbe Gerät sperrt.
|
||||
|
||||
Bei einem Rückruf sucht FLORIAN anhand von Bauart, Modell, Seriennummernbereich
|
||||
und Herstellungszeitraum nach betroffenen Geräten. Das Ergebnis ist ein
|
||||
**Vorschlag**, keine automatische Sperre: eine Chargenangabe des Herstellers
|
||||
passt selten eins zu eins auf die Seriennummern im eigenen Bestand.
|
||||
|
||||
### Zusätzliche Umgebungsvariablen
|
||||
|
||||
| Variable | Vorgabe | Bedeutung |
|
||||
|---|---|---|
|
||||
| `WARTUNG_NACHTLAUF` | `15 3 * * *` | wann Termine geplant werden (cron, Europe/Berlin) |
|
||||
| `WARTUNG_ERINNERUNG_LAUF` | `45 3 * * *` | wann Erinnerungen verschickt werden |
|
||||
| `WARTUNG_PLANUNGSHORIZONT_TAGE` | `180` | wie weit im Voraus Termine angelegt werden |
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Befehle
|
||||
|
||||
Reference in New Issue
Block a user