- Bundesland confirmed: Niederösterreich; spec references seed catalog - Vorlagen list corrected to NÖ HLF system + aliases + Allrad rule - Geräte-Kategorien derived from Beladelisten - Allrad designation is HLFA n (A infixed), not 'HLF n A' Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
11 KiB
FlorianNetz — Design-Spezifikation
Datum: 2026-06-08 Status: Entwurf (zur Freigabe) Sprache der Anwendung: Deutsch (österreichischer Feuerwehr-Standard, ÖBFV)
1. Zweck
FlorianNetz ist eine ausschließlich für authentifizierte Benutzer zugängliche Web-Plattform, auf der österreichische Freiwillige Feuerwehren ihre Fahrzeuge und Geräte/Ausrüstung erfassen. Andere Wehren können diese durchsuchen, um für die überörtliche Hilfe die am schnellsten eintreffende Ressource zu finden.
Oberstes Prinzip: Kein anonymer Zugriff — kein einziger Seiten- oder API-Endpunkt ist ohne gültige Sitzung erreichbar (default-deny, serverseitig erzwungen).
Nicht-Ziele (vorerst)
- Kein In-App-Ausleih-/Anfrage-Workflow (nur Kontaktaufnahme out-of-band; für später vorgesehen, Datenmodell offen halten).
- Keine 2-Faktor-Authentifizierung in v1 (später leicht ergänzbar).
- Keine Kopplung mit
feuerwehr_dashboardin v1 (Architektur hält die spätere Kopplung offen). - Kein Mehrmandanten-SaaS — eine selbst gehostete Instanz mit vielen Wehren.
2. Rollen & Zugriff
| Rolle | Login über | Berechtigungen |
|---|---|---|
| Platform-Admin | Authentik SSO (OIDC) | Verwaltet die Taxonomie (Merkmal-Katalog, Fahrzeug-Vorlagen inkl. zugeordneter Merkmale & Auswahloptionen, Geräte-Kategorien); gibt von Wehren vorgeschlagene Merkmale frei; legt Wehren an und stellt den ersten Wehr-Admin-Login bereit; sieht Audit-Log |
| Wehr-Admin | App-Konto (erster Login vom Platform-Admin bereitgestellt) | Verwaltet das eigene Wehr-Profil, eigene Fahrzeuge & Geräte (Werte, Zuordnung, Status); legt weitere Wehr-Admins und Lese-Benutzer der eigenen Wehr selbst an |
| Lese-Benutzer | App-Konto (vom Wehr-Admin angelegt) | Durchsucht und sieht alle Wehren-Daten inkl. Kontaktinfo; keine Bearbeitung |
- Zwei Authentifizierungswege, eine einheitliche Sitzung mit
role+brigadeId. - Autorisierung serverseitig: Schreibzugriffe sind auf die eigene Wehr beschränkt; Lesezugriff über alle Wehren (offenes Verzeichnis).
- Login-Seite zeigt ausschließlich den Login — keine weiteren Inhalte.
3. Informationsarchitektur
- Startseite (nach Login): eine globale Suche mit prominentem „Meinen Standort verwenden" (GPS). Tabs: Fahrzeuge · Geräte · Wehren.
- Pro Tab: Namens-/Funkrufnamen-Suche + dynamisch aus dem Merkmal-Katalog erzeugte Filter (typabhängig: Schieberegler / Dropdown / Ja-Nein-Schalter) + Status-Filter („nur einsatzbereit").
- Trefferliste: sortiert nach Eintreffzeit (Fahrzeit-ETA); jede Zeile zeigt Wehr, Eckdaten, ETA/Entfernung, Status und 📞 Kontakt (Telefonnummer der Wehr).
- Detailseiten:
- Fahrzeug: Eckdaten-Raster (aus Merkmalwerten) · Beladung als verlinkte Geräteliste · Wehr-Karte · expliziter Button „Wehr kontaktieren".
- Gerät: Merkmale · zugeordnetes Fahrzeug oder „im Gerätehaus" · Wehr-Karte · Kontakt.
- Wehr: Profil (Adresse, Kontakt, Funkrufnamen-Schema), eigener Fuhrpark, Kontakt.
Design / Corporate Identity
- Richtung „Amtlich": seriös, behördlich, ruhig. Navy-Primärfarbe, Signalrot als Akzent/Signal, Serifen-Überschriften, viel Weißraum, tabellarische Ziffern.
- Logo „Netzknoten": vernetzte Wehren-Knoten um einen roten Mittelpunkt (Florian + Netz).
- Palette: Navy
#1B3A5B, Signalrot#E2231A, Anthrazit#1A2530, Nebelgrau#F6F8FA, Grün/bereit#1F8F5A, Bernstein/Wartung#B5460F. - Typografie: Serif-Display (Source Serif / Georgia) für Überschriften, humanistische Sans (Inter / System-UI) für UI, Tabular-Nums für Datenspalten.
- Bewusst kein generischer „KI-Look" (keine Verlaufsflächen, nicht alles abgerundet, keine Emoji-Dekoration).
4. Dynamisches Merkmal-System (Kernstück)
Ein starres Spaltenschema skaliert nicht — die Vielfalt an Fahrzeugen/Geräten ist zu groß. Stattdessen typisierte, vom Admin gepflegte Merkmale.
- Merkmal-Katalog (Admin): jedes Merkmal hat Name, Typ (
Zahl/Auswahl/Ja-Nein/Text), optional Einheit; beiAuswahldefiniert der Admin die erlaubten Optionen. - Fahrzeug-Vorlagen (Admin): definieren die niederösterreichischen Standard-Bezeichnungen (HLF 1, HLF 1 W, HLF 2, HLF 3, HLF 4 inkl. HLF 4-U, VRF, VF, ALF, SSTF, WLF, MTF) und pro Vorlage, welche Merkmale gelten sowie deren Optionen/Vorgabewerte. Inklusive Standard-Beladung. Jede Vorlage führt Such-Aliasse (frühere/umgangssprachliche Namen wie RLF/RLFA 2000, KLFA, TLFA …) und eine Allrad-Namensregel (Einschub „A" in die Abkürzung, z. B. „HLFA 3" =
Allradantrieb = Ja, gleiche Vorlage wie „HLF 3"). Seed-Daten siehedocs/reference/fahrzeug-katalog-noelfv.md. - Geräte-Kategorien (Admin): je Kategorie ein eigener Merkmal-Satz. Anfangsbestand wird aus den Beladelisten der Fahrzeug-Richtlinien abgeleitet (Atemschutz, hydraul. Rettungsgerät, Pumpen, Schläuche/Armaturen, Strom/Licht, Schadstoff/Ölwehr …); per Hybrid-Governance erweiterbar.
- Anlegen durch die Wehr: Vorlage wählen (füllt Merkmale & Beladung vor, alles editierbar) oder „Eigenes Fahrzeug/Gerät" frei aus dem Katalog zusammenstellen.
- Hybrid-Governance: Ein von einer Wehr neu angelegtes Merkmal ist sofort am eigenen Objekt nutzbar und auf dessen Detailseite sichtbar; es wird erst nach Admin-Freigabe (prüfen / zusammenführen) zu einem globalen Suchfilter. Hält die Suche über alle Wehren konsistent.
- Suche: Filter werden dynamisch aus dem Katalog erzeugt; der Typ bestimmt das Eingabeelement und die Abfrage (Range / Gleichheit / Boolean).
5. Geografie & „am schnellsten eintreffend"
- Jede Wehr hat Koordinaten (aus der Adresse geokodiert).
- Suchstandort = Geräte-GPS oder eingegebene Adresse (geokodiert).
- Treffer werden nach Fahrzeit-ETA von der jeweils besitzenden Wehr zum Suchstandort sortiert.
- Selbst gehostet zur Wahrung der Privatsphäre (keine Standortdaten an Dritte):
- OSRM für Fahrzeit/Routing (Österreich-OSM-Extrakt), als Distanz-/Zeit-Matrix.
- Nominatim (oder Photon) für Geokodierung (Österreich-Extrakt).
- Fallback: Luftlinie (Haversine), falls der Routing-Dienst nicht erreichbar ist — klar gekennzeichnet.
- Optionale MapLibre-GL-Kartenansicht (Liste bleibt primär).
6. Datenmodell (PostgreSQL, indikativ)
Typisierte Merkmalwerte in einer eigenen Wert-Tabelle (EAV mit typisierten Spalten) für saubere Range-/Enum-/Boolean-Indizes.
- brigades:
id, name, art (FF), strasse, plz, ort, bundesland, lat, lng, funkrufname_schema, telefon, email, wehrführer, aktiv, erstellt_am - users:
id, brigade_id (NULL für Platform-Admin), rolle (platform_admin | wehr_admin | wehr_read), auth_typ (authentik | local), email, name, passwort_hash (NULL bei authentik), aktiv, erstellt_von, erstellt_am - merkmale (Attributdefinitionen):
id, name, typ (number|enum|boolean|text), einheit, geltungsbereich (vehicle|equipment|both), status (active|proposed), vorgeschlagen_von_brigade_id, erstellt_am - merkmal_optionen (für
enum):id, merkmal_id, wert, label, reihenfolge - vehicle_templates (Vorlagen):
id, code (z. B. "TLFA 4000"), name, beschreibung - vehicle_template_merkmale:
template_id, merkmal_id, vorgabewert (NULL), pflicht (bool), reihenfolge - equipment_categories:
id, name - equipment_category_merkmale:
category_id, merkmal_id, reihenfolge - vehicles:
id, brigade_id, template_id (NULL bei Eigenbau), name, funkrufname, status (einsatzbereit|wartung|ausser_dienst), notiz, erstellt_am - equipment:
id, brigade_id, category_id, vehicle_id (NULL = im Gerätehaus), name, status, erstellt_am - merkmal_values:
id, merkmal_id, entity_typ (vehicle|equipment), entity_id, value_num, value_text, value_bool— Indizes:(merkmal_id, value_num),(merkmal_id, value_bool),(merkmal_id, value_text); sowie(entity_typ, entity_id) - audit_log:
id, actor_user_id, aktion, ziel_typ, ziel_id, details (jsonb), zeitpunkt
7. Tech-Stack
- Next.js (App Router, TypeScript) — Full-Stack (Server Components + Route Handlers / Server Actions), wenig Boilerplate.
- PostgreSQL + Drizzle ORM — typsicher und SQL-nah; besser geeignet als Prisma für die dynamischen Merkmal-Abfragen (Range/Enum-Filter).
- Auth.js (NextAuth v5) — Authentik-OIDC-Provider (Platform-Admins) + Credentials-Provider mit argon2id (Wehr-Konten); default-deny Middleware auf allen Routen; einheitliche Session mit
role+brigadeId. - Tailwind CSS + Radix-UI-Primitives, eigens auf die „Amtlich"/Netzknoten-Identität gethemt (volle Kontrolle über den eigenständigen Look; bewusst nicht MUI).
- Zod (Validierung), MapLibre GL (Karte), OSRM + Nominatim (Docker, Österreich-Extrakt).
- Tests: Playwright (E2E, insbesondere Auth-Gating-Tests) + Vitest (Units).
8. Sicherheit
- Default-deny serverseitig auf allen Seiten und API-Routen; keine reine Client-Absicherung.
- Rollen- + Wehr-Scoping bei jedem Schreibzugriff serverseitig erzwungen.
- argon2id-Passwort-Hashing; sichere Cookies (
httpOnly,secure,sameSite); CSRF-Schutz; Rate-Limiting am Login; Security-Header. - Audit-Log für Admin- und Bereitstellungsaktionen (Wehr/Benutzer anlegen, Merkmal-Freigaben).
- 2FA für Wehr-Konten als spätere, einfache Erweiterung vorgesehen.
9. Deployment
- Docker Compose: Container für
app(Next.js),postgres,osrm,nominatim. - Reverse Proxy: vorhandener Traefik (extern). Kein gebündelter Proxy. Der App-Container wird per Traefik-Labels (Router/Service-Port, TLS, ggf. Middlewares) am externen Traefik-Netzwerk angebunden.
- Die App muss
X-Forwarded-Proto/X-Forwarded-Hostvon Traefik vertrauen, damit sichere Cookies und Auth.js-Callback-URLs korrekt funktionieren; vertrauenswürdige Hosts konfigurieren. - Authentik: Redirect-URI der App in Authentik registrieren; Client-ID/-Secret + Issuer-URL via Umgebungsvariablen.
10. Eingaben / Abhängigkeiten
- Bundesland: Niederösterreich (bestätigt) — maßgeblich NÖ-LFV-Richtlinien (FA 01–10) + ÖBFV FA 30; relevant fürs Funkrufnamen-Schema.
- Standarddokumente vorhanden: 11 Fahrzeug-Richtlinien in
docs/reference/analysiert; Seed-Katalog (Vorlagen, Merkmal-Katalog, Aliasse) indocs/reference/fahrzeug-katalog-noelfv.md. - Geräte-Kategorien: Anfangsbestand aus den Beladelisten abgeleitet (siehe §4); separate Geräte-Standarddokumente können später ergänzt werden.
- Offen (nicht blockierend): Bestätigung der noch tentativen Such-Aliasse (KLF/KLFA, TLFA, GTLF, KRF/KRFA, LAST, WLFA, MTFA) — als Aliasse jederzeit im Admin pflegbar.
11. Zukünftige Kopplung mit feuerwehr_dashboard
In v1 eigenständig, aber kopplungsfreundlich: gemeinsamer Authentik-Identitätsanbieter, kompatible PostgreSQL- und Docker/Traefik-Konventionen. Eine spätere Integration (geteilte Identitäten, Querverweise) bleibt dadurch unkompliziert.