fix(levelcode): show account activity spend in credits, not dollars - #88
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the Levelcode account activity heatmap panel to display spend in credits (consistent with the credit-denominated balance) rather than $, and stabilizes number formatting by pinning numeric locale to en-US.
Changes:
- Convert
/account/activitycost_microsvalues into credits for display (including small-amount floor formatting like<0.1). - Pin
toLocaleStringcalls in this panel toen-USto avoid per-machine numeric formatting differences. - Update UI labels to say credits (day detail line + table header) instead of cost/$.
Comments suppressed due to low confidence (2)
src/levelcode/pages/ContributionsHeatmap.tsx:215
- If you rename fmtCost to fmtCredits (recommended), update this call site to keep the component compiling and the naming consistent with the displayed unit.
{fmtCost(selectedDay.cost_micros)} credits
src/levelcode/pages/ContributionsHeatmap.tsx:245
- If you rename fmtCost to fmtCredits (recommended), remember to update the per-model table body as well; otherwise this column will still call fmtCost and the helper name won’t match the “credits” header.
<th className="py-1.5 px-3 text-right font-normal">credits</th>
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The activity panel on the account page still showed per-day and per-model spend in dollars, directly below a balance now denominated in credits — two units on one page for the same quantity. REQUIRES the thin.ly change that makes /account/activity return RETAIL micro-$. Until that ships, these figures are computed from raw wire COST and understate what the user actually spent by the margin. Do not deploy this ahead of it. Formatting matches AccountPage's rate() exactly — whole credits from 10 up, one decimal below, and a "<0.1" floor so a cheap day never reads as free. Locale is pinned to en-US for the same reason as the balance: a bare toLocaleString() renders one number three ways across machines. The admin panel is deliberately NOT converted. Its figures carry no retail conversion — they are real COGS, what we pay providers. Credits are a retail unit (~2x cost), so showing them there would conflate what we pay with what the customer is charged and destroy the only view where margin is legible. Verified: tsc --noEmit clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…orced PR #88 review. My comment claimed the heatmap's formatting was "kept identical to AccountPage", but nothing enforced that: each file declared its own LOCALE and MICROS_PER_CREDIT and re-implemented the rounding rule. A promise in a comment is exactly how two surfaces drift apart while both look correct. Now src/levelcode/credits.ts owns the conversion rate, the pinned locale, and the two formatters, and both surfaces import them. The claim is structural. Also renames fmtCost: it returns credits, not dollars, and the column it feeds is now labelled "credits" — the old name actively misled. FOUND WHILE VERIFYING, and it matters beyond this PR: `npx tsc --noEmit` checks NOTHING in this repo. The root tsconfig is `{"files": [], "references": [...]}`, and in that layout tsc --noEmit builds no referenced project — a deliberate type error goes unreported. Every "tsc --noEmit clean" I claimed on the recent levelcode PRs was vacuous. The command that works is `tsc -b`, which is what `npm run build` already runs. Under it this branch initially FAILED: importing LOCALE while still declaring it locally is TS2440, which would have broken the build. Removed the local copy. Verified with `tsc -b`: clean. Behaviour unchanged — balance $12.79 -> "1,279", an overage clamps to "0", a $0.0036 turn -> "0.4", a tiny spend -> "<0.1", and a zero per-turn price still reads as an em dash rather than "0". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ndemianc
force-pushed
the
fix/heatmap-credits
branch
from
July 24, 2026 01:58
30863ef to
88d561c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The activity panel on the account page still showed per-day and per-model spend in dollars, directly below a balance now denominated in credits — two units on one page for the same quantity.
Requires thin.ly #383 first, which makes
/account/activityreturn RETAIL micro-$. Until that ships, these figures are computed from raw wire COST and understate what the user actually spent by the margin. Do not deploy this ahead of it.Details
Formatting matches
AccountPage'srate()exactly — whole credits from 10 up, one decimal below, and a<0.1floor so a cheap day never reads as free. Locale is pinned toen-USfor the same reason as the balance: a baretoLocaleString()renders one number three ways across machines.The column header and the day-detail line now say
creditsrather than showing$.The admin panel is deliberately NOT converted
Its figures carry no retail conversion — they are real COGS, what we pay providers. Credits are a retail unit (≈2× cost), so showing them there would conflate what we pay with what the customer is charged, and destroy the only view where margin is legible.
Verified:
tsc --noEmitclean.🤖 Generated with Claude Code