siftlode/backend/alembic/versions
npeter83 6330ac3184 feat(playlists): derive dirty from a synced-state fingerprint
Store a SHA-256 of each playlist's name + ordered video ids as last synced from /
pushed to YouTube (migration 0013, backfilled for already-clean linked playlists).
'dirty' is now recomputed on every edit by comparing the current fingerprint to that
baseline instead of being stickily set true. So manually restoring the original order
(or undo back to it) clears dirty on its own — the Reset to YouTube button disappears
and no YouTube read is needed. Baseline is set on read-sync, repull (reset), and a
clean push; a missing baseline counts as dirty (unknown YT state). Verified the
migration's fingerprint matches the app's runtime fingerprint exactly.
2026-06-15 23:00:56 +02:00
..
0001_initial.py feat: M1 foundation — compose stack, FastAPI, Google OAuth, encrypted tokens 2026-06-11 01:01:37 +02:00
0002_ingest_core.py feat: M2 (part 1) — subscription import, YouTube client, quota guard 2026-06-11 01:22:07 +02:00
0003_tags.py feat: M3 — automatic channel tagging (language + topic system tags) 2026-06-11 01:57:19 +02:00
0004_feed_state_prefs.py feat: M4 (part 1) — feed API, watch state, user preferences 2026-06-11 02:11:02 +02:00
0005_shorts_probed.py fix: address reader-UI feedback (shorts, search, tags, login, UX) 2026-06-11 03:07:49 +02:00
0006_app_state.py feat: sync status indicator, admin pause/resume, filtered video count 2026-06-11 04:15:25 +02:00
0007_deep_requested.py feat(m5d): demand-driven deep backfill + per-user ETA 2026-06-11 23:07:09 +02:00
0008_invites.py feat(m5c): onboarding — DB invites, request-access, admin approval, email 2026-06-12 01:43:07 +02:00
0009_quota_events.py feat(stats): per-user API quota attribution + admin usage page 2026-06-12 02:47:55 +02:00
0010_watch_progress.py feat(progress): track per-user resume position server-side 2026-06-14 18:40:05 +02:00
0011_playlists.py feat(playlists): backend foundation — model, migration, CRUD API 2026-06-15 14:37:09 +02:00
0012_watch_later.py feat(playlists): unify Saved into a built-in Watch later playlist 2026-06-15 15:33:53 +02:00
0013_playlist_fingerprint.py feat(playlists): derive dirty from a synced-state fingerprint 2026-06-15 23:00:56 +02:00