"""Retention jobs for audit data (``INFRASYNTH_AUDIT.RETENTION_DAYS``).""" from __future__ import annotations import logging from datetime import timedelta from celery import shared_task from django.utils import timezone from infrasynth.shared.settings_utils import get_setting logger = logging.getLogger(__name__) @shared_task(name="infrasynth.audit.purge_expired_logs") def purge_expired_logs(tenant_id=None): """Deletes audit rows older than the configured retention window. ``RETENTION_DAYS <= 0`` disables retention (rows are kept forever). Returns a ``{model_label: deleted_count}`` mapping. """ retention_days = int(get_setting("INFRASYNTH_AUDIT", "RETENTION_DAYS", 365)) if retention_days <= 0: return {} from .models import APIInteractionLog, ModelChangeLog, SecurityEvent cutoff = timezone.now() - timedelta(days=retention_days) deleted: dict[str, int] = {} for model in (ModelChangeLog, APIInteractionLog, SecurityEvent): qs = model.objects.filter(timestamp__lt=cutoff) if tenant_id: qs = qs.filter(tenant_id=tenant_id) count, _ = qs.delete() deleted[model._meta.label] = count logger.info("Audit retention purge removed %s", deleted) return deleted