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>
756 lines
29 KiB
Markdown
756 lines
29 KiB
Markdown
# Anleitung
|
||
|
||
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.
|
||
|
||
> Einsätze, Atemschutz und die Kiosk-Oberfläche kommen in den folgenden Phasen
|
||
> dazu. Siehe [ROADMAP.md](ROADMAP.md).
|
||
|
||
---
|
||
|
||
## 1. Anmelden
|
||
|
||
Aufgerufen wird FLORIAN im Browser unter der Adresse, die der Administrator
|
||
eingerichtet hat — in der Entwicklung `http://localhost:3100`.
|
||
|
||

|
||
|
||
Die Anmeldeseite zeigt genau die Wege, die in dieser Installation eingerichtet
|
||
sind:
|
||
|
||
| Weg | Wann |
|
||
|---|---|
|
||
| **Anmeldung über authentik** | Der Regelweg, sobald authentik eingerichtet ist. Ein Klick, keine Passworteingabe in FLORIAN. |
|
||
| **E-Mail und Passwort** | Beim Erststart, und wenn authentik gerade nicht erreichbar ist. |
|
||
| **Terminal im Gerätehaus** | Am Wandtablet, mit PIN oder Ausweiskarte. Eigene Oberfläche, kommt in Phase 4. |
|
||
|
||
Beim allerersten Start gibt es genau ein Konto: das aus `SEED_ADMIN_EMAIL` und
|
||
`SEED_ADMIN_PASSWORT` in der `.env`. Vorgabe:
|
||
|
||
```
|
||
admin@beispielwehr.de
|
||
Feuerwehr2026
|
||
```
|
||
|
||
**Dieses Passwort gehört nach dem ersten Login geändert.**
|
||
|
||
### Wenn die Anmeldung nicht klappt
|
||
|
||
Nach mehreren Fehlversuchen wird das Konto vorübergehend gesperrt — voreingestellt
|
||
nach fünf Versuchen für fünf Minuten (`KIOSK_MAX_FEHLVERSUCHE`,
|
||
`KIOSK_SPERRDAUER`). Die Meldung nennt nicht, ob die E-Mail-Adresse oder das
|
||
Passwort falsch war; das ist Absicht und verhindert, dass sich vorhandene
|
||
Konten erraten lassen.
|
||
|
||
---
|
||
|
||
## 2. Die Übersicht
|
||
|
||
Nach der Anmeldung steht die Übersicht der eigenen Wehr.
|
||
|
||

|
||
|
||
Von oben nach unten:
|
||
|
||
**Kopfzeile.** Name der Wehr und darunter, wer angemeldet ist und mit welchen
|
||
Rollen. Wer mehrere Rollen trägt — der Gerätewart ist oft auch Ausbilder —
|
||
sieht alle.
|
||
|
||
**Sicherheitshinweis.** Der gelbe Kasten bleibt stehen, solange die Wehr die
|
||
Anwendung nicht ausdrücklich freigegeben hat. Er ist keine Formalität:
|
||
Atemschutzüberwachung und Alarmmonitor sind sicherheitsrelevant, und bis zur
|
||
Freigabe bleibt die analoge Überwachung führend.
|
||
|
||
**Kennzahlen.** Vier Kacheln mit aktiven Mitgliedern, Fahrzeugen, Geräten und
|
||
fälligen Prüfungen. Sie zählen nur die eigene Wehr — was eine andere Wehr auf
|
||
derselben Installation hat, ist nicht sichtbar und nicht abfragbar.
|
||
|
||
**Stand des Aufbaus.** Welche Phasen fertig sind und was als Nächstes kommt.
|
||
|
||
### Die Seitenleiste
|
||
|
||
Links stehen alle Module. Was noch nicht existiert, ist ausgegraut und trägt
|
||
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:
|
||
das Ausblenden ist nur Bequemlichkeit. Der eigentliche Schutz sitzt auf dem
|
||
Server — wer eine Adresse direkt aufruft, für die ihm das Recht fehlt, bekommt
|
||
trotzdem nichts.
|
||
|
||
---
|
||
|
||
## 3. Helle und dunkle Darstellung
|
||
|
||
Oben rechts wird zwischen hell und dunkel umgeschaltet. Voreingestellt ist die
|
||
Einstellung des Betriebssystems.
|
||
|
||

