test: golden valuation fixture shared with recoupable/api#44
test: golden valuation fixture shared with recoupable/api#44sweetmantech wants to merge 1 commit into
Conversation
Guards the twin implementations of the catalog valuation model (computeCatalogValuation here, computeValuationBand in api) against silent divergence: a byte-identical fixture JSON is committed in both repos and each repo's CI asserts its implementation reproduces every case to the cent (recoupable/chat#1850). 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: 17 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 Run ID: 📒 Files selected for processing (2)
✨ 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.
1 issue found across 2 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="lib/valuation/__tests__/fixtures/valuation-golden.json">
<violation number="1" location="lib/valuation/__tests__/fixtures/valuation-golden.json:2">
P3: The formula description's `msSince(earliestReleaseDate) / 365.25d` notation skips the ms‑to‑days conversion factor (86400000). Since this fixture is the canonical reference shared verbatim across two repos, a reader re‑implementing from the description alone could mis‑compute the age. Suggest `msSince(earliestReleaseDate) / (365.25 * 86400000)` (or `daysSince(…) / 365.25`) to make the unit conversion explicit.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| @@ -0,0 +1,61 @@ | |||
| { | |||
| "description": "Golden valuation-band cases shared verbatim between recoupable/api (lib/catalog/computeValuationBand.ts) and recoupable/marketing (lib/valuation/computeCatalogValuation.ts). The two copies of this file must stay byte-identical, and each repo has a test asserting its implementation reproduces every case to the cent. If a test fails, the implementations have diverged: fix the code or update this fixture in BOTH repos in the same change. Formula: annualGross = (totalStreams / catalogAgeYears) * 0.0035; band = annualGross * grossUp{1.25,1.4,1.6} * (1 - 0.15) * (1 - 0.25) * multiple{10,13,16}; catalogAgeYears = round(msSince(earliestReleaseDate) / 365.25d) clamped to >= 1, defaulting to 5 when earliestReleaseDate is null. Band keys here are low/mid/high; marketing names the middle value 'central'.", | |||
There was a problem hiding this comment.
P3: The formula description's msSince(earliestReleaseDate) / 365.25d notation skips the ms‑to‑days conversion factor (86400000). Since this fixture is the canonical reference shared verbatim across two repos, a reader re‑implementing from the description alone could mis‑compute the age. Suggest msSince(earliestReleaseDate) / (365.25 * 86400000) (or daysSince(…) / 365.25) to make the unit conversion explicit.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/valuation/__tests__/fixtures/valuation-golden.json, line 2:
<comment>The formula description's `msSince(earliestReleaseDate) / 365.25d` notation skips the ms‑to‑days conversion factor (86400000). Since this fixture is the canonical reference shared verbatim across two repos, a reader re‑implementing from the description alone could mis‑compute the age. Suggest `msSince(earliestReleaseDate) / (365.25 * 86400000)` (or `daysSince(…) / 365.25`) to make the unit conversion explicit.</comment>
<file context>
@@ -0,0 +1,61 @@
+{
+ "description": "Golden valuation-band cases shared verbatim between recoupable/api (lib/catalog/computeValuationBand.ts) and recoupable/marketing (lib/valuation/computeCatalogValuation.ts). The two copies of this file must stay byte-identical, and each repo has a test asserting its implementation reproduces every case to the cent. If a test fails, the implementations have diverged: fix the code or update this fixture in BOTH repos in the same change. Formula: annualGross = (totalStreams / catalogAgeYears) * 0.0035; band = annualGross * grossUp{1.25,1.4,1.6} * (1 - 0.15) * (1 - 0.25) * multiple{10,13,16}; catalogAgeYears = round(msSince(earliestReleaseDate) / 365.25d) clamped to >= 1, defaulting to 5 when earliestReleaseDate is null. Band keys here are low/mid/high; marketing names the middle value 'central'.",
+ "cases": [
+ {
</file context>
Part of recoupable/chat#1850 (video/experience parity, item 2 — valuation derivation guard).
Why
The catalog valuation model is intentionally implemented twice:
lib/valuation/computeCatalogValuation.tshere (the /valuation card computes its band client-side for the progressive in-card state) andlib/catalog/computeValuationBand.tsin recoupable/api. The constants are mirrored by comment-discipline only — nothing fails if one side drifts. This PR adds the guard.What
lib/valuation/__tests__/fixtures/valuation-golden.json— canonical inputs → expected band cases derived independently from the published formula ($0.0035/stream, gross-ups 1.25/1.4/1.6, NLS = gross x 0.85 x 0.75, multiples 10/13/16, age = round(ms/365.25d) clamped >= 1, default 5y). Cases: the real verified 16.3B-stream catalog (age fallback), zero streams, a 10y catalog aged from its release date, and the 1y age clamp. The fixture'smidkey maps to this repo'scentral.lib/valuation/__tests__/valuationGoldenFixture.test.ts— runscomputeCatalogValuationagainst every case, asserting to within one cent. GREEN on first run against the existing implementation (zero divergence today).Lockstep rule: this fixture's twin lives at
api/lib/catalog/__tests__/fixtures/valuation-golden.json(recoupable/api#765) and the two files must stay byte-identical (SHA-1a2c9737f167a25e3589b5d53fa4bf832d4f1e0bd). Any model change must update the fixture in BOTH repos in the same coordinated change, or one repo's CI goes red — which is the point.Follow-up (out of scope): extract a true shared package so the formula exists once; until then this fixture is the divergence tripwire.
Verification
pnpm test— 21 files / 71 tests pass (4 new)pnpm build— passes (route table generated). Two local-env notes, both pre-existing on clean origin/main and unrelated to this diff: (1) local pnpm 9 rejects the committed pnpm-10-stylepnpm-workspace.yaml("packages field missing or empty"), worked around with--ignore-workspace; (2) the build requiresNEXT_PUBLIC_PRIVY_APP_ID(deliberate fail-closed gate incontexts/PrivyAuthProvider.tsx) — set to the public value inlined in the live site's client bundle.Siblings
🤖 Generated with Claude Code
Summary by cubic
Add a shared golden fixture and test to guard the catalog valuation model from drifting between marketing and API. CI now verifies
computeCatalogValuationmatches expected bands to the cent using the same JSON used inrecoupable/api.lib/valuation/__tests__/fixtures/valuation-golden.jsonwith canonical cases (5y age fallback, zero streams, 10y from release date, 1y age clamp). Must stay byte-identical toapi/lib/catalog/__tests__/fixtures/valuation-golden.json.lib/valuation/__tests__/valuationGoldenFixture.test.tsto assertlow/central/highwithin $0.01 for each case; fixturemidmaps tocentral.recoupable/chat#1850(valuation derivation guard).Written for commit ea158ec. Summary will update on new commits.