Skip to content

Fix catalog filtering for small catalogs and bound large results - #914

Merged
sidneyswift merged 1 commit into
mainfrom
codex/catalog-filtering
Sep 19, 2026
Merged

sidneyswift merged 1 commit into
mainfrom
codex/catalog-filtering

Conversation

@sidneyswift

@sidneyswift sidneyswift commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Catalog requests with 1,000 songs or fewer previously returned the entire catalog without applying the criteria. Larger catalogs repeatedly invoked AI filtering until fewer than 1,001 songs remained, which could continue indefinitely when all songs matched.

Filter every nonempty catalog in one pass, then cap matching results at 1,000 in catalog order. All pages are considered before limiting. This is a deterministic cap, not a new global relevance ranking; the model and response shape are unchanged. Empty catalogs avoid inference, and inference errors propagate rather than returning unfiltered songs.

Validation:

  • Added nine regression tests through the full catalog-analysis pipeline, mocking only database and model boundaries. Seven failed before the fix.
  • All 149 catalog tests pass, including boundary sizes, no matches, a last-page match, all-match termination, invented/duplicate IDs and inference failure.
  • Repository lint and diff whitespace checks pass.
  • Repository-wide TypeScript check remains failing with errors in unrelated files; no diagnostics reference the changed files.

Small catalogs now incur the intended model calls (one per 100-song batch). Large catalogs retain the existing parallel batching. No production inference or deployment was performed.


Summary by cubic

Fixes catalog filtering so catalogs of 1,000 songs or fewer are no longer returned unfiltered, and large all-matching catalogs no longer loop forever. Filter every nonempty catalog once, then cap matches at 1,000 in catalog order; the cap is deterministic, and the model and response shape are unchanged.

Validation

  • Empty catalogs skip inference; inference errors propagate instead of returning unfiltered songs.
  • All pages are considered before limiting, so a match on the last page is retained.
  • Added nine regression tests through the catalog-analysis pipeline; all 149 catalog tests pass.
  • Repository TypeScript check still fails in unrelated files; no diagnostics reference the changed files.

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

Review in cubic

@coderabbitai

coderabbitai Bot commented Sep 19, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Repository: recoupable/api/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: b7d353dc-00f1-4f52-91f9-28a99644a666


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.

@vercel

vercel Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated
api Ready Ready Preview Sep 19, 2026 9:41pm UTC

Request Review

@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 3 files

Confidence score: 5/5

  • lib/catalog/__tests__/analyzeFullCatalog.test.ts exceeds the 100-line style limit, which modestly reduces test maintainability; extract the catalog() and select() helpers as suggested.
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/catalog/__tests__/analyzeFullCatalog.test.ts">

<violation number="1" location="lib/catalog/__tests__/analyzeFullCatalog.test.ts:42">
P3: Custom agent: **Enforce Clear Code Style and Maintainability Practices**

This test file is 111 lines long, exceeding the 100-line limit in the code-style rule. Extract the `catalog()` and `select()` helpers into a shared test helper file (or split the regression tests) to bring the file under 100 lines while keeping the suite cohesive.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant Client as API Client
    participant Route as Catalog Route
    participant Analyze as analyzeFullCatalog
    participant DB as Supabase DB
    participant Refine as refineResults
    participant Model as AI Model (generateObject)

    Note over Client,Model: Catalog Filtering Flow

    Client->>Route: Request catalog analysis with criteria
    Route->>Analyze: analyzeFullCatalog({catalogId, criteria})

    Analyze->>DB: selectCatalogSongsWithArtists(page 1)
    DB-->>Analyze: Page 1 songs + total_count
    Analyze->>DB: selectCatalogSongsWithArtists(page N)
    DB-->>Analyze: Page N songs + total_count

    Analyze->>Analyze: Flatten all pages into allSongs

    alt allSongs is empty
        Analyze-->>Route: { results: [], totalSongs: 0, totalPages: 0 }
        Note over Analyze,Model: No inference performed for empty catalogs
    else allSongs non-empty
        Analyze->>Refine: refineResults(allSongs, criteria)

        loop For each batch of 100 songs in parallel
            Refine->>Model: generateObject(songs batch, criteria)
            Model-->>Refine: selected_song_isrcs
        end

        Refine->>Refine: Deduplicate and validate ISRCs against catalog
        Refine->>Refine: Cap results at first 1000 in catalog order
        Refine-->>Analyze: Filtered results up to 1000
        Analyze-->>Route: { results, totalSongs, totalPages }
    end

    alt Inference error occurs
        Model-->>Refine: Error thrown
        Refine-->>Analyze: Propagate error
        Analyze-->>Route: 500 error
        Note over Refine,Analyze: Errors propagate - no unfiltered fallback
    end

    Route-->>Client: Response with filtered results
Loading

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

Re-trigger cubic

@@ -0,0 +1,111 @@
import { beforeEach, describe, expect, it, vi } from "vitest";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Custom agent: Enforce Clear Code Style and Maintainability Practices

This test file is 111 lines long, exceeding the 100-line limit in the code-style rule. Extract the catalog() and select() helpers into a shared test helper file (or split the regression tests) to bring the file under 100 lines while keeping the suite cohesive.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/catalog/__tests__/analyzeFullCatalog.test.ts, line 42:

<comment>This test file is 111 lines long, exceeding the 100-line limit in the code-style rule. Extract the `catalog()` and `select()` helpers into a shared test helper file (or split the regression tests) to bring the file under 100 lines while keeping the suite cohesive.</comment>

<file context>
@@ -0,0 +1,111 @@
+  } as Awaited<ReturnType<typeof generateObject>>);
+}
+
+describe("analyzeFullCatalog filtering", () => {
+  beforeEach(() => vi.resetAllMocks());
+
</file context>

@sidneyswift
sidneyswift merged commit a7e5fd6 into main Sep 19, 2026
6 checks passed
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