PROCUREX · Statische HTML-Dokumentation

Datenaufbewahrung und Anonymisierungskonzept

Aus docs\data-retention.md konvertiert – vollständig lokal lesbar.

Datenaufbewahrung und Anonymisierungskonzept

Aktueller Stand

Dieses Dokument füllt eine Lücke, die beim Abgleich von PROCUREX-PLANUNGSENTSCHEIDUNGEN.md

gegen den tatsächlichen Repo-Zustand identifiziert wurde (2026-08-17): Confluence Seite 10 nennt

unter [ANNAHME] ein „Lösch-/Anonymisierungskonzept für Supplier-Kontaktdaten und

ApprovalRequest-Begründungen nach fiktiver Aufbewahrungsfrist von 24 Monaten“, ohne dass dieses

Konzept bisher irgendwo ausformuliert war. PROCUREX ist ein fiktives Lernprojekt ohne echte

Personendaten (siehe README.md); dieses Dokument ist entsprechend eine konzeptionelle

Übung, keine Umsetzung einer realen Compliance-Anforderung.

Umsetzungsstatus: implementiert (seit 2026-08-29). SupplierRetentionJob

(procurex-supplier/.../retention/) und ApprovalRetentionJob

(procurex-approval/.../retention/) setzen die unten beschriebene Fristlogik als

@Scheduled-Jobs um, analog zu den bestehenden Outbox-Relays. Keine Flyway-Migration nötig, da

kein neues Spaltenschema entsteht — nur bestehende Felder werden überschrieben. Beide Jobs sind

per procurex.retention.enabled abschaltbar (Standard: an) und in Tests deaktiviert, damit

Integrationstests nicht mit dem periodischen Lauf um dieselbe Testcontainers-Datenbank

konkurrieren.

Betroffene Daten

Entität Feld(er) Schema.Tabelle Fristbeginn
Supplier contact_email supplier.supplier updated_at (letzte Statusänderung)
ApprovalRequest reason approval.approval_request decided_at

Beide Felder enthalten die einzigen personenbezogen wirkenden Freitext-/Kontaktdaten im

Datenmodell (siehe procurex-supplier/.../domain/Supplier.java und

procurex-approval/.../domain/ApprovalRequest.java). Alle übrigen Entitäten (Katalogartikel,

Bestellungen, Wareneingänge, Rechnungen) enthalten ausschließlich Geschäftsdaten ohne

Personenbezug.

Konzept: Anonymisierung statt Löschung

Vollständiges Löschen der Datensätze würde die revisionssichere Nachvollziehbarkeit von

Bestellungen und Genehmigungsentscheidungen zerstören (siehe ApprovalRequest-Klassenkommentar:

„Revisionssicherer Beleg einer Genehmigungsentscheidung“, PRX-5/PRX-8). Deshalb: Anonymisierung

statt Löschung.

(anonymized@procurex.invalid) ersetzt. name, taxId und status bleiben erhalten, da sie

für die Nachvollziehbarkeit historischer Bestellungen (welcher Lieferant war zum Zeitpunkt X

aktiv) benötigt werden und keinen direkten Personenbezug haben (Firmendaten, keine

Kontaktperson).

([anonymisiert nach Aufbewahrungsfrist]) ersetzt. orderId, decision und decidedAt

bleiben erhalten — die revisionssichere Kernaussage („wer hat wann wie entschieden“) bleibt

damit auch nach Anonymisierung nachvollziehbar, nur der potenziell personenbezogene Freitext

entfällt.

Fristlogik (konzeptionell)

IF Supplier.updatedAt < now() - 24 Monate
   AND Supplier.contactEmail != 'anonymized@procurex.invalid'
THEN Supplier.contactEmail = 'anonymized@procurex.invalid'

IF ApprovalRequest.decidedAt < now() - 24 Monate
   AND ApprovalRequest.reason != '[anonymisiert nach Aufbewahrungsfrist]'
THEN ApprovalRequest.reason = '[anonymisiert nach Aufbewahrungsfrist]'

Tatsächliche Umsetzung: ein @Scheduled-Job je Modul (analog zu den bestehenden Outbox-Relays,

siehe ADR-0003 und AbstractOutboxRelay), der periodisch (Standard: alle 24h,

procurex.retention.check-interval-ms) prüft und in Batches von 200 Datensätzen anonymisiert, um

Lock-Contention mit dem laufenden Betrieb zu vermeiden. Bewusst kein hartes DELETE, damit

referentielle Integrität zu PurchaseOrder bzw. Fremdschlüsseln erhalten bleibt. Die 24-Monats-

Frist wird als 730 Tage angenähert (procurex.retention.supplier-contact-email-days /

procurex.retention.approval-reason-days, je Standard 730) — eine bewusste, dokumentierte

Vereinfachung für einfache Instant-Arithmetik ohne Kalendermonate.

Bewusste Grenze

Übungsdaten ohne echte betroffene Personen handelt (siehe Lernprojekt-Hinweis auf

Confluence-Seiten 01/02/07).

Rechtsgrundlage abgeleitete Vorgabe; die Umsetzung nähert sie als feste 730-Tage-Dauer an statt

echter Kalendermonate.

(audit.audit_log_entry) — Events und Audit-Einträge enthalten orderId/decision, aber

keine Kontaktdaten, daher aktuell kein zusätzlicher Bedarf identifiziert.

Unit-Tests mit gemocktem Repository (SupplierRetentionJobTest, ApprovalRetentionJobTest)

plus Domain-Tests für die Anonymisierungs-Methoden selbst.

Weitere Informationen

Siehe Confluence Seite 10 „APIs, Events, Daten und Security“ (CONFIRMED, Abschnitt „Daten“) sowie

docs/runbooks/backup-restore.md für die verwandte Frage der Datensicherung (nicht Löschung).

⌂ Cockpit