fix(archive): RET-05 retention_class fehlte, AC1 verlangt es explizit

Vor Board-Flip bemerkt: Akzeptanzkriterium 1 fordert Objekttyp MIT
Aufbewahrungsklasse UND Rueckruf-Adresse, retention_class fehlte im
ersten Entwurf komplett. Migration, Registration-Struct, Register,
ListRegistrations und RegisterHandler ergaenzt, Tests angepasst
(Idempotenz jetzt auch fuer retention_class geprueft, nicht nur
callback_url). Real auf 131 gedroppt und neu angewendet.
This commit is contained in:
sysops
2026-08-30 01:43:33 +02:00
parent 19dca43012
commit 0db32007ba
6 changed files with 52 additions and 31 deletions
+14 -13
View File
@@ -21,10 +21,11 @@ import (
// Registration ist EIN registrierter Objekttyp eines Moduls.
type Registration struct {
ID string
ModuleName string
ObjectType string
CallbackURL string
ID string
ModuleName string
ObjectType string
RetentionClass string
CallbackURL string
}
// Register registriert einen Objekttyp eines Moduls mit Rückruf-Adresse
@@ -36,23 +37,23 @@ type Registration struct {
// UPSERT-artig), weil ein bereits registrierter Rückruf nicht
// stillschweigend durch eine zweite, möglicherweise abweichende
// Registrierung ersetzt werden darf.
func Register(ctx context.Context, pool *pgxpool.Pool, moduleName, objectType, callbackURL string) (Registration, error) {
func Register(ctx context.Context, pool *pgxpool.Pool, moduleName, objectType, retentionClass, callbackURL string) (Registration, error) {
var reg Registration
err := pool.QueryRow(ctx, `
INSERT INTO module_registrations (module_name, object_type, callback_url)
VALUES ($1, $2, $3)
INSERT INTO module_registrations (module_name, object_type, retention_class, callback_url)
VALUES ($1, $2, $3, $4)
ON CONFLICT (module_name, object_type) DO NOTHING
RETURNING id, module_name, object_type, callback_url
`, moduleName, objectType, callbackURL).Scan(&reg.ID, &reg.ModuleName, &reg.ObjectType, &reg.CallbackURL)
RETURNING id, module_name, object_type, retention_class, callback_url
`, moduleName, objectType, retentionClass, callbackURL).Scan(&reg.ID, &reg.ModuleName, &reg.ObjectType, &reg.RetentionClass, &reg.CallbackURL)
if err == nil {
return reg, nil
}
// ON CONFLICT DO NOTHING liefert keine Zeile zurueck (pgx: ErrNoRows) -
// bestehende Registrierung unveraendert nachlesen und zurueckgeben.
err = pool.QueryRow(ctx, `
SELECT id, module_name, object_type, callback_url FROM module_registrations
SELECT id, module_name, object_type, retention_class, callback_url FROM module_registrations
WHERE module_name = $1 AND object_type = $2
`, moduleName, objectType).Scan(&reg.ID, &reg.ModuleName, &reg.ObjectType, &reg.CallbackURL)
`, moduleName, objectType).Scan(&reg.ID, &reg.ModuleName, &reg.ObjectType, &reg.RetentionClass, &reg.CallbackURL)
if err != nil {
return Registration{}, fmt.Errorf("moduleadapter: registrierung lesen/anlegen: %w", err)
}
@@ -63,7 +64,7 @@ func Register(ctx context.Context, pool *pgxpool.Pool, moduleName, objectType, c
// für Statusübersichten und Tests (Pflichtprüfung 1: zwei Module
// parallel registriert ohne Kollision).
func ListRegistrations(ctx context.Context, pool *pgxpool.Pool) ([]Registration, error) {
rows, err := pool.Query(ctx, `SELECT id, module_name, object_type, callback_url FROM module_registrations ORDER BY module_name, object_type`)
rows, err := pool.Query(ctx, `SELECT id, module_name, object_type, retention_class, callback_url FROM module_registrations ORDER BY module_name, object_type`)
if err != nil {
return nil, fmt.Errorf("moduleadapter: registrierungen auflisten: %w", err)
}
@@ -72,7 +73,7 @@ func ListRegistrations(ctx context.Context, pool *pgxpool.Pool) ([]Registration,
var regs []Registration
for rows.Next() {
var r Registration
if err := rows.Scan(&r.ID, &r.ModuleName, &r.ObjectType, &r.CallbackURL); err != nil {
if err := rows.Scan(&r.ID, &r.ModuleName, &r.ObjectType, &r.RetentionClass, &r.CallbackURL); err != nil {
return nil, fmt.Errorf("moduleadapter: registrierungs-zeile lesen: %w", err)
}
regs = append(regs, r)