Skip to content

fix(ledger): include corrections in credit history - #5195

Open
GAlexIHU wants to merge 2 commits into
mainfrom
codex/credit-history-corrections
Open

GAlexIHU wants to merge 2 commits into
mainfrom
codex/credit-history-corrections

Conversation

@GAlexIHU

@GAlexIHU GAlexIHU commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Subscription edits can reverse credit usage in the ledger while credit transaction history still shows only the original consumption. Add correction activity for both legacy and origin-tracked corrections, preserving booking times, creation times, charge labels, currency identity, and balance-before/after values.

Combine each correction batch's customer balance effects by booked time and currency so advance and backfill reversals do not appear as extra consumption. Exclude correction legs from consumed rows and fix backward pagination to select the nearest activities across types. No links to original usage or funding rows are exposed.

Validation:

  • Subscription-driven regression under test/subscription: create an inline custom subscription with one monthly flat fee, check history, replace the item halfway through the month, and verify proration corrections, recreated item metadata, timestamps, and the final balance. Full subscription suite and focused lint pass.
  • PostgreSQL-backed credit history tests, including prorated fee edits, deletion, uncovered and backfilled advances, legacy corrections, type filters, and bidirectional pagination.
  • Projection tests for feature scopes, managed currencies sharing a code, effective times, and hidden/zero-impact movements.
  • API mapping tests, focused Go lint, and Go/TypeScript SDK checks.
  • Regenerated v3 API/SDK artifacts and completed make generate. Full make gen-api was blocked by a missing legacy Python emitter interpreter; the v3 generators were run directly.

Summary by CodeRabbit

  • New Features
    • Added support for correction credit transactions, which adjust balances to reverse previously recorded usage.
    • Correction transactions can be listed and filtered alongside other credit transaction types, with their balance impacts and transaction details reflected in credit history.
    • Added support for paging through credit transactions in either direction.

RetriggerConfidence Score: 4/5

The PR is not ready to merge because the new subscription integration test fails at its item-version assertion.

Fix All in Claude CodeFindings

  1. P1 Item version assertion fails ▶
  2. P2 Unbounded correction group cache ▶
Fix with agent prompt
### Issue 1
test/subscription/credit_history_test.go:157
After the edit, items are sorted by start time, so `versions[0]` is still the original item. This assertion compares the original ID with itself and fails before the test reaches its correction-history checks. Compare it with `versions[1]` instead.

```suggestion
	require.NotEqual(t, originalItem.ID, versions[1].SubscriptionItem.ID, "the edit must exercise recreated subscription items")
```

### Issue 2
openmeter/ledger/customerbalance/correction_loader.go:undefined-26
When a customer has a long correction history, this cache retains every scanned group until the request ends, even groups with no visible balance impact. A request for a small page can therefore use memory proportional to the customer's full correction history. Please bound or evict cached groups as scanning advances.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

The PR adds correction movements to customer credit history, separates them from consumption, updates pagination, and synchronizes the API and SDK transaction types. The latest changes add a subscription integration test and its service wiring.

Reviews (2) · Last reviewed commit: "test(subscription): cover prorated credi..."

@GAlexIHU
GAlexIHU requested a review from a team as a code owner September 24, 2026 09:55
@GAlexIHU GAlexIHU added the release-note/bug-fix Release note: Bug Fixes label Sep 24, 2026
@coderabbitai

coderabbitai Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: openmeterio/openmeter/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: df082135-16b1-4573-b5bf-cf25debc9709

📥 Commits

Reviewing files that changed from the base of the PR and between 8b9e4b7 and f04abe0.

📒 Files selected for processing (2)
  • test/subscription/credit_history_test.go
  • test/subscription/framework_test.go

Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

This change adds correction as a credit transaction type across the API and client models. It projects eligible ledger corrections into customer-visible credit transactions and includes them in listing, pagination, and subscription credit history.

Changes

Credit correction transactions

