445 lines
22 KiB
Bash
445 lines
22 KiB
Bash
# =============================================================================
|
|
# FLORIAN — Feuerwehr-Verwaltungsplattform
|
|
# Kopiere diese Datei nach ".env" und passe die Werte an:
|
|
# cp .env.example .env
|
|
# Alles, was hier steht, wird von docker-compose.yml und von lib/env.ts gelesen.
|
|
# lib/env.ts validiert beim Start mit Zod — fehlt eine Pflichtvariable, startet
|
|
# die App gar nicht erst, statt später halb zu funktionieren.
|
|
# =============================================================================
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Allgemein
|
|
# -----------------------------------------------------------------------------
|
|
# development | production | test — steuert Logging, Fehlerseiten und Caching.
|
|
NODE_ENV=development
|
|
# Öffentliche Basis-URL der Anwendung, ohne abschließenden Schrägstrich.
|
|
# Muss exakt der Adresse entsprechen, unter der Nutzer die App aufrufen —
|
|
# Auth.js baut daraus die OIDC-Redirect-URI.
|
|
APP_URL=http://localhost:3100
|
|
# Zeitzone für alle serverseitigen Fristen- und Terminberechnungen.
|
|
# Nicht ändern, außer die Wehr liegt außerhalb Deutschlands.
|
|
TZ=Europe/Berlin
|
|
# Host-Ports fuer die Entwicklung. Bewusst nicht die Standardports,
|
|
# damit FLORIAN neben anderen lokalen Stacks laufen kann.
|
|
APP_PORT=3100
|
|
GOTENBERG_PORT=3101
|
|
MAILPIT_UI_PORT=8125
|
|
MAILPIT_SMTP_PORT=1125
|
|
ADMINER_PORT=8081
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Traefik / Domains (nur für den Produktionsbetrieb relevant)
|
|
# In der Entwicklung greift docker-compose.override.yml und veröffentlicht die
|
|
# Dienste direkt auf localhost — Traefik wird dort nicht gebraucht.
|
|
# -----------------------------------------------------------------------------
|
|
# Hostname der Anwendung hinter Traefik, z. B. florian.beispielwehr.de
|
|
APP_DOMAIN=florian.localhost
|
|
# Hostname der MinIO-S3-API (Datei-Uploads, presignte URLs).
|
|
MINIO_DOMAIN=s3.florian.localhost
|
|
# Hostname der MinIO-Weboberfläche (Administration der Buckets).
|
|
MINIO_CONSOLE_DOMAIN=minio.florian.localhost
|
|
# Hostname des Traefik-Dashboards. Leer lassen, um es nicht zu veröffentlichen.
|
|
TRAEFIK_DASHBOARD_DOMAIN=traefik.florian.localhost
|
|
# E-Mail-Adresse für die ACME-Zertifikate (Let us Encrypt).
|
|
ACME_EMAIL=kommandant@beispielwehr.de
|
|
# Traefik-Entrypoint für HTTPS. "websecure" ist der Standard aus dieser Datei.
|
|
TRAEFIK_ENTRYPOINT=websecure
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# PostgreSQL 17 + PostGIS
|
|
# -----------------------------------------------------------------------------
|
|
POSTGRES_USER=florian
|
|
# Vor dem ersten Start ersetzen: openssl rand -base64 24
|
|
POSTGRES_PASSWORD=bitte_aendern_postgres
|
|
POSTGRES_DB=florian
|
|
# Port, unter dem Postgres auf dem Host erreichbar ist (nur Entwicklung).
|
|
POSTGRES_PORT=5442
|
|
# Verbindungszeichenfolge der Anwendung. Läuft über den Datenbankbenutzer
|
|
# "florian_app", für den Row Level Security AKTIV ist — dieser Zugang sieht nur
|
|
# Daten der Organisation, die per SET LOCAL app.current_organisation gesetzt
|
|
# wurde (siehe src/lib/db.ts).
|
|
DATABASE_URL=postgresql://florian_app:bitte_aendern_app@postgres:5432/florian?schema=public
|
|
# Passwort des Anwendungsbenutzers. Muss zu DATABASE_URL passen und wird beim
|
|
# ersten Start von docker/postgres/10-init-app-role.sh gesetzt.
|
|
POSTGRES_APP_PASSWORD=bitte_aendern_app
|
|
# Verbindung für Migrationen und Seed. Nutzt den Eigentümer-Zugang, der RLS
|
|
# umgehen darf. Niemals im Anwendungscode verwenden.
|
|
DIRECT_DATABASE_URL=postgresql://florian:bitte_aendern_postgres@postgres:5432/florian?schema=public
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Redis (Warteschlangen für BullMQ, Rate-Limiting)
|
|
# -----------------------------------------------------------------------------
|
|
# Vor dem ersten Start ersetzen: openssl rand -base64 24
|
|
REDIS_PASSWORD=bitte_aendern_redis
|
|
REDIS_URL=redis://:bitte_aendern_redis@redis:6379
|
|
# Port auf dem Host (nur Entwicklung).
|
|
REDIS_PORT=6389
|
|
# Anzahl paralleler Jobs je Worker-Prozess.
|
|
WORKER_CONCURRENCY=5
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# MinIO (S3-kompatibler Objektspeicher — ALLE Dateien liegen hier, nie im FS)
|
|
# -----------------------------------------------------------------------------
|
|
MINIO_ROOT_USER=florian
|
|
# Mindestens 8 Zeichen, vor dem ersten Start ersetzen.
|
|
MINIO_ROOT_PASSWORD=bitte_aendern_minio
|
|
# Endpunkt, den App und Worker intern ansprechen — im Compose-Netz der
|
|
# Dienstname, außerhalb der externe Hostname.
|
|
S3_ENDPOINT=minio
|
|
S3_PORT=9000
|
|
# true, sobald MinIO hinter Traefik mit TLS läuft.
|
|
S3_USE_SSL=false
|
|
S3_ACCESS_KEY=florian
|
|
S3_SECRET_KEY=bitte_aendern_minio
|
|
S3_REGION=eu-central-1
|
|
# Bucket für alle Nutzdateien (Prüfprotokolle, Fotos, Rechnungen, Exporte).
|
|
S3_BUCKET=florian
|
|
# Öffentlich erreichbare Basis-URL für presignte Download-Links. In der
|
|
# Entwicklung http://localhost:9010, in Produktion https://$MINIO_DOMAIN
|
|
S3_PUBLIC_URL=http://localhost:9010
|
|
# Gültigkeitsdauer presignter Links in Sekunden (Standard: 15 Minuten).
|
|
S3_URL_TTL=900
|
|
# Ports auf dem Host (nur Entwicklung): API und Weboberfläche.
|
|
MINIO_API_PORT=9010
|
|
MINIO_CONSOLE_PORT=9011
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Gotenberg (PDF-Erzeugung für Prüfprotokolle, Berichte, Rechnungen)
|
|
# -----------------------------------------------------------------------------
|
|
GOTENBERG_URL=http://gotenberg:3000
|
|
# Zeitlimit je PDF-Auftrag in Sekunden.
|
|
GOTENBERG_TIMEOUT=30
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Auth.js — Sitzungsverwaltung
|
|
# -----------------------------------------------------------------------------
|
|
# Signiert die Sitzungs-Cookies. Zwingend erforderlich, pro Installation neu:
|
|
# openssl rand -base64 32
|
|
AUTH_SECRET=bitte_aendern_mindestens_32_zeichen_lang
|
|
# Muss hinter einem Reverse Proxy (Traefik) auf true stehen, damit Auth.js die
|
|
# X-Forwarded-Header auswertet und korrekte Redirect-URIs erzeugt.
|
|
AUTH_TRUST_HOST=true
|
|
# Lebensdauer einer Sitzung in Sekunden (Standard: 8 Stunden).
|
|
AUTH_SESSION_MAX_AGE=28800
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# OIDC gegen authentik
|
|
# Die authentik-Instanz wird SEPARAT betrieben und ist nicht Teil dieses Stacks.
|
|
# In authentik anzulegen: Provider "OAuth2/OpenID" (Client-Typ: confidential),
|
|
# Redirect-URI exakt $APP_URL/api/auth/callback/authentik
|
|
# Scopes: openid profile email — plus einen Gruppen-Scope, wenn Rollen aus
|
|
# authentik-Gruppen vorbelegt werden sollen (siehe AUTH_OIDC_GROUP_CLAIM).
|
|
# -----------------------------------------------------------------------------
|
|
# false blendet den OIDC-Knopf aus; dann bleibt nur der lokale Login. Sinnvoll
|
|
# für den Erststart, bevor authentik konfiguriert ist.
|
|
AUTH_OIDC_ENABLED=false
|
|
# Issuer-URL des Providers, OHNE /.well-known/openid-configuration.
|
|
# Bei authentik: https://<authentik-host>/application/o/<application-slug>/
|
|
AUTH_OIDC_ISSUER=https://auth.beispiel.de/application/o/florian/
|
|
AUTH_OIDC_CLIENT_ID=
|
|
AUTH_OIDC_CLIENT_SECRET=
|
|
# Beschriftung des Anmeldeknopfes in der Oberfläche.
|
|
AUTH_OIDC_NAME=Anmeldung über authentik
|
|
# Claim, aus dem die Gruppenzugehörigkeit gelesen wird. In authentik über ein
|
|
# Scope-Mapping bereitzustellen. Leer lassen, um das Mapping abzuschalten —
|
|
# dann werden Rollen ausschließlich in FLORIAN gepflegt.
|
|
AUTH_OIDC_GROUP_CLAIM=groups
|
|
# Zuordnung authentik-Gruppe -> FLORIAN-Rolle, kommagetrennt als "gruppe:ROLLE".
|
|
# Wirkt nur als VORBELEGUNG beim ersten Login; danach ist die in FLORIAN
|
|
# gepflegte Rolle führend und wird nicht mehr überschrieben.
|
|
AUTH_OIDC_GROUP_MAPPING=feuerwehr-kommandant:KOMMANDANT,feuerwehr-geraetewart:GERAETEWART,feuerwehr-atemschutz:ATEMSCHUTZGERAETEWART,feuerwehr-kassier:KASSIER,feuerwehr-schriftfuehrer:SCHRIFTFUEHRER,feuerwehr-ausbilder:AUSBILDER,feuerwehr-mitglied:MITGLIED
|
|
# true legt einen in authentik bekannten Nutzer beim ersten Login automatisch
|
|
# als Person an. false verlangt, dass die Person vorher in FLORIAN existiert
|
|
# und über die E-Mail-Adresse verknüpft wird.
|
|
AUTH_OIDC_AUTO_PROVISION=true
|
|
# Organisation (Slug), der automatisch angelegte Personen zugeordnet werden.
|
|
AUTH_OIDC_STANDARD_ORGANISATION=ff-musterhausen
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Lokaler E-Mail/Passwort-Login (Rückfalloption für Erststart und Notbetrieb)
|
|
# -----------------------------------------------------------------------------
|
|
# Nach der Einrichtung von authentik auf false setzen, damit nur noch OIDC geht.
|
|
AUTH_LOCAL_ENABLED=true
|
|
# Zugangsdaten des ersten Administrators, angelegt vom Seed-Skript.
|
|
# Nach dem ersten Login das Passwort in der Oberfläche ändern.
|
|
SEED_ADMIN_EMAIL=admin@beispielwehr.de
|
|
SEED_ADMIN_PASSWORT=Feuerwehr2026
|
|
# Das Konto der Kreisebene aus dem Beispielbestand (Phase 10): Mitglied in der
|
|
# eigenen Wehr, Aufsicht in der Nachbarwehr. Vorgabe leitet sich aus der
|
|
# Wehrkennung ab, also kbi@ff-musterhausen.de.
|
|
# SEED_KBI_EMAIL=
|
|
# SEED_KBI_PASSWORT=Feuerwehr2026
|
|
# bcrypt-Kostenfaktor. 12 ist ein guter Kompromiss aus Sicherheit und Tempo.
|
|
AUTH_BCRYPT_ROUNDS=12
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Terminal-/Kiosk-Anmeldung im Gerätehaus (PIN und RFID)
|
|
# -----------------------------------------------------------------------------
|
|
# Schaltet den Kiosk-Modus samt Terminal-Login frei.
|
|
KIOSK_ENABLED=true
|
|
# Gemeinsames Geheimnis, mit dem sich ein Terminal-Gerät gegenüber dem Server
|
|
# ausweist, bevor überhaupt eine PIN oder ein Token akzeptiert wird:
|
|
# openssl rand -hex 32
|
|
KIOSK_DEVICE_SECRET=bitte_aendern_kiosk_geheimnis
|
|
# Länge der Personen-PIN. 4 ist bequem, 6 ist sicherer.
|
|
KIOSK_PIN_LAENGE=6
|
|
# Nach wie vielen Fehlversuchen eine PIN gesperrt wird.
|
|
KIOSK_MAX_FEHLVERSUCHE=5
|
|
# Sperrdauer nach zu vielen Fehlversuchen, in Sekunden.
|
|
KIOSK_SPERRDAUER=300
|
|
# Automatische Abmeldung am Terminal nach Untätigkeit, in Sekunden.
|
|
KIOSK_IDLE_TIMEOUT=120
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Kartenmodule (Phase 6)
|
|
# -----------------------------------------------------------------------------
|
|
# FLORIAN laedt keine Kacheln aus dem Netz. Wo eine Wehr ausrueckt und wo ihre
|
|
# Hydranten liegen, ist niemandes Geschaeft — der Kartenserver laeuft selbst:
|
|
#
|
|
# docker compose --profile karte up -d
|
|
#
|
|
# Dafuer wird eine MBTiles-Datei des Ausrueckegebiets gebraucht (siehe README).
|
|
# Ohne KARTE_STIL_URL zeigt die Karte einen leeren Hintergrund mit Gitternetz;
|
|
# Hydranten, Objekte und Lagekarte funktionieren trotzdem.
|
|
KARTE_STIL_URL=http://localhost:8085/styles/basic/style.json
|
|
# Kartenmittelpunkt beim Oeffnen (Musterhausen).
|
|
KARTE_BREITENGRAD=48.5
|
|
KARTE_LAENGENGRAD=12.15
|
|
KARTE_ZOOM=13
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Atemschutz nach FwDV 7 (Phase 5)
|
|
# -----------------------------------------------------------------------------
|
|
# Der Sicherheitshinweis ueber jeder Ansicht der Atemschutzueberwachung:
|
|
# "Ergaenzendes System — die analoge Atemschutzueberwachung bleibt fuehrend."
|
|
# Er gehoert dorthin. Auf false setzen darf ihn nur, wer eine schriftliche
|
|
# Freigabe des Kommandanten hat — und deren Fundstelle gehoert in
|
|
# ATEMSCHUTZ_FREIGABE, sonst bleibt der Hinweis stehen.
|
|
ATEMSCHUTZ_HINWEIS=true
|
|
# Aktenzeichen oder Fundstelle der Freigabe, z. B. "Kommandantenbeschluss vom 12.03.2026".
|
|
ATEMSCHUTZ_FREIGABE=
|
|
# Abstand der Druckabfrage in Sekunden. FwDV 7 nennt keinen festen Wert;
|
|
# zehn Minuten sind die uebliche Praxis.
|
|
ATEMSCHUTZ_ABFRAGE_INTERVALL=600
|
|
# Ansprechdruck der Warneinrichtung in bar. Je nach Baujahr 50 bis 60.
|
|
ATEMSCHUTZ_WARNDRUCK=55
|
|
# Sicherheitszuschlag auf den errechneten Rueckzugsdruck, in bar.
|
|
ATEMSCHUTZ_ZUSCHLAG=10
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Wetterwarnungen auf dem Hallenmonitor (optional, DWD)
|
|
# Die einzige Verbindung nach draussen, die FLORIAN von sich aus aufbaut —
|
|
# deshalb standardmaessig aus. Ohne WETTER_ENABLED=true wird nichts abgerufen.
|
|
# -----------------------------------------------------------------------------
|
|
WETTER_ENABLED=false
|
|
# Warnzellen-Nummer der eigenen Gemeinde aus der DWD-Warnzellenliste:
|
|
# https://www.dwd.de/DE/leistungen/opendata/help/warnungen/cap_warncellids_csv.csv
|
|
DWD_WARNCELL=
|
|
DWD_WARNUNGEN_URL=https://www.dwd.de/DWD/warnungen/warnapp/json/warnings.json
|
|
# Zeitlimit fuer den Abruf, in Sekunden. Der Monitor darf davon nicht haengen.
|
|
WETTER_TIMEOUT=5
|
|
# Wie lange eine Antwort gilt, bevor neu gefragt wird, in Sekunden.
|
|
WETTER_ZWISCHENSPEICHER=300
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# E-Mail-Versand (optional, hinter lib/integrations/mail.ts abstrahiert)
|
|
# Ohne MAIL_ENABLED=true wird nur ins Log geschrieben — praktisch für Tests.
|
|
# -----------------------------------------------------------------------------
|
|
MAIL_ENABLED=false
|
|
MAIL_HOST=smtp.beispiel.de
|
|
MAIL_PORT=587
|
|
MAIL_SECURE=false
|
|
MAIL_USER=
|
|
MAIL_PASSWORD=
|
|
MAIL_FROM=FLORIAN <florian@beispielwehr.de>
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Telegram-Benachrichtigungen (optional, abschaltbar)
|
|
# -----------------------------------------------------------------------------
|
|
TELEGRAM_ENABLED=false
|
|
TELEGRAM_BOT_TOKEN=
|
|
TELEGRAM_CHAT_ID=
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Push über ntfy (Phase 7, optional)
|
|
#
|
|
# ntfy ist ein winziger Push-Dienst, den man selbst betreibt: ein Container,
|
|
# eine App im Store, fertig. Man abonniert ein "Thema" (einen frei gewählten
|
|
# Namen) und bekommt Meldungen darauf — ohne Konto, ohne Telefonnummer.
|
|
#
|
|
# Läuft der Server im eigenen Netz, verlässt keine Nachricht das Gerätehaus.
|
|
# Deshalb gilt ntfy in FLORIAN als INTERNER Kanal und bekommt die
|
|
# ausführlichen Texte. Wer stattdessen das öffentliche ntfy.sh einträgt, macht
|
|
# ihn zu einem externen Dienst wie jeden anderen.
|
|
#
|
|
# ACHTUNG: Ein Thema ist nur so geheim wie sein Name. Wer ihn kennt, liest mit.
|
|
# FLORIAN schlägt deshalb Namen mit Zufallsanteil vor.
|
|
# -----------------------------------------------------------------------------
|
|
NTFY_ENABLED=false
|
|
# NTFY_URL=http://ntfy:80
|
|
# Nur nötig, wenn der eigene ntfy Zugriffsschutz eingeschaltet hat.
|
|
NTFY_TOKEN=
|
|
NTFY_TIMEOUT=10
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Web-Push in den Browser (Phase 7, optional)
|
|
#
|
|
# Der Weg, der ohne App auskommt. Die Meldung läuft über den Push-Dienst des
|
|
# Browserherstellers (Mozilla, Google, Apple) — verschlüsselt, aber sie
|
|
# verlässt das Netz der Wehr. Deshalb ist Web-Push ein EXTERNER Kanal und
|
|
# bekommt nur Kurzfassungen: "3 Prüfungen fällig", nicht welche.
|
|
#
|
|
# Schlüsselpaar erzeugen mit: npm run vapid
|
|
#
|
|
# ACHTUNG: Beide Schlüssel gehören ins Backup. Ein neuer öffentlicher Schlüssel
|
|
# macht alle bestehenden Push-Abos wertlos — jeder müsste Push neu erlauben,
|
|
# und niemand merkt es, die Meldungen bleiben einfach aus.
|
|
# -----------------------------------------------------------------------------
|
|
WEBPUSH_ENABLED=false
|
|
WEBPUSH_PUBLIC_KEY=
|
|
WEBPUSH_PRIVATE_KEY=
|
|
# Kontaktweg für den Push-Dienst, "mailto:..." oder eine Adresse.
|
|
WEBPUSH_KONTAKT=
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# WhatsApp: bewusst NICHT.
|
|
#
|
|
# Es gibt keine WHATSAPP_-Variablen, und das ist eine Entscheidung, keine Lücke.
|
|
# Die Begründung steht im README unter "Warum kein WhatsApp" — kurz: die
|
|
# Business-Plattform kostet je Konversation, verlangt einen Vertrag mit Meta
|
|
# als Auftragsverarbeiter, und die App gleicht das Telefonbuch ab. Für eine
|
|
# Wehr, deren Daten im Gerätehaus bleiben sollen, ist das der falsche Weg.
|
|
# -----------------------------------------------------------------------------
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Benachrichtigungen und Termine (Phase 7)
|
|
# -----------------------------------------------------------------------------
|
|
# Wann der Worker die Erinnerungen anlegt und verschickt (cron, Europe/Berlin).
|
|
# Bewusst am frühen Morgen und nicht nachts: eine Push-Meldung um drei Uhr
|
|
# weckt Leute, die am nächsten Tag arbeiten müssen.
|
|
BENACHRICHTIGUNG_LAUF=0 7 * * *
|
|
# Wie viele Tage vor einem Termin erinnert wird (kommagetrennt).
|
|
# "7,1": einmal in der Woche davor, damit man den Abend freihalten kann, und
|
|
# einmal am Vortag, weil man es bis dahin wieder vergessen hat.
|
|
TERMIN_ERINNERUNG_TAGE=7,1
|
|
# Wie oft eine fehlgeschlagene Zustellung wiederholt wird, bevor sie als
|
|
# fehlgeschlagen stehen bleibt. Stehen bleiben ist Absicht: eine still
|
|
# verschluckte Benachrichtigung ist schlimmer als eine sichtbar gescheiterte.
|
|
BENACHRICHTIGUNG_VERSUCHE=3
|
|
# Wie lange ZUGESTELLTE Benachrichtigungen aufgehoben werden.
|
|
# Fehlgeschlagene bleiben — sie zeigen einen kaputten Kanal an.
|
|
BENACHRICHTIGUNG_AUFBEWAHRUNG_TAGE=90
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# LLM-Anbindung (optional; nur selbstgehostete Endpunkte, kein Cloud-Zwang)
|
|
# -----------------------------------------------------------------------------
|
|
# ES GIBT KEINEN RUECKFALL AUF EINEN ANBIETER. Laeuft der eigene Endpunkt
|
|
# nicht, fehlen die KI-Funktionen — sie werden nicht durch einen fremden
|
|
# Dienst ersetzt. Ein Einsatzbericht spricht ueber Menschen in ihrer
|
|
# schlechtesten Stunde; solche Texte gehoeren nirgendwo anders hin.
|
|
#
|
|
# Container starten: docker compose --profile ki up -d
|
|
# Modelle holen: docker compose exec ollama ollama pull <modell>
|
|
LLM_ENABLED=false
|
|
# OpenAI-kompatibler Endpunkt, z. B. eine lokale Ollama- oder vLLM-Instanz.
|
|
LLM_BASE_URL=http://ollama:11434/v1
|
|
LLM_API_KEY=
|
|
LLM_MODELL=qwen2.5:14b
|
|
# Zeitlimit fuer eine Antwort. Ein Bericht darf dauern, aber nicht ewig.
|
|
LLM_TIMEOUT=120
|
|
|
|
# Modell fuer Einbettungen (semantische Suche im Wiki).
|
|
#
|
|
# ACHTUNG: Die Spalte wikiabschnitt.einbettung ist auf 768 Dimensionen
|
|
# festgelegt — das liefert nomic-embed-text. Ein Modell mit anderer Laenge
|
|
# braucht eine Migration; wie, steht im README unter Phase 8.
|
|
LLM_EINBETTUNG_MODELL=nomic-embed-text
|
|
LLM_EINBETTUNG_DIMENSIONEN=768
|
|
|
|
# Modell, das Bilder lesen kann — fuer die Belegerfassung. Ohne dieses Modell
|
|
# werden Belege trotzdem abgelegt, die Angaben nur von Hand eingetragen.
|
|
# LLM_VISION_MODELL=llama3.2-vision
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Spracherkennung fuers Diktat (Phase 8, optional)
|
|
#
|
|
# Selbst betriebener faster-whisper im Compose-Profil "ki". Groesse ueber
|
|
# WHISPER_MODELL: "tiny" laeuft auf jedem Buerorechner, "base" ist der
|
|
# brauchbare Kompromiss, "small" erkennt Fachbegriffe merklich besser und
|
|
# will dafuer Zeit oder eine Grafikkarte.
|
|
# -----------------------------------------------------------------------------
|
|
WHISPER_ENABLED=false
|
|
WHISPER_URL=http://whisper:8000
|
|
WHISPER_MODELL=base
|
|
WHISPER_SPRACHE=de
|
|
# Zeitlimit fuer eine Aufnahme. Zehn Minuten Sprache brauchen Zeit.
|
|
WHISPER_TIMEOUT=300
|
|
# Hoechstlaenge einer Aufnahme in Sekunden.
|
|
DIKTAT_MAX_SEKUNDEN=600
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Einsätze und Übungen (Phase 3)
|
|
# -----------------------------------------------------------------------------
|
|
# Adressen zu Koordinaten auflösen. Vorgesehen ist ein SELBST betriebener
|
|
# Nominatim — Einsatzadressen gehören nicht an einen öffentlichen Dienst, und
|
|
# dessen Nutzungsbedingungen erlauben es ohnehin nicht.
|
|
GEOCODING_ENABLED=false
|
|
# NOMINATIM_URL=http://nominatim:8080
|
|
GEOCODING_TIMEOUT=5
|
|
# Auf welche Länder die Suche eingegrenzt wird (ISO-Codes, kommagetrennt).
|
|
GEOCODING_LAENDER=de,at,ch
|
|
|
|
# Einsatzportal für Fremdwehren: ein signierter Link ohne Anmeldung, über den
|
|
# eine Nachbarwehr den Stand sieht und Lagemeldungen absetzen kann.
|
|
PORTAL_ENABLED=true
|
|
# Wie lange ein neu erzeugter Link gilt.
|
|
PORTAL_GUELTIGKEIT_STUNDEN=24
|
|
# Höchstzahl Zugriffe je Link und Stunde.
|
|
PORTAL_MAX_ZUGRIFFE=120
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Wartung und Prüfung (Phase 2)
|
|
# -----------------------------------------------------------------------------
|
|
# Wann der nächtliche Lauf Prüftermine plant. Cron-Syntax, Zeitzone
|
|
# Europe/Berlin. Der Worker trägt den Zeitplan beim Start je Wehr selbst ein.
|
|
WARTUNG_NACHTLAUF=15 3 * * *
|
|
# Wann die Erinnerungen verschickt werden. Bewusst nach der Planung: sonst
|
|
# erinnert der Lauf an Termine, die es noch gar nicht gibt.
|
|
WARTUNG_ERINNERUNG_LAUF=45 3 * * *
|
|
# Wie weit im Voraus Termine angelegt werden. Ohne Horizont stünden Termine für
|
|
# die nächsten zehn Jahre im Dashboard.
|
|
WARTUNG_PLANUNGSHORIZONT_TAGE=180
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Datenschutz und Aufbewahrung (DSGVO)
|
|
# -----------------------------------------------------------------------------
|
|
# Aufbewahrungsfrist für Einsatz- und Prüfdokumentation in Jahren.
|
|
AUFBEWAHRUNG_JAHRE=10
|
|
# Aufbewahrungsfrist für den Audit-Log in Tagen. Der Log ist append-only;
|
|
# Älteres wird vom Worker exportiert, bevor es entfernt wird.
|
|
AUDIT_AUFBEWAHRUNG_TAGE=3650
|
|
# Frist in Tagen, nach der ein ausgetretenes Mitglied anonymisiert wird.
|
|
PERSON_ANONYMISIERUNG_TAGE=365
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Telemetrie bleibt aus. Nicht ändern.
|
|
# -----------------------------------------------------------------------------
|
|
NEXT_TELEMETRY_DISABLED=1
|
|
CHECKPOINT_DISABLE=1
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Testwehr fuer die E2E-Tests
|
|
#
|
|
# Die Playwright-Tests laufen gegen eine EIGENE Wehr, nicht gegen die
|
|
# Beispielwehr aus der Anleitung. Sonst wachsen deren Listen bei jedem Lauf,
|
|
# und die Bildschirmfotos aendern sich, ohne dass sich die Oberflaeche
|
|
# geaendert haette.
|
|
#
|
|
# Vor dem Lauf einmal: npm run db:test-reset
|
|
# -----------------------------------------------------------------------------
|
|
E2E_SLUG=ff-teststelle
|
|
E2E_NAME=Freiwillige Feuerwehr Teststelle
|
|
E2E_KURZNAME=FF Teststelle
|
|
E2E_ADMIN_EMAIL=e2e@teststelle.de
|
|
E2E_ADMIN_PASSWORT=Feuerwehr2026
|