[Billing Credits] PR-I3: Credit usage card#1990
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Internal previewPreview URL: https://mcp-inspector-pr-1990.up.railway.app |
38fe6b7 to
8ef879f
Compare
8ef879f to
c1eb58a
Compare
c1eb58a to
a63f96b
Compare
a55ab8c to
a42fcee
Compare
a63f96b to
86e1318
Compare
a42fcee to
58f56f9
Compare
86e1318 to
02cbce1
Compare
58f56f9 to
eca8ffc
Compare
02cbce1 to
de5265f
Compare
de5265f to
355b020
Compare
355b020 to
e1e3a0f
Compare
eca8ffc to
ee6a70f
Compare
5d59d58 to
8fb4dcb
Compare
619b6de to
717bd2a
Compare
717bd2a to
eade3c4
Compare
eade3c4 to
277bf6d
Compare
8fb4dcb to
272406d
Compare
277bf6d to
3dfc063
Compare
272406d to
535a22d
Compare
3dfc063 to
0c7f604
Compare
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |

[Billing Credits] PR-I3: Credit usage card
Adds a usage card to the organization billing page. Two stacked progress
bars (daily limit + paid credits) gated on user state. Replaces the
placeholder copy that previously sat above the plan-comparison table.
Visual
The paid bar is hidden until the user's first top-up. Both bars use a
bare percent ("X% used") with no dollar values surfaced anywhere on
the card.
Changes
useCreditBalancehook. Calls the server's read-side balanceendpoint, normalizes defensively, and
useMemos the result soconsumers don't churn on every parent render. Auth-gated via
useConvexAuth().isAuthenticated+ Convex"skip"sentinel.CreditBalanceCard: header + sub-line clarifying credits areuser-scoped (not org-scoped) + two usage bars + Top up button.
TopupActionButton: renders the Top up button only when thepreset endpoint resolves with at least one preset. Wrapped in an
inner error boundary so a missing-function error collapses to no
button rather than crashing the whole card.
OrganizationBillingSectionslots the card in above theplan-comparison view, wrapped in
<ErrorBoundary fallback={null}>,and removes a stale placeholder note that surfaced an outdated
per-user-per-day pricing line.
ErrorBoundaryfrom@/components/ui/error-boundary(moved out ofevals/in PR-I2 —no longer a domain-specific primitive).
Why no dollar values
The card surfaces only percentages. Showing dollar amounts on the
paid-credits row would invite the user to compute a wrong remaining
dollar value (since the bar's denominator is in the credited domain,
not the paid domain). Bare percentages match the well-validated
gas-gauge UX pattern used by similar credit pages — the row label
("Daily limit", "Paid credits") tells the user what the pool is, and
the percent tells them where they are within it.
Tests
CreditBalanceCard.test.tsx: skeleton loading state, hidden paidbar before any top-up, paid row renders as
% usedonly,top-up button opens dialog, regression guard that neither row
ever renders a
$character, lock-in test for the user-scopesub-line copy.
TopupActionButton.test.tsx: renders only when presets areavailable, hides on loading + empty, click handler.
OrganizationsTab.billing.test.tsx: extendedconvex/reactmockto include
useQuerystub for the new auth-gated hook.Stack
Notes
mcpjam-backend#184; remaining gate is full backend deploy toproduction.
review — Stripe email receipts are the source of truth for payment
history; in-inspector duplication added complexity and surface area
without a clear win.
Risk
Low. Net-new card on the billing page; only existing surface changed
is the removal of a stale tooltip line in the plan-comparison table
and a small semantic tightening of the shared
ErrorBoundaryprimitive (in PR-I2). The card handles missing data, missing
endpoints, and unauthenticated states without crashing.