checksum_sha256 (FDN-02) wird von keinem Schreibpfad in FDN-03 befuellt. Nachgetragen als AC/Pruefung in DOC-01 (Upload-API), Voraussetzung fuer Archive BAK-08 (neues Ticket: Checksum-basierte Objekt-Integritaetspruefung fuer extern eingebundenes, nicht selbst ueberwachtes Kunden-S3-Storage). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
85 lines
4.9 KiB
Markdown
85 lines
4.9 KiB
Markdown
# 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 über `s3.PresignClient`.
|
||
- `ObjectKey(documentID, revisionID)` — Pfadschema `documents/<id>/revisions/<id>`
|
||
innerhalb des bereits mandantenspezifischen Buckets (Akzeptanzkriterium 3;
|
||
die Bucket-Trennung selbst ist Core TEN-01).
|
||
- `Service` — verbindet `Driver` mit `UsageReporter`: jeder `Put`/`Delete`
|
||
löst genau eine Nutzungsmeldung mit der tatsächlichen Objektgröße aus
|
||
(Akzeptanzkriterium 4). Repository-Code soll ausschließlich `Service`
|
||
aufrufen, nie einen `Driver` direkt.
|
||
- `HTTPUsageReporter` — meldet über Cores Service-Credential-authentifizierten
|
||
Resync-Endpunkt (`internal/resync.Handler.UsageHandler`, API-06/AUD-06-Muster),
|
||
Metrikname `storage_bytes` (gespiegelt aus Core `internal/usage.StorageBytesMetric`,
|
||
LIC-05 — DMS kann Cores `internal/`-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)
|
||
```
|
||
|
||
## Offener Punkt: Prüfsummen-Schreibpfad noch nicht befüllt
|
||
|
||
`file_revisions.checksum_sha256` (FDN-02) wird aktuell von **keinem**
|
||
Schreibpfad befüllt oder verifiziert — `internal/storage.Service.Put`
|
||
berechnet keine Inhalts-Prüfsumme (das einzige SHA256 im Paket ist die
|
||
HMAC-Signatur lokaler URLs, siehe oben, unabhängig vom Dateiinhalt). Die
|
||
Spalte existiert seit FDN-02 ungenutzt. Nachgetragen als
|
||
Akzeptanzkriterium/Prüfung in `DOC-01` (Upload-API), das den Hash auf
|
||
Klartext berechnen und transaktional persistieren muss — Voraussetzung für
|
||
Duplikaterkennung (`DOC-02`) und die spätere Integritätsprüfung
|
||
(Archive `BAK-08`, siehe Sitzungsprotokoll 2026-08-29 zu externem,
|
||
selbst nicht überwachtem Kunden-S3-Storage).
|
||
|
||
## 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.
|