feat(storage): add local storage framework

This commit is contained in:
Schubert Ferenc 2026-07-03 18:11:58 +02:00
parent 228da8f814
commit 964b545bc5
24 changed files with 890 additions and 98 deletions

View file

@ -244,6 +244,16 @@ Kunden:
- `customers.read`
- `customers.create`
- `customers.update`
- `customers.delete`
Knowledge:
- `knowledge.read`
- `knowledge.create`
- `knowledge.update`
- `knowledge.delete`
- `knowledge.upload`
- `knowledge.download`
### Initial Admin Bootstrap
@ -294,7 +304,6 @@ customer_number;company_name;legal_name;customer_type;status;industry;website;em
```
Pflichtfeld ist `company_name`. Wenn `customer_number`, `customer_type` oder `status` fehlen, erzeugt der Import fuer neue Kunden eine Kundennummer bzw. nutzt produktive Defaults und weist in der Preview darauf hin. Vollstaendige CSV-Inhalte werden nicht im Audit Log gespeichert.
- `customers.delete`
Projekte:
@ -527,14 +536,19 @@ Athena stellt die BFF-Routen unter `/api/knowledge/...` bereit. Der Browser spri
### Knowledge-Dateispeicherung
Dokumentuploads werden in v0.6.0 lokal im Hermes-Container oder in einem gemounteten Volume gespeichert.
Seit v0.7.0 laufen Knowledge-Dateien ueber das zentrale Storage Framework. KnowledgeService speichert, liest und loescht Dateien nicht mehr direkt ueber verstreute Dateioperationen, sondern ueber `StorageService`.
Neue Uploads werden im Namespace `knowledge/documents/<manufacturer_id>` gespeichert. Die Datenbank-Metadaten bleiben kompatibel: `knowledge_documents.file_path` enthaelt den Storage-Key fuer neue Dateien oder einen bestehenden Legacy-Pfad fuer alte Dateien.
Konfiguration:
- `KNOWLEDGE_STORAGE_PATH`, Default `/data/knowledge`
- `KNOWLEDGE_MAX_UPLOAD_MB`, Default `50`
- `STORAGE_PROVIDER`, Default `local`
- `STORAGE_BASE_PATH`, Default `/data/storage`
- `STORAGE_MAX_UPLOAD_MB`, Default `50`
- `KNOWLEDGE_STORAGE_PATH`, Legacy-Fallback fuer bestehende Installationen
- `KNOWLEDGE_MAX_UPLOAD_MB`, Legacy-Fallback fuer bestehende Installationen
Docker Compose bindet das persistente Volume `knowledge-data` nach `/data/knowledge` ein. Dieses Volume darf nicht geloescht werden, wenn lokale Knowledge-Dateien erhalten bleiben sollen.
Docker Compose bindet den Host-Pfad aus `STORAGE_HOST_PATH` nach `/data/storage` ein. Fuer den VPS ist `/opt/olympus-storage` empfohlen. Bestehende Dateien unter `/data/knowledge` werden nicht automatisch verschoben; wenn Migration noetig ist, muss sie kontrolliert geplant und vorher gebackupt werden.
Erlaubte Uploadtypen:
@ -545,7 +559,71 @@ Erlaubte Uploadtypen:
- TXT
- ZIP
Hermes normalisiert Dateinamen, validiert Extension und MIME-Type, begrenzt die Uploadgroesse und erzwingt, dass gespeicherte und heruntergeladene Dateien innerhalb von `KNOWLEDGE_STORAGE_PATH` liegen.
Hermes normalisiert Dateinamen, erzeugt eindeutige gespeicherte Dateinamen, validiert Extension und MIME-Type, begrenzt die Uploadgroesse, berechnet SHA256 und verhindert Path Traversal.
## Storage Framework
Das Storage Framework liegt unter `backend/hermes/app/storage`.
Bestandteile:
- `StorageProvider` als Interface
- `LocalDiskStorageProvider` als erste Implementierung
- `StorageService` als zentrale API fuer Fachmodule
- Storage-Schemas und eigene Storage-Exceptions
Zentrale Operationen:
- `save_file()`
- `open_file()`
- `delete_file()`
- `file_exists()`
- `get_file_metadata()`
- `calculate_checksum()`
- `safe_filename()`
- `validate_file_type()`
- `validate_file_size()`
Der aktuelle Provider ist `local`. Die Architektur ist bewusst fuer spaetere Provider vorbereitet:
- NAS
- S3
- MinIO
- Paperless
- Azure Blob
- Backblaze / Wasabi
Pfadstruktur im lokalen Provider:
```text
/data/storage/
knowledge/
documents/
thumbnails/
customers/
projects/
tickets/
imports/
temp/
```
Datei-Inhalte werden nicht geloggt. Browser greifen nie direkt auf Storage oder Hermes-Dateipfade zu; Downloads laufen ueber Athena-BFF und Hermes-Berechtigungspruefung.
## Backup und Deployment
Im Projektroot liegen robuste Bash-Skripte fuer Betrieb und Deployment:
- `scripts/migrate.sh`
- `scripts/healthcheck.sh`
- `scripts/deploy.sh`
- `scripts/backup.sh`
- `scripts/restore.sh`
`deploy.sh` baut Images, startet Docker Compose, fuehrt Migrationen aus und startet den Healthcheck. Es erzwingt kein `git pull`.
`backup.sh` sichert PostgreSQL, wenn `POSTGRES_CONTAINER` oder `DATABASE_URL` mit lokalem `pg_dump` verfuegbar ist, und archiviert den Storage-Host-Pfad. `.env` wird bewusst nicht automatisch ins Backup kopiert und muss sicher separat verwaltet werden.
`restore.sh` ist bewusst bestaetigungspflichtig und startet erst nach Eingabe von `RESTORE`.
### Knowledge-RBAC
@ -627,11 +705,23 @@ docker-compose.yml
`LOG_LEVEL`
: Runtime-Loglevel fuer Hermes, z. B. `INFO`, `WARNING` oder `ERROR`.
`STORAGE_PROVIDER`
: Storage Provider. Aktuell produktiv implementiert: `local`.
`STORAGE_BASE_PATH`
: Interner Storage-Basispfad in Hermes. Default `/data/storage`.
`STORAGE_MAX_UPLOAD_MB`
: Maximale Uploadgroesse fuer Storage-Dateien in MB. Default `50`.
`STORAGE_HOST_PATH`
: Docker-Host-Pfad, der nach `/data/storage` gemountet wird. Lokal z. B. `./storage`, auf dem VPS empfohlen `/opt/olympus-storage`.
`KNOWLEDGE_STORAGE_PATH`
: Lokales Speicherverzeichnis fuer Knowledge-Dateien. Default `/data/knowledge`.
: Legacy-Fallback fuer bestehende Knowledge-Dateien. Neue Installationen sollen `STORAGE_*` verwenden.
`KNOWLEDGE_MAX_UPLOAD_MB`
: Maximale Uploadgroesse fuer Knowledge-Dokumente in MB. Default `50`.
: Legacy-Fallback fuer die maximale Knowledge-Uploadgroesse.
### Athena