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>
290 lines
13 KiB
Markdown
290 lines
13 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 | **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 |
|
||
| 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** · **Tatsächlich: 2:25 h Sitzungszeit** — 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.
|
||
|
||
**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**
|
||
|
||
| 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.
|