Layer / File(s) Summary
Correction transaction type and API mapping
api/spec/packages/aip/src/customers/credits/ledger.tsp, api/spec/packages/aip-client-javascript/src/models/*, api/v3/client/models_customers.go, api/v3/handlers/customers/credits/convert.go, api/v3/handlers/customers/credits/list_transactions_test.go, openmeter/ledger/customerbalance/transactions.go
The API and client models accept correction. The Go client and internal transaction types validate it. The handlers map the type in both directions, with a test for the API mapping.
Correction projection and loader
openmeter/ledger/customerbalance/correction_loader.go, openmeter/ledger/customerbalance/loaders.go, openmeter/ledger/customerbalance/correction_loader_test.go, openmeter/ledger/customerbalance/README.md
The correction loader queries and groups ledger transactions, then projects eligible correction impacts into paginated rows. Tests cover amounts, filtering, pagination, and legacy corrections. The README documents correction rows and balance resolution.
Listing order and transaction filtering
openmeter/ledger/customerbalance/transactions.go, openmeter/ledger/customerbalance/ledger_loader.go, openmeter/ledger/customerbalance/ledger_loader_test.go
Before-page merging uses an inverted cursor order. The regular ledger loader excludes correction-direction transactions, and its test checks the exclusion filter.
Subscription credit history validation
test/subscription/framework_test.go, test/subscription/credit_history_test.go
The subscription test setup initializes the customer-balance service when charges are enabled. The subscription edit test checks the correction and replacement consumption rows in credit history.

Priority: ➖ Normal

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

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant ListCreditTransactions
  participant correctionCreditTransactionLoader
  participant Ledger
  participant correctionCreditTransactions
  ListCreditTransactions->>correctionCreditTransactionLoader: load correction rows
  correctionCreditTransactionLoader->>Ledger: list correction ledger transactions
  correctionCreditTransactionLoader->>correctionCreditTransactions: project transaction groups
  correctionCreditTransactions-->>correctionCreditTransactionLoader: return balance-impact rows
  correctionCreditTransactionLoader-->>ListCreditTransactions: return paginated rows
Loading

Suggested reviewers: rolosp

Merge Risk: ⚪ Minimal · up to f04ab

Credit history can now show correction activity when a subscription edit or ledger correction refunds earlier usage. The latest changes add test coverage for a prorated subscription edit and set up the test service to support it. No concrete defect was found, so the change looks ready to merge after normal checks.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: including correction transactions in credit history.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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.

func (l *correctionCreditTransactionLoader) Load(ctx context.Context, input creditTransactionLoaderInput) (creditTransactionLoaderResult, error) {
items := make([]CreditTransaction, 0, input.Limit+1)
after, before := input.After, input.Before
resolved := make(map[string][]CreditTransaction)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Unbounded correction group cache When a customer has a long correction history, this cache retains every scanned group until the request ends, even groups with no visible balance impact. A request for a small page can therefore use memory proportional to the customer's full correction history. Please bound or evict cached groups as scanning advances.

Prompt To Fix With AI
This is a comment left during a code review.
Path: openmeter/ledger/customerbalance/correction_loader.go
Line: 26

Comment:
**Unbounded correction group cache** When a customer has a long correction history, this cache retains every scanned group until the request ends, even groups with no visible balance impact. A request for a small page can therefore use memory proportional to the customer's full correction history. Please bound or evict cached groups as scanning advances.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

require.NoError(t, err)
versions := edited.Phases[0].ItemsByKey[rateCard.Key()]
require.Len(t, versions, 2)
require.NotEqual(t, originalItem.ID, versions[0].SubscriptionItem.ID, "the edit must exercise recreated subscription items")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Item version assertion fails After the edit, items are sorted by start time, so versions[0] is still the original item. This assertion compares the original ID with itself and fails before the test reaches its correction-history checks. Compare it with versions[1] instead.

Suggested change
require.NotEqual(t, originalItem.ID, versions[0].SubscriptionItem.ID, "the edit must exercise recreated subscription items")
require.NotEqual(t, originalItem.ID, versions[1].SubscriptionItem.ID, "the edit must exercise recreated subscription items")
Prompt To Fix With AI
This is a comment left during a code review.
Path: test/subscription/credit_history_test.go
Line: 157

Comment:
**Item version assertion fails** After the edit, items are sorted by start time, so `versions[0]` is still the original item. This assertion compares the original ID with itself and fails before the test reaches its correction-history checks. Compare it with `versions[1]` instead.

```suggestion
	require.NotEqual(t, originalItem.ID, versions[1].SubscriptionItem.ID, "the edit must exercise recreated subscription items")
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note/bug-fix Release note: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant