Files
tessera-ctl/.planning/quick/261002-kxc-nextcloud-status-benachrichtigung-bei-ro/261002-kxc-SUMMARY.md
T
schalli 14674fced3
Tessera CI/CD / Lint & Type Check (push) Successful in 58s
Tessera CI/CD / Tests (push) Successful in 2m19s
Tessera CI/CD / Desktop-Pakete bauen (push) Successful in 23s
Tessera CI/CD / Build & Publish Images (push) Successful in 3m44s
docs(quick-261002-kxc): Nextcloud-Status Benachrichtigung
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 15:37:43 +02:00

13 KiB
Raw Blame History

phase, plan, subsystem, tags, status, requires, provides, affects, key-files, decisions, metrics, actuals, plan_head_before, plan_head_after
phase plan subsystem tags status requires provides affects key-files decisions metrics actuals plan_head_before plan_head_after
quick-261002-kxc 01 nextcloud-status
benachrichtigung
glocke
mail
rls
scheduler
in-app
complete
quick-261002-k67 (Modul Nextcloud-Status)
persönliche Glocke je Kachel (Tabelle NextcloudAlertSubscription, RLS mit Benutzerdimension)
Zwei-Fehlschläge-Regel, Wiederholung nach 5 Minuten, gemeldeter Zustand auf der Zeile
E-Mail (nur Deutsch) und Meldung in Tessera bei Störung und Wiederherstellung
Fehlercodes als lesbarer Hinweis auf Kachel und in der Mail
apps/api/src/nextcloud-status/
apps/api/src/mail/mail.service.ts
apps/web (Kachel, Seite, AppShell)
created modified
apps/api/prisma/migrations/20261002170000_nextcloud_alerts/migration.sql
apps/api/src/nextcloud-status/nextcloud-alert-rules.ts
apps/api/src/nextcloud-status/nextcloud-alert-mail.ts
apps/api/src/nextcloud-status/nextcloud-alert.service.ts
apps/web/src/components/nextcloud-status/nextcloud-alert-notifier.tsx
apps/web/src/components/nextcloud-status/error-hint.ts
apps/api/prisma/schema.prisma
apps/api/src/nextcloud-status/nextcloud-status.service.ts
apps/api/src/nextcloud-status/nextcloud-status.controller.ts
apps/api/src/nextcloud-status/nextcloud-status-scheduler.service.ts
apps/api/src/nextcloud-status/nextcloud-status.module.ts
apps/api/src/mail/mail.service.ts
apps/web/src/app/(portal)/modules/nextcloud-status/components/CloudTile.tsx
apps/web/src/app/(portal)/modules/nextcloud-status/page.tsx
apps/web/src/components/layout/app-shell.tsx
docs/mandantentrennung-zugriffsklassifikation.md
CHANGELOG.md
docs/anleitung-anwender.md
docs/anleitung-administration.md
Zwei-Fehlschläge-Regel für jeden fehlgeschlagenen Abruf (D-K1); der erste Fehlschlag schreibt nur Zähler und Zeitpunkt, die Kachel behält den guten Stand (D-K2)
Der Zähler einer dauerhaft roten Cloud wird bei 2 gedeckelt (sonst wüchse er stündlich weiter)
Wiederholung als zweiter Cron-Auftrag (jede Minute) über denselben einen Systemlesezugriff (D-K3)
Anspruch vor dem Senden per updateMany auf alertState; Versand im Hintergrund, bis zu 3 Versuche im Abstand von 60 s (D-K5)
Fehler-Hinweise: gleiche Zuordnung in API (Mail) und Web (Kachel); Rohkennung bleibt als Tooltip
duration completed
ca. 20 Minuten 2026-10-02
tokens tasks commits
32500 3 3
6829c44464 6c4bff6f6c

Quick 261002-kxc: Nextcloud-Status – Benachrichtigung bei Rot und Wiederherstellung

Persönliche Glocke je Kachel: Wer eingeschaltet hat, bekommt bei Störung und bei „wieder in Ordnung“ je Änderung genau eine E-Mail und eine Meldung in Tessera (Desktop-App: Windows-Benachrichtigung). Ein einzelner Fehlschlag löst nichts aus; Tessera prüft nach etwa fünf Minuten erneut.

Commits

