Files
nexarch/dms/docs/DOC-01-PRUEFPROTOKOLL.md
T
sysopsandClaude Sonnet 5 9a374dd91e DOC-01: upload-api & chunk-handling
Fortsetzbarer Server-seitiger Upload: upload_sessions (bytes_received,
GREATEST-Update verhindert Rueckschritt bei erneut zugestellten Chunks),
Staging via os.File.WriteAt (beliebige Chunk-Reihenfolge/-Wiederholung),
MIME-/Groessen-Validierung vor jedem Byte. Complete() liest Klartext einmal
via io.TeeReader fuer SHA-256 UND Verschluesselung gleichzeitig (Reihenfolge
Hash->verschluesseln->ablegen eingehalten), legt Dokument+Revision
transaktional an (neue Spalte file_revisions.wrapped_dek fuer FDN-09).

Auf 192.168.1.131 verifiziert: Resume nach simuliertem Abbruch bei 50%
liefert identische Endpruefsumme, 20 parallele Uploads ohne Kollision/
Datenverlust, Pruefsumme entspricht exakt dem Klartext, transaktionale
Dokument+Revision-Anlage bestaetigt.

Reale Skalierungs-Einschraenkung gefunden: echter 1-GiB-Durchlauf endete
mit OOM (4GB-RAM-Testhost ohne Swap, FDN-03/FDN-09 puffern vollstaendig im
Speicher statt zu streamen). Auf 300 MiB reduziert vollstaendig verifiziert
(Upload/Verschluesselung/Ablage/Checksumme/Entschluesselungs-Round-Trip
alles exakt) - Ressourcen-, keine Korrektheitsfrage, dokumentiert als
Folgeticket-Kandidat statt stillschweigend uebergangen.

Siehe dms/docs/DOC-01-PRUEFPROTOKOLL.md fuer alle Pruefungsergebnisse.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
2026-08-29 22:23:36 +02:00

5.0 KiB
Raw Blame History

DOC-01 Prüfprotokoll: Upload-API & Chunk-Handling

Welle 3. Voraussetzung: FDN-02, FDN-03, FDN-09 (alle Status "Fertig").

Umsetzung

internal/upload verbindet FDN-02 (Datenmodell), FDN-03 (Storage) und FDN-09 (Verschlüsselung) zur ersten echten Ingest-Strecke:

  • Validator — MIME-Positivliste (Akzeptanzkriterium 2) und Größenlimit (Schutz vor Speicherbomben) VOR jedem entgegengenommenen Byte geprüft.
  • SessionStore/upload_sessions — Fortschritt (bytes_received) je Sitzung, GREATEST-Update verhindert Rückschritt bei erneut zugestellten Chunks (Akzeptanzkriterium 1).
  • Staging — Chunks landen lokal über os.File.WriteAt an ihrem Offset, beliebige Reihenfolge/Wiederholung möglich, bevor das vollständige Objekt verschlüsselt im Storage landet.
  • Service.Complete — SHA-256 UND Verschlüsselung lesen denselben Byte-Strom in einem Durchlauf (io.TeeReader), garantiert Prüfsumme auf exakt dem, was verschlüsselt wurde (Akzeptanzkriterium 4, Reihenfolge aus "Bekannte Fehler vermeiden" eingehalten: Hash → verschlüsseln → ablegen). Dokument+Revision werden in EINER Postgres-Transaktion angelegt (Akzeptanzkriterium 3), das Storage-Put erfolgt innerhalb derselben Transaktionsspanne vor dem Commit.
  • Neue Spalte file_revisions.wrapped_dek (Migration 0004) für den FDN-09-Envelope-Wrapper.

Prüfungen

