Files
omsorg/omsorgCore/CONFIGURATION.md
T
Felix KemmlerandClaude Sonnet 5 e9e96a57dc Add facilities, contracts, orders, value lists, audit log, and desktop app modules
Extends omsorgCore with full CRUD for Facility/Contract/Order plus
configurable value lists and an audit trail, and wires the omsorgapp
frontend up to the new facilities, settings, and audit-log modules;
includes a sidebar active-nav-item highlight.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-08 23:29:16 +02:00

9.1 KiB

CONFIGURATION.md — omsorgCore

Übersicht aller Konfigurationswerte des Backends: was ist einstellbar, was ist der Default, wie überschreibt man ihn. Ziel: kein Wert, den ein Betreiber sinnvoll ändern könnte, steckt fest im Code.

Wie Konfiguration geladen wird

ASP.NET Core liest Konfiguration in dieser Reihenfolge (später gewinnt):

  1. appsettings.json — Defaults, die für jede Umgebung gelten.
  2. appsettings.{ASPNETCORE_ENVIRONMENT}.json (z. B. appsettings.Development.json) — Overrides pro Umgebung. Enthält keine echten Secrets, nur CHANGE_ME_...-Platzhalter.
  3. Umgebungsvariablen — verschachtelte Keys wie Jwt:Secret werden zu Jwt__Secret (doppelter Unterstrich statt Doppelpunkt).
  4. In Development zusätzlich: dotnet user-secrets (lokal, nicht eingecheckt) — dotnet user-secrets init im OmsorgCore.Api-Projekt einmalig ausführen, dann z. B. dotnet user-secrets set "ConnectionStrings:OmsorgCore" "...".

Secrets nie einchecken. Jwt:Secret, ConnectionStrings:OmsorgCore und (sobald produktiv genutzt) Seed:AdminPassword haben in den eingecheckten appsettings*.json-Dateien nur Platzhalter — echte Werte kommen aus Umgebungsvariablen oder User-Secrets.

Auth / JWT

Key Default Env-Var Beschreibung
Jwt:Secret (kein Default, Platzhalter in Dev) Jwt__Secret Signaturschlüssel für Access-Tokens. Muss mind. 32 Zeichen, produktiv nur per Env-Var/Secret-Store.
Jwt:Issuer "OmsorgCore" Jwt__Issuer JWT-iss-Claim, wird beim Validieren geprüft.
Jwt:Audience "OmsorgClients" Jwt__Audience JWT-aud-Claim, wird beim Validieren geprüft.
Jwt:ExpiryMinutes 60 Jwt__ExpiryMinutes Gültigkeitsdauer eines Access-Tokens.
RefreshToken:ExpiryDays 60 RefreshToken__ExpiryDays Gültigkeitsdauer eines Refresh-Tokens (sliding — jede Nutzung/Rotation verlängert effektiv die Session).
Auth:MaxLoginFailures 5 Auth__MaxLoginFailures Fehlversuche pro IP innerhalb von Auth:LoginLockoutMinutes, ab denen POST /api/auth/login mit 429 sperrt (zentral für alle Clients, siehe AuthService.LoginAsync/LoginAttempt).
Auth:LoginLockoutMinutes 10 Auth__LoginLockoutMinutes Zeitfenster, in dem Fehlversuche gezählt werden, bevor die Sperre wieder abläuft.
PasswordPolicy:MinLength 8 PasswordPolicy__MinLength Mindestlänge für jedes neu gesetzte Passwort (Account-Anlage, Admin-Reset, Passwort ändern, Passwort-vergessen-Reset — zentral über IPasswordPolicy, siehe omsorgCore/CLAUDE.md). Über GET /api/auth/password-policy auch unauthentifiziert abrufbar, damit Clients denselben Wert für Hinweistexte/Vorab-Validierung nutzen können.

Passwort-Reset / E-Mail

Key Default Env-Var Beschreibung
Email:Provider "Console" Email__Provider Mail-Versandweg. Console schreibt Mails nur ins Log (sicherer Default). Smtp versendet echt über die Werte unten (implementiert über MailKit).
Email:PinExpiryMinutes 5 Email__PinExpiryMinutes Gültigkeitsdauer des 6-stelligen PINs beim "Passwort vergessen"-Flow.
Email:MaxAttempts 3 Email__MaxAttempts Maximale Anzahl Fehlversuche bei der PIN-Eingabe, bevor der Code invalidiert wird.
Email:ResetTokenExpiryMinutes 10 Email__ResetTokenExpiryMinutes Gültigkeitsdauer des Reset-Tokens nach erfolgreicher PIN-Verifikation.
Email:RequestCooldownSeconds 60 Email__RequestCooldownSeconds Mindestabstand zwischen zwei Reset-Anfragen desselben Users (Spam-Schutz).

Ein SMTP-Server, mehrere Accounts: die Verbindungsdaten (Email:Smtp:*) sind einmal gemeinsam konfiguriert, Login + Absenderidentität liegen pro benanntem Account unter Email:Accounts:<Name>:* — so lässt sich z. B. ein Account exklusiv für Passwort-Reset-Mails führen, getrennt von einem künftigen allgemeinen Absender, ohne einen zweiten Server zu brauchen.

