Skip to content

Show observed release format and disc numbers in release cases - #2220

Open
sidneyswift wants to merge 3 commits into
mainfrom
claude/ctx-2139-release-format
Open

sidneyswift wants to merge 3 commits into
mainfrom
claude/ctx-2139-release-format

Conversation

@sidneyswift

@sidneyswift sidneyswift commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Reviewers could not tell a single from an album, or see disc structure, on the release review page, even though the saved Spotify observation carries that metadata. This PR renders the server-projected release_format (recoupable/database#109, typed in recoupable/api#1021) as one line under the release title, for example Album · 2 discs · 3 tracks reported · Released 2024-05-17 · <label> · UPC not observed · Reissue/physical format unknown, and prefixes each track cell with Disc N · when the release is multi-disc. When only part of the track list was collected (track_coverage: partial), the line says Track list incomplete and shows Multiple discs (a partial list already reaching disc 2) or Disc count unknown, never a definite disc count. This advances ticket Done-when 1 (distinguish singles, albums and formats on canonical releases with ordered, disc-aware membership).

Only observed values are shown: a UPC appears only when the server reports one, reissue and physical format are always stated as unknown, and an observed-but-unknown type (Format unknown) stays distinct from an uncollected one (Format not collected). The field is optional in lib/releases/types.ts, so a response from an API without the migration still renders. No sorting or grouping changes to the track table.

Refs #2139 (child of epic #2116).

Merge sequencing

docs (no change) → database recoupable/database#109 → api recoupable/api#1021 → app (this PR). Safe to merge before the backend because the field is optional; the line then reads Format not collected. Depends on no other OPEN PR; builds on merged app#2172/#2173/#2178.

Verification

  • Ran (after the last change) pnpm exec vitest run components/Releases lib/releases → 24 files, 74 tests passed, 0 failed (includes ReleaseCaseFormat.test.tsx, 6 tests, ReleaseCaseFormatCoverage.test.tsx, 2 tests, and the unchanged ReleaseCasePresentation, ReleaseCaseReview, ReleaseCaseScope, ReleaseCaseAccess, ReleaseCaseRecovery suites).
  • Ran pnpm exec tsc --noEmit → 1 error, pre-existing and unrelated (components/VercelChat/tools/SpotifyDeepResearchResult.tsx: cannot find module @/public/brand-logos/spotify.png, because the untracked generated next-env.d.ts is absent without a Next build); 0 errors in changed files.
  • Ran pnpm exec eslint and pnpm exec prettier --check on the 8 changed files → clean.
  • Red → green: ReleaseCaseFormat.test.tsx was written first; with the component and the two render edits absent, all 5 tests failed (Unable to find an element with the text: /^Album · 2 discs · 3 tracks reported/, ... Format not collected, etc.). With the implementation, 5/5 pass.
  • Red → green (review follow-up, second commit): a sixth test asserts upc_state: "uncollected" reads UPC not collected, not UPC not observed; it failed (expected 'Album · 2 discs · 3 tracks reported ·…' to contain 'UPC not collected') before the label change and passes after. Test fixtures moved to components/Releases/__tests__/releaseFormatFixture.ts, following the existing streamFixture.ts pattern.
  • Red → green (third commit, independent review follow-up matching database#109's partial-coverage fix): ReleaseCaseFormatCoverage.test.tsx (50 of 60 tracks collected; partial list reaching disc 2) and the updated observed-but-unknown case were written first and failed 3/8 (Unable to find an element with the text: /^Album · Disc count unknown · 60 tracks reported · Track list incomplete/, /^Album · Multiple discs · .../, /^Format unknown · Disc count unknown · .../). With the render change, all pass. The shared render helper moved to components/Releases/__tests__/renderReleaseCase.tsx so both test files stay under 100 lines.
  • Not verified: hosted deployment (Vercel built its automatic PR preview; not exercised), the production database, live API responses with release_format, visual review in a browser, any live provider.

Out of scope / known gaps

  • Catalog member expansion with bounded concurrency and resumable child requests (Done-when 2 remainder).
  • Reissue and physical-format detection (not observable from Spotify).
  • Saved review snapshots created before database#109 contain no release_format; the current-case page always renders the live projection.
  • ReleaseCaseDetails.tsx was already 140 lines on main; this PR adds two lines (142) and does not split it, to avoid conflicts with sibling tickets editing the same page. The cubic comment about it is intentionally left open for the approver; a split belongs in a follow-up.
  • label is shown as an observed string only; it does not verify rights, ownership or distribution.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Release details now show available format information, including disc count, reported track count, track coverage, release date, label, and UPC. Missing or unobserved information is clearly labeled rather than inferred.
    • Track listings now show a disc number alongside each track when the release has multiple discs and that track’s disc number is available.

Reviewers could not tell a single from an album or see disc structure on
the release review page, even though the saved Spotify observation carries
that metadata. Render the server-projected release_format as one line under
the title and prefix track cells with the disc number when the release is
multi-disc. The field is optional so responses from an older API still
render, in which case the page says "Format not collected".

Only observed values are shown: a UPC appears only when the server reports
one, reissue and physical format are always stated as unknown, and an
observed-but-unknown type stays distinct from an uncollected one.

Refs #2139

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated
app Ready Ready Preview Oct 10, 2026 9:46pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: recoupable/app/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3d46365c-1930-4260-84ef-0c791ca92396

📥 Commits

Reviewing files that changed from the base of the PR and between 025342d and 3deaae6.


⛔ Files ignored due to path filters (2)
  • components/Releases/__tests__/ReleaseCaseFormat.test.tsx is excluded by !**/*.test.* and included by components/**
  • components/Releases/__tests__/ReleaseCaseFormatCoverage.test.tsx is excluded by !**/*.test.* and included by components/**

📒 Files selected for processing (6)
  • components/Releases/ReleaseCaseDetails.tsx
  • components/Releases/ReleaseCaseFormat.tsx
  • components/Releases/ReleaseCaseTracks.tsx
  • components/Releases/__tests__/releaseFormatFixture.ts
  • components/Releases/__tests__/renderReleaseCase.tsx
  • lib/releases/types.ts

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.



📝 Walkthrough

Walkthrough

The release case model now supports optional observed-format metadata. The release details view displays format information and uses disc numbers in track labels when the release is marked as multi-disc.

Changes

Release format display

Layer / File(s) Summary
Format contract and display
lib/releases/types.ts, components/Releases/ReleaseCaseFormat.tsx
Adds the ReleaseFormat interface and optional ReleaseCase.release_format property. The component displays observed format details or fallback labels without inferring values.
Release view integration and test support
components/Releases/ReleaseCaseDetails.tsx, components/Releases/ReleaseCaseTracks.tsx, components/Releases/__tests__/*
The release details view renders format information beneath the title. Track labels show a disc prefix for numbered tracks when the release is multi-disc. Adds format fixtures and a render helper.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Feature


Merge Risk: ⚪ Minimal · up to 3deaa

No actionable issue was established in the release-format display change. Live API compatibility remains unverified.

Pre-merge checks | Passed 2 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Solid & Clean Code Warning ReleaseCaseFormat is a new 32-line function (lines 9-40). It both handles the observed/uncollected state and builds all display fields, which exceeds the check's 20-line function guideline and combi… Refactor ReleaseCaseFormat into small, named helpers. Keep the component responsible for rendering and move release-format state handling and metadata assembly into helpers such as a formatter for the observed ReleaseFormat, with separa…
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

Full details: Solid & Clean Code

Explanation

ReleaseCaseFormat is a new 32-line function (lines 9-40). It both handles the observed/uncollected state and builds all display fields, which exceeds the check's 20-line function guideline and combines formatting responsibilities in one component.

Resolution

Refactor ReleaseCaseFormat into small, named helpers. Keep the component responsible for rendering and move release-format state handling and metadata assembly into helpers such as a formatter for the observed ReleaseFormat, with separate helpers for disc-count and UPC labels. Keep each function at 20 lines or fewer and preserve the existing tests and output.


  • Fix all pre-merge checks with AI
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR


🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

A format arrives, its fields in view
Unknowns stay marked as unknown too
Two discs lend tracks a numbered sign
Observed details follow the line
The case now shows what it can know

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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-10T20:40:05.944678Z d300433 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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.

2 issues found across 5 files

Confidence score: 4/5

  • In ReleaseCaseFormat.tsx, “UPC not observed” makes an uncollected UPC sound checked and absent. Show “UPC not collected” for that state.
  • ReleaseCaseDetails.tsx combines the header, empty state, tracks, review controls, and sources disclosure in one 142-line component, which makes it harder to maintain. Consider splitting those responsibilities.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="components/Releases/ReleaseCaseFormat.tsx">

<violation number="1" location="components/Releases/ReleaseCaseFormat.tsx:27">
P2: For `upc_state: "uncollected"`, this renders “UPC not observed,” falsely implying collection established that no UPC was present. Render “UPC not collected” for that state.</violation>
</file>

<file name="components/Releases/ReleaseCaseDetails.tsx">

<violation number="1" location="components/Releases/ReleaseCaseDetails.tsx:43">
P2: Custom agent: **Code Structure and Size Limits for Readability and Single Responsibility**

`ReleaseCaseDetails.tsx` is 142 lines and still combines the header, empty state, tracks, review controls, and sources disclosure, exceeding the rule’s 100-line limit. Split the remaining page sections into focused components rather than continuing to grow this component.</violation>
</file>

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

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread components/Releases/ReleaseCaseFormat.tsx Outdated
<h2 className="text-xl font-semibold">
{current.title ?? "Spotify release"}
</h2>
<ReleaseCaseFormat current={current} />

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Custom agent: Code Structure and Size Limits for Readability and Single Responsibility

ReleaseCaseDetails.tsx is 142 lines and still combines the header, empty state, tracks, review controls, and sources disclosure, exceeding the rule’s 100-line limit. Split the remaining page sections into focused components rather than continuing to grow this component.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At components/Releases/ReleaseCaseDetails.tsx, line 43:

<comment>`ReleaseCaseDetails.tsx` is 142 lines and still combines the header, empty state, tracks, review controls, and sources disclosure, exceeding the rule’s 100-line limit. Split the remaining page sections into focused components rather than continuing to grow this component.</comment>

<file context>
@@ -39,6 +40,7 @@ export default function ReleaseCaseDetails({
           <h2 className="text-xl font-semibold">
             {current.title ?? "Spotify release"}
           </h2>
+          <ReleaseCaseFormat current={current} />
           <p className="mt-1 text-sm text-muted-foreground">
             {awaitingMetadata
</file context>

Comment thread components/Releases/__tests__/ReleaseCaseFormat.test.tsx
"UPC not observed" claims a collection looked for a UPC and found none.
When the server reports upc_state "uncollected" the release line now says
"UPC not collected" instead, keeping uncollected distinct from not
observed. Move the release format test fixtures into their own module,
following the existing streamFixture pattern, so the test file stays
focused on the cases.

Refs #2139

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@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.

0 issues found across 3 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.

View guided diff | Turn on auto-fix | Re-trigger cubic

database#109 now leaves disc_count null when only part of a release's
track list was collected and reports track_coverage. Render "Multiple
discs" when a partial list already reaches disc 2, "Disc count unknown"
otherwise, and "Track list incomplete" for partial coverage, so a
truncated album is never shown as a definite single disc.

Moves the shared render helper out of the format test so both test files
stay small.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@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 6 files (changes from recent commits).

Confidence score: 4/5

  • ReleaseCaseFormat.tsx handles only partial, so formats with track_coverage: "uncollected" lose that state in the UI. Add a separate “Track list not collected” label.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="components/Releases/ReleaseCaseFormat.tsx">

<violation number="1" location="components/Releases/ReleaseCaseFormat.tsx:29">
P2: Observed formats with `track_coverage: "uncollected"` lose the uncollected state because this branch handles only `"partial"`. Add a separate `Track list not collected` label so the UI does not present an uncollected track list as merely unknown.</violation>
</file>

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

View guided diff | Turn on auto-fix | Re-trigger cubic

format.reported_total_tracks === null
? null
: `${count(format.reported_total_tracks, "track")} reported`,
format.track_coverage === "partial" ? "Track list incomplete" : null,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Observed formats with track_coverage: "uncollected" lose the uncollected state because this branch handles only "partial". Add a separate Track list not collected label so the UI does not present an uncollected track list as merely unknown.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At components/Releases/ReleaseCaseFormat.tsx, line 29:

<comment>Observed formats with `track_coverage: "uncollected"` lose the uncollected state because this branch handles only `"partial"`. Add a separate `Track list not collected` label so the UI does not present an uncollected track list as merely unknown.</comment>

<file context>
@@ -18,10 +18,15 @@ export default function ReleaseCaseFormat({
     format.reported_total_tracks === null
       ? null
       : `${count(format.reported_total_tracks, "track")} reported`,
+    format.track_coverage === "partial" ? "Track list incomplete" : null,
     format.release_date ? `Released ${format.release_date}` : null,
     format.label,
</file context>
Suggested change
format.track_coverage === "partial" ? "Track list incomplete" : null,
format.track_coverage === "partial"
? "Track list incomplete"
: format.track_coverage === "uncollected"
? "Track list not collected"
: null,

This branch was successfully deployed

1 active deployment
Preview – app — 3deaae60 Deployed Oct 10, 2026 by vercel[bot]
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