Technischer Aufbau¶
SLAtus ist eine selbst gehostete Statusseite mit SLA-Verwaltung. Sie veröffentlicht den Zustand Ihrer Services, Incidents und Wartungsfenster, misst die Verfügbarkeit gegen SLA-Ziele und benachrichtigt Abonnenten.
Was läuft wo¶
SLAtus besteht aus zwei Prozessen, die aus derselben Codebasis gebaut werden und sich eine PostgreSQL-Datenbank teilen:
| Prozess | Einstieg | Aufgabe |
|---|---|---|
| Web-App | next start (Docker-Image: Port 3100) |
Öffentliche Statusseite, Admin-Oberfläche, öffentliche API-Routen, Server Actions, Export der SLA-Reports |
| Worker | scripts/worker.ts (pnpm worker) |
Hintergrundjobs: Zustellung von E-Mail, SMS, Webhooks und Push, Wartungsübergänge, Uptime-Checks, Aufräumjobs |
| PostgreSQL 16 | Docker Compose (Entwicklung: Port 5433) | Einzige Quelle der Wahrheit für den gesamten Zustand |
Info
In Produktion müssen Web-App und Worker laufen. Ohne Worker werden Benachrichtigungen zwar eingereiht, aber nie zugestellt, und geplante Checks laufen nicht. Die Web-App startet nur mit gesetztem SESSION_SECRET (siehe Authentifizierung & Sicherheit).
Technologie-Stack¶
- Framework: Next.js 16 (App Router), React 19, TypeScript im Strict Mode
- Oberfläche: Tailwind CSS 4, shadcn/ui-Komponenten auf Basis von Base UI (nicht Radix), Schrift Lato über
next/font - Daten: PostgreSQL 16, Drizzle ORM auf
postgres.js, Schema inlib/db/schema.ts - Hintergrundjobs: pg-boss (PostgreSQL-basierte Queues und Scheduler)
- Validierung: Zod 4 für jede Formular- und API-Eingabe
- Integrationen: nodemailer (SMTP), Resend, Twilio (über
fetch),web-push(VAPID),pdf-lib(PDF-Export der SLA-Reports),exceljs(Excel-Export der SLA-Reports) - i18n: next-intl für die öffentliche Oberfläche (Deutsch und Englisch). Die Sprache ist eine Site-weite Einstellung (
settings.language), ohne Sprach-Routing. Die Admin-Oberfläche ist nur englisch. - Tests: Vitest (Unit- und Integrationstests), Playwright (End-to-End)
- Paketmanager: pnpm 12 (Version gepinnt über
packageManagerinpackage.json), Node.js 26
Zwei Bereiche, eine Codebasis¶
- Öffentlicher Bereich (
app/(public)/): Statusseite/, Historie, Service-Detailseite, Badge, Rechtstexte, Abonnement-Abläufe. Seiten werden bei jedem Aufruf dynamisch gerendert und nicht gecacht.<html lang>folgtsettings.language. - Admin-Bereich (
app/admin/(dashboard)/): geschützt durch rollenbasierte Prüfungen, siehe Authentifizierung & Sicherheit. Der Admin-Bereich und die API-Dokumentation unter/api-docssind als englischer Teilbaum (lang="en") ausgezeichnet.
Die genaue Verzeichnisstruktur und die Schichtenregeln beschreibt Struktur & Stack.
Zentrale Designprinzipien¶
- Ereignisbasierte Historie. Statusänderungen werden als Zeitfenster gespeichert, nicht als tägliche Snapshots. Uptime-, Verfügbarkeits- und SLA-Werte werden daraus berechnet. Siehe Statusmodell.
- Ein Einstiegspunkt für Statusänderungen. Manuelle Änderungen in der Admin-Oberfläche, die API-Routen und der Uptime-Checker laufen über
applyComponentStatusChange, das in einer Transaktion mit Zeilensperre arbeitet. Die Ausnahmen beschreibt das Statusmodell. - Eingefrorene SLA-Reports. Ist ein Monatsreport bestätigt, werden seine Zahlen als Snapshot gespeichert und ändern sich nicht mehr, wenn Pläne oder Ziele geändert werden. Exporte als PDF und Excel werden bei jedem Abruf aus diesem Snapshot erzeugt, in der Zeitzone, die im Snapshot steht.
- Benachrichtigungen fail-closed. Eine Benachrichtigung wird nur gesendet, wenn ihre Template-Zeile existiert und aktiviert ist. Mail-only-Typen wie
double_optingehen nie über Webhook, SMS oder Push. - Geheimnisse verschlüsselt gespeichert. SMTP-Passwörter, API-Keys, Twilio-Tokens, Webhook-Secrets und VAPID-Private-Keys werden mit AES-256-GCM verschlüsselt.