- 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
92 lines
5.0 KiB
Markdown
92 lines
5.0 KiB
Markdown
# 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.
|