"""Scheduled cleanup tasks — IP log purge (1-year retention).""" import asyncio import logging from datetime import datetime, timedelta, timezone from sqlalchemy import delete from sqlalchemy.ext.asyncio import AsyncSession from meshbay_hub.db.models import IPLog log = logging.getLogger(__name__) RETENTION_DAYS = 365 CLEANUP_INTERVAL_HOURS = 24 async def purge_old_ip_logs(db: AsyncSession, retention_days: int = RETENTION_DAYS) -> int: cutoff = datetime.now(timezone.utc) - timedelta(days=retention_days) result = await db.execute(delete(IPLog).where(IPLog.timestamp < cutoff)) await db.commit() return result.rowcount async def cleanup_loop(get_session): """Run cleanup once at startup, then every 24 hours.""" try: while True: try: async with get_session() as db: deleted = await purge_old_ip_logs(db) if deleted: log.info("Purged %d IP log entries older than %d days", deleted, RETENTION_DAYS) except asyncio.CancelledError: raise except Exception as e: log.error("IP log cleanup failed: %s", e) await asyncio.sleep(CLEANUP_INTERVAL_HOURS * 3600) except asyncio.CancelledError: return