Schliesst die letzte offene Luecke aus Phase 1. Bis dahin liessen sich Geraete
nur ueber den Import erfassen — fuer einen Bestand richtig, fuer ein einzelnes
nachbeschafftes Geraet umstaendlich.
Neu:
- /geraete/neu und /geraete/<id>/bearbeiten, beide ueber dieselbe Komponente
- Die Lagerung ist ein Umschalter statt zweier Auswahlfelder. Standort und
Fahrzeug schliessen sich aus; so kann der Fehler gar nicht erst entstehen,
den die Datenbank sonst abweisen wuerde. Beim Wechsel des Fahrzeugs wird die
Raumangabe zurueckgesetzt.
- Prueftermin und Lebensdauerende werden beim Tippen vorgerechnet, mit
denselben Funktionen wie auf dem Server. Beim Speichern rechnet der Server
erneut und behaelt das letzte Wort.
- Gibt es nur einen Standort, ist er beim Anlegen vorbelegt.
- Knopf "Neues Geraet" in der Liste, "Bearbeiten" auf der Detailseite
Behoben:
- Das Formular stuerzte beim ersten Rechnen ab. Die Vorgabewerte lagen in einem
"use client"-Modul und wurden von einer Server-Komponente importiert; dort
kommt nur eine Client-Referenz an, kein Objekt, und das Spreaden ergibt lauter
undefined. Die Werte liegen jetzt in geraet-formular-werte.ts ohne
"use client".
- Das Sternchen an Pflichtfeldern wurde von Sprachausgaben mitgelesen
("Bezeichnung Stern"). Es traegt jetzt aria-hidden; dass ein Feld ausgefuellt
werden muss, sagt bereits das required-Attribut.
- Fehlermeldungen in Formularen sind eindeutig ansteuerbar. Next.js haengt
einen eigenen Routen-Ansager mit der Rolle "alert" in jede Seite.
Tests:
- 7 neue Playwright-Tests zum Formular, darunter die Lagerungsregel und die
Fristenvorschau
- Zwei davon laufen nicht unter Touch-Emulation: Chromium nimmt dort keine
zeichenweise Eingabe in Datumsfelder an. Begruendet uebersprungen, die
Rechnung selbst deckt qr-und-fristen.test.ts ab.
- Insgesamt 104 Unit-Tests und 56 E2E-Tests gruen
Anleitung, Changelog, Devlog, Aufwandsschaetzung und Roadmap fortgeschrieben.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
12 KiB
Aufwandsschätzung
Schätzung je Phase, daneben der tatsächliche Aufwand aus dem Devlog. Stand: 3. September 2026.
Wie hier gerechnet wird
Es stehen bewusst zwei Größen nebeneinander, weil sie Verschiedenes aussagen:
| Größe | Bedeutung |
|---|---|
| Sitzungszeit | Wie lange Claude tatsächlich gearbeitet hat. Das ist die Zahl, die im Devlog steht, und die Grundlage für die Planung der nächsten Sitzung. |
| Vergleichsaufwand | Was eine einzelne Person mit diesem Stack für dasselbe Ergebnis gebraucht hätte, in Personentagen zu 8 Stunden. Das ist die Zahl, die gegenüber der Wehr etwas bedeutet — sie beantwortet „was wäre das sonst wert gewesen". |
Der Vergleichsaufwand ist eine Schätzung, keine Messung. Er unterstellt jemanden, der den Stack kennt, die Feuerwehr-Fachlichkeit aber erst klären muss — also Recherche zu DGUV-Fristen, FwDV 3 und FwDV 7 einschließt.
Faktoren, die in die Schätzung eingehen:
- Fachlichkeit — wie viel muss geklärt werden, bevor gebaut werden kann?
- Sicherheitsbezug — Atemschutz und Prüfnachweise brauchen mehr Tests und mehr Sorgfalt als eine Adressliste.
- Fremdsysteme — Gotenberg, Nominatim, tileserver-gl, Ollama, RFID-Leser. Jedes ist eine eigene Fehlerquelle.
- Offline und Echtzeit — die teuersten Anforderungen im ganzen Projekt.
Übersicht
| Phase | Inhalt | Vergleichsaufwand | Sitzungszeit geschätzt | Sitzungszeit tatsächlich |
|---|---|---|---|---|
| 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 |
| 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 |
| 6 | Kartenmodule | 14–18 PT | 3,5–4,5 h | offen |
| 7 | Benachrichtigungen und Termine | 10–13 PT | 2,5–3,5 h | offen |
| 8 | Lokale KI | 9–12 PT | 2,5–3 h | offen |
| 9 | Kassenverwaltung | 8–11 PT | 2–3 h | offen |
| Summe | 123–164 PT | 28–37 h |
123–164 Personentage entsprechen etwa 6 bis 8 Monaten Vollzeitarbeit einer einzelnen Person. Zum Vergleich: eine kommerzielle Feuerwehrverwaltung kostet je nach Umfang 500 bis 2.500 Euro im Jahr, dauerhaft, mit den Daten beim Anbieter.
Phase 0 — Fundament
Vergleichsaufwand: 12–16 PT · Tatsächlich: 1:00 h Sitzungszeit
| Baustein | PT |
|---|---|
| Monorepo, Werkzeuge, TypeScript, Tailwind, shadcn | 1,5 |
| Docker Compose, Dockerfile, Traefik, Healthchecks | 2,5 |
| Prisma-Schema der Basismodelle | 2,0 |
| Row Level Security samt Rollen- und Rechtekonzept in Postgres | 2,5 |
| Auth.js mit OIDC, lokalem Login und Terminal-Anmeldung | 3,0 |
| storage, audit, warteschlange, Integrationsschnittstellen | 2,0 |
| Basis-Layout, Anmeldeseite, Übersicht, Dark Mode | 1,5 |
| Seed, Vitest, Playwright, Dokumentation | 1,5 |
Das Teuerste war nicht der sichtbare Teil, sondern die Mandantentrennung. RLS so aufzusetzen, dass Migrationen, Seed und Anmeldung funktionieren und die Anwendung trotzdem nichts Fremdes sieht, verlangt zwei getrennte Datenbankzugänge und ein sauberes Verständnis davon, wann welcher greift. Wer das nachträglich einbaut, zahlt ein Vielfaches.
Phase 1 — Stammdaten
Vergleichsaufwand: 10–14 PT · Tatsächlich: 2:05 h Sitzungszeit (1:15 h Hauptteil, 0:50 h Nachtrag)
| Baustein | PT |
|---|---|
| Modelle: Standort, Geraeteraum, Geraetetyp, Qualifikation | 1,5 |
| Fahrzeug und Geraet um DIN-Typisierung und Lebensdauer erweitern | 1,5 |
| Tabellen mit Sortierung, Filter, Volltextsuche, Spaltenauswahl | 3,0 |
| QR-Code je Gerät, Etikettenbogen als PDF (65 Etiketten, DIN A4) | 1,5 |
| QR-Scan im Browser über die Kamera | 1,0 |
| CSV-/Excel-Import mit Spaltenzuordnung und Vorschau | 2,5 |
| Gerätehistorie aus dem Audit-Log | 1,0 |
| Massenbearbeitung und Tastaturbedienung | 1,0 |
Der Import ist der Posten, der erfahrungsgemäß aus dem Ruder läuft. Jede Wehr bringt eine andere Excel-Datei mit, und die Vorschau vor dem Übernehmen ist kein Komfort, sondern die Bedingung dafür, dass die Wehr dem Ergebnis traut.
Rückblick. Die Schätzung hat gut getroffen — mit einer Verschiebung: Der Import war teurer als angesetzt (deutsche Datumsformate, Semikolon-CSV, Windows-1252, Excel-Seriennummern, Dubletten in der Datei), die Tabellen dagegen billiger, weil Sortierung und Blättern serverseitig laufen und keine Tabellenbibliothek nötig war. Nicht eingeplant war die Zeitzonen-Falle in der Fristenrechnung; sie hätte in Phase 2 deutlich mehr gekostet, wenn sie erst dort aufgefallen wäre.
Das zunächst offen gebliebene Formular zum einzelnen Anlegen von Geräten wurde
als Nachtrag ergänzt — geschätzt waren 0,5 PT, tatsächlich 0:50 h Sitzungszeit.
Die Hälfte davon ging für zwei Dinge drauf, die nichts mit dem Formular zu tun
hatten: eine Server/Client-Grenze, die stillschweigend undefined liefert, und
Datumsfelder, die sich in Chromium nicht automatisiert füllen lassen.
Phase 2 — Wartung und Prüfung
Vergleichsaufwand: 18–24 PT — die aufwendigste Phase
| Baustein | PT |
|---|---|
| Modelle: Vorlage, Checklistenpunkt, Termin, Prüfung, Ergebnis, Mangel, Rückruf | 3,0 |
| Fristen-Dashboard mit Gruppierungen | 2,5 |
| Nächtlicher BullMQ-Job: Termine erzeugen, Status setzen, erinnern | 2,5 |
| Prüfungs-Wizard mit Fotoupload je Checklistenpunkt | 3,5 |
| Unterschrift auf Canvas, Touch und Maus | 1,5 |
| PDF-Protokoll über Gotenberg mit Fotos und Signatur | 3,0 |
| Unveränderlichkeit und Korrekturprotokolle mit Verweis | 1,5 |
| Lebensdauerüberwachung und Aussonderungsvorschlag | 1,5 |
| Rückrufe, externe Wartung, Mängel-Workflow | 2,5 |
Hier entsteht der eigentliche Wert: die Software wird zum Nachweis gegenüber 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.
Phase 3 — Einsätze und Übungen
Vergleichsaufwand: 12–16 PT
| Baustein | PT |
|---|---|
| Modelle: Einsatz, Einsatzfahrzeug, Einsatzkraft, Material, Lagemeldung, Übung | 2,0 |
| Schnellerfassung mit Nachtragen | 1,5 |
| Geocoding über self-hosted Nominatim mit Rückfallweg | 1,5 |
| Personalauswahl nach Verfügbarkeit und Qualifikation | 2,0 |
| Stärkeberechnung nach FwDV 3 | 1,0 |
| Einsatzbericht als PDF, Jahresexport für die Gemeinde | 2,0 |
| Statistik: Kategorien, Eintreffzeiten, Beteiligung, Auslastung | 2,5 |
| Externes Portal mit signiertem QR-Link, ohne Login, rate-limited | 2,0 |
Das externe Portal für Fremdwehren ist sicherheitsrelevant: ein Zugang ohne Anmeldung, der zeitlich begrenzt und mengenbegrenzt sein muss. Der Aufwand steckt weniger in der Funktion als in der Absicherung.
Phase 4 — Kiosk-PWA
Vergleichsaufwand: 16–22 PT
| Baustein | PT |
|---|---|
| Eigenes Kiosk-Layout, 64px-Ziele, hoher Kontrast, kein Hover-Zwang | 2,0 |
| Anmeldung per RFID (WebHID), PIN und QR vom Handy | 2,5 |
| Wizards: Wartung, Fahrtenbuch, Mangel, Inventur, Wäsche, Anwesenheit | 4,0 |
| Hallen-Monitor mit DWD-Wetterwarnung | 2,0 |
| Service Worker, App-Shell und Stammdaten offline | 3,0 |
| IndexedDB-Outbox mit Idempotenzschlüssel und Synchronisation | 4,0 |
| Konfliktbehandlung und Konfliktliste für den Administrator | 2,0 |
| Playwright-Tests für den Offline-Fall | 1,5 |
Offline-Fähigkeit mit schreibenden Aktionen ist die technisch schwierigste Anforderung des ganzen Projekts. Eine Outbox ist schnell gebaut; dass sie unter Verbindungsabbruch, Doppelklick und parallelem Zugriff von zwei Terminals nichts verliert und nichts doppelt schreibt, ist die eigentliche Arbeit. Die Idempotenzschlüssel sind dafür der Schlüssel, nicht die Synchronisation.
Phase 5 — Atemschutz nach FwDV 7
Vergleichsaufwand: 14–18 PT
| Baustein | PT |
|---|---|
| Modelle: Atemschutzeinsatz, Trupp, Druckmessung, G26, Belastungsübung | 2,0 |
| Truppanlage per RFID, Eingangsdruck | 1,5 |
| Serverseitig autoritative Timer, Socket.IO-Verteilung | 3,5 |
| Rückzugsdruck-Berechnung, Ampel, akustischer Alarm | 2,0 |
| Erinnerung zur Druckabfrage im Intervall | 1,0 |
| Mayday-Knopf mit Protokolleintrag | 1,0 |
| Lückenloses PDF-Protokoll am Einsatz | 1,5 |
| G26.3-Fristen, Belastungsübungen, Tauglichkeitsampel | 2,0 |
| Tests: Reload und Verbindungsabbruch überstehen | 2,0 |
Der Aufwand liegt nicht in der Funktion, sondern im Beweis, dass sie hält. Ein Timer, der einen Reload überlebt, ist Pflicht — deshalb muss die Zeit serverseitig geführt werden und der Browser nur anzeigen. Diese Phase bekommt den höchsten Testanteil im Projekt.
Phase 6 — Kartenmodule
Vergleichsaufwand: 14–18 PT
| Baustein | PT |
|---|---|
| MapLibre GL, tileserver-gl, MBTiles fürs Ausrückegebiet | 2,5 |
| Hydranten mit PostGIS, Cluster, Filter, Umkreissuche | 3,0 |
| Import aus GeoJSON und Stadtwerke-CSV | 1,5 |
| Objekte und Feuerwehrpläne nach DIN 14095, Volltextsuche | 3,0 |
| Lagekarte mit taktischen Zeichen nach FwDV 102 als SVG-Set | 3,5 |
| Echtzeit-Sync der Lagekarte zwischen Geräten | 2,0 |
| Wasserförderung: Höhenprofil, Druckverlust, Verstärkerpumpen | 2,5 |
Das SVG-Set für die taktischen Zeichen ist Fleißarbeit, aber unvermeidbar — fertige Sets sind selten frei verwendbar. Die Wasserförderungsberechnung ist Physik mit klaren Formeln und deshalb gut testbar.
Phase 7 — Benachrichtigungen und Termine
Vergleichsaufwand: 10–13 PT
| Baustein | PT |
|---|---|
| Kanalabstraktion: E-Mail, Telegram, ntfy, Web-Push | 2,5 |
| Vorlagen mit Platzhaltern, je Ereignis und Rolle | 2,0 |
| Abonnements je Person | 1,0 |
| Kalender mit Serienterminen und Selbstanmeldung | 3,0 |
| CalDAV-/ICS-Feed je Person mit Token | 1,5 |
| Digitaler Dienstausweis mit signiertem QR und Prüfseite | 2,0 |
Das Grundgerüst der Kanalabstraktion steht bereits aus Phase 0
(lib/integrations/), das spart hier etwa einen Personentag.
Phase 8 — Lokale KI
Vergleichsaufwand: 9–12 PT
| Baustein | PT |
|---|---|
lib/ai/ mit OpenAI-kompatiblem Client, abschaltbar |
1,0 |
| Diktat: Aufnahme im Browser, faster-whisper, Transkript | 2,5 |
| Berichtsassistent mit Übernehmen/Verwerfen | 2,0 |
| Wiki mit pgvector, semantische Suche, RAG mit Quellenangabe | 3,5 |
| Belegerfassung über ein Vision-Modell, immer bestätigen | 2,0 |
Der Client aus Phase 0 (lib/integrations/llm.ts) ist bereits vorhanden. Die
Kennzeichnungspflicht — jede KI-Ausgabe ist als solche erkennbar und muss
bestätigt werden, bevor sie in ein Dokument mit Nachweischarakter gelangt —
kostet wenig Zeit, ist aber nicht verhandelbar.
Phase 9 — Kassenverwaltung
Vergleichsaufwand: 8–11 PT — am 03.09.2026 ergänzt
| Baustein | PT |
|---|---|
| Modelle: Konto, Kategorie, Buchung, Beitragssatz, Beitrag, Rechnung, Abschluss | 2,0 |
| Buchungsmaske mit Kategorievorschlag, Beleg als Datei | 1,5 |
| Beitragslauf, Mahnstufen, Zahlungsabgleich aus CAMT.053 oder MT940 | 2,5 |
| Rechnungen mit Nummernkreis und PDF | 1,0 |
| Kassenabschluss mit Zeitraumsperre und Prüfbericht | 1,5 |
| Auswertungen und Exporte | 1,5 |
Der Zahlungsabgleich ist der unsichere Posten: CAMT.053 ist gut spezifiziert, MT940 dagegen je nach Bank unterschiedlich ausgelegt. Falls die Hausbank nur MT940 liefert, kommt ein halber bis ganzer Tag für die Eigenheiten dazu.
Die Unveränderlichkeit festgeschriebener Buchungen kostet hier fast nichts — das Muster steht seit Phase 0 mit dem Audit-Log-Trigger und lässt sich übernehmen.
Was hier nicht drin ist
Betrieb und Einführung. Datenübernahme aus der Altsoftware, Schulung der Wehr, Sicherungskonzept, Monitoring: nach Erfahrung noch einmal 15 bis 25 Prozent des Entwicklungsaufwands.