docs(catalogs): GET /api/catalogs/{catalogId}/valuations — persisted valuation history (chat#1889 row 15) - #279
Conversation
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
📝 WalkthroughWalkthroughThe OpenAPI specification now documents persisted catalog valuation history and adds a retrieval endpoint with its response schema. A new API reference page and navigation entry expose the endpoint documentation. ChangesCatalog valuation history
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api-reference/openapi/releases.json`:
- Around line 2910-2913: Update the successful response status schema near the
existing status property to add an enum constraint containing only "success",
while preserving its string type and example.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 80d852ce-cda6-49bd-a79d-df10fe710445
📒 Files selected for processing (3)
api-reference/openapi/releases.jsonapi-reference/songs/catalog-valuations.mdxdocs.json
| "status": { | ||
| "type": "string", | ||
| "example": "success" | ||
| }, |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Constrain successful response status to success.
The example implies "success", but the schema accepts any string. Add enum: ["success"] so generated clients receive the actual 200-response contract.
Proposed fix
"status": {
"type": "string",
+ "enum": ["success"],
"example": "success"
},📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "status": { | |
| "type": "string", | |
| "example": "success" | |
| }, | |
| "status": { | |
| "type": "string", | |
| "enum": ["success"], | |
| "example": "success" | |
| }, |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@api-reference/openapi/releases.json` around lines 2910 - 2913, Update the
successful response status schema near the existing status property to add an
enum constraint containing only "success", while preserving its string type and
example.
There was a problem hiding this comment.
1 issue found across 3 files
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="api-reference/openapi/releases.json">
<violation number="1" location="api-reference/openapi/releases.json:2912">
P3: The `status` property in `CatalogValuationsResponse` uses `"example": "success"` and lacks a `description`, but every other schema in this file that defines a `status` field uses `"enum"` (e.g., `["success"]`, `["error"]`, or `["success", "error"]`) plus a `"description"`. Since this endpoint returns 200 only on success (errors use 4xx HTTP responses), align with the established pattern by replacing `example` with `enum: ["success"]` and adding `description: "Status of the request"`.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| "properties": { | ||
| "status": { | ||
| "type": "string", | ||
| "example": "success" |
There was a problem hiding this comment.
P3: The status property in CatalogValuationsResponse uses "example": "success" and lacks a description, but every other schema in this file that defines a status field uses "enum" (e.g., ["success"], ["error"], or ["success", "error"]) plus a "description". Since this endpoint returns 200 only on success (errors use 4xx HTTP responses), align with the established pattern by replacing example with enum: ["success"] and adding description: "Status of the request".
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At api-reference/openapi/releases.json, line 2912:
<comment>The `status` property in `CatalogValuationsResponse` uses `"example": "success"` and lacks a `description`, but every other schema in this file that defines a `status` field uses `"enum"` (e.g., `["success"]`, `["error"]`, or `["success", "error"]`) plus a `"description"`. Since this endpoint returns 200 only on success (errors use 4xx HTTP responses), align with the established pattern by replacing `example` with `enum: ["success"]` and adding `description: "Status of the request"`.</comment>
<file context>
@@ -2821,6 +2900,61 @@
+ "properties": {
+ "status": {
+ "type": "string",
+ "example": "success"
+ },
+ "valuations": {
</file context>
…valuation history Contract for chat#1889 row 15 (the keystone): the valuation band is persisted wherever it is computed (valuation runs; measurement reads at most once per catalog per day) and read back as a latest-first series. limit=1 is the current value. History is what makes week-over-week deltas possible - the retention hook the weekly report needs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
464b75f to
3d12c97
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api-reference/openapi/releases.json`:
- Line 1417: Update the endpoint descriptions at both referenced entries to
explicitly reconcile per-run valuation persistence with the
one-row-per-catalog-per-day limit, stating whether same-day runs are coalesced
into one row or replace the existing row. Clarify the resulting history-length
and week-over-week comparison behavior without changing unrelated endpoint
details.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 82887cb1-6111-4c3b-a7c9-a65941de066b
📒 Files selected for processing (3)
api-reference/openapi/releases.jsonapi-reference/songs/catalog-valuations.mdxdocs.json
🚧 Files skipped from review as they are similar to previous changes (1)
- docs.json
| "post": { | ||
| "summary": "Run valuation", | ||
| "description": "Generate a catalog from a Spotify artist in one call. Resolves the artist's releases, captures current Spotify play counts (spending the account's credits), materializes an account-owned catalog from the resulting snapshot (idempotent - see [Create catalog](/api-reference/songs/catalogs-create)), and returns the catalog with its estimated value band. The owning account is taken from the credentials, never the body. The searched artist is also linked to the caller's roster (so a funnel signup lands with a populated `GET /api/artists` it can confirm); when the catalog's songs already resolve a canonical artist that one is used, otherwise the searched Spotify artist is linked directly. Synchronous: the request waits for the capture to land (typically under two minutes).", | ||
| "description": "Generate a catalog from a Spotify artist in one call. Resolves the artist's releases, captures current Spotify play counts (spending the account's credits), materializes an account-owned catalog from the resulting snapshot (idempotent - see [Create catalog](/api-reference/songs/catalogs-create)), and returns the catalog with its estimated value band. The owning account is taken from the credentials, never the body. The searched artist is also linked to the caller's roster (so a funnel signup lands with a populated `GET /api/artists` it can confirm); when the catalog's songs already resolve a canonical artist that one is used, otherwise the searched Spotify artist is linked directly. Synchronous: the request waits for the capture to land (typically under two minutes). Each run also persists a row in the catalog's valuation history, readable via [Get Catalog Valuations](/api-reference/songs/catalog-valuations).", |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Reconcile per-run persistence with daily deduplication.
These descriptions say each run writes a row, but also say there is at most one row per catalog per day. Clarify whether the daily row is coalesced or replaced so clients can reason correctly about history length and week-over-week comparisons.
Also applies to: 1654-1654
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@api-reference/openapi/releases.json` at line 1417, Update the endpoint
descriptions at both referenced entries to explicitly reconcile per-run
valuation persistence with the one-row-per-catalog-per-day limit, stating
whether same-day runs are coalesced into one row or replace the existing row.
Clarify the resulting history-length and week-over-week comparison behavior
without changing unrelated endpoint details.
Local verification — Mintlify render of
|
| # | Check | Expected (contract) | Actual (rendered) | Result |
|---|---|---|---|---|
| 1 | releases.json |
parses after rebase | json.load clean |
✅ |
| 2 | Nav entry | Catalogs group, after Get Catalog Measurements | sidebar shows GET Get Catalog Valuations directly under GET Get Catalog Measurements |
✅ |
| 3 | Path + method | GET /api/catalogs/{catalogId}/valuations |
rendered exactly; cURL example shows ?limit=30 |
✅ |
| 4 | catalogId param |
uuid, required, 400 on malformed | string<uuid> required + "Malformed (non-uuid) values are rejected with 400" |
✅ |
| 5 | limit param |
integer, default 30, range 1–100 | default: 30, "Required range: 1 <= x <= 100" |
✅ |
| 6 | Status codes | 200 / 400 / 401 / 404 | exactly those four response tabs | ✅ |
| 7 | 200 shape | {status, valuations[]} flat |
example renders status: "success" + array of {low, mid, high, measured_song_count, total_streams, measured_at} |
✅ |
| 8 | Child attributes | 6 fields, USD/measurement descriptions | all six expand with descriptions ("Low end of the estimated catalog value band, USD." etc.) | ✅ |
| 9 | Auth | apiKeyAuth + bearerAuth | both schemes in the Authorizations selector | ✅ |
| 10 | Run Valuation description | persistence note + link | "Each run also persists a row in the catalog's valuation history, readable via Get Catalog Valuations" — link resolves to the new page | ✅ |
| 11 | Em-dash sweep | 0 in rendered copy | /[—–]/ DOM assertion: 0 on both pages |
✅ |
Screenshots
New endpoint page (params + cURL + 200 example):

Response schema, child attributes expanded:

Run Valuation description with the persistence note + cross-link:

Rebased onto main (git rebase origin/main, clean — no overlap with docs#280/#281) and force-pushed. Merge order unchanged: this PR → database#52 → api#795. Contract ↔ implementation reconciliation against the live api#795 preview happens in that PR's verification pass once the table exists.
Contract-first PR for chat#1889 row 15 — the keystone (2026-07-29 reorder decision).
GET /api/catalogs/{catalogId}/valuations: persisted history latest-first,limit(default 30, max 100;limit=1= current value), rows{ low, mid, high, measured_song_count, total_streams, measured_at }; 400/401/404 via the shared Error schema, mirroring the measurements sibling.POST /api/valuationdescription notes that runs persist a history row.Merge order: this → database#TBD (
catalog_valuationstable) → api#TBD (persist + GET). JSON re-validated after anchored edits.🤖 Generated with Claude Code
Summary by cubic
Adds docs for
GET /api/catalogs/{catalogId}/valuations, exposing a persisted valuation history so teams can compute week‑over‑week deltas and fetch the current value withlimit=1. Supports the chat#1889 row 15 requirement to persist the valuation band wherever it’s computed.GET /api/catalogs/{catalogId}/valuations: latest‑first history,limit(default 30, max 100;limit=1= current), rows include{ low, mid, high, measured_song_count, total_streams, measured_at }; 400/401/404 via shared Error.POST /api/valuationdocs note each run persists a history row.Written for commit 464b75f. Summary will update on new commits.
Summary by CodeRabbit
New Features
Documentation