Skip to content

Test#682

Merged
sweetmantech merged 9 commits into
mainfrom
test
Jun 18, 2026
Merged

Test#682
sweetmantech merged 9 commits into
mainfrom
test

Conversation

@sweetmantech

@sweetmantech sweetmantech commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary by cubic

Fix catalog-songs read to include tracks without artist links by switching artist joins to LEFT joins; materialized catalogs now return songs with artists: [] when none are present.

  • Bug Fixes
    • Removed !inner on song_artists and nested accounts in selectCatalogSongsWithArtists (keeps songs!inner).

Written for commit a520a1d. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved song catalog retrieval to handle cases with incomplete or missing artist data. Songs can now display properly in the catalog even when associated artist information is unavailable, enhancing data availability and catalog completeness.

sweetmantech and others added 9 commits June 16, 2026 11:40
…ckfill drain (#671)

Two chat#1796 refinements on the historical (Songstats) path:

1. Free-tier card-on-file link. The gate was issuing the paid subscription
   checkout ($99/mo after a 30-day trial). New createCardOnFileSession uses
   Stripe Checkout `mode: "setup"` — collects a card for $0, no subscription,
   no Stripe product. The account then pays only for metered usage via credits.

2. Instant drain. After enqueuing a historical job, fire-and-forget
   start(songstatsBackfillWorkflow) so the backfill begins immediately instead
   of waiting up to 24h for the cron. Safe by reuse: the workflow's budget gate
   (limit − reserve − rolling-30d ledger) caps it to the Songstats quota and
   SKIP LOCKED prevents double-claiming with the daily cron, which stays as the
   backstop. Only kicks when something was actually enqueued.

26 new/updated unit tests; research+stripe+workflows suite 453 green; tsc/lint/format clean.
…t#1797) (#673)

Pacing/backoff + per-step logging for the Songstats backfill drain (chat#1797 bullets 1 & 3). Bounded exponential backoff (fetchSongstatsWithBackoff, 502/503/504/408/429), defer-to-pending past the bound with claimed-batch release, per-step + per-batch logging.
…97) (#674)

Bullet 2 of chat#1797 (code half). Songstats is the rate authority — removes getBackfillBudgetStep, the budget gate, and insertSongstatsQuotaLedger/selectSongstatsQuotaSpent. The drain now claims+processes regardless of the ledger (un-stalls the backfill); the songstats_quota_ledger table is dropped in recoupable/database#35 (apply AFTER this deploys).
…t) (#677)

* feat: POST /api/catalogs create + materialize from valuation snapshot

Creates a catalog owned by the authenticated account (account derived
from credentials via validateAuthContext, never the body). With
from.snapshot_id, materializes the catalog from a completed valuation
snapshot: creates the catalogs row, links account_catalogs, adds the
snapshot's measured ISRCs as catalog_songs, and records the catalog on
the snapshot. Re-claiming the same snapshot is idempotent.

TDD: validateCreateCatalogBody (6 tests) + createCatalogHandler (8 tests),
red->green. New supabase wrappers: insertCatalog, selectCatalogById,
insertAccountCatalog, updateSnapshotCatalog.

Implements recoupable/chat#1801 Phase 2. Matches docs contract recoupable/docs#243.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor: re-anchor POST /api/catalogs to merged contract + review fixes

- Flatten request to the merged docs#243 contract: from:{snapshot_id} -> a
  root snapshot field (validator + handler + tests). Error copy follows.
- DRY/SRP: drop the inline success() helper; use the shared successResponse().
- KISS rename: materializeSnapshotCatalog.ts -> createSnapshotCatalog.ts.
- DRY: delete the redundant updateSnapshotCatalog helper; reuse the existing
  updatePlaycountSnapshot(id, fields).

Validator change done red->green. lib/catalog: 24 tests pass; tsc + eslint clean.

Addresses review on PR #677.

* fix: materialize catalog songs from song_measurements, not snapshot.isrcs

Testing the full materialize path surfaced a real bug: a valuation snapshot
is album_ids-scoped, so its own isrcs column is null — createSnapshotCatalog
read snapshot.isrcs and would link an EMPTY catalog. The measured ISRCs live
in song_measurements (snapshot lineage), so source them there.

New selectSnapshotIsrcs(snapshotId) helper (distinct song_measurements.song
for the snapshot). createSnapshotCatalog now uses it.

TDD: new createSnapshotCatalog.test.ts (3 tests) red->green; lib/catalog 27 pass.

Addresses PR #677 verification.

* refactor: reuse selectSongMeasurements (snapshot filter) instead of a new helper

KISS/DRY per review: drop selectSnapshotIsrcs; add an optional snapshot
filter to the existing selectSongMeasurements, and derive distinct ISRCs
in createSnapshotCatalog. lib/catalog + song_measurements: 36 tests pass.

Addresses review on PR #677.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e hidden) (#681)

* fix: LEFT-join artists in catalog-songs read so materialized tracks surface

selectCatalogSongsWithArtists used song_artists!inner -> accounts!inner, so
valuation-captured tracks (which have songs + song_measurements but no
song_artists yet) were filtered out — a materialized catalog read back as 0
songs (verified live on api#677). Drop the two !inner so artist-less songs
return with artists: []; songs!inner stays (catalog_songs.song FK guarantees it).

Closes the read-path half of the song_artists follow-up in recoupable/chat#1801.
Longer-term (option a): the capture pipeline should also write song_artists.

* Update lib/supabase/catalog_songs/selectCatalogSongsWithArtists.ts
@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
api Building Building Preview Jun 18, 2026 10:01pm

Request Review

@sweetmantech sweetmantech merged commit 78cf38e into main Jun 18, 2026
4 of 6 checks passed
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9a5f7e3d-5172-4bdc-8f45-e9e2157a9c83

📥 Commits

Reviewing files that changed from the base of the PR and between 4551e6a and a520a1d.

📒 Files selected for processing (1)
  • lib/supabase/catalog_songs/selectCatalogSongsWithArtists.ts

📝 Walkthrough

Walkthrough

In selectCatalogSongsWithArtists.ts, the Supabase select() query string removes !inner from both the song_artists and accounts nested relationship selectors, converting them from inner joins to left outer joins so that songs without associated artist or account records are no longer excluded from results.

Changes

Catalog Songs Query Join Semantics

Layer / File(s) Summary
Switch to outer joins for song_artists and accounts
lib/supabase/catalog_songs/selectCatalogSongsWithArtists.ts
Removes !inner from both the song_artists and accounts nested Supabase relationship selectors, allowing songs with no linked artist or account rows to be included in query results; song_artists may now be null/empty in the response payload.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

  • recoupable/api#681: Modifies the same selectCatalogSongsWithArtists.ts file with the same intent of removing !inner join semantics from the song_artists and accounts relationships.

Poem

Two bangs removed, the joins now breathe,
No inner walls for songs to seethe.
An artist missing? Still come through!
The outer join lets all songs queue.
Clean contracts win — no data left behind! 🎵

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Confidence score: 2/5

  • In lib/supabase/catalog_songs/selectCatalogSongsWithArtists.ts, removing !inner makes the artistName filter ineffective at the top-level query, so songs from other artists can still be returned and user-facing search/filter results become incorrect. Restore the inner join behavior (or add an equivalent top-level filter that enforces artist matching) before merging.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="lib/supabase/catalog_songs/selectCatalogSongsWithArtists.ts">

<violation number="1" location="lib/supabase/catalog_songs/selectCatalogSongsWithArtists.ts:58">
P0: Removing `!inner` breaks the `artistName` filter — with left joins, `.eq("songs.song_artists.accounts.name", artistName)` only filters which nested accounts rows appear, not which top-level catalog_songs are returned. All songs will be returned regardless of the artistName parameter.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

notes,
updated_at,
song_artists!inner (
song_artists (

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0: Removing !inner breaks the artistName filter — with left joins, .eq("songs.song_artists.accounts.name", artistName) only filters which nested accounts rows appear, not which top-level catalog_songs are returned. All songs will be returned regardless of the artistName parameter.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/supabase/catalog_songs/selectCatalogSongsWithArtists.ts, line 58:

<comment>Removing `!inner` breaks the `artistName` filter — with left joins, `.eq("songs.song_artists.accounts.name", artistName)` only filters which nested accounts rows appear, not which top-level catalog_songs are returned. All songs will be returned regardless of the artistName parameter.</comment>

<file context>
@@ -55,9 +55,9 @@ export async function selectCatalogSongsWithArtists(
         notes,
         updated_at,
-        song_artists!inner (
+        song_artists (
           artist,
-          accounts!inner (
</file context>
Suggested change
song_artists (
song_artists!inner (

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant