Aktualisieren
Ein neuer Stand bringt Migrationen mit, und einige davon legen Bedingungen an, die es vorher nicht gab:
- keine überlappenden Verrechnungssätze,
- keine zwei laufenden Einsatzzeiten je Mitarbeiter.
Findet die Datenbank Zeilen, die dem widersprechen, bricht die Migration ab und der Container startet nicht. Das ist gewollt: lieber ein Start, der sagt warum, als eine Datenbank, die stillschweigend Daten verwirft.
Vorher nachsehen
Das Prüfskript ändert nichts; Lesezugriff genügt.
psql "$DATABASE_URL_MIGRATIONS" -f packages/database/scripts/vor-dem-einspielen.sql
Im laufenden Docker-Aufbau:
docker compose exec -T postgres psql -U worktime -d worktime \
< packages/database/scripts/vor-dem-einspielen.sql
Es beantwortet drei Fragen: Läuft die Migration durch? Wo überlappen sich Verrechnungssätze? Und welche Buchungen tragen noch eine zu hohe Nettozeit, weil eine Korrektur die gebuchten Pausen verworfen hat?
Aufräumen
Zu jedem Befund gehört ein eigenes Skript, das zuerst nur anzeigt und den korrigierenden Teil auskommentiert enthält — eine Zeitkorrektur gehört nicht in einen Automatismus:
packages/database/scripts/saetze-ueberlappung-pruefen.sqlpackages/database/scripts/pausen-nachrechnen.sql
Die Reihenfolge
- Sichern — siehe Sicherung. Vor jeder Aktualisierung, ohne Ausnahme.
- Prüfskript laufen lassen und Befunde bereinigen.
- Neuen Stand holen und Abbilder bauen.
- Starten. Der Entrypoint der API übernimmt Migrationen, Seed, Richtlinien und den Anwendungsbenutzer selbst.
- Nachsehen:
docker compose psundcurl -s localhost:4000/api/v1/ready.
Die Adresse der API neu einbacken
Ändert sich die Adresse, unter der die API erreichbar ist, muss das Abbild der Oberfläche neu gebaut werden: Next wertet die Weiterleitung beim Bauen aus.
docker build --build-arg API_URL=http://meine-api:4000 -f apps/web/Dockerfile .
Überwachung
| Endpunkt | Bedeutung |
|---|---|
GET /api/v1/health | Läuft der Prozess? Ohne jede Abhängigkeit |
GET /api/v1/ready | Trägt die Anwendung? Datenbank, Mandantentrennung, Lizenz |
Die Liveness-Probe fasst bewusst nichts an: Eine, die die Datenbank prüft, startet den Container neu, wenn die Datenbank hakt — und verlängert den Ausfall nur.
Der Statuscode ist die eigentliche Aussage: 200 wenn es trägt, 503 bei einer Störung. Warnungen — etwa eine Lizenz, die in zehn Tagen abläuft — ergeben weiterhin 200: Sie sollen auffallen, aber den Betrieb nicht aus dem Lastverteiler nehmen.
curl -s localhost:4000/api/v1/ready | jq
{
"status": "ready",
"database": "up",
"zustand": "ok",
"pruefungen": [
{ "name": "datenbank", "befund": "ok", "meldung": "Erreichbar (2 ms)." },
{ "name": "mandantentrennung", "befund": "ok", "meldung": "Greift." },
{ "name": "lizenz", "befund": "ok", "meldung": "Gültig bis 2027-01-01." }
]
}
Alle fünf Minuten prüft die Anwendung sich selbst. Kippt der Zustand, geht eine Nachricht an ALERT_EMAIL — und noch eine, wenn es wieder in Ordnung ist. Gemeldet wird nur der Wechsel: Eine Nachricht alle fünf Minuten, solange etwas kaputt ist, liest nach der dritten niemand mehr, und die eine, die zählt, geht darin unter.
UEBERWACHUNG_STILLE_STUNDEN schaltet zusätzlich die Frage frei, ob überhaupt noch gebucht wird. Ohne Angabe bleibt sie aus, und das mit Absicht: Ein Betrieb mit Wochenende, Feiertagen und Betriebsferien liefe sonst jeden Montagmorgen rot an — und eine Überwachung, die regelmäßig grundlos anschlägt, wird abgeschaltet und fehlt dann, wenn es darauf ankommt. Für eine Fünftagewoche sind 72 ein brauchbarer Wert.