Files
FireAdministration/CHANGELOG.md
T
Florian WildeandClaude Opus 5 1744403620 Geraeteformular zum Anlegen und Bearbeiten ergaenzen
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>
2026-09-03 09:20:30 +02:00

9.1 KiB
Raw Blame History

Changelog

Alle nennenswerten Änderungen an FLORIAN. Format nach Keep a Changelog, Versionierung nach Semantic Versioning.

Die Regeln dazu stehen in docs/VERSIONIERUNG.md.

[Unveröffentlicht]

Nächster Schritt ist Phase 2 (Wartungs- und Prüfmanagement).

Hinzugefügt

  • Formular zum Anlegen und Bearbeiten eines Geräts (/geraete/neu und /geraete/<id>/bearbeiten). Damit ist die letzte offene Lücke aus Phase 1 geschlossen: Ein Neuzugang lässt sich einzeln erfassen, ohne den Umweg über eine Importdatei.
    • Die Lagerung wird als Umschalter geführt statt als zwei Auswahlfelder, die man versehentlich beide füllen kann.
    • Prüftermin und Lebensdauerende werden schon beim Tippen ausgerechnet und angezeigt — mit denselben Funktionen, mit denen der Server anschließend rechnet.
    • Ist nur ein Standort angelegt, wird er vorbelegt.
  • 7 weitere Playwright-Tests zum Formular (nun 58 statt 44, zwei davon unter Touch-Emulation begründet übersprungen).

Behoben

  • Das Formular stürzte 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. Das Spreaden davon ergab lauter undefined. Die Werte liegen jetzt in einem eigenen Modul ohne "use client".
  • Das Sternchen an Pflichtfeldern wurde vorgelesen. Eine Sprachausgabe nannte das Feld „Bezeichnung Stern". Das Sternchen trägt jetzt aria-hidden; dass ein Feld ausgefüllt werden muss, sagt das required-Attribut.
  • Fehlermeldungen in Formularen sind eindeutig ansteuerbar (data-testid) — Next.js hängt einen eigenen Routen-Ansager mit derselben Rolle in jede Seite.

[0.2.0] — 2026-09-03

Phase 1: Stammdaten. Ab hier führt die Wehr ihren Bestand in FLORIAN — mit Standorten, Fahrzeugen samt Beladeordnung, Gerätetypen als Vorgabe und Geräten, die per QR-Code am Regal auffindbar sind.

Hinzugefügt

Datenmodell

  • Standort (Gerätehaus, Lager, Außenstelle, Werkstatt) mit PostGIS-Punkt für die Karte ab Phase 6.
  • Geraeteraum — die Fächer am Fahrzeug (G1 bis G6, Heck, Dach, Mannschaftsraum), in Beladereihenfolge sortierbar.
  • Geraetetyp als Vorgabe für Prüfintervall, Prüfvorschrift und Lebensdauer. Ein einzelnes Gerät darf davon abweichen; sonst gilt der Typ.
  • Qualifikationstyp und Qualifikation mit Gültigkeitsdauer und eigener Vorwarnzeit je Typ.
  • Fahrzeug erweitert um Fahrgestellnummer, DIN-Typkurzzeichen, Erstzulassung, Sitzplätze, Tankinhalt, Gesamtmasse und die UVV-Frist.
  • Geraet erweitert um Gerätetyp, Lebensdauerkategorie, errechnetes Lebensdauerende, Anschaffungspreis und die Lagerung.

Regeln in der Datenbank

  • Ein Gerät steht entweder an einem Standort oder ist auf einem Fahrzeug verlastet — eine Prüfbedingung setzt das durch, ein Trigger stellt zusätzlich sicher, dass ein angegebener Geräteraum auch zum angegebenen Fahrzeug gehört.
  • Row Level Security auf allen neuen Tabellen.
  • Trigram-Indizes für die Volltextsuche über Geräte, Fahrzeuge und Personen.

Funktionen

  • Geräteliste mit Volltextsuche, Statusfilter, serverseitiger Sortierung, Blättern und Spaltenauswahl. Die Spaltenauswahl bleibt je Browser gespeichert.
  • Massenbearbeitung: Status mehrerer Geräte auf einmal setzen, Geräte umlagern. Jede Änderung erzeugt einen eigenen Protokolleintrag am jeweiligen Gerät.
  • QR-Code je Gerät. Der Code zeigt auf /g/<inventarnummer> und führt nach der Anmeldung direkt zur Gerätedetailseite.
  • Etikettenbogen als PDF über Gotenberg: DIN A4 mit 65 Etiketten (38,1 × 21,2 mm). Der Druck kann an einer beliebigen Position beginnen, damit angebrochene Bögen weiterverwendet werden können.
  • QR-Scan über die Kamera im Browser, mit Eingabefeld als Rückfallweg.
  • Import aus CSV und Excel: Spalten werden nach den Überschriften automatisch zugeordnet, die Vorschau zeigt Zeile für Zeile, was übernommen würde und was daran nicht stimmt. Geschrieben wird erst nach Bestätigung.
  • Gerätehistorie und Fahrzeughistorie, gerendert aus dem Audit-Log.
  • Qualifikationen mit Ablaufwarnung, gerechnet mit der Vorwarnzeit des jeweiligen Typs.
  • Fahrzeugdetail zeigt die Beladung nach Geräteräumen statt alphabetisch.

Daten und Tests

  • Der Seed legt jetzt zusätzlich 3 Standorte, 20 Geräteräume, 14 Gerätetypen mit echten Prüfvorgaben (DGUV, DIN, vfdb), 49 Geräte und 107 Qualifikationen an. Fristen sind bewusst gestreut, damit die Ampeln etwas zeigen.
  • 104 Vitest-Tests (vorher 32), davon 40 zum Import und 32 zu QR und Fristen.
  • 44 Playwright-Tests (vorher 10) über Desktop und Tablet.