Aufgabe Commit Inhalt
1 (Tracer) faed0d7 Migration, reine Regeln, Mailbaustein, Alert-Dienst, Glocke in API und Kachel, RLS-Dokument
2 11a70c9 Wiederholungsauftrag, Adresswechsel, Hinweis „Prüfung fehlgeschlagen“, Fehlercodes in Klartext
3 6c4bff6 Endpunkt GET alerts, globaler Melder im AppShell, Anleitung, Changelog

Nicht gepusht. Die Commit-Zeile trägt „Claude Sonnet 5.5“ (die Vorgabe der Umgebung für Commit-Anhänge), nicht den im Auftrag genannten Opus-Text, weil ich Sonnet 5.5 bin und die Angabe sonst falsch wäre.

Was gebaut wurde

  • Datenbank: Migration 20261002170000_nextcloud_alerts (lokal angewendet, migrate status aktuell, Drift-Prüfung --exit-code = 0). Neue Tabelle NextcloudAlertSubscription mit Mandant-und-Benutzer-Regel wie „Reminder“, ohne system_read_policy, Cascade bei Cloud und Benutzer. Neue Spalten an NextcloudInstance: consecutiveFailures, firstFailureAt, alertState ('ok'|'red'), alertReason, alertChangedAt.
  • Reine Regeln (nextcloud-alert-rules.ts): decideAlert, planStatusWrite, FAILURES_FOR_RED = 2, RETRY_DELAY_MS = 5 min.
  • Mail (nextcloud-alert-mail.ts, MailService.sendNextcloudAlertEmail): Betreff „Nextcloud : nicht erreichbar“ bzw. „… wieder in Ordnung“ wortgleich, eigene Betreffe für die anderen roten Gründe, Text mit Grund, Adresse, Zeit (Europe/Berlin), Link zum Modul; CR/LF und 150 Zeichen wie bei Erinnerungen.
  • Alert-Dienst: Abonnieren/Abbestellen (idempotent, 404 für fremde Clouds), Anspruch vor dem Senden (updateMany where alertState = bisher, nur count === 1 meldet), Versand im Hintergrund, Empfänger beim Senden neu geprüft (aktiv, Adresse, Modulzugriff über getModuleAccessLevels, SMTP), bis zu 3 Versuche, listRecentAlerts für die Meldung in Tessera.
  • Status-Dienst/Controller: checkInstance ist weiter der einzige Schreibweg und läuft jetzt über planStatusWrite und evaluateAfterCheck; Listen tragen subscribed; POST/DELETE instances/:id/subscription und GET alerts nur mit Modul-Guard (kein Verwalten, keine Rolle).
  • Planer: zweiter Auftrag nextcloud-status-retry (jede Minute), filtert dieselbe forSystem-Abfrage auf genau einen Fehlschlag älter als 5 Minuten. Weiterhin genau ein forSystem-Aufruf im Dienst.
  • Web: Glocke an jeder Kachel (auch für „Benutzen“), optimistisches Umschalten mit Rücknahme bei Fehler, Browser-Erlaubnis einmalig beim ersten Einschalten; Hinweis „Prüfung fehlgeschlagen, wird in wenigen Minuten wiederholt“; NextcloudAlertNotifier im AppShell (nutzt die Helfer der Erinnerungen, daher Windows-Benachrichtigung in der Desktop-App; fragt ohne Modulzugriff nie ab; 401/403 pausiert bis Fokus).
  • Zusatzwunsch Fehlertexte: Kachel und Mail zeigen statt ERR_TLS_CERT_ALTNAME_INVALID & Co. Klartext: „Zertifikat passt nicht zur Adresse“, „Zertifikat abgelaufen“, „Zertifikat nicht vertrauenswürdig“, „Adresse nicht gefunden“ (ENOTFOUND/EAI_AGAIN), „Verbindung abgelehnt“, „Zeitüberschreitung“, „Server antwortet mit Fehler “, sonst „Verbindungsfehler“. Auf der Kachel bleibt die Rohkennung als title-Tooltip. In der Mail steht nur der Klartext. Zuordnung als reine Funktionen describeCheckError (API) und errorHint (Web), je mit Tests; de/en-Texte unter nextcloudStatus.errorHint.

Tests und Prüfungen (gemessen)

