fix: LEFT-join artists in catalog-songs read (materialized tracks were hidden)

Merged
SW
4mo ago
+2-2

What

GET /api/catalogs/songs (selectCatalogSongsWithArtists) inner-joined song_artists!inner → accounts!inner. Valuation-captured tracks have songs + song_measurements but no song_artists, so a freshly materialized catalog read back as 0 songs — verified live on recoupable/api#677 (claim → songs_added: 23, but GET /api/catalogs/songs → total_count: 0).

Drop the two !inner so artist-less songs surface with artists: []. songs!inner stays — the catalog_songs.song FK guarantees the song row. The existing transform already handles empty artists (song_artists?.map(...) || []), and count: "exact" now reflects all catalog songs.

Scope

Only selectCatalogSongsWithArtists (the catalog-songs read powering the chat /catalogs/[id] page). GET /api/songs has the same inner-join trait but is out of scope here. Longer term (option a on the issue): the capture pipeline should write song_artists for measured tracks so they have real artist linkage.

Verification

tsc clean · eslint clean · lib/catalog + lib/songs → 58 tests, no regression. Live preview check against a real materialized catalog to follow in a comment.

Closes the read-path half of the song_artists follow-up in recoupable/chat#1801.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed catalog song retrieval to display songs even when artist or account information is unavailable, ensuring users can access the complete song collection.

Summary by cubic

Fixes hidden songs in GET /api/catalogs/songs by switching artist joins to LEFT joins. Materialized tracks without song_artists now show up and are counted, with artists: [].

  • Bug Fixes
    • Use LEFT joins for song_artists and accounts in selectCatalogSongsWithArtists, so songs without artists are included and count: "exact" reflects all songs.
    • Keep songs!inner (FK ensures the row); other endpoints unchanged.