fix(levelcode): report account activity spend at RETAIL, not raw wire cost#383
Merged
Conversation
… cost
The account page showed two units for the same quantity: a RETAIL-converted
balance ("1,279 credits left") above, and per-day / per-model spend summed
straight from usage_events.cost_micros below. The ledger stores what a request
cost US at the wire, so those rows understated what the customer actually spent —
by the margin — and could not be reconciled against the credits the same page
reported as spent.
Activity.for_user now takes an optional plan_key and converts the AGGREGATES
through retail_micros (one rounding per figure, not one per ledger row). The
account controller passes the caller's plan.
Left opt-in rather than baked into the aggregation, deliberately: this is a
shared service, and an operator-side caller wants real COGS, not what the
customer was charged. Passing no plan_key still yields raw cost. (The admin panel
does not use this service today, and stays in dollars for exactly that reason —
credits are a retail unit, so showing them there would conflate what we pay with
what we charge.)
Verified: 971 examples, 0 failures. New specs assert the retail figure on the
per-model row, the per-day total AND the per-day model rows, with a precondition
that retail actually exceeds cost so the assertion cannot pass vacuously — plus
one pinning that the no-plan_key path still returns raw cost.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a unit mismatch on the Levelcode account activity endpoint by reporting customer-facing spend in the same retail denomination as the displayed balance, while preserving an opt-in path for operator/internal callers to retrieve raw COGS.
Changes:
- Add optional
plan_key:toLevelcode::Activity.for_userto convert aggregatedcost_microsvalues viaLevelcode.retail_microswhen provided. - Pass
current_plan_keyfrom the account activity controller action so the account page receives retail-denominated spend. - Add request specs asserting retail conversion for per-model + per-day figures, and that omitting
plan_keypreserves raw cost.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| spec/requests/api/levelcode/v1/account_spec.rb | Adds coverage for retail spend reporting and the opt-in raw-cost behavior. |
| app/services/levelcode/activity.rb | Introduces plan_key: and applies retail conversion to aggregated cost figures when present. |
| app/controllers/api/levelcode/v1/account_controller.rb | Passes the current plan key into Activity.for_user for retail reporting on the account activity endpoint. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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 account page has been showing two different units for the same quantity: a retail-converted balance (
1,279 credits left) above, and per-day / per-model spend summed straight fromusage_events.cost_microsbelow.The ledger stores what a request cost us at the wire. So those rows understated what the customer actually spent — by the margin — and could not be reconciled against the credits the same page reported as spent.
This is a real bug independent of credits: the per-model "cost" on the account page has been understating user spend in dollars all along.
What changed
Activity.for_usertakes an optionalplan_keyand converts the aggregates throughretail_micros— one rounding per figure, rather than one per ledger row. The account controller passes the caller's plan.Left opt-in rather than baked into the aggregation, deliberately: this is a shared service, and an operator-side caller wants real COGS, not what the customer was charged. Passing no
plan_keystill yields raw cost.Why the admin panel is not converted
Its figures carry no retail conversion — they are real COGS, what we pay providers. Credits are a retail unit (≈2× cost via
CREDIT_COGS_RATIO), so rendering them there would conflate what we pay with what the customer is charged, and destroy the one view where margin is legible. Dollars are correct there.Verification
971 examples, 0 failures. New specs assert the retail figure on the per-model row, the per-day total and the per-day model rows — with a precondition that retail actually exceeds cost, so the assertion cannot pass vacuously. One more pins that the no-
plan_keypath still returns raw cost.Deploy order
The matching frontend change (onetime #88) renders these figures as credits. Ship this first — until it lands, that UI would divide raw cost and understate spend by the margin.
🤖 Generated with Claude Code