Phase 0: Fundament der Feuerwehr-Verwaltungsplattform
Legt den kompletten Unterbau an, auf dem die Fachmodule aufsetzen. Betrieb: - docker-compose.yml mit Traefik, App, Worker, PostgreSQL 17 + PostGIS, Redis, MinIO und Gotenberg; Entwicklungs-Override ohne Traefik, dafuer mit Mailpit und Adminer - Mehrstufiges Dockerfile: eigener Benutzer, tini als PID 1, Healthcheck - .env.example mit einem Kommentar zu jeder Variable Mandantentrennung: - Row Level Security auf allen mandantenpflichtigen Tabellen - Zwei getrennte Datenbankverbindungen: florian_app mit aktiver RLS fuer die Anwendung, Eigentuemer-Zugang nur fuer Migration, Seed und Anmeldung - fuerOrganisation() als einziger Weg zu Fachdaten Nachvollziehbarkeit: - AuditLog append-only per Trigger; UPDATE ist dauerhaft gesperrt, DELETE nur im gekennzeichneten Aufbewahrungslauf - Geheimnisse werden vor dem Schreiben entfernt Anmeldung: - OIDC gegen ein extern betriebenes authentik, Rollen aus Gruppen nur als Vorbelegung beim ersten Login - Lokaler E-Mail/Passwort-Login als Rueckfallweg - Terminal per PIN und RFID mit zwei Schranken (Geraet, dann Person) Weiteres: - lib/authz.ts mit 9 Rollen und 38 Einzelrechten - lib/storage.ts (MinIO), lib/audit.ts, lib/warteschlange.ts (BullMQ) - Integrationen fuer Mail, Telegram und LLM hinter abschaltbaren Interfaces - tRPC v11, Basis-Layout mit Seitenleiste und dunkler Darstellung - Seed mit einer Beispielwehr: 16 Personen, 3 Fahrzeuge, 40 Geraete - 32 Vitest-Tests (davon 8 gegen eine echte Datenbank), 10 Playwright-Tests - README, Anleitung mit Screenshots, Roadmap, Aufwandsschaetzung, Devlog, Versionierungsregeln und Changelog Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
# 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 | offen |
|
||||
| 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 |
|
||||
| | **Summe** | **115–153 PT** | **26–34 h** | |
|
||||
|
||||
115–153 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**
|
||||
|
||||
| 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.
|
||||
|
||||
## 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.
|
||||
|
||||
---
|
||||
|
||||
## Was hier nicht drin ist
|
||||
|
||||
**Kassenmodul.** Die Rolle `KASSIER` ist in Phase 0 gefordert und angelegt,
|
||||
die Rechte `kasse.lesen`, `kasse.bearbeiten` und `kasse.abschluss` stehen
|
||||
bereit. Ein Kassenmodul kommt in keiner der Phasen 0 bis 8 vor. Geschätzter
|
||||
Vergleichsaufwand, falls gewünscht: **8–11 PT** für Buchungen, Beiträge,
|
||||
Rechnungen, Kassenabschluss und Jahresauswertung. Siehe
|
||||
[ROADMAP.md](ROADMAP.md).
|
||||
|
||||
**Betrieb und Einführung.** Datenübernahme aus der Altsoftware, Schulung der
|
||||
Wehr, Sicherungskonzept, Monitoring: nach Erfahrung noch einmal 15 bis 25
|
||||
Prozent des Entwicklungsaufwands.
|
||||
Reference in New Issue
Block a user