Fix: run_retention_cleanup fehlte im vorherigen Push (Fehler mit stale Datei behoben)
This commit is contained in:
parent
6720a8a3c8
commit
da70bbfac3
51
db.py
51
db.py
|
|
@ -270,3 +270,54 @@ def update_ticket_status(tenant_id, ticket_id, status, actor_label):
|
|||
VALUES (%s,%s,%s,%s)""",
|
||||
(ticket_id, tenant_id, actor_label, "Status geaendert auf '%s'." % status),
|
||||
)
|
||||
|
||||
|
||||
# ── Aufbewahrungsfrist-Bereinigung (DSGVO Speicherbegrenzung) ─────────────────
|
||||
_RETENTION_LOCK_KEY = 727271 # feste Postgres-Advisory-Lock-ID fuer diesen Job
|
||||
|
||||
|
||||
def run_retention_cleanup():
|
||||
"""Loescht abgeschlossene Tickets und Audit-Log-Eintraege, die aelter sind
|
||||
als die pro Mandant hinterlegte Aufbewahrungsfrist (retention_tickets_days /
|
||||
retention_audit_days). Offene/laufende Tickets werden NIE geloescht, nur
|
||||
solche im Status 'Geloest'/'Geschlossen'.
|
||||
|
||||
Nutzt einen Postgres-Advisory-Lock: laeuft der Job bereits (z. B. durch
|
||||
einen anderen Worker-Prozess), wird dieser Aufruf uebersprungen statt
|
||||
parallel zu loeschen.
|
||||
"""
|
||||
with get_conn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("SELECT pg_try_advisory_lock(%s)", (_RETENTION_LOCK_KEY,))
|
||||
got_lock = cur.fetchone()[0]
|
||||
if not got_lock:
|
||||
return {"skipped": "lock_not_acquired"}
|
||||
try:
|
||||
with _dict_cursor(conn) as cur:
|
||||
cur.execute("SELECT id, name, retention_tickets_days, retention_audit_days FROM tenants")
|
||||
tenants = cur.fetchall()
|
||||
summary = []
|
||||
for t in tenants:
|
||||
tid = t["id"]
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""DELETE FROM tickets WHERE tenant_id=%s AND status IN ('Geloest','Geschlossen')
|
||||
AND updated_at < now() - (%s || ' days')::interval""",
|
||||
(tid, t["retention_tickets_days"]),
|
||||
)
|
||||
tickets_deleted = cur.rowcount
|
||||
cur.execute(
|
||||
"""DELETE FROM audit_log WHERE tenant_id=%s AND aktion <> 'retention_cleanup'
|
||||
AND zeit < now() - (%s || ' days')::interval""",
|
||||
(tid, t["retention_audit_days"]),
|
||||
)
|
||||
audit_deleted = cur.rowcount
|
||||
if tickets_deleted or audit_deleted:
|
||||
log_audit(tid, None, "retention_cleanup", "tenant", str(tid),
|
||||
{"tickets_deleted": tickets_deleted, "audit_log_deleted": audit_deleted})
|
||||
summary.append({"tenant_id": tid, "tenant": t["name"],
|
||||
"tickets_deleted": tickets_deleted, "audit_log_deleted": audit_deleted})
|
||||
return {"summary": summary}
|
||||
finally:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("SELECT pg_advisory_unlock(%s)", (_RETENTION_LOCK_KEY,))
|
||||
|
|
|
|||
Loading…
Reference in New Issue