|
||
|
||
Die dunkle Darstellung ist bewusst kein invertiertes Schwarz, sondern ein
|
||
warmes Grau. Wer abends vom Fahrzeug hereinkommt und ans Terminal tritt, soll
|
||
nicht geblendet werden.
|
||
|
||
---
|
||
|
||
## 4. Geräte
|
||
|
||

|
||
|
||
Die Geräteliste ist die Ansicht, die am häufigsten offen ist. Von links nach
|
||
rechts steht dort, was man beim Suchen braucht: Inventarnummer, was es ist, von
|
||
wem, wo es liegt, in welchem Zustand und wann es wieder geprüft werden muss.
|
||
|
||
### Suchen und filtern
|
||
|
||
**Das Suchfeld** durchsucht Inventarnummer, Bezeichnung, Hersteller, Modell und
|
||
Seriennummer gleichzeitig. Es genügt ein Teil — „press" findet alle
|
||
Pressluftatmer. Gesucht wird erst, wenn man kurz aufhört zu tippen; das
|
||
verhindert eine Abfrage bei jedem Anschlag.
|
||
|
||
**Alle Zustände** schränkt auf einen Status ein. Praktisch, wenn man wissen
|
||
will, was gerade fällig oder gesperrt ist.
|
||
|
||
**Spalten** blendet Spalten ein und aus. Zwölf stehen zur Auswahl, sechs sind
|
||
voreingestellt. Die Auswahl bleibt im Browser gespeichert — der Gerätewart
|
||
schaut auf Prüftermine, der Kassier auf Anschaffungspreise, und beide finden
|
||
ihre Einstellung beim nächsten Mal wieder.
|
||
|
||
**Sortiert** wird durch einen Klick auf die Spaltenüberschrift, ein zweiter
|
||
Klick dreht die Richtung um.
|
||
|
||
### Farben und Fristen
|
||
|
||
| Farbe | Bedeutung |
|
||
|---|---|
|
||
| grün | einsatzbereit |
|
||
| gelb | Prüfung fällig, oder eine Frist läuft in den nächsten 30 Tagen ab |
|
||
| rot | gesperrt, ausgesondert oder überfällig |
|
||
| grau | in Reparatur |
|
||
|
||
Hinter jedem Datum steht, wie viele Tage noch bleiben — „in 12 Tagen" sagt mehr
|
||
als ein Datum, das man erst im Kopf ausrechnen muss. Was vorbei ist, steht als
|
||
„seit 62 Tagen" da.
|
||
|
||
Die Farbe allein trägt nie die Information: daneben steht immer Klartext.
|
||
|
||
### Mehrere Geräte auf einmal
|
||
|
||
Über die Kästchen links lassen sich Geräte auswählen. Sobald mindestens eines
|
||
ausgewählt ist, erscheint eine Leiste mit zwei Möglichkeiten:
|
||
|
||
- **Etiketten drucken** erzeugt den Etikettenbogen als PDF.
|
||
- **Status setzen auf …** ändert den Zustand aller ausgewählten Geräte. Der
|
||
häufigste Handgriff überhaupt: Nach einer Sammelprüfung stehen zwanzig Geräte
|
||
auf einmal wieder auf einsatzbereit.
|
||
|
||
Jede Änderung wird einzeln protokolliert — am jeweiligen Gerät, nicht als
|
||
Sammelvorgang, den später niemand mehr zuordnen kann.
|
||
|
||
---
|
||
|
||
## 5. Ein einzelnes Gerät
|
||
|
||

