// Package storage implementiert ARC-01: die Objekt-Speicher-Anbindung // für archivierte Mails und Anhänge. Baut auf demselben bewährten // Muster wie DMS FDN-03 auf (austauschbare Driver, LocalDriver für // Entwicklung, S3Driver für Produktion) — Mail kann DMS' internal/ // nicht importieren (eigenständiges Go-Modul), daher eine bewusste, // angepasste Neuimplementierung statt eines Cross-Modul-Imports. // // Erweiterung gegenüber FDN-03: ARC-01 verlangt Prüfsummenverifikation // AN DIESER SCHICHT (Akzeptanzkriterium 2), nicht erst an einer // späteren DB-Schicht — siehe service.go. package storage import ( "context" "errors" "io" "strconv" ) // ErrNotFound wird geliefert, wenn ein angefragtes Objekt nicht // existiert. var ErrNotFound = errors.New("storage: objekt nicht gefunden") // Driver ist die EINE Schnittstelle, gegen die der Rest von Mail // arbeitet (Akzeptanzkriterium 1). Zwei Implementierungen: LocalDriver // (Entwicklung) und S3Driver (Produktion, S3-kompatibel). type Driver interface { Put(ctx context.Context, key string, r io.Reader, size int64, contentType string) (int64, error) Get(ctx context.Context, key string) (io.ReadCloser, error) Delete(ctx context.Context, key string) error } // ObjectKey liefert das feste, dokumentierte Pfadschema für einen // Mail-Anhang/-Teil INNERHALB des bereits mandantenspezifischen // Buckets (Akzeptanzkriterium 1) — Bucket-Trennung selbst ist Sache // von Core TEN-01. Lesezugriff hängt NUR von messageID+partIndex ab, // nicht vom ursprünglichen Importpfad (IMAP/SMTP/manueller Import — // Akzeptanzkriterium 3): derselbe Key wird unabhängig davon berechnet, // über welchen Weg die Nachricht ins System kam. func ObjectKey(messageID string, partIndex int) string { return "messages/" + messageID + "/parts/" + strconv.Itoa(partIndex) } // checksumKey ist der Sidecar-Objektschlüssel für die beim Schreiben // berechnete Prüfsumme (siehe service.go) — liegt bewusst im selben // Driver/Bucket wie der Inhalt, keine separate DB-Abhängigkeit nötig. func checksumKey(key string) string { return key + ".sha256" }