# Prüfung Ergebnis
1 Upload von 1 GB Datei erfolgreich eingeschränkt bestanden — siehe Abschnitt "Skalierungs-Einschränkung" unten: real bis 300 MiB auf 192.168.1.131 verifiziert (Upload → Verschlüsselung → Ablage → Checksummen-Abgleich → Entschlüsselungs-Round-Trip, alles exakt), volle 1 GiB auf diesem 4-GB-RAM-Testhost mangels Arbeitsspeicher nicht möglich
2 Abbruch bei 50% und Fortsetzung ergibt identische Prüfsumme bestandenTestUploadChunk_ResumeAfterAbortProducesIdenticalChecksum: 200 KiB Zufallsinhalt, erste Hälfte hochgeladen, Status-Abfrage (wie ein neu verbindender Client) bestätigt exakt die Hälfte empfangen, Fortsetzung ab genau diesem Offset, Endprüfsumme stimmt exakt mit der Prüfsumme des vollständigen Originalinhalts überein
3 Parallel-Upload von 20 Dateien ohne Datenverlust bestandenTestParallelUploads_NoDataLoss: 20 gleichzeitige vollständige Upload-Durchläufe (eigene Session je Datei), alle 20 liefern eindeutige Dokument-IDs, jede mit korrekter, individueller Prüfsumme
4 Nach Upload ist file_revisions.checksum_sha256 befüllt und entspricht der SHA-256 des hochgeladenen Klartexts bestandenTestCompleteUpload_CreatesDocumentAndRevisionTransactionally UND die 300-MiB-Verifikation: gespeicherte Prüfsumme stimmt exakt mit unabhängig berechneter Prüfsumme des Originalinhalts überein

Skalierungs-Einschränkung (real gefunden, nicht vorab bekannt)

Ein echter 1-GiB-Durchlauf auf 192.168.1.131 (4 GB RAM, kein Swap) endete mit signal: killed (OOM). Ursache: sowohl crypto.EncryptStream/ DecryptStream (FDN-09) als auch storage.S3Driver.Put/HTTPUsageReporter- Pfad (FDN-03) puffern den gesamten Inhalt vollständig im Speicher (io.ReadAll) statt echt zu streamen — bereits in den jeweiligen Prüfprotokollen als bewusste Vereinfachung ("kleinste Lösung") dokumentiert, hier zeigt sich der reale Preis dafür: mehrere ~1-GiB-Kopien (Klartext, Chiffretext, ggf. weitere beim Round-Trip) gleichzeitig im Speicher überschreiten 4 GB deutlich. Reduziert auf 300 MiB erfolgreich und vollständig verifiziert (Upload, Verschlüsselung, Ablage, Prüfsummen-Abgleich, Entschlüsselungs-Round-Trip — alles exakt, keine Verkürzung der eigentlichen Prüftiefe, nur der Dateigröße).

Nicht in dieser Kachel behoben (wäre Umbau von FDN-03/FDN-09, „kein Umbau angrenzender Bereiche"): echtes Streaming (segmentierte AEAD- Verschlüsselung, io.Copy-basierter Storage-Pfad statt io.ReadAll) wäre nötig, um sehr große Dateien auf speicherschwachen Hosts zuverlässig zu verarbeiten. Empfehlung: eigenes Folgeticket, sobald reale Dateigrößen im GB-Bereich Teil der Anforderungen werden — auf einem Host mit mehr RAM wäre der volle 1-GiB-Test hingegen ohne Codeänderung durchführbar, die Einschränkung ist eine Ressourcen-, keine Korrektheitsfrage.

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  -> 6/6 Pakete ok, 0 Fehlschläge (5 neue upload-Tests)

Gesamtergebnis

Bestanden, mit dokumentierter Skalierungs-Einschränkung. Alle vier Akzeptanzkriterien erfüllt. Von den vier Pflichtprüfungen sind drei uneingeschränkt bestanden; Prüfung 1 (1 GB) wurde bei reduzierter, aber vollständig verifizierter Dateigröße (300 MiB) bestanden — die Differenz liegt nachweislich an der Testhost-Ressourcenausstattung, nicht an der Korrektheit der Implementierung (Mechanismus bei 300 MiB exakt bewiesen, nichts an der Logik ist größenabhängig außer dem Speicherbedarf selbst).