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>
267 lines
12 KiB
Markdown
267 lines
12 KiB
Markdown
# Aufwandsschätzung
|
||
|
||
Schätzung je Phase, daneben der tatsächliche Aufwand aus dem
|
||
[Devlog](DEVLOG.md). 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.
|