|
||
|
||
### Woher das Prüfintervall kommt
|
||
|
||
Steht am Gerät kein eigenes Intervall, gilt die Vorgabe des Gerätetyps. Das
|
||
Bild zeigt es: „alle 12 Monate (aus dem Gerätetyp)". So muss man bei vierzig
|
||
Pressluftatmern nicht vierzigmal dasselbe eintragen. Schreibt der Hersteller
|
||
für eine bestimmte Charge etwas anderes vor, wird der Wert am Gerät gesetzt und
|
||
gewinnt dann.
|
||
|
||
Dasselbe gilt für die Lebensdauer. Ob sie ab Herstellung oder ab
|
||
Indienststellung zählt, hängt von der Vorschrift ab: Seile und Druckbehälter
|
||
altern ab Herstellung, Schutzkleidung meist ab Indienststellung.
|
||
|
||
### QR-Code
|
||
|
||
Rechts steht der QR-Code des Geräts. **Etikett drucken** erzeugt daraus einen
|
||
Aufkleber für den Geräteraum.
|
||
|
||
Der Code zeigt auf `.../g/<Inventarnummer>`. Wer ihn scannt und angemeldet ist,
|
||
landet direkt auf dieser Seite. Wer nicht angemeldet ist, landet zuerst auf der
|
||
Anmeldung und danach hier — **der Aufkleber ist keine Berechtigung.** Wer ihn
|
||
fotografiert, bekommt dadurch keinen Zugang.
|
||
|
||
Bewusst steht die Inventarnummer im Code und nicht die interne Kennung: Eine
|
||
UUID wäre 36 Zeichen lang, das Muster entsprechend fein, und auf einem
|
||
38 × 21 mm großen Aufkleber im staubigen Geräteraum wird das unzuverlässig.
|
||
|
||
### Verlauf
|
||
|
||
Unten steht, was mit dem Gerät passiert ist — direkt aus dem Audit-Log. Es gibt
|
||
bewusst keine zweite Historie: zwei Quellen könnten auseinanderlaufen.
|
||
|
||
---
|
||
|
||
## 5a. Ein Gerät anlegen oder ändern
|
||
|
||

