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:
@ -8,6 +8,8 @@
|
||||
//! `holzleitner-infrastructure`. Der Use Case erhält eine relative
|
||||
//! Referenz zurück, die in `delivery_completions` persistiert wird.
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use uuid::Uuid;
|
||||
|
||||
@ -47,8 +49,14 @@ pub trait SignatureStorage: Send + Sync {
|
||||
/// Einbetten in den PDF-Report. `None`, wenn die Datei fehlt.
|
||||
async fn load(&self, reference: &str) -> Result<Option<Vec<u8>>, ApplicationError>;
|
||||
|
||||
/// Löscht beide Unterschriften (Kunde + Fahrer) einer Lieferung — Aufräumen
|
||||
/// nach erfolgreichem Report-Upload (die Unterschriften stecken dann
|
||||
/// eingebettet im PDF in DOCUframe). Idempotent (fehlende Datei = ok).
|
||||
/// Löscht beide Unterschriften (Kunde + Fahrer) einer Lieferung. Idempotent
|
||||
/// (fehlende Datei = ok). Hinweis: Wird NICHT mehr beim Report-Upload
|
||||
/// aufgerufen — Unterschriften bleiben erhalten und werden per Cron über
|
||||
/// [`delete_older_than`](Self::delete_older_than) nach Frist entfernt.
|
||||
async fn delete_for_delivery(&self, delivery_id: Uuid) -> Result<(), ApplicationError>;
|
||||
|
||||
/// Löscht alle Unterschrifts-Dateien, deren letzte Änderung länger als
|
||||
/// `max_age` zurückliegt (Aufbewahrungsfrist). Für den periodischen
|
||||
/// Cron-Cleanup. Liefert die Anzahl gelöschter Dateien.
|
||||
async fn delete_older_than(&self, max_age: Duration) -> Result<u64, ApplicationError>;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user