Skip to content

feat(api): expose booked and spendable credit balances - #5316

Merged
GAlexIHU merged 2 commits into
codex/ledger-error-telemetryfrom
codex/public-spendable-balances
Oct 26, 2026
Merged

GAlexIHU merged 2 commits into
codex/ledger-error-telemetryfrom
codex/public-spendable-balances

Conversation

@GAlexIHU

@GAlexIHU GAlexIHU commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Expose booked and spendable credit balances separately. booked contains the ledger balance at the requested timestamp, including credit-only advance debt. The existing settled field remains an identical deprecated alias.

spendable preserves credit allocated to later recorded usage and prevents future grants from being spent early. live now applies unbooked usage impacts to spendable sources, preserving feature restrictions and settlement policy. Advance debt can make balances negative.

Notes for reviewer

  • Stacked on feat(ledger): add accounting diagnostics and balance telemetry #5304.
  • Transaction history retains its existing booked before/after balances; its documentation now makes that explicit.
  • Pending balance behavior is unchanged. Historical queries still return zero for live; all balance reads use currently recorded postings.
  • Regenerated OpenAPI, Go server models, and Go/TypeScript clients. settled is marked deprecated in OpenAPI.
  • PostgreSQL-backed customer balance and credit integration tests, API handler tests, app/server builds, Go SDK build/vet/tests, TypeScript typechecking, and focused lint passed.
  • Regression coverage checks future consumption, future grants, expiry, live usage, unchanged history balances, and equality of booked and settled, including negative balances.

Summary by CodeRabbit

  • New Features

    • Credit balance responses now distinguish booked, spendable, live, and pending balances. Spendable balances account for committed usage, future grants, and scheduled expiry; balances may be negative when debt or usage exceeds available credit.
    • Credit transaction history identifies before-and-after amounts as booked balances, including credit-only advance debt.
  • Documentation

    • Clarified that historical balance queries include corrections recorded later and do not represent a snapshot of what was known at the requested time. Historical live balances are zero.
    • Documented settled as a deprecated alias for booked.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge.

Summary

Separates booked credit from credit still available to spend.

  • Credit balance responses distinguish booked credit from credit available to spend.
  • Historical balance and transaction docs explain their booked-time meaning.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  FBO[FBO source histories] --> Minimum[Spendable source balances]
  Minimum --> Spendable[spendable]
  Debt[Booked advance debt] --> Spendable
  Journal[Booked FBO balance] --> Booked[booked]
  Debt --> Booked
  Booked --> Settled[settled alias]
  Spendable --> Live[live]
  Usage[Unbooked usage impacts] --> Live
Loading

Reviews (5) · Last reviewed commit: "fix(test): wire FBO into billing balance..." · Reviewed by Greptile

@GAlexIHU
GAlexIHU requested a review from a team as a code owner October 19, 2026 15:36
@GAlexIHU GAlexIHU added release-note/deprecation Release note: Deprecations release-note/feature Release note: Exciting New Features labels Oct 19, 2026
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between a0deb40 and 08f0def.

Files ignored due to path filters: 1
  • api/v3/openapi.yaml is excluded by !**/openapi.yaml
Files selected for processing: 2
  • api/spec/packages/aip-client-javascript/src/models/schemas.ts
  • api/v3/api.gen.go

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 4 remain after this review.

Walkthrough

The customer credit balance contract now exposes booked and spendable values, with settled retained as a deprecated alias. The balance service uses FBO data for balance calculations. API mappings, historical timestamp descriptions, documentation, and tests now use the updated balance semantics.

Changes: Customer credit balances

Layer / File(s) Summary
Balance fields and timestamp semantics
api/spec/packages/aip/src/customers/credits/*, api/spec/packages/aip-client-javascript/src/models/*, api/v3/client/models_customers.go, api/v3/api.gen.go, openmeter/ledger/customerbalance/README.md
The balance contract defines booked and spendable values, documents settled as a deprecated alias, and clarifies transaction-history and historical timestamp semantics.
FBO-backed balance calculation
openmeter/ledger/customerbalance/*.go, app/common/customerbalance.go, cmd/server/wire_gen.go
The service queries FBO spendable buckets, returns booked and spendable balances, and uses spendable sources for current live-balance calculations. Application wiring constructs and supplies the FBO service.
API balance mapping
api/v3/handlers/customers/credits/convert.go, api/v3/handlers/customers/credits/convert_test.go
The API conversion populates booked and spendable values and maps settled to booked. Tests cover custom-currency and fiat balances, including a negative booked value.
Balance tests and FBO test setup
openmeter/ledger/customerbalance/*_test.go, openmeter/ledger/fbo/testutils/service.go, openmeter/billing/charges/service/customcurrency_ledger_integration_test.go, test/credits/*
Tests use booked balances and cover spendable, live, pending, historical, and transaction-history results. Test setup now provides an FBO service.

Priority: Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant BalanceFacade
  participant CustomerBalanceService
  participant AccountResolver
  participant FBO
  participant BalanceQuerier
  BalanceFacade->>CustomerBalanceService: Request customer balance
  CustomerBalanceService->>AccountResolver: Resolve customer accounts
  CustomerBalanceService->>FBO: Query spendable buckets
  FBO-->>CustomerBalanceService: Return buckets and routes
  CustomerBalanceService->>BalanceQuerier: Read FBO and receivable balances
  BalanceQuerier-->>CustomerBalanceService: Return balances
  CustomerBalanceService-->>BalanceFacade: Return balance values
Loading

Suggested labels: area/billing

Suggested reviewers: turip, borosr

Merge Risk: Minimal · up to 08f0d

The change adds booked and spendable credit balance fields to the API and keeps settled as a deprecated alias. The supplied generated-code changes show no concrete merge-blocking risk.

Pre-merge checks: Passed 4
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely summarizes the main change: exposing booked and spendable credit balances.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@GAlexIHU
GAlexIHU added this pull request to stack #5295 October 19, 2026 15:37
Comment thread openmeter/ledger/customerbalance/service.go
@GAlexIHU
GAlexIHU force-pushed the codex/public-spendable-balances branch from d0a5c27 to cb62a45 Compare October 19, 2026 15:45

// Read spendable credit once, then use the same amounts for the live projection.
// Advance debt is still a journal balance and can make the total negative.
func (s *service) getBalanceSources(ctx context.Context, input GetBalanceServiceInput) (balance, []liveBalanceSource, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this function can receive it's own return type instead of returning a half initialized balance struct.

@GAlexIHU
GAlexIHU force-pushed the codex/public-spendable-balances branch from 5ccc8d2 to a0deb40 Compare October 21, 2026 13:44
@GAlexIHU
GAlexIHU force-pushed the codex/public-spendable-balances branch from a0deb40 to 08f0def Compare October 26, 2026 11:03
@GAlexIHU
GAlexIHU merged commit a58fc42 into main Oct 26, 2026
44 of 67 checks passed
@GAlexIHU
GAlexIHU deleted the codex/public-spendable-balances branch October 26, 2026 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note/deprecation Release note: Deprecations release-note/feature Release note: Exciting New Features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants