Discovery lift (2/N): cancel_*_sync + delete_*_playlist -> shared helpers
Second cluster. Two more sets of byte-identical per-source bodies:
cancel_<source>_sync (Tidal, Deezer, Qobuz, Spotify-Public, iTunes-Link,
YouTube, ListenBrainz) -> core.discovery.endpoints.cancel_sync(states, key,
*, label, not_found_message, sync_lock, sync_states, active_sync_workers).
Returns (payload, status_code); a thin web_server glue (_cancel_source_sync)
wires the sync-infra globals + jsonify. Caller passes the resolved key
(ListenBrainz transforms via _lb_state_key) and the exact 404 string
(iTunes-Link uses "iTunes Link not found").
delete_<source>_playlist (Tidal, Deezer, Qobuz, Spotify-Public) ->
delete_playlist_state(states, key, *, label, not_found_message), wired via
_delete_source_playlist.
Intentionally left with their own bodies (genuinely divergent, not 1:1):
- Beatport cancel (cancels a stored sync_future, no message, warning log).
- iTunes-Link / YouTube / ListenBrainz / Beatport deletes (different
success messages, info-log wording, playlist-name extraction, /remove
route, chart key).
Tests: +11 in tests/discovery/test_discovery_endpoints.py covering cancel
(404, active-worker cancel + state revert, worker-absent, no-sync-in-progress,
label in message, exception->500) and delete (404, future cancel + removal,
no/falsy future, exception->500 leaves state). Full discovery suite: 162 passed.
web_server.py: -216 lines.