|
||
|
||
Über **Neues Gerät** in der Geräteliste, oder über **Bearbeiten** auf der
|
||
Detailseite eines vorhandenen Geräts. Für größere Bestände ist der Import der
|
||
schnellere Weg; dieses Formular ist für den Neuzugang zwischendurch.
|
||
|
||
Pflicht sind nur zwei Angaben: **Inventarnummer** und **Bezeichnung**. Alles
|
||
andere kann später nachgetragen werden.
|
||
|
||
### Der Gerätetyp nimmt Arbeit ab
|
||
|
||
Wird oben ein Gerätetyp gewählt, gelten dessen Prüfintervall, Prüfvorschrift
|
||
und Lebensdauer — man muss sie nicht eintragen. Die Felder darunter bleiben
|
||
trotzdem änderbar: Was dort steht, überschreibt die Vorgabe für dieses eine
|
||
Gerät. Das braucht man, wenn der Hersteller für eine bestimmte Charge etwas
|
||
anderes vorschreibt.
|
||
|
||
Ist die Bezeichnung noch leer, wird sie aus dem Typ übernommen.
|
||
|
||
### „Daraus ergibt sich"
|
||
|
||
Der graue Kasten zeigt, was aus den Angaben folgt: wann die nächste Prüfung
|
||
fällig wird und wann die Nutzungsdauer endet. Er rechnet beim Tippen mit,
|
||
sodass man vor dem Speichern sieht, was herauskommt. Gerechnet wird mit
|
||
denselben Regeln wie auf dem Server — beim Speichern rechnet dieser erneut und
|
||
behält das letzte Wort.
|
||
|
||
Steht dort „keine", fehlt entweder das Prüfintervall oder die Indienststellung.
|
||
Das ist kein Fehler: Für Geräte ohne Prüfpflicht ist es der Normalfall.
|
||
|
||
### Wo liegt es?
|
||
|
||
Entweder an einem Standort **oder** auf einem Fahrzeug. Der Umschalter lässt
|
||
nur eines von beidem zu — deshalb kann hier gar nicht erst der Fehler
|
||
entstehen, den die Datenbank sonst abweisen würde.
|
||
|
||
Bei „Auf einem Fahrzeug" lässt sich zusätzlich der Geräteraum angeben. Er darf
|
||
leer bleiben: Manches liegt lose in der Kabine. Wird das Fahrzeug gewechselt,
|
||
wird die Raumangabe zurückgesetzt — der Raum gehört zum Fahrzeug.
|
||
|
||
Gibt es in der Wehr nur einen Standort, ist er beim Anlegen schon ausgewählt.
|
||
|
||
> Jede Änderung landet im Verlauf des Geräts. Wer wissen will, wann ein
|
||
> Prüftermin verschoben wurde und von wem, findet es dort.
|
||
|
||
---
|
||
|
||
## 6. Etiketten drucken
|
||
|
||
Der Bogen ist auf das gängige Format mit **65 Etiketten je DIN-A4-Seite**
|
||
(38,1 × 21,2 mm, 5 Spalten × 13 Zeilen) ausgelegt — den gibt es in jedem
|
||
Schreibwarenladen und er passt in jeden Laserdrucker.
|
||
|
||
Auf jedem Etikett stehen drei Dinge: der QR-Code, die Inventarnummer zum
|
||
Ablesen ohne Handy, und die Bezeichnung. Bei verlasteten Geräten kommt der
|
||
Funkrufname des Fahrzeugs dazu.
|
||
|
||
Der Druck kann an einer beliebigen Position des Bogens beginnen. Wer drei
|
||
Etiketten braucht, muss so keinen ganzen Bogen opfern.
|
||
|
||
> Erzeugt wird das PDF von Gotenberg, einem eigenen Container im Stack. Kommt
|
||
> die Meldung „Der Etikettenbogen ließ sich nicht erzeugen", läuft er nicht:
|
||
> `docker compose ps` zeigt es.
|
||
|
||
---
|
||
|
||
## 7. Gerät scannen
|
||
|
||
Über **Scannen** in der Geräteliste öffnet sich der QR-Scanner. Der Browser
|
||
fragt beim ersten Mal nach der Kamerafreigabe. Das Bild verlässt das Gerät
|
||
nicht — ausgewertet wird direkt im Browser.
|
||
|
||
Zwei Dinge sind bewusst so gebaut:
|
||
|
||
- **Es geht immer auch ohne Kamera.** Darunter steht ein Eingabefeld für die
|
||
Inventarnummer. Wenn die Freigabe verweigert wurde oder das Etikett zerkratzt
|
||
ist, tippt man sie ein.
|
||
- **Fremde Codes brechen nichts ab.** Der Barcode des Herstellers klebt oft
|
||
direkt daneben. Wird er erkannt, kommt ein Hinweis statt einer Fehlermeldung.
|
||
|
||
---
|
||
|
||
## 8. Fahrzeuge
|
||
|
||

|
||
|
||
Die Übersicht zeigt die Fahrzeuge als Kacheln — eine Wehr hat drei bis zehn,
|
||
nicht dreihundert. Auf jeder Kachel stehen der nächste TÜV-Termin und die Zahl
|
||
der verlasteten Geräte.
|
||
|
||
Auf der Detailseite steht die **Beladung nach Geräteräumen**, in der Reihenfolge
|
||
der Beladeordnung: G1 bis G6, Heck, Dach, Mannschaftsraum. Genau so sucht der
|
||
Gerätewart — nicht „wo ist die Motorsäge", sondern „was ist in G3".
|
||
|
||
Beim Anlegen eines neuen Fahrzeugs werden diese Räume auf Wunsch gleich
|
||
mitangelegt. Ein Mannschaftstransportwagen bekommt weniger Fächer als ein
|
||
Löschfahrzeug.
|
||
|
||
Ein Gerät liegt **entweder** an einem Standort **oder** auf einem Fahrzeug.
|
||
Beides gleichzeitig lässt die Datenbank nicht zu — das ist keine Formalität,
|
||
sondern verhindert, dass ein Gerät zweimal gezählt wird.
|
||
|
||
Was verlastet ist, aber keinem Raum zugeordnet wurde, erscheint unter „Ohne
|
||
Raumangabe" statt stillschweigend zu verschwinden.
|
||
|
||
---
|
||
|
||
## 9. Mitglieder und Qualifikationen
|
||
|
||

