Files
nexarch/archive/docs/RET-07-PRUEFPROTOKOLL.md
T
sysops 0db8fa1377 RET-07: fristablauf-benachrichtigungen
- archive/internal/notifyclient: HTTP-Client fuer Core CFG-05 (gleiches
  Muster wie rbacclient/RET-08 fuer RBAC-06)
- archive/internal/retentionnotify.Run: ermittelt faellige Objekte ueber
  dieselbe Funktion wie RET-02-Job/RET-06-API-Preview, filtert je
  Klasse nach Vorlauf+Ein-Aus-Schalter, Postgres-persistente Dedupe
  (retention_notifications), Fehlschlag wird protokolliert statt
  verworfen (kein Eintrag -> Retry beim naechsten Durchlauf)
- archive/cmd/retention-notify-job: systemd-Timer-CLI, analog scrub-cli
- Abweichung vom urspruenglichen Ticket-Text dokumentiert: CFG-05 statt
  direktem CFG-02-Import (Modul-Trennung), konfigurierte zustaendige
  Rolle statt Objekt-Owner (RET-01 fuehrt keinen)
- real deployed auf 131 (timer taeglich 07:00 UTC), end-zu-ende
  bewiesen: echte notification_jobs-Zeile in Core-DB, zweiter
  Dienststart ohne Doppelversand

Pruefungen siehe archive/docs/RET-07-PRUEFPROTOKOLL.md
2026-08-30 09:13:01 +02:00

5.0 KiB
Raw Blame History

RET-07 Prüfprotokoll: Fristablauf-Benachrichtigungen

Voraussetzung RET-02, CFG-05 beide bereits Fertig.

Abweichung vom ursprünglichen Ticket-Text (bewusst, dokumentiert)

Der ursprüngliche Ticket-Text sprach von einer direkten "Kopplung an Core CFG-02 (Postgres-Job-Queue, E-Mail-Versand)". Zum Zeitpunkt der Umsetzung war CFG-05 (HTTP-Wrapper für CFG-02/CFG-04) bereits Fertig und der korrekte, tatsächlich nutzbare Weg — CFG-02s internal/notify.Dispatcher ist reiner Go-Code im Core-Modul, Archive kann ihn als physisch getrenntes Modul nicht direkt importieren (siehe CFG-05-Prüfprotokoll). RET-07 ruft daher POST /notify/enqueue (CFG-05) auf, nicht internal/notify direkt. Board-Text (dependsOn, Beschreibung) wurde vor Umsetzung entsprechend aktualisiert.

Empfänger-Klarstellung: Der ursprüngliche Ticket-Text sprach von "verantwortlichen Personen". retention_objects (RET-01) führt bewusst KEINE Objekt-Owner-Beziehung. Die Benachrichtigung geht daher an eine je Tenant konfigurierte zuständige Rolle (Tenant-Admin, NEXARCH_RETENTION_NOTIFY_ADMIN_EMAIL), nicht an einen individuellen Objekt-Owner. Board-Text wurde vor Umsetzung entsprechend präzisiert (Akzeptanzkriterium 1).

Umsetzung

  • archive/migrations/0006_retention_notify.up/down.sql retention_class_rules.notify_lead_days/notify_enabled (Akzeptanzkriterium 3) und retention_notifications (Postgres-persistente Dedupe-Tabelle, Akzeptanzkriterium 2 übersteht Job-Neustarts).
  • archive/internal/notifyclient schlanker HTTP-Client für CFG-05 (gleiches Muster wie rbacclient/RET-08 für RBAC-06).
  • archive/internal/retentionnotify.Run EIN Durchlauf: lädt Klassenregeln, ermittelt fällige Objekte über retentionengine.ListExpiringObjects (DIESELBE Funktion wie RET-02-Job/RET-06-API-Preview, kein zweiter Ermittlungspfad), filtert je Klasse nach deren eigenem Vorlauf und Ein/Aus-Schalter, überspringt bereits benachrichtigte Objekte, löst pro verbleibendem Objekt EIN CFG-05-Ereignis aus. Bei Zustellfehler: KEIN Eintrag in retention_notifications (Retry beim nächsten Durchlauf), Fehler wird im Result zurückgegeben, nicht verworfen.
  • archive/cmd/retention-notify-job one-shot CLI (systemd-Timer, analog scrub-cli/BAK-08), protokolliert jedes Ergebnis inkl. Fehler über log.Printf.
  • deploy/systemd/nexarch-archive-retention-notify.{service,timer}.tmpl.

Prüfungen

# Prüfung Ergebnis
1 Testfrist mit kurzem Vorlauf löst genau eine Benachrichtigung aus bestanden TestRun_ShortLeadTimeTriggersExactlyOneNotification: fake-CFG-05-Server zählt Aufrufe, genau 1; real auf 131: Testobjekt mit 1-Tage-Frist/1-Tage-Vorlauf, Job manuell gestartet, journalctl zeigt genau eine Benachrichtigung mit echter job_id, echte Zeile in Core-notification_jobs (Status pending) bestätigt
2 Deaktivierte Benachrichtigung verschickt nachweislich nichts bestanden TestRun_DisabledNotificationSendsNothing: notify_enabled=false, 0 Ergebnisse, 0 CFG-05-Aufrufe (Zähler geprüft, nicht nur "kein Fehler")
3 Fehlgeschlagener Versand wird protokolliert und nicht stillschweigend verworfen bestanden TestRun_FailedDeliveryIsReportedNotSwallowed: fake-CFG-05-Server liefert 500, Result.Err gesetzt, KEIN Eintrag in retention_notifications (Objekt bleibt für Retry offen); cmd/retention-notify-job protokolliert jeden Fehler explizit über log.Printf

Akzeptanzkriterium 2 zusätzlich real auf 131 bewiesen: Job zweimal hintereinander gestartet (simulierter Neustart, kein In-Memory-Zustand zwischen den systemd-Aufrufen) — zweiter Lauf liefert 0 Ergebnisse, journalctl bestätigt, kein zweiter CFG-05-Aufruf.

Echte Verdrahtung auf 192.168.1.131

  • Migration 0006_retention_notify real auf dms_tenant_test angewendet.
  • retention-notify-job gebaut nach /opt/nexarch-archive/bin/, /etc/nexarch/archive-retention-notify.env (0600).
  • nexarch-archive-retention-notify.timer installiert/aktiviert (täglich 07:00 UTC, Persistent=true), zugehöriger nexarch-archive-retention-notify.service (Type=oneshot).
  • Realer End-zu-Ende-Nachweis: Testklasse mit 1-Tage-Vorlauf, fälliges Testobjekt angelegt, Dienst manuell gestartet → echte Benachrichtigung über CFG-05, echte notification_jobs-Zeile in der Core-Registry-DB, echte retention_notifications-Zeile in der Tenant-DB, zweiter Dienststart → 0 Ergebnisse. Alle Testdaten anschließend entfernt.

Build/Test-Ergebnis (192.168.1.131)

go build ./...  -> clean
go vet ./...    -> clean
golangci-lint run ./...  -> 0 issues
go test ./... -p 1  -> alle Archive-Pakete bestanden (inkl. retentionnotify, objectbackup, restoretest)

Gesamtergebnis

Bestanden. Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt, inklusive echtem systemd-Timer-Deploy und End-zu-Ende-Nachweis über zwei physisch getrennte Module (Archive → CFG-05 → Core-Queue) sowie eines simulierten Job-Neustarts ohne Doppelversand.