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.
95 lines
4.8 KiB
Markdown
95 lines
4.8 KiB
Markdown
# RET-05 – Prüfprotokoll: Modul-Adapter-Schnittstelle
|
||
|
||
Voraussetzung RET-01 – erledigt, siehe eigenes Protokoll.
|
||
|
||
## Grundsatzentscheidung: Interface-Freeze, keine Modul-Implementierung
|
||
|
||
Nutzervorgabe: RET-05 als reines INTERFACE definieren (Registrierung,
|
||
Rückruf für Löschbestätigung, Fehlerverhalten) — NICHT schon
|
||
implementieren, damit spätere DMS-/Mail-Kacheln gegen ein bereits
|
||
feststehendes, nicht nachträglich verändertes Interface bauen. Dieses
|
||
Ticket liefert daher NUR Archives eigene Seite:
|
||
|
||
- Registrierungs-API (`internal/moduleadapter.Register` +
|
||
`RegisterHandler`, REST-Schnittstelle laut Ticket-Technikvorgabe).
|
||
- Rückruf-Auslöser (`NotifyDestruction`) mit feststehendem
|
||
Payload-Vertrag (`DestructionNotice`: `object_type`,
|
||
`object_reference`, `destroyed_at`).
|
||
|
||
**Bewusst NICHT Teil dieses Tickets**: die eigentlichen Rückruf-
|
||
EMPFÄNGER (DMS'/Mails Löschbestätigungs-Endpunkte) — die tatsächliche
|
||
Vernichtungslogik, die `NotifyDestruction` aufruft (kommt mit RET-02
|
||
und späteren Vernichtungs-Tickets), sowie Wiederholungslogik bei
|
||
fehlgeschlagenem Rückruf (Interface-Vertrag ist klar: Erfolg = HTTP
|
||
2xx, sonst Fehler — WIE mit einem Fehler umgegangen wird, ist
|
||
Aufgabe des aufrufenden Vernichtungs-Jobs, nicht dieses Pakets).
|
||
|
||
## Korrektur vor Abschluss: `retention_class` fehlte im ersten Entwurf
|
||
|
||
Akzeptanzkriterium 1 verlangt "Objekttyp MIT Aufbewahrungsklasse UND
|
||
Rückruf-Adresse" — der erste Entwurf von `module_registrations` und
|
||
`Register` hatte nur `callback_url`, `retention_class` fehlte komplett.
|
||
Vor dem Board-Flip auf „Fertig" bemerkt und korrigiert: Migration,
|
||
`Registration`-Struct, `Register`, `ListRegistrations` und
|
||
`RegisterHandler` um `retention_class` ergänzt, alle Tests entsprechend
|
||
angepasst (inkl. Idempotenz-Nachweis auch für `retention_class`, nicht
|
||
nur `callback_url`). Reale, bereits angewendete Migration auf
|
||
`dms_tenant_test` musste dafür gedroppt und neu angewendet werden (kein
|
||
Produktivbestand betroffen, Testsystem).
|
||
|
||
## Umsetzung
|
||
|
||
- `migrations/0003_module_registrations.up.sql`/`.down.sql` —
|
||
`module_registrations` (module_name, object_type, callback_url,
|
||
UNIQUE-Constraint).
|
||
- `internal/moduleadapter.Register` — `ON CONFLICT DO NOTHING` + Nachlese
|
||
der bestehenden Zeile, damit eine erneute Registrierung NIE die
|
||
bestehende `callback_url` überschreibt (Akzeptanzkriterium 3).
|
||
- `internal/moduleadapter.ListRegistrations`.
|
||
- `internal/moduleadapter.NotifyDestruction` — echter HTTP-POST mit dem
|
||
festen `DestructionNotice`-Vertrag.
|
||
- `internal/moduleadapter.RegisterHandler` — REST-Endpunkt
|
||
(`POST /register`).
|
||
|
||
## Prüfungen
|
||
|
||
| # | Prüfung | Ergebnis |
|
||
|---|---|---|
|
||
| 1 | Zwei fiktive Module (DMS, Mail) parallel registriert ohne Kollision | **bestanden** — `TestRegister_TwoModulesNoCollision`: unterschiedliche IDs, `ListRegistrations` zeigt beide |
|
||
| 2 | Rückruf bei Vernichtung erfolgreich gegen einen Testendpunkt ausgeführt | **bestanden** — `TestNotifyDestruction_CallsRealTestEndpoint`: echter `httptest.Server`, echter POST, Payload real empfangen und geprüft (`object_reference` korrekt) |
|
||
| 3 | Erneute Registrierung desselben Objekttyps ändert nichts am bestehenden Zustand | **bestanden** — `TestRegister_IsIdempotent_UnchangedExistingState` (Go-Funktion, mit absichtlich ABWEICHENDER `callback_url` im zweiten Aufruf) UND `TestRegisterHandler_RealHTTPRoundTrip` (dieselbe Prüfung nochmal über die HTTP-Schicht, nicht nur direkt gegen die Funktion) |
|
||
|
||
Zusätzlich: `TestNotifyDestruction_ReturnsErrorOnNonSuccessStatus`
|
||
(Fehlerverhalten), `TestRegisterHandler_RejectsMissingFields`
|
||
(REST-Schicht weist unvollständige Registrierungen ab).
|
||
|
||
## Echte Verdrahtung auf 192.168.1.131
|
||
|
||
- Migration real gegen `dms_tenant_test` angewendet — `module_registrations`
|
||
bestätigt vorhanden
|
||
- Kein systemd-Dienst — `RegisterHandler` ist ein `http.HandlerFunc`,
|
||
wird in einen künftigen Core-/Archive-HTTP-Server eingehängt, sobald
|
||
ein solcher für Archive existiert (aktuell kein eigener Archive-
|
||
API-Server, nur die bisherigen CLI/Metrics-Prozesse) — dokumentierter,
|
||
kein stiller Gap, entspricht dem Interface-Freeze-Charakter dieses
|
||
Tickets
|
||
|
||
## Build/Test-Ergebnis (192.168.1.131, `make check`)
|
||
|
||
```
|
||
go build ./... -> clean
|
||
go vet ./... -> clean
|
||
golangci-lint run ./... -> 0 issues
|
||
go test ./... -p 1 -count=1 -> 9/9 Pakete mit Tests ok, 0 Fehlschläge
|
||
(nach Korrektur; internal/retention und internal/moduleadapter brauchen
|
||
TEST_TENANT_DSN/TEST_TENANT_DSN_B bzw. TEST_TENANT_DSN)
|
||
```
|
||
|
||
## Gesamtergebnis
|
||
|
||
**Bestanden.** Alle drei Akzeptanzkriterien und alle drei
|
||
Pflichtprüfungen real erfüllt — Idempotenz sowohl auf Go- als auch auf
|
||
HTTP-Ebene bewiesen, Rückruf-Vertrag gegen einen echten Testendpunkt
|
||
verifiziert. Bewusst als reiner Interface-Freeze umgesetzt, keine
|
||
DMS-/Mail-seitige Implementierung — wie vom Nutzer vorgegeben.
|