|
||
|
||
Die Mitgliederliste ist nach Abteilung gruppiert — Aktive, Jugendfeuerwehr,
|
||
Passive. Eine durchlaufende alphabetische Liste vermischt Gruppen, die in der
|
||
Wehr nichts miteinander zu tun haben.
|
||
|
||
Auf der Seite **Qualifikationen** steht oben, was abgelaufen ist oder demnächst
|
||
abläuft. Das ist der Grund, warum jemand diese Seite öffnet.
|
||
|
||
**Gewarnt wird mit der Vorwarnzeit des jeweiligen Typs**, nicht mit einer
|
||
pauschalen Frist. Eine G26.3-Untersuchung braucht 120 Tage Vorlauf, weil erst
|
||
ein Termin beim Betriebsarzt gefunden werden muss; eine jährliche Unterweisung
|
||
kommt mit deutlich weniger aus. Einsatzrelevante Qualifikationen sind
|
||
gekennzeichnet.
|
||
|
||
Das Ablaufdatum wird beim Speichern aus der Gültigkeitsdauer des Typs
|
||
gerechnet — lässt sich aber überschreiben. Auf einer Urkunde steht manchmal
|
||
etwas anderes, als die Regel hergäbe.
|
||
|
||
---
|
||
|
||
## 10. Daten importieren
|
||
|
||

|
||
|
||
Der Import geht in drei Schritten, und der mittlere ist der eigentliche Punkt.
|
||
|
||
### Schritt 1: Datei wählen
|
||
|
||
CSV oder Excel (`.xlsx`). Die erste Zeile muss die Spaltenüberschriften
|
||
enthalten. Höchstens 10 MB und 5.000 Zeilen.
|
||
|
||
Erkannt werden die Formate, die in der Praxis herauskommen:
|
||
|
||
| Fall | Wird verstanden |
|
||
|---|---|
|
||
| Trennzeichen | Semikolon, Komma, Tabulator, senkrechter Strich |
|
||
| Zeichensatz | UTF-8 (auch mit BOM) und Windows-1252 |
|
||
| Datum | 02.09.2026, 2.9.26, 2026-09-02, und die Seriennummer aus Excel |
|
||
| Zahlen | 1.234,56 und 1,234.56, mit und ohne Eurozeichen |
|
||
| Ja/Nein | ja, j, x, 1, wahr — und die Gegenstücke |
|
||
|
||
### Schritt 2: Zuordnung prüfen
|
||
|
||
FLORIAN rät die Zuordnung anhand der Überschriften. „Inv.-Nr." landet bei
|
||
Inventarnummer, „Fabrikat" bei Hersteller. Jede Zuordnung lässt sich ändern,
|
||
und die Vorschau passt sich sofort an.
|
||
|
||
**Die Vorschau ist der Grund, warum es diesen Zwischenschritt gibt.** Sie zeigt
|
||
Zeile für Zeile, was übernommen würde, und markiert rot, was nicht stimmt:
|
||
fehlende Pflichtfelder, unlesbare Daten, Inventarnummern, die in der Datei
|
||
doppelt vorkommen. Eine falsch zugeordnete Spalte verteilt sonst Seriennummern
|
||
auf Inventarnummern, und das merkt man erst Wochen später am Regal.
|
||
|
||
### Schritt 3: Übernehmen
|
||
|
||
Übernommen wird nur, was fehlerfrei ist. Zeilen mit Fehlern bleiben in der
|
||
Datei und lassen sich nach der Korrektur erneut einlesen.
|
||
|
||
**Vorhandene Datensätze aktualisieren** entscheidet, was mit Datensätzen
|
||
passiert, die es schon gibt: überspringen (Vorgabe) oder überschreiben.
|
||
Erkannt werden sie über die Inventarnummer, bei Mitgliedern über die
|
||
Mitgliedsnummer oder die E-Mail-Adresse.
|
||
|
||
Zum Schluss steht da, wie viele Datensätze angelegt, aktualisiert und
|
||
übersprungen wurden. Der ganze Vorgang steht auch im Protokoll.
|
||
|
||
---
|
||
|
||
---
|
||
|
||
## 11. Prüfungen und Fristen
|
||
|
||

