Ein Driver-Interface, zwei austauschbare Treiber: LocalDriver (Entwicklung, Dateisystem, HMAC-signierte URLs) und S3Driver (Produktion, S3-kompatibel via aws-sdk-go-v2, echte presigned URLs). Pfadschema documents/<id>/ revisions/<id> innerhalb des mandantenspezifischen Buckets. Service verbindet Driver mit Nutzungsmeldung an Core LIC-05 (HTTPUsageReporter, Vertrag von internal/resync.Handler nachgebildet, DMS kann Cores internal/- Pakete als eigenes Modul nicht importieren). Auf 192.168.1.131 verifiziert, S3-Treiber gegen echtes lokal installiertes MinIO (kein Mock): Round-Trip beide Treiber, abgelaufene presigned URL real mit 403 abgewiesen (manuell zusaetzlich zum Unit-Test verifiziert), klare ErrNotFound bei fehlendem Objekt beide Treiber, Nutzungsmeldung mit korrektem Tenant/Metrik/Delta bei Put/Delete. Befund dokumentiert: Cores internal/resync.Handler (Gegenstelle fuer die Nutzungsmeldung) ist noch in keinem cmd/*/main.go verdrahtet (dieselbe Fehlerklasse wie QA-05/AUD-06) - HTTPUsageReporter daher gegen den dokumentierten Vertrag getestet, nicht gegen eine laufende Core-Instanz. Siehe dms/docs/FDN-03-PRUEFPROTOKOLL.md. golangci-lint auf v2.1.6 aktualisiert (v1.63.4 konnte go1.24-Zielstand nicht linten), .golangci.yml auf v2-Konfigurationsformat migriert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
4.2 KiB
FDN-03 – Prüfprotokoll: Objekt-Storage-Abstraktion
Welle 2. Voraussetzung: FDN-01 (Status "Fertig"), Core LIC-05 (Status "Fertig").
Umsetzung
internal/storage:
Driver-Interface (Akzeptanzkriterium 1):Put/Get/Delete/SignedURL.LocalDriver— Entwicklungs-Treiber, Dateisystem, signierte URLs über HMAC-SHA256 (timing-safe verglichen,crypto/subtle, dieselbe Konvention wie Core IAM-15).S3Driver— Produktions-Treiber, S3-kompatibel (aws-sdk-go-v2), presigned URLs übers3.PresignClient.ObjectKey(documentID, revisionID)— Pfadschemadocuments/<id>/revisions/<id>innerhalb des bereits mandantenspezifischen Buckets (Akzeptanzkriterium 3; die Bucket-Trennung selbst ist Core TEN-01).Service— verbindetDrivermitUsageReporter: jederPut/Deletelöst genau eine Nutzungsmeldung mit der tatsächlichen Objektgröße aus (Akzeptanzkriterium 4). Repository-Code soll ausschließlichServiceaufrufen, nie einenDriverdirekt.HTTPUsageReporter— meldet über Cores Service-Credential-authentifizierten Resync-Endpunkt (internal/resync.Handler.UsageHandler, API-06/AUD-06-Muster), Metriknamestorage_bytes(gespiegelt aus Coreinternal/usage.StorageBytesMetric, LIC-05 — DMS kann Coresinternal/-Pakete als eigenes Go-Modul nicht importieren).
Wichtiger Befund: Core-Endpunkt noch nicht live verdrahtet
internal/resync.Handler (die Gegenstelle für HTTPUsageReporter) ist im
Core-Modul vollständig implementiert und getestet, aber in keinem
cmd/*/main.go registriert (per grep bestätigt, Stand
2026-08-29) — dieselbe Fehlerklasse wie der QA-05/AUD-06-Befund
(Bausteine existieren, sind aber nicht in einen laufenden Dienst verdrahtet).
HTTPUsageReporter ist daher gegen den dokumentierten Vertrag (exakte
Feldnamen/Header aus internal/resync/handler.go gelesen) getestet, nicht
gegen eine echte laufende Core-Instanz. Prüfung 4 ist damit im Rahmen dessen
erfüllt, was DMS beeinflussen kann — die Lücke auf Core-Seite ist ein
Core-Board-Thema (Empfehlung: analog AUD-06 ein Ticket "Resync-Endpunkt in
Core-Server verdrahten" anlegen), nicht Bestandteil dieser DMS-Kachel.
Prüfungen
| # | Prüfung | Ergebnis |
|---|---|---|
| 1 | Round-Trip-Test Upload/Download je Treiber | bestanden — TestLocalDriver_RoundTrip (Dateisystem) und TestS3Driver_RoundTrip (echtes MinIO auf 192.168.1.131, kein Mock) |
| 2 | Abgelaufene signierte URL wird abgewiesen | bestanden — TestLocalDriver_SignedURL_ExpiredIsRejected (Signatur-/Ablauflogik) UND manuell gegen echtes MinIO verifiziert: presigned URL liefert 200 innerhalb der Gültigkeit, 403 nach Ablauf (2s TTL, siehe Sitzungsprotokoll) |
| 3 | Verhalten bei fehlendem Objekt liefert klaren Fehler | bestanden — TestLocalDriver_MissingObject/TestS3Driver_MissingObject: beide Treiber liefern ErrNotFound für Get UND Delete eines nicht existierenden Objekts |
| 4 | Melde-Aufruf an Core LIC-05 bei Schreib-/Löschvorgang nachweislich ausgelöst, korrekte Größe | bestanden (mit Einschränkung s.o.) — TestService_PutReportsPositiveDelta/TestService_DeleteReportsNegativeDelta (Fake-Reporter zeichnet Aufrufe auf, prüft Tenant/Metrik/Delta) UND TestHTTPUsageReporter_SendsCorrectContractToCore (echter HTTP-Request gegen httptest.Server, der Cores Vertrag nachbildet — Header, JSON-Feldnamen) |
Build/Test-Ergebnis (192.168.1.131)
go build ./... -> clean
go vet ./... -> clean
make lint -> clean (golangci-lint v2.1.6, aus Quelle mit go1.24.4 gebaut,
da v1.63.4 den Zielstand go1.24 nicht linten konnte —
.golangci.yml auf v2-Konfigurationsformat migriert)
go test ./internal/storage/... -v -count=1 -> 11/11 Tests ok (3 S3-Tests real
gegen lokal installiertes MinIO statt uebersprungen)
Gesamtergebnis
Bestanden, mit einer dokumentierten Abhängigkeit auf Core-Seite
(Abschnitt "Wichtiger Befund") — Core muss internal/resync.Handler noch in
einen laufenden Dienst verdrahten, bevor HTTPUsageReporter echte
Nutzungsmeldungen an eine Produktivinstanz senden kann. Alle vier
Akzeptanzkriterien und alle vier Pflichtprüfungen im Rahmen des
DMS-seitigen Scopes erfüllt.