refactor(backend): select() and an inline now everywhere, held by a test

CLAUDE.md's canonical table names SQLAlchemy 2.0 select() and an inline
datetime.now(timezone.utc), and both had drifted: five db.query(...) calls
remained in routes/auth.py and routes/me.py (seven before the demo went),
and four private now helpers stood in sync/videos.py, utils.py (imported
as _now by explore and maintenance), scheduler.py (_now_iso) and the e2e
seed. All are the canonical form now.

Ruff cannot ban a method call on an instance or a function by name, so
tests/test_canonical_patterns.py reads every app module's AST and fails on
a .query(...) call or a now/_now/now_utc helper — seen red on a planted file.
This commit is contained in:
2026-10-05 00:19:39 +02:00
parent ab76166878
commit 24c47d12bd
10 changed files with 111 additions and 59 deletions
+4 -5
View File
@@ -8,7 +8,7 @@ stay private to users who explored (or subscribe to) the channel — the feed qu
otherwise the cleanup job hard-deletes the channel and its untouched ephemeral videos after a
grace period (mirrors the maintenance job's grace-then-delete safety)."""
from datetime import timedelta
from datetime import datetime, timedelta, timezone
from sqlalchemy import delete, or_, select
from sqlalchemy.orm import Session
@@ -24,7 +24,6 @@ from app.models import (
VideoState,
)
from app.sync.videos import insert_stubs, stub_from_playlist_item, apply_video_details
from app.utils import now_utc as _now
from app.youtube.client import YouTubeClient, YouTubeError, is_playlist_gone
log = logs.get_logger(__name__)
@@ -59,7 +58,7 @@ def _enrich_new(db: Session, yt: YouTubeClient, video_ids: list[str]) -> int:
if not videos:
return 0
items = {it["id"]: it for it in yt.get_videos([v.id for v in videos])}
now = _now()
now = datetime.now(timezone.utc)
for video in videos:
item = items.get(video.id)
if item is None:
@@ -115,7 +114,7 @@ def purge_unkept_explored(db: Session) -> dict:
or surfaced by the user's own search (SearchFind) — these survive even if the channel goes.
A channel row is dropped only once it holds no videos at all. 0 quota."""
grace_days = sysconfig.get_int(db, "explore_grace_days")
cutoff = _now() - timedelta(days=grace_days)
cutoff = datetime.now(timezone.utc) - timedelta(days=grace_days)
expired = db.execute(
delete(ExploredChannel).where(ExploredChannel.created_at < cutoff)
@@ -166,7 +165,7 @@ def purge_unkept_search(db: Session, grace_days: int | None = None) -> dict:
SearchFinds. `grace_days=0` purges immediately (the admin "purge now" path); None uses config.
0 quota."""
grace = sysconfig.get_int(db, "search_grace_days") if grace_days is None else grace_days
cutoff = _now() - timedelta(days=grace)
cutoff = datetime.now(timezone.utc) - timedelta(days=grace)
state_exists = select(VideoState.id).where(VideoState.video_id == Video.id).exists()
pl_exists = select(PlaylistItem.id).where(PlaylistItem.video_id == Video.id).exists()
sub_exists = select(Subscription.id).where(Subscription.channel_id == Video.channel_id).exists()