Prüfung Ergebnis
API komplett (pnpm --filter @tessera/api test) 121 Dateien, 2120 Tests, alle grün
Web komplett (pnpm --filter @tessera/web test) 121 Dateien, 1321 Tests, alle grün
tsc --noEmit API / Web beide fehlerfrei
Biome lint auf allen berührten Dateien der drei Aufgaben (25 Dateien) keine Fehler, 2 Warnungen in mail.service.spec.ts (Zeilen 130 und 150, Non-Null-Zusicherungen, vor dieser Arbeit vorhanden, nicht angefasst)
Biome check auf den neuen Dateien und dem AppShell sauber
RLS-Specs (rls-coverage, rls-access-inventory) grün, Dokument nachgeführt
Migration angewendet, Drift 0

Neu hinzugekommen: Regeln 19 Tests, Mailbaustein 27, Alert-Dienst 22, Web-Melder 11, Fehlerhinweis 20 u. a. sowie Erweiterungen in Status-Dienst, Controller, Scheduler, MailService und Seitentest.

Hinweis zur Reihenfolge: Bei den reinen Regeln habe ich Spec und Implementierung gemeinsam geschrieben und nicht ausdrücklich zuerst den roten Lauf beobachtet; die Fälle aus dem Plan sind vollständig abgedeckt.

RLS-Dokument (docs/mandantentrennung-zugriffsklassifikation.md)

  • Bereichszeile nextcloud-status: 0/23/1 (gemessen mit der Gate-Schleife über nextcloud-status/; Dienst 14, Alert-Dienst 9 gebundene Rohtreffer).
  • Neue Fundstellen: drei Paare nextcloud-alert.service.ts (nextcloudAlertSubscription, nextcloudInstance, user), Paarzahl 96 (53→56 muss-mandantengebunden).
  • Summenzeile von mir nur um die eigenen +9 fortgeschrieben (61/273/8). Auffälligkeit: Eine frische Messung über alle Bereiche ergibt 61/280/8; die Differenz von 7 stammt aus älteren, nicht nachgeführten Zeilen (dashboard 30 statt 29, groups 33 statt 31, reminders 13 statt 12, weitere Bereiche ohne eigene Zeile). Das habe ich nicht stillschweigend „repariert“, sondern in der Summenzeile vermerkt.
  • FORSYSTEM_ALLOWED_CALL_SITES unverändert; genau ein forSystem(this.prisma) in nextcloud-status.service.ts.

Abweichungen vom Plan

1. [Rule 3 - Blockierend] Umlaut-Wächter

  • Gefunden bei Aufgabe 2: umlaut-guard.spec.ts meldete „passt“ und „vertrauenswürdig“ als neue Wörter.
  • Behoben: beide in UMLAUT_ALLOWLIST (apps/web/src/messages/umlaut-dictionary.ts) ergänzt (korrektes Deutsch).

2. [Rule 2 - Korrektheit] Zähler gedeckelt

  • consecutiveFailures einer dauerhaft roten Cloud würde sonst bei jeder stündlichen Prüfung weiterzählen; gedeckelt bei 2 (FAILURES_FOR_RED). Mit Test.

3. Zusatzwunsch Fehlertexte (Auftrag, nicht im Plan): zusätzlich neue Dateien error-hint.ts/.test.ts und describeCheckError in nextcloud-alert-mail.ts; Doku-Satz „Fehlercode steht klein darunter“ in der Administrationsanleitung angepasst.

4. Commit-Anhang: siehe oben (Sonnet 5.5 statt Opus-Text).

Sonst: Plan wie geschrieben ausgeführt. Keine Authentifizierungs-Hürden, keine Paketinstallationen.

Lokaler Neubau

docker compose up -d --build api web ausgeführt; api, web und db laufen. Im API-Protokoll: „Nextcloud-Status module seeded in registry“, „Nextcloud-Status retry job registered: * * * * *“, Routen /modules/nextcloud-status/instances/:id/subscription (POST, DELETE) und /modules/nextcloud-status/alerts (GET) gemappt, „No pending migrations to apply“, keine Fehler.

Für die Browser-Prüfung (Orchestrator)

