Worker & Benachrichtigungen¶
Der Worker-Prozess¶
scripts/worker.ts startet eine pg-boss-Instanz und registriert alle Queues und Scheduler. Eine Instanz genügt. Lokal: pnpm worker. Im Container: node --import tsx scripts/worker.ts, direkt mit node gestartet, damit SIGTERM den geordneten Shutdown auslöst.
Der Worker braucht DATABASE_URL und denselben SETTINGS_ENCRYPTION_KEY wie die Web-App, außerdem APP_URL, weil er beim Versand Links auf die Statusseite baut. SESSION_SECRET braucht er nicht.
| Queue / Job | Aufgabe | Auslöser |
|---|---|---|
email-send |
Versand von E-Mails (über lib/email/) |
Ereignis |
sms-send |
SMS-Versand über Twilio | Ereignis |
webhook-dispatch |
Zustellung von Webhooks, signiert per HMAC | Ereignis |
push-send |
Versand von Web-Push-Nachrichten | Ereignis |
maintenance-transitions |
Sendet maintenance_started einmalig für laufende Fenster ohne Startmarkierung und setzt abgelaufene Wartungen still auf completed. Beide Sweeps laufen unabhängig voneinander. |
Jede Minute |
uptime-check-sweep |
Führt HTTP-Checks für fällige, nicht pausierte Komponenten mit aktivierten Checks aus | Jede Minute |
notification-event-reaper |
Setzt E-Mail-Events, die länger als 30 Minuten in pending/processing hängen, auf failed |
Alle 10 Minuten |
failed-notification-alert |
Loggt eine Warnung „notification events failed in the last window“ mit Anzahl und bis zu 50 Event-IDs, wenn in den letzten 10 Minuten E-Mail-Events fehlgeschlagen sind. Grundlage für logbasiertes Alerting, es wird nichts versendet. | Alle 10 Minuten |
uptime-check-retention |
Löscht Uptime-Check-Ergebnisse, die älter als 30 Tage sind | Täglich um 03:00 |
verify-token-cleanup |
Leert den Bestätigungs-Token bestätigter Abonnenten, deren Bestätigung älter als 30 Tage ist | Täglich um 03:00 |
Beim Start führt der Worker außerdem ensureNotificationTemplateRows() aus. Fehlt für einen Event-Typ die Template-Zeile, wird sie mit allen Kanälen aktiv angelegt.
Dispatch-Pipeline¶
Jede Benachrichtigung durchläuft denselben Weg:
- Eine Fachaktion ruft
dispatchNotification(lib/notifications/notify.ts) mit Event-Typ und betroffenen Entitäten auf. - Stummschaltung wird geprüft: Sind alle betroffenen Komponenten stummgeschaltet, wird nichts gesendet (
skipped_disabled). Kanal-Schalter je Komponente werden separat geprüft. - Template-Gates werden je Kanal geprüft (
mail,sms,webhook,push). Jeder Kanal hat ein eigenes Aktivierungs-Flag innotification_templates. Fail-closed: Ohne Zeile wird nicht gesendet. - Mail-only-Typen (
MAIL_ONLY_EVENT_TYPESinlib/notifications/mail-only.ts, derzeitdouble_optin) gehen nur per E-Mail. Webhook, SMS und Push werden für sie übersprungen, unabhängig von den Flags. - Je Kanal entstehen Zustellzeilen:
- E-Mail: eine Zeile in
notification_eventsund ein Job, sofern ein Provider eingerichtet ist und es Empfänger gibt. - Webhook, SMS, Push: je Endpunkt, Empfänger bzw. Abo eine Zeile in
webhook_deliveries,sms_deliveriesbzw.push_deliveriesund je Zeile ein Job. - Der Processor sendet. Jede Zustellung hat bis zu 3 Versuche mit Wartezeiten von 2 und danach 4 Sekunden. Das Ergebnis landet in der Zustelltabelle des Kanals.
Die Kanäle sind unabhängig. Ein deaktivierter E-Mail-Kanal blockiert SMS und Webhooks nicht.
Kanäle¶
| Kanal | Empfänger | Transport | Hinweise |
|---|---|---|---|
| Benutzerkonten und bestätigte Abonnenten (je nach Abo-Modus), E-Mail-Adresse je Komponente | SMTP (nodemailer) oder Resend | Templates je Event-Typ sind im Admin editierbar. Abonnenten-Mails nutzen Double Opt-in. Versand in Empfänger-Blöcken per BCC. | |
| Webhook | Konfigurierte Endpunkte, optional gefiltert nach Event-Typ | HTTP POST, 10 Sekunden Timeout je Versuch | Header X-SLAtus-Signature: sha256=<hex>, X-SLAtus-Event und X-SLAtus-Delivery. Zieltypen generic, slack, teams, discord formatieren den Body für das Zielsystem. Secrets sind rotierbar. |
| SMS | Vom Admin verwaltete Telefonnummern | Twilio-REST-API | Text aus einem festen Builder, auf 300 Zeichen gekürzt. Keine Selbstanmeldung. |
| Web-Push | Browser-Abos, die Besucher selbst anlegen | web-push mit VAPID-Schlüsseln |
Abos, die mit HTTP 404 oder 410 antworten, werden automatisch gelöscht. |
Bei Webhooks wird die HMAC-Signatur über den formatierten Body berechnet, der tatsächlich gesendet wird.
Event-Typen¶
Die Event-Typen sind in NOTIFICATION_EVENT_TYPES (lib/db/schema.ts) definiert, u. a.: double_optin, outage_started, service_operational, service_outage_change, incident_created, incident_updated, incident_resolved, incident_reviewed, incident_closed, maintenance_scheduled, maintenance_started, maintenance_completed und sla_report_started.
double_optin ist mail-only. Serverseitig lehnen fanOutEventTypesSchema (lib/validations/event-types.ts, Event-Filter von SMS, Webhook und Push) und setNotificationTemplateChannelEnabledAction (Kanal-Flags) diesen Typ ab.
Wiederholungen und Fehler¶
- Wiederholungen finden nur im Processor statt, also genau eine Retry-Ebene. pg-boss nutzt
retryLimit: 1nur als Absicherung gegen Abstürze. - Kein Processor wirft. Eine unerwartete Exception setzt die Zustellung auf
failedmitlastError„unexpected error: …“. Beim E-Mail-Processor bleibtsent_chunksdabei unverändert. - E-Mails werden in Empfänger-Blöcken versendet.
notification_events.sent_chunkshält fest, wie viele Blöcke schon zugestellt sind. Jeder Versuch, der Crash-Retry von pg-boss und das manuelle Resend setzen dort fort, niemand bekommt eine Mail doppelt. - E-Mail-Events, die alle Versuche verbraucht haben, können unter
/admin/notification-eventserneut gesendet werden. Dabei wird die Zeile aufpendingzurückgesetzt und erneut eingereiht. Bei teilweise zugestellten Events heißt der Button Resend remaining. failed-notification-alertmeldet fehlgeschlagene E-Mail-Events alle 10 Minuten im Log (Issue #126).