Key Default Env-Var Beschreibung
Email:Smtp:Host (leer) Email__Smtp__Host SMTP-Server-Adresse. Nur wirksam, wenn Email:Provider = "Smtp".
Email:Smtp:Port 587 Email__Smtp__Port SMTP-Port.
Email:Smtp:EnableSsl true Email__Smtp__EnableSsl Ob StartTLS/SSL beim Verbindungsaufbau verwendet wird.
Email:Accounts:<Name>:Username (leer, Platzhalter in Dev) Email__Accounts__<Name>__Username SMTP-Login-Username dieses Accounts. Secret — nie echten Wert einchecken.
Email:Accounts:<Name>:Password (leer, Platzhalter in Dev) Email__Accounts__<Name>__Password SMTP-Login-Passwort dieses Accounts. Secret — produktiv nur per Env-Var/user-secrets, nie in appsettings*.json einchecken.
Email:Accounts:<Name>:SenderAddress (leer) Email__Accounts__<Name>__SenderAddress Absenderadresse dieses Accounts.
Email:Accounts:<Name>:SenderDisplayName "OMSORG" Email__Accounts__<Name>__SenderDisplayName Absendername dieses Accounts.
Email:PasswordResetAccount "PasswordReset" Email__PasswordResetAccount Welcher Account-Name aus Email:Accounts für Passwort-Reset-Mails verwendet wird. Standardmäßig ist "PasswordReset" bereits als Account in appsettings.json angelegt (leer, muss per Env-Var/user-secrets befüllt werden).
Email:PasswordResetTemplate:Subject "Ihr OMSORG Passwort-Reset-Code" Email__PasswordResetTemplate__Subject Betreff der Passwort-Reset-Mail.
Email:PasswordResetTemplate:BodyTemplate siehe appsettings.json Email__PasswordResetTemplate__BodyTemplate Text der Passwort-Reset-Mail. Platzhalter im Format $NAME$: $RESET_PIN$ (der 6-stellige Code) und $RESET_PIN_EXPIRY_MINUTES$ (aus Email:PinExpiryMinutes). Ersetzung über OmsorgCore.Email.EmailTemplateRenderer.
Email:UserInviteAccount "UserInvite" Email__UserInviteAccount Welcher Account-Name aus Email:Accounts für Account-Einladungsmails (neuer User-Account für einen Mitarbeiter) verwendet wird.
Email:UserInviteTemplate:Subject "Ihr OMSORG-Zugang" Email__UserInviteTemplate__Subject Betreff der Einladungsmail.
Email:UserInviteTemplate:BodyTemplate siehe appsettings.json Email__UserInviteTemplate__BodyTemplate Text der Einladungsmail. Platzhalter: $INVITE_PIN$, $INVITE_PIN_EXPIRY_DAYS$. Die Gültigkeitsdauer wird beim Anlegen des Accounts pro Einladung gewählt (POST /api/users, PinValidityDays, Default 7), nicht global konfiguriert — der Einladungs-PIN läuft über dieselbe PasswordResetCode-Tabelle wie der Passwort-vergessen-Flow, nur mit individuell längerer Gültigkeit statt der 5 Minuten aus Email:PinExpiryMinutes.

Kein API-Endpoint zum Setzen dieser Werte: SMTP-Zugangsdaten und Mail-Texte werden bewusst nie über eine vom Client erreichbare Route entgegengenommen oder ausgeliefert — nur über die üblichen serverseitigen Konfigurationswege oben. Ein POST /api/admin/email/test-send (siehe AdminEmailController) löst lediglich den Versand einer festen Testmail über die bereits konfigurierte Verbindung aus, liefert aber nie Host/Username/Passwort an den Client zurück.

Seed (nur Development)

Key Default Env-Var Beschreibung
Seed:AdminUsername "admin" Seed__AdminUsername Username des automatisch angelegten Standard-Admin-Users.
Seed:AdminPassword "abersicher" Seed__AdminPassword Passwort des Standard-Admin-Users.

Der Seed läuft nur, wenn ASPNETCORE_ENVIRONMENT=Development und noch kein User in der DB existiert (idempotent, siehe src/OmsorgCore.Infrastructure/Persistence/DbSeeder.cs). In Produktion läuft er nicht — dort braucht es einen echten User-Anlage-Flow (noch nicht gebaut, siehe omsorgCore/CLAUDE.md, "Offene Punkte").

Datenbank

Key Default Env-Var Beschreibung
ConnectionStrings:OmsorgCore (kein Default, Platzhalter in Dev) ConnectionStrings__OmsorgCore Postgres-Connection-String (Host=...;Port=5432;Database=omsorg_core;Username=...;Password=...).

Logging / Hosting

Key Default Env-Var Beschreibung
Logging:LogLevel:Default "Information" Logging__LogLevel__Default Standard-Log-Level.
Logging:LogLevel:Microsoft.AspNetCore "Warning" Logging__LogLevel__Microsoft.AspNetCore Log-Level für das ASP.NET-Core-Framework selbst.
AllowedHosts "*" AllowedHosts Host-Header-Filter von ASP.NET Core.

Bewusst nicht konfigurierbar

Diese Werte sind absichtlich fest im Code und keine Konfigurationslücke:

  • ModuleType, PermissionAction, PermissionEffect (src/OmsorgCore.Domain/Enums/) — die Rechtematrix-Bausteine. Compile-Time-Domänenkonzepte: ein neues Modul oder eine neue Aktion braucht ohnehin neuen Controller-Code, ein Config-Wert würde hier nur Scheinflexibilität vortäuschen.
  • JWT-Validierungs-Invarianten in Program.cs (ValidateIssuer/Audience/Lifetime/IssuerSigningKey = true) — Sicherheits-Grundannahmen, kein Betriebsparameter.
  • Passwort-Hashing-Algorithmus (PasswordHasher<T>, ASP.NET-Identity-Standard-PBKDF2-Iterationszahl) — bewusst der Framework-Default, kein eigenes Krypto-Rad.