Geändert

  • Fristenrechnung auf UTC-Kalenderarithmetik umgestellt. Vorher wurde über startOfDay aus date-fns gerechnet, das die Zeitzone des Servers verwendet. Ein Prüfdatum kommt aus der Datenbank als UTC-Mitternacht und wurde dabei auf den Vortag zurückgeschoben — Fristen wären einen Tag zu früh fällig geworden.
  • CardTitle rendert eine echte Überschrift statt eines div. Wer mit einer Sprachausgabe arbeitet, springt von Überschrift zu Überschrift; Karten tauchten in dieser Navigation vorher gar nicht auf.
  • Die Entwicklungsanzeige von Next.js ist abgeschaltet, damit sie nicht in den Bildern der Anleitung mitläuft.

Sicherheit

  • Der Etikettendruck wird protokolliert (EXPORTIERT) — damit ist nachvollziehbar, wann welche Aufkleber erzeugt wurden.
  • Der Import übernimmt keine Werte, die der Browser geschickt hat: die Datei wird beim Übernehmen erneut serverseitig eingelesen und geprüft. Sonst ließe sich die Vorschau umgehen.

[0.1.0] — 2026-09-03

Phase 0: das Fundament. Ab hier steht ein lauffähiger Stack mit Mandantentrennung, Anmeldung, Dateiablage und lückenloser Protokollierung.

Hinzugefügt

Betrieb

  • docker-compose.yml mit Traefik, App, Worker, PostgreSQL 17 + PostGIS, Redis, MinIO und Gotenberg.
  • docker-compose.override.yml für die Entwicklung: ohne Traefik, mit Mailpit als SMTP-Auffangkorb und Adminer für den Blick in die Datenbank. Host-Ports bewusst abseits der Standardwerte (3100, 5442, 6389, 9010/9011), damit FLORIAN neben anderen lokalen Stacks laufen kann.
  • Mehrstufiges docker/Dockerfile: eigener Benutzer florian (UID 1001, kein root), tini als PID 1, Healthcheck gegen /api/health, Standalone-Build von Next.js.
  • docker/entrypoint.sh wendet ausstehende Migrationen an — nur im App-Container, nicht im Worker.
  • docker/postgres/10-init-app-role.sh legt beim ersten Start die Rolle florian_app (NOBYPASSRLS) samt Vorgabeprivilegien an.
  • .env.example mit einem Kommentar zu jeder einzelnen Variable.

Datenmodell

  • Prisma-Schema mit Organisation, Person, Rolle, Berechtigung, RolleBerechtigung, PersonRolle, AusweisToken, AuditLog, Datei.
  • Fahrzeug und Geraet bereits schmal angelegt, damit der Seed eine realistische Wehr aufbauen kann. Phase 1 erweitert beide.
  • Migration 20260902000100_rls_policies: Row Level Security auf allen mandantenpflichtigen Tabellen, Funktion aktuelle_organisation(), Append-only-Trigger auf audit_log.
  • Migration 20260902000200_audit_bereinigung: UPDATE auf audit_log bleibt dauerhaft gesperrt, DELETE ist nur im gekennzeichneten Aufbewahrungslauf möglich.

Anwendungskern

  • lib/env.ts — Zod-Validierung der gesamten Umgebung beim Start.
  • lib/db.ts — getrennte Verbindungen für Anwendung (RLS aktiv) und System (RLS-frei), fuerOrganisation() als einziger Weg zu Fachdaten.
  • lib/authz.ts — 9 Rollen, 38 Einzelrechte, zentrale Prüffunktionen.
  • lib/storage.ts — MinIO, presignte Up- und Downloads, SHA-256-Prüfsumme.
  • lib/audit.ts — Protokolleinträge mit Vorher/Nachher-Vergleich, entfernt Geheimnisse vor dem Schreiben.
  • lib/auth.ts — Auth.js mit OIDC gegen authentik, lokalem Passwort-Login und Terminal-Anmeldung über PIN oder RFID.
  • lib/warteschlange.ts und src/worker/ — BullMQ-Gerüst mit den Auftragsarten für Fristen, Erinnerungen, PDF und Aufbewahrung.
  • lib/integrations/ — Mail, Telegram und LLM hinter abschaltbaren Schnittstellen.
  • tRPC v11 mit den Prozedurarten oeffentlich, angemeldet und mitRecht(...).

Oberfläche

  • Basis-Layout mit Seitenleiste, heller und dunkler Darstellung (Systemvorgabe als Standard) und durchgängig deutschen Texten.
  • Anmeldeseite, die genau die eingerichteten Anmeldewege zeigt.
  • Übersicht mit Kennzahlen und dem Sicherheitshinweis zur analogen Atemschutzüberwachung.
  • Farbwelt in OKLCH mit festen Statusfarben für Gerätezustände.

Daten und Tests

  • Seed mit einer vollständigen Beispielwehr: 15 Personen mit Rollen und Terminal-Ausweisen, 3 Fahrzeuge, 40 Geräte mit gemischten Prüffristen.
  • Vitest: 32 Tests, darunter acht, die die Mandantentrennung gegen eine echte Datenbank prüfen.
  • Playwright: 10 Tests über Desktop und Tablet.
  • npm run screenshots erzeugt die Bilder für die Anleitung.

Dokumentation

  • README mit Schnellstart in sechs Zeilen.
  • Anleitung, Roadmap, Aufwandsschätzung, Devlog und Versionierungsregeln.