|
||
|
||
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
|
||
|
||

|
||
|
||
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
|
||
|
||

|
||
|
||
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
|
||
|
||

|
||
|
||
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
|
||
|
||

|
||
|
||
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
|
||
|
||

|
||
|
||
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
|
||
|
||

|
||
|
||
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
|
||
kann sie also nachträglich zuschneiden, ohne dass jemand Code ändert.
|
||
|
||
| Rolle | Darf im Kern |
|
||
|---|---|
|
||
| **Administrator** | alles, auch über Wehren hinweg |
|
||
| **Kommandant** | alles innerhalb der eigenen Wehr, einschließlich Rollen vergeben und Protokoll einsehen |
|
||
| **Gerätewart** | Fahrzeuge und Geräte anlegen, ändern, aussondern; Prüfungen planen und durchführen |
|
||
| **Atemschutzgerätewart** | zusätzlich Atemschutzgeräte, Träger und die Überwachung nach FwDV 7 |
|
||
| **Kassier** | Buchungen und Kassenabschluss (Modul noch nicht geplant, siehe Roadmap) |
|
||
| **Schriftführer** | Mitglieder pflegen, Einsätze und Berichte erfassen |
|
||
| **Ausbilder** | Übungen planen, Teilnahme und Qualifikationen erfassen |
|
||
| **Mitglied** | eigene Daten, Listen lesen |
|
||
| **Terminal** | nur anmelden und erfassen — nie verwalten |
|
||
|
||
Zwei Dinge sind bewusst so gebaut:
|
||
|
||
**Der Gerätewart kommt nicht an die Kasse, der Kassier nicht an die Geräte.**
|
||
Trennung nach Verantwortung, nicht nach Bequemlichkeit.
|
||
|
||
**Das Terminal darf fast nichts.** Wer am Wandtablet arbeitet, meldet sich
|
||
zusätzlich mit PIN oder Karte an und handelt dann unter seiner eigenen Person.
|
||
Das Terminal selbst ist nur die Tür.
|
||
|
||
---
|
||
|
||
## 19. Anmeldung über authentik einrichten
|
||
|
||
authentik läuft **getrennt** von FLORIAN und ist nicht Teil dieses Stacks.
|
||
|
||
### In authentik
|
||
|
||
1. Neuen Provider anlegen, Typ **OAuth2/OpenID Provider**
|
||
2. Client-Typ: **Confidential**
|
||
3. Redirect-URI genau so eintragen:
|
||
```
|
||
https://<ihre-florian-adresse>/api/auth/callback/authentik
|
||
```
|
||
4. Scopes: `openid`, `profile`, `email`
|
||
5. Für die Rollenvorbelegung zusätzlich ein Scope-Mapping, das die Gruppen des
|
||
Benutzers als Claim `groups` ausliefert
|
||
6. Eine Application anlegen und mit dem Provider verbinden. Der Slug der
|
||
Application ist der letzte Teil der Issuer-URL.
|
||
|
||
### In der `.env`
|
||
|
||
```bash
|
||
AUTH_OIDC_ENABLED=true
|
||
AUTH_OIDC_ISSUER=https://auth.beispiel.de/application/o/florian/
|
||
AUTH_OIDC_CLIENT_ID=<aus authentik>
|
||
AUTH_OIDC_CLIENT_SECRET=<aus authentik>
|
||
AUTH_OIDC_GROUP_CLAIM=groups
|
||
AUTH_OIDC_GROUP_MAPPING=feuerwehr-kommandant:KOMMANDANT,feuerwehr-geraetewart:GERAETEWART
|
||
AUTH_OIDC_AUTO_PROVISION=true
|
||
AUTH_OIDC_STANDARD_ORGANISATION=ff-musterhausen
|
||
```
|
||
|
||
Danach die Anwendung neu starten. Auf der Anmeldeseite erscheint der Knopf für
|
||
authentik.
|
||
|
||
### Wie die Rollenvorbelegung wirkt
|
||
|
||
Die Zuordnung greift **nur beim allerersten Login** einer Person. Danach ist
|
||
die in FLORIAN gepflegte Rolle führend, und authentik überschreibt sie nicht
|
||
mehr. Wer also einem Mitglied in FLORIAN die Rolle „Gerätewart" gibt, behält
|
||
sie — auch wenn die authentik-Gruppe etwas anderes sagt.
|
||
|
||
Steht `AUTH_OIDC_AUTO_PROVISION=false`, muss die Person vorher in FLORIAN
|
||
angelegt sein. Verknüpft wird über die E-Mail-Adresse.
|
||
|
||
### Wenn authentik ausfällt
|
||
|
||
Solange `AUTH_LOCAL_ENABLED=true` steht, bleibt der Passwort-Login als
|
||
Rückfallweg erreichbar. Für den Wirkbetrieb ist es sinnvoll, mindestens ein
|
||
Konto mit Passwort zu behalten — sonst sperrt ein Ausfall von authentik die
|
||
ganze Wehr aus.
|
||
|
||
---
|
||
|
||
## 20. Terminal-Anmeldung im Gerätehaus
|
||
|
||
Die Oberfläche dazu kommt in Phase 4; der Anmeldeweg steht bereits.
|
||
|
||
Am Terminal wird zweifach geprüft:
|
||
|
||
1. **Das Gerät** weist sich mit `KIOSK_DEVICE_SECRET` aus. Ohne diesen Wert
|
||
nimmt der Server keine PIN und keine Karte an.
|
||
2. **Die Person** meldet sich mit einer sechsstelligen PIN (zusammen mit ihrer
|
||
Mitgliedsnummer) oder mit einer RFID-Karte an.
|
||
|
||
Beides wird nur als Hash gespeichert — weder die PIN noch die Kartenkennung
|
||
liegen im Klartext in der Datenbank.
|
||
|
||
PINs, die sich zu leicht raten lassen, weist FLORIAN ab: lauter gleiche
|
||
Ziffern und fortlaufende Folgen wie `123456`.
|
||
|
||
Aus dem Seed lässt sich das ausprobieren: Mitgliedsnummer `0001` (Andreas
|
||
Huber), PIN `471203`.
|
||
|
||
---
|
||
|
||
## 21. Was protokolliert wird
|
||
|
||
Jede schreibende Änderung erzeugt einen Eintrag mit Zeitpunkt, Person,
|
||
betroffenem Datensatz und den geänderten Feldern im Vorher-Nachher-Vergleich.
|
||
Auch jede Anmeldung — erfolgreich wie gescheitert.
|
||
|
||
Zwei Eigenschaften sind wichtig:
|
||
|
||
**Der Log lässt sich nicht ändern.** Nicht über die Oberfläche, nicht über die
|
||
Datenbank, auch nicht vom Administrator. Die Datenbank selbst verhindert es.
|
||
|
||
**Er lässt sich nur im Aufbewahrungslauf kürzen.** Nach der eingestellten
|
||
Frist (`AUDIT_AUFBEWAHRUNG_TAGE`, Vorgabe 10 Jahre) sichert der
|
||
Hintergrundprozess die alten Einträge und entfernt sie danach. Das ist der
|
||
einzige Weg, auf dem etwas aus dem Log verschwindet.
|
||
|
||
**Passwörter, PINs und Kartenkennungen stehen nie im Log** — sie werden vor
|
||
dem Schreiben herausgenommen.
|
||
|
||
Einsehbar ist der Log mit dem Recht `system.auditlog`, das Kommandant und
|
||
Administrator haben. Am Gerät und am Fahrzeug ist der Verlauf bereits auf der
|
||
jeweiligen Detailseite sichtbar.
|
||
|
||
---
|
||
|
||
## 22. Wenn etwas nicht geht
|
||
|
||
| Beobachtung | Wahrscheinliche Ursache | Was hilft |
|
||
|---|---|---|
|
||
| Die Anwendung startet nicht und meldet fehlende Variablen | `.env` unvollständig | Die Meldung nennt jede fehlende Variable. Erklärungen dazu stehen in `.env.example`. |
|
||
| Anmeldung schlägt immer fehl, obwohl das Passwort stimmt | Konto nach Fehlversuchen gesperrt | Fünf Minuten warten, oder `gesperrtBis` in der Datenbank zurücksetzen |
|
||
| Listen sind leer, obwohl Daten da sind | Kein Mandantenkontext gesetzt | Das ist der Schutzmechanismus. Der Zugriff muss über `fuerOrganisation()` laufen. |
|
||
| Dateien lassen sich nicht hochladen | MinIO nicht erreichbar oder Bucket fehlt | `http://localhost:9011` öffnen; `docker compose logs minio-init` |
|
||
| Der Knopf für authentik fehlt | Issuer, Client-ID oder Secret nicht gesetzt | Alle drei sind nötig, sonst wird der Weg ausgeblendet |
|
||
| Etikettenbogen lässt sich nicht erzeugen | Gotenberg läuft nicht | `docker compose ps`, dann `docker compose up -d gotenberg` |
|
||
| Kamera bleibt schwarz | Freigabe abgelehnt, oder die Seite läuft nicht über HTTPS | Der Browser fragt nur bei HTTPS oder localhost. Sonst die Inventarnummer eintippen |
|
||
| Import meldet fehlende Pflichtfelder | Keine Spalte ist Inventarnummer oder Bezeichnung zugeordnet | In Schritt 2 die Zuordnung von Hand setzen |
|
||
| Umlaute im Import verstümmelt | Die Datei ist weder UTF-8 noch Windows-1252 | In Excel als „CSV UTF-8" speichern |
|
||
| Gerät lässt sich nicht speichern | Standort **und** Fahrzeug gesetzt, oder keines von beidem | Genau eines von beiden angeben |
|
||
| `docker compose up` startet Traefik mit | Override-Datei wurde nicht mitgeladen | In Produktion `-f docker-compose.yml` angeben |
|
||
|
||
Zustand aller Randsysteme auf einen Blick:
|
||
|
||
```
|
||
http://localhost:3100/api/health
|
||
```
|
||
|
||
Antwortet mit `200` und `"status": "ok"`, wenn Datenbank, Objektspeicher und
|
||
Warteschlange erreichbar sind — sonst mit `503` und der Angabe, welcher Dienst
|
||
fehlt.
|
||
|
||
---
|
||
|
||
## Bilder erneuern
|
||
|
||
```bash
|
||
docker compose up -d
|
||
npm run dev
|
||
npm run screenshots
|
||
```
|
||
|
||
Die Bilder entstehen in `docs/screenshots/`, jeweils in heller und dunkler
|
||
Darstellung, und werden mit eingecheckt — die Anleitung soll auch dann lesbar
|
||
sein, wenn gerade kein Stack läuft.
|