● Zion Boggan
repos/Sightline/backend/app/services/retention.py
zionboggan.com ↗
28 lines · python
History for this file →
1
"""Retention enforcement. Deletes plate reads past the cutoff together with the rows that
2
reference them (sightings, watchlist hits) so the delete doesn't violate foreign keys.
3
Shared by the admin endpoint and the scheduled Celery task."""
4
from __future__ import annotations
5
 
6
from datetime import datetime
7
 
8
from sqlalchemy import delete, func, select
9
from sqlalchemy.orm import Session
10
 
11
from app.models import PlateRead, Sighting, WatchlistHit
12
 
13
 
14
def count_expired(db: Session, cutoff: datetime) -> int:
15
    return db.scalar(select(func.count()).select_from(PlateRead)
16
                     .where(PlateRead.read_ts < cutoff)) or 0
17
 
18
 
19
def purge_expired(db: Session, cutoff: datetime) -> int:
20
    """Delete reads older than cutoff and their dependents. Returns reads deleted."""
21
    old_ids = [r[0] for r in db.execute(
22
        select(PlateRead.id).where(PlateRead.read_ts < cutoff)).all()]
23
    if not old_ids:
24
        return 0
25
    db.execute(delete(WatchlistHit).where(WatchlistHit.plate_read_id.in_(old_ids)))
26
    db.execute(delete(Sighting).where(Sighting.plate_read_id.in_(old_ids)))
27
    result = db.execute(delete(PlateRead).where(PlateRead.id.in_(old_ids)))
28
    return result.rowcount