"""Data retention policies — scheduled cleanup of aged records.""" from __future__ import annotations import logging from datetime import datetime, timedelta, timezone from sqlalchemy.orm import Session from app.database import SessionLocal from app.models.audit import AuditLog from app.services.notification_service import cleanup_old_notifications logger = logging.getLogger(__name__) AUDIT_LOG_RETENTION_DAYS = 730 def apply_retention_policies(db: Session) -> dict[str, int]: """Apply retention rules. Commits the session before returning.""" cutoff = datetime.now(timezone.utc) - timedelta(days=AUDIT_LOG_RETENTION_DAYS) deleted_audit = ( db.query(AuditLog) .filter(AuditLog.timestamp < cutoff) .delete(synchronize_session=False) ) if deleted_audit: logger.info( "Retention: deleted %d audit logs older than %d days", deleted_audit, AUDIT_LOG_RETENTION_DAYS, ) deleted_notifications = cleanup_old_notifications(db, days=90) db.commit() return { "audit_logs_deleted": deleted_audit, "notifications_deleted": deleted_notifications, } def run_retention_job() -> None: """Entry point for the daily retention scheduler job.""" logger.info("Scheduled retention job starting...") db = SessionLocal() try: summary = apply_retention_policies(db) logger.info("Retention job finished — %s", summary) except Exception: logger.exception("Retention job failed") db.rollback() finally: db.close()