feat(signature): Signaturen beim Report-Upload behalten + Cron-Cleanup nach Frist

Bisher loeschte die Report-Pipeline die Unterschriften nach erfolgreichem
DOCUframe-Upload. Wir brauchen die Signatur-Dateien aber weiterhin, daher:

- ProcessDeliveryReportUseCase: Signatur-Loeschung (delete_for_delivery) aus dem
  Cleanup entfernt + SignatureStorage-Dependency raus (Report-PDF/Bild-Notiz-
  Cleanup bleibt).
- SignatureStorage: neue Methode delete_older_than(max_age) -> Anzahl; lokaler
  Adapter loescht PNGs aelter als die Frist (per mtime).
- Config [signature]: retention_days (Default 90, 0 = aus) + cleanup_cron
  (Default taeglich 04:00).
- main.rs: Signatur-Cleanup-Scheduler (gated retention_days > 0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dennis Nemec
2026-06-18 16:16:12 +02:00
parent 2f4368ec52
commit 47eb8ec57d
6 changed files with 140 additions and 12 deletions

View File

@ -23,7 +23,7 @@ use uuid::Uuid;
use crate::error::ApplicationError;
use crate::ports::{
AttachmentRepository, AttachmentStorage, DeliveryReportJobRepository, DeliveryReportSink,
DocuframeReportGateway, ReportJobStatus, SignatureStorage,
DocuframeReportGateway, ReportJobStatus,
};
use crate::usecases::GenerateDeliveryReportUseCase;
@ -33,7 +33,6 @@ pub struct ProcessDeliveryReportUseCase {
gateway: Arc<dyn DocuframeReportGateway>,
attachment_repo: Arc<dyn AttachmentRepository>,
attachment_storage: Arc<dyn AttachmentStorage>,
signatures: Arc<dyn SignatureStorage>,
report_sink: Arc<dyn DeliveryReportSink>,
}
@ -45,7 +44,6 @@ impl ProcessDeliveryReportUseCase {
gateway: Arc<dyn DocuframeReportGateway>,
attachment_repo: Arc<dyn AttachmentRepository>,
attachment_storage: Arc<dyn AttachmentStorage>,
signatures: Arc<dyn SignatureStorage>,
report_sink: Arc<dyn DeliveryReportSink>,
) -> Self {
Self {
@ -54,7 +52,6 @@ impl ProcessDeliveryReportUseCase {
gateway,
attachment_repo,
attachment_storage,
signatures,
report_sink,
}
}
@ -107,11 +104,14 @@ impl ProcessDeliveryReportUseCase {
/// Aufräumen nach erfolgreichem Upload — best-effort (Fehler werden
/// geschluckt; der Report liegt bereits sicher in DOCUframe):
/// * lokale Report-PDFs
/// * Unterschriften (Kunde + Fahrer)
/// * Bild-Notizen (Datei löschen + `deleted_at` setzen, Metadaten bleiben)
///
/// **Unterschriften werden hier bewusst NICHT gelöscht.** Die Signatur-
/// Dateien bleiben im Backend erhalten (wir brauchen sie weiterhin) und
/// werden separat per Cron-Job gelöscht, sobald sie älter als die
/// Aufbewahrungsfrist (`signature.retention_days`) sind.
async fn cleanup_local(&self, delivery_id: Uuid, belegnummer: &str) {
let _ = self.report_sink.delete(belegnummer).await;
let _ = self.signatures.delete_for_delivery(delivery_id).await;
if let Ok(refs) = self.attachment_repo.list_active_for_delivery(delivery_id).await {
for r in refs {
let _ = self.attachment_storage.delete(&r.reference).await;