Skip to content

feat(frontend): converge billing to backend-computed usage endpoint (flag-gated)#5383

Open
jog1t wants to merge 1 commit into
mainfrom
converge-billing-backend
Open

feat(frontend): converge billing to backend-computed usage endpoint (flag-gated)#5383
jog1t wants to merge 1 commit into
mainfrom
converge-billing-backend

Conversation

@jog1t

@jog1t jog1t commented Jul 7, 2026

Copy link
Copy Markdown
Contributor
  • Move the dashboard billing frontend onto the backend-computed GET /projects/{id}/billing/usage endpoint (useBillingUsage), matching the enterprise flavor, instead of computing plan/overage/compute math in the frontend.
  • Remove the frontend-side billing math (useBilledMetrics, per-metric overage, BILLING.prices overage formulas) in favor of the single fully-computed breakdown returned by the backend.
  • Add currentProjectBillingUsageQueryOptions to the cloud data provider and the usage-metrics config the page renders.
  • Bump the @rivet-gg/cloud pin to a build that includes the billing usage endpoint.
  • Gated behind the billing feature flag, so self-hosted/OSS deployments (flag off) simply don't render billing.
  • Keeps frontend/ byte-identical with the enterprise repo so the shared dashboard never diverges.

@claude

claude Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review (updated for latest push)

The branch was substantially reworked after my last pass (billing-page.tsx now delegates to usage-metrics.ts + billedMetricsMap, billing-panel.tsx swapped its inline ComputeUsageRow for the shared ComputeUsageCard). Re-reviewed the new diff.

Bug still present: BillingPage's UsageCards show month-to-date cost 100x too high

frontend/src/app/billing/billing-page.tsx:88:

monthToDate={BigInt(m?.overageCents ?? 0)}

This is unchanged from the previous revision and still passes raw cents into UsageCard, which calls formatCurrency(monthToDate) directly (usage-card.tsx, formatCurrency in frontend/src/components/lib/formatter.ts:46 treats its argument as dollars, no /100). Every per-metric card on the full billing page (Awake actors, State storage, Reads, Writes, Egress) will render 100x inflated, e.g. $12.34 of actual overage shown as $1,234.00.

The page total is correct (billing-page.tsx:66: total={usage.totalCents / 100}), and the sibling drawer component in this same PR does it correctly too — frontend/src/app/settings-pages/billing-panel.tsx's UsageRow does const cost = Number(costCents) / 100; before formatCurrency(cost). So the fix pattern already exists elsewhere in this diff, it just wasn't applied to billing-page.tsx. Suggest: monthToDate={Number(m?.overageCents ?? 0) / 100} and update UsageCard's monthToDate prop to number (or divide inside UsageCard/formatCurrency consistently, but the two call sites need to agree on units either way).

Worth double-checking: settings-drawer compute card swap

billing-panel.tsx replaced the compact, grid-row-styled ComputeUsageRow (sized to match the other rows in the SettingsCard divided list) with the shared ComputeUsageCard from compute-card.tsx, whose own doc comment calls it the "Full-page compute pricing card, matching the usage cards on the billing page." Rendering that full card (icon header, rate table, CAPS_NOTE paragraph) inside the narrow settings drawer may look inconsistent with the compact rows above it. Per CLAUDE.md's frontend visual-change guidance, worth a quick look in the browser (both cloud and OSS/flag-off, since billing is feature-flagged) before merging.

Worth confirming: dropped client-side compute cap

The previous drawer body computed billedCompute = computeCapUsd != null ? Math.min(computeDollars, computeCapUsd) : computeDollars and used that (capped) figure in the displayed total. The new code just uses usage.totalCents / 100 directly, trusting the backend to already apply the same per-plan compute cap in that total (per the inline comment: "already included in usage.totalCents"). If the backend's cap logic doesn't match COMPUTE_MONTHLY_CAP_USD exactly, capped-plan users' displayed total could differ from before. Also, COMPUTE_MONTHLY_CAP_USD in frontend/src/content/billing.ts no longer appears to be referenced anywhere in the changed files — worth confirming it isn't now dead and removing it if so.

Minor (carried over, still unaddressed)

  • frontend/src/app/data-providers/cloud-data-provider.tsx:27,35 — two bare @ts-expect-error with no comment on what's actually mismatched from the @rivet-gg/cloud bump.
  • usage-card.tsx still adds unused vcpu-hours / gib-hours MetricType variants (not referenced by USAGE_METRICS); presumably intentional parity with the enterprise repo per the PR description, just flagging so it's not mistaken for orphaned code.

Other notes

  • The usage-metrics.ts extraction removing the duplicate USAGE_METRICS arrays between billing-page.tsx and billing-panel.tsx is a good consistency win.
  • NamespaceBillingPageBillingPage route wiring looks correct.

@railway-app

railway-app Bot commented Jul 7, 2026

Copy link
Copy Markdown

🚅 Deployed to the rivet-pr-5383 environment in rivet-frontend

Service Status Web Updated (UTC)
frontend-cloud 😴 Sleeping (View Logs) Web Jul 8, 2026 at 12:30 am
frontend-inspector 😴 Sleeping (View Logs) Web Jul 8, 2026 at 12:28 am
kitchen-sink 😴 Sleeping (View Logs) Web Jul 8, 2026 at 12:25 am
ladle ✅ Success (View Logs) Web Jul 8, 2026 at 12:18 am
website 😴 Sleeping (View Logs) Web Jul 7, 2026 at 11:14 pm
mcp-hub ✅ Success (View Logs) Web Jul 7, 2026 at 11:06 pm

@jog1t jog1t force-pushed the converge-billing-backend branch from f76cf2a to 63832d3 Compare July 8, 2026 00:02
@railway-app railway-app Bot temporarily deployed to rivet-frontend / rivet-pr-5383 July 8, 2026 00:02 Destroyed
@jog1t jog1t force-pushed the converge-billing-backend branch from 63832d3 to 3d3cf54 Compare July 8, 2026 00:15
@railway-app railway-app Bot temporarily deployed to rivet-frontend / rivet-pr-5383 July 8, 2026 00:15 Destroyed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant