""" Maintenance tasks — cleanup and housekeeping. Scheduled via Celery Beat to run daily at 03:00 UTC. """ import logging from datetime import timedelta from django.utils import timezone from config.celery import app logger = logging.getLogger(__name__) @app.task(name="tasks.maintenance.prune_old_heartbeat_logs", bind=True) def prune_old_heartbeat_logs(self, days: int = 30) -> dict: # type: ignore[type-arg] """ Delete HeartbeatLog records older than `days` days. Returns the count of deleted rows for monitoring/alerting. Runs as a single bulk DELETE to avoid row-by-row overhead. """ from apps.core.models import HeartbeatLog cutoff = timezone.now() - timedelta(days=days) deleted_count, _ = HeartbeatLog.objects.filter(timestamp__lt=cutoff).delete() logger.info( "maintenance.prune_old_heartbeat_logs: deleted %d records older than %d days", deleted_count, days, ) return {"status": "ok", "deleted": deleted_count, "cutoff_days": days}