fix: valuation run shows progress and stops prefetching the alphabet - #59
Conversation
Two /valuation defects from the web UX conversion audit (recoupable/chat#1902, item M5): 1. The synchronous POST /api/valuation (~60s on a 238-track catalog) disabled every control with no visible feedback. Add a progress card that mounts with the run: pulsing dot, staged status line, live elapsed-time ticker, and expectation copy. Replace the bare error line with a readable error card and a Try again button. 2. Mounting the search box prefetched /api/spotify/search for every letter a-z (26 requests per fresh page load). Remove the prefetch; the cache now seeds lazily from the debounced fetch on the first keystroke. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
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. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 57 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (11)
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 |
Preview verification — 2026-07-30Preview https://marketing-o5jbp5lhp-recoup.vercel.app/valuation, built from head Results
Row 1 is the headline, and I nearly reported it wrong. My first probe matched Row 7: what I could and could not verifyNot exercised live. The run is behind the Privy gate — Established from the code, and it is a stronger guarantee than a stopwatch: async function doRun(artist: Artist) {
setPhase("running"); // ← synchronous
setError("");
startProgress(); // ← sets PROGRESS_STAGES[0] synchronously
try {
const token = await getAccessToken(); // first await comes after
Not established: that it looks right in a browser — spacing, the pulsing dot, the elapsed ticker incrementing, and the stage copy advancing every 9s. That needs one authenticated run and I would like to do it before merge. Pre-run state (artist picked, run enabled, no prefetch fired)One thing surfaced, deliberately not fixed hereThe elapsed counter and the whole run are client-side React state with nothing persisted — no That is a plausible route to the "I went through twice" report this row traces back to. It is out of scope for this PR — making a run survive a refresh needs the endpoint to become asynchronous and hand back an id the page can track, which is an architecture change, not a progress indicator. Two mitigations already landed today: this PR makes the wait legible, and api#800's 60-minute reuse window means a re-run no longer re-scrapes or re-bills. Recommend tracking the resumable run as its own row rather than expanding this one. Local build note
|
Happy path completed — 2026-07-30Follow-up to the previous comment, which stopped at the Privy gate. Signed in as Results
Timings are Progress state, mid-runCompleted resultOne thing I could not captureThe stage copy advancing ( Related and worth stating: those stages are advanced by a timer, not by server phases — Combined with the earlier commentFull picture for this PR: alphabet prefetch 26 → 0 (measured against prod as a control), search and selection unaffected, 23 tests / 6 files, The refresh limitation from the previous comment still stands and is still out of scope: a mid-run refresh drops the counter, the progress line and the in-flight request. Recommend tracking the resumable run separately. |



Part of recoupable/chat#1902 (web UX conversion audit, item M5). Two defects on
/valuation(also the homepage hero, which renders the sameCatalogValuation):1. The valuation run looked broken for ~60 seconds
Clicking "Value my catalog" fires one synchronous
POST /api/valuationthat measured ~60s on a 238-track catalog (Mac DeMarco) while every control went disabled, with the only feedback buried in the input's placeholder text. Users assumed the page broke.This PR keeps the synchronous POST (async/workflow conversion is out of scope) and adds a visible progress state that appears immediately on click:
ValuationProgress: a card below the search box with a subtle pulsing dot, the existing staged status line ("Finding your releases…" → "Measuring play counts…" → "Computing your valuation…"), a live elapsed-time ticker ("42s", "1m 15s"), and a persistent expectation line: "Measuring live play counts across your catalog. Large catalogs can take a minute or two." Announced viarole="status"/aria-live="polite".ValuationError: the error state is now a readable card with a "Try again" button that re-fires the run for the same picked artist (previously a bare red line with no recovery path). Error copy rewritten without dashes.formatElapsedSeconds(+ unit tests) and auseElapsedSecondshook.2. Page load fired 26 search requests
Mounting the search box prefetched
GET /api/spotify/search?q=<letter>for every letter a-z to warm the autocomplete cache: 26 requests on every fresh page load before the user touched anything. Removedlib/spotify/prefetchLetters.tsand its mount effect; the cache now seeds lazily from the existing debounced fetch on the first keystroke (getCachedApproxstill narrows from previously cached prefixes). A fresh page load now fires zero search requests.How to test
/valuationwith the network panel filtered tospotify/search: zero requests on load. Type a letter: the first (debounced) request fires.Preview verification + screenshots to follow in a PR comment.
🤖 Generated with Claude Code
Summary by cubic
Show progress during valuation runs and remove alphabet prefetch in artist search to fix broken-looking UX and prevent unnecessary requests on load. Addresses
recoupable/chat#1902(M5).New Features
Bug Fixes
Written for commit d456486. Summary will update on new commits.