soulsync/core/discovery
BoulderBadgeDad d5f6a14ba1 Discovery lift (10/N): save_*_bubble_snapshot -> shared helper
Final cluster: the four structurally-identical snapshot endpoints
(discover_downloads, artist_bubbles, search_bubbles, beatport_bubbles) ->
core.discovery.endpoints.save_bubble_snapshot(...), wired via
_save_source_bubble_snapshot. All four validate a payload key, persist via
db.save_bubble_snapshot(kind, items, profile_id=...), and return a count +
timestamp; they differ only by:
- payload_key ('downloads' for discover, 'bubbles' for the rest) + its
  no_data_error message.
- snapshot_kind, success_noun, and the info/except log subject + noun
  ("downloads"/"artists"/"albums/tracks"/"charts").

get_database / get_current_profile_id injected; get_json (request.json) invoked
inside the try, preserving the original 400/500 behavior incl. traceback dump.

Tests: +5 (missing key 400, None body 400, happy path with kind/profile/count/
timestamp, discover_downloads variant, exception -> 500). Full discovery suite:
210 passed.

web_server.py: -98 lines.
2026-05-28 18:17:36 -07:00
..
__init__.py
beatport.py
deezer.py
endpoints.py
hero.py
listenbrainz.py
manual_match.py
matching.py
playlist.py
qobuz.py
quality_scanner.py
scoring.py
spotify_public.py
sync.py
tidal.py
youtube.py