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
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
// retention-notify-job ist der Aufrufpunkt fuer RET-07 (systemd-Timer,
|
||||
// konfigurierbare Kadenz, analog scrub-cli/BAK-08): ein Durchlauf pro
|
||||
// Aufruf, ermittelt bald ablaufende Objekte (RET-02) und loest fuer noch
|
||||
// nicht benachrichtigte je ein Ereignis ueber Core CFG-05 aus. Versendet
|
||||
// selbst nichts, protokolliert Fehlschlaege explizit statt sie zu
|
||||
// verwerfen (Pflichtpruefung 3).
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"gitea.perlbach24.de/scripte/nexarch/archive/internal/notifyclient"
|
||||
"gitea.perlbach24.de/scripte/nexarch/archive/internal/retentionnotify"
|
||||
)
|
||||
|
||||
func requireEnv(name string) string {
|
||||
v := os.Getenv(name)
|
||||
if v == "" {
|
||||
log.Fatalf("%s muss gesetzt sein", name)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func main() {
|
||||
dsn := requireEnv("NEXARCH_RETENTION_TENANT_DSN")
|
||||
notifyBaseURL := requireEnv("NEXARCH_RETENTION_NOTIFY_BASE_URL")
|
||||
notifyServiceToken := requireEnv("NEXARCH_RETENTION_NOTIFY_SERVICE_TOKEN")
|
||||
recipient := retentionnotify.Recipient{
|
||||
TenantSlug: requireEnv("NEXARCH_RETENTION_NOTIFY_TENANT_SLUG"),
|
||||
UserID: requireEnv("NEXARCH_RETENTION_NOTIFY_ADMIN_USER_ID"),
|
||||
Email: requireEnv("NEXARCH_RETENTION_NOTIFY_ADMIN_EMAIL"),
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
pool, err := pgxpool.New(ctx, dsn)
|
||||
if err != nil {
|
||||
log.Fatalf("datenbankverbindung: %v", err)
|
||||
}
|
||||
defer pool.Close()
|
||||
|
||||
client := notifyclient.New(notifyBaseURL, notifyServiceToken)
|
||||
|
||||
results, err := retentionnotify.Run(ctx, pool, client, time.Now().UTC(), recipient)
|
||||
if err != nil {
|
||||
log.Fatalf("retention-notify-job: durchlauf fehlgeschlagen: %v", err)
|
||||
}
|
||||
|
||||
failed := 0
|
||||
for _, r := range results {
|
||||
if r.Err != nil {
|
||||
failed++
|
||||
log.Printf("retention-notify-job: FEHLER bei objekt %s (klasse %s): %v", r.RetentionObjectID, r.RetentionClass, r.Err)
|
||||
continue
|
||||
}
|
||||
log.Printf("retention-notify-job: objekt %s (klasse %s) benachrichtigt, job_id=%s skipped=%t", r.RetentionObjectID, r.RetentionClass, r.JobID, r.Skipped)
|
||||
}
|
||||
log.Printf("retention-notify-job: durchlauf abgeschlossen, %d ergebnis(se), %d fehlgeschlagen", len(results), failed)
|
||||
}
|
||||
Reference in New Issue
Block a user