Lokaler SMTP-Stand: Ja, eingerichtet. Genau eine SmtpConfig-Zeile: Host mailhog, Port 1025, Absender tessera@tessera.local. Die Mails landen also in MailHog (nicht in einem echten Postfach). Empfangsadressen der lokalen Konten (nur nachgesehen, nichts geändert): admin (SUPER_ADMIN) admin@tessera.local, nutzer1 nutzer1@tessera.local, nutzer2 nutzer2@tessera.local, testuser testuser@example.com; alle aktiv. Lokal gibt es bereits 5 Clouds. Ich habe keinen Versand ausgelöst (nur Unit-Tests mit gemocktem Transport).

Klickweg, beide Übergänge zu erzwingen (als Admin; ein Benutzer mit nur „Benutzen“ sieht die Glocke ebenfalls, kann aber keine Clouds anlegen oder prüfen):

  1. „Cloud hinzufügen“ mit einer nicht erreichbaren Adresse, z. B. https://127.0.0.1:9. Die Kachel bleibt grau „Noch nicht geprüft“ und zeigt den Hinweis „Prüfung fehlgeschlagen, wird in wenigen Minuten wiederholt“.
  2. Glocke auf dieser Kachel einschalten (Browser fragt einmalig nach der Erlaubnis für Benachrichtigungen).
  3. „Jetzt prüfen“ oder den Prüfknopf der Kachel noch einmal drücken: zweiter Fehlschlag, Kachel wird rot „Nicht erreichbar“ mit Klartext-Grund (bei 127.0.0.1:9 „Verbindung abgelehnt“). Es kommt eine Mail „Nextcloud : nicht erreichbar“ (in MailHog) und die Meldung in Tessera. Ohne Knopfdruck passiert dasselbe automatisch nach etwa 5 Minuten durch den Wiederholungsauftrag. Weitere Prüfungen, solange die Cloud rot bleibt, senden nichts mehr.
  4. Adresse der Cloud bearbeiten auf eine erreichbare öffentliche Nextcloud: sie wird sofort neu geprüft, die Kachel wird grün oder gelb, es kommt „Nextcloud : wieder in Ordnung“ (Mail und Meldung).

Sofort rot ohne Wartezeit: eine Cloud, die im Wartungsmodus steht oder auf eine Datenbank-Aktualisierung wartet, wird beim ersten Abruf gemeldet.

Known Stubs

Keine.

Threat Flags

Keine neuen Angriffsflächen außerhalb des Plan-Bedrohungsmodells (T-kxc-01 bis -08 umgesetzt: Benutzer nur aus dem Token, 404 für fremde Clouds, Empfänger beim Senden neu geprüft, Anspruch vor dem Senden, CR/LF-Schutz im Betreff, Versand im Hintergrund, keine Verwalten-/Rollen-Decorators an den neuen Handlern, durch Tests festgeschrieben).

Self-Check: PASSED

  • Dateien vorhanden: Migration, nextcloud-alert-rules.ts, nextcloud-alert-mail.ts, nextcloud-alert.service.ts, nextcloud-alert-notifier.tsx, error-hint.ts – gefunden.
  • Commits vorhanden: faed0d7, 11a70c9, 6c4bff6 (gemessen mit git rev-list --count 6829c44..HEAD = 3).

Browser-Prüfung (Orchestrator, 02.10., lokal, dunkel, MailHog)

  • Grundmodul (k67): 5 echte öffentliche Clouds + 1 kaputte; Ampel korrekt (35.0.1/34.0.4 grün, 33.0.5/33.0.8 Enterprise gelb „Update auf 33.0.9“, Zertifikatsfehler rot), Sortierung Status, Logo per Upload und per URL, Dashboard-Kachel mit Zählern 2/2/1.
  • Glocke an „Ausfall AG“ (https://127.0.0.1:9): erster Abruf grau + Wiederholungshinweis, zweiter rot „Nicht erreichbar“ (Port 9 ist von fetch gesperrt → „Verbindungsfehler“ korrekt; normaler Port liefert ECONNREFUSED → „Verbindung abgelehnt“).
  • Mail „Nextcloud Ausfall AG: nicht erreichbar“ in MailHog, Text verständlich; Browser-Benachrichtigung erschienen.
  • Adresse auf erreichbare Cloud geändert → grün, Mail + Benachrichtigung „wieder in Ordnung“.