- 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
64 lines
2.0 KiB
Go
64 lines
2.0 KiB
Go
// 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)
|
|
}
|