soulsync/core/automation
Broque Thomas d861a40277 Personalized pipeline: refresh snapshot on first-run too
Reproduced: selecting Fresh Tape (or any kind never generated before)
and running the pipeline silently skipped — UI showed
"No tracks in Fresh Tape — skipping sync" with no clue why.

Root cause: ensure_playlist auto-creates the playlist row on first
access with `track_count=0` and `last_generated_at=NULL`, but
`is_stale=0` by default (the column default — fresh rows aren't
"stale", they're "never generated"). Pipeline only refreshed when
`is_stale=True` OR `refresh_first=True`, so first-run rows fell
through both branches → read the empty snapshot → skip.

Fix: pipeline now also refreshes when `existing.last_generated_at is
None`. Same control flow, one extra condition:

    if refresh_first OR is_stale OR last_generated_at is None:
        refresh
    else:
        read existing snapshot

This is the right signal: "has the generator ever run for this row"
is exactly what `last_generated_at` tracks (the column is set in
`_persist_snapshot` after every successful refresh).

Stubs in test_handlers_personalized_pipeline.py updated to expose
`last_generated_at` on their SimpleNamespace returns so the new
attribute read doesn't AttributeError. Fresh stubs get a non-None
timestamp so they're treated as already-generated; the new test
`test_never_generated_snapshot_triggers_first_refresh` pins the
first-run-forces-refresh behavior with `last_generated_at=None`.
2026-05-15 21:13:16 -07:00
..
handlers Personalized pipeline: refresh snapshot on first-run too 2026-05-15 21:13:16 -07:00
__init__.py Extract automation handlers (1/N): infrastructure + 3 simple handlers 2026-05-15 10:25:41 -07:00
api.py Lift /api/automations/* into core/automation/ 2026-04-27 18:05:14 -07:00
blocks.py Personalized playlist pipeline: auto-sync discover-page playlists 2026-05-15 18:41:08 -07:00
deps.py Personalized playlist pipeline: auto-sync discover-page playlists 2026-05-15 18:41:08 -07:00
progress.py Surface silent exceptions across remaining modules — ~70 sites 2026-05-07 10:28:58 -07:00
signals.py Add module logger + surface silent exceptions in 7 logger-less files — 12 sites 2026-05-07 10:27:04 -07:00