Skip to content

feat(customcurrencies): support resolving costbases#4772

Merged
turip merged 3 commits into
mainfrom
feat/custom-currency-cost-basis-resolution
Jul 23, 2026
Merged

feat(customcurrencies): support resolving costbases#4772
turip merged 3 commits into
mainfrom
feat/custom-currency-cost-basis-resolution

Conversation

@turip

@turip turip commented Jul 22, 2026

Copy link
Copy Markdown
Member

Summary

Custom-currency charges need a stable cost basis before their value can be applied consistently. This change adds that resolution flow for flat-fee and usage-based charges.

Subscriptions will follow the same approach, so charge resolution establishes the behavior they will depend on.

Behavior

  • Charges record how their custom-currency cost basis should be determined.
  • Cost bases that are already known are captured when the charge is created.
  • Dynamic cost bases are captured when the charge reaches the applicable credit-then-invoice state.
  • Once captured, the persisted result is reused so retries do not select a different value.
  • Reading a charge returns both its cost-basis intent and any resolved result.

Validation

  • make lint-go-fast
  • make test-nocache: 6,272 tests passed and 9 skipped; the only failure was the acknowledged Svix integration test because the local Svix service was unavailable on port 8071.

Summary by CodeRabbit

  • New Features

    • Added end-to-end cost-basis support for flat-fee and usage-based charges, including manual, pinned, and dynamic modes.
    • Dynamic cost basis is resolved when a charge becomes active and is stored for future retrieval.
    • Introduced time-based currency cost-basis lookup by currency, fiat code, and effective timestamp.
  • Bug Fixes

    • Tightened validation so cost-basis is only accepted for supported settlement/currency scenarios and pinned fiat/currency mismatches are rejected.
    • Improved cost-basis loading and update consistency, including retry-safe dynamic resolution.

Greptile Summary

This PR adds cost-basis resolution for custom-currency charges. The main changes are:

  • New manual, pinned, and dynamic cost-basis models.
  • Persisted cost-basis intent and resolved state for flat-fee and usage-based charges.
  • Dynamic resolution during charge activation with retry-safe persistence.
  • Currency-service wiring, Ent generation, migrations, and lifecycle tests.

Confidence Score: 4/5

The flat-fee manual attachment path needs a cost-basis guard before merging.

  • Dynamic resolution and retry-safe persistence are consistent on normal activation.
  • Manual flat-fee attachment can bypass the active-state resolution hook and create an invoice-backed charge without a resolved value.

openmeter/billing/charges/flatfee/service/lineengine.go

Important Files Changed

Filename Overview
openmeter/billing/charges/models/costbasis/resolver.go Adds initial and lifecycle-time resolution for manual, pinned, and dynamic cost bases.
openmeter/billing/charges/flatfee/service/creditheninvoice.go Resolves dynamic cost bases when flat-fee charges enter the active state.
openmeter/billing/charges/flatfee/service/lineengine.go Leaves manual attachment able to bypass the state that owns dynamic resolution.
openmeter/billing/charges/usagebased/service/creditheninvoice.go Adds dynamic cost-basis resolution to usage-based charge activation.
openmeter/billing/charges/flatfee/adapter/costbasis.go Adds tenant-scoped, first-write-wins persistence for resolved flat-fee cost bases.
openmeter/billing/charges/usagebased/adapter/costbasis.go Adds matching retry-safe persistence for usage-based cost bases.
tools/migrate/migrations/20260722145858_add_charge_cost_basis.up.sql Creates constrained cost-basis tables and charge references.
app/common/charges.go Injects the currencies service into both charge services.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Create custom-currency charge] --> B{Cost-basis mode}
    B -->|Manual or pinned| C[Resolve at creation]
    B -->|Dynamic| D[Persist unresolved intent]
    D --> E[Enter active state]
    E --> F[Resolve at service-period start]
    F --> G[Persist first resolved value]
    G --> H[Create invoice realization]
    D -. Manual flat-fee attachment .-> H
Loading

Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
openmeter/billing/charges/flatfee/service/lineengine.go:539-542
**Manual Attachment Skips Resolution**

When a flat-fee charge with an unresolved dynamic cost basis reaches manual line attachment, this path bypasses `StatusActive`, where `ResolveDynamicCostBasis` is registered. It can therefore create an invoice-backed charge with `ResolvedCostBasis == nil`; reject cost-basis-backed charges here or resolve the basis before firing the attachment transition.

Reviews (1): Last reviewed commit: "feat(customcurrencies): support resolvin..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Context used (3)

  • Context used - CLAUDE.md (source)
  • Context used - AGENTS.md (source)
  • Context used - api/spec/AGENTS.md (source)

@turip turip added release-note/feature Release note: Exciting New Features area/billing labels Jul 22, 2026
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds end-to-end cost-basis support for flat-fee and usage-based charges, including typed intents and states, currency lookup APIs, database persistence, lifecycle resolution, adapter mapping, service wiring, and comprehensive tests.

Changes

Cost-basis domain and currency resolution

Layer / File(s) Summary
Cost-basis models and resolver
openmeter/billing/charges/models/costbasis/*, openmeter/currencies/*, pkg/currencyx/*
Adds dynamic, pinned, and manual cost-basis intents, validated resolution state, point-in-time currency lookup, and fiat currency helpers.
Charge contracts and lifecycle
openmeter/billing/charges/{flatfee,usagebased}/*
Carries cost-basis intent/state through validation, overrides, creation, activation, and idempotent dynamic resolution.
Persistence and schema
openmeter/billing/charges/*/adapter/*, openmeter/ent/schema/*, tools/migrate/migrations/*
Creates and links cost-basis records, loads and maps edges, and adds the related Ent schema and migration tables.
Wiring and tests
app/common/*, cmd/*/wire_gen.go, openmeter/billing/charges/service/*_test.go, openmeter/billing/charges/testutils/*
Threads the currencies service through constructors and adds validation, persistence, rollback, retry-safety, and lifecycle coverage.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: kind/feature

Suggested reviewers: tothandras, chrisgacsal, galexihu, gergely-kurucz-konghq

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding custom-currency cost-basis resolution support.
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
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/custom-currency-cost-basis-resolution

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.

@turip
turip marked this pull request as ready for review July 22, 2026 17:10
@turip
turip requested a review from a team as a code owner July 22, 2026 17:10
@turip

turip commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

@greptile-apps please review this PR.

Comment thread openmeter/billing/charges/flatfee/service/lineengine.go

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🧹 Nitpick comments (3)
pkg/currencyx/currency.go (1)

197-199: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Consider guarding GetFiatCode() against a nil receiver.

Validate() on *FiatCurrency explicitly checks for f == nil, but GetFiatCode() dereferences f.def directly. Every call site we can see validates first, so this isn't an active bug today, but it's an easy defensive win in case a future caller skips validation.

🛡️ Optional defensive guard
 func (f *FiatCurrency) GetFiatCode() FiatCode {
+	if f == nil || f.def == nil {
+		return ""
+	}
 	return FiatCode(f.def.ISOCode)
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/currencyx/currency.go` around lines 197 - 199, Update
FiatCurrency.GetFiatCode to handle a nil receiver before dereferencing f.def,
returning the appropriate zero or invalid FiatCode value for nil while
preserving the existing ISOCode conversion for non-nil receivers.
openmeter/ent/schema/charges.go (1)

330-335: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

currency_cost_basis_id could use .Immutable() like its sibling fields.

Per costbasis.Create/Set (model.go), currency_cost_basis_id is only ever written once, at creation time for pinned mode — it's never touched again. mode, fiat_currency, currency_id, and manual_rate all get the same "set-once" treatment and are marked .Immutable(), but this field isn't. Locking it down would statically prevent a future update path from accidentally mutating the pinned reference.

🔒 Proposed fix
 		field.String("currency_cost_basis_id").
 			Optional().
 			Nillable().
+			Immutable().
 			SchemaType(map[string]string{
 				dialect.Postgres: "char(26)",
 			}),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@openmeter/ent/schema/charges.go` around lines 330 - 335, Update the
currency_cost_basis_id field definition in the charges schema to include
Immutable(), matching the set-once treatment of mode, fiat_currency,
currency_id, and manual_rate while preserving its existing optional, nillable,
and PostgreSQL type configuration.
openmeter/billing/charges/usagebased/service/service.go (1)

6-6: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

No change needed for this import.

testing is used for the *testing.T guard in SetEnableCustomCurrency, and this pattern already exists in the mirrored flatfee service, so changing it for maintainability would be lower priority.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@openmeter/billing/charges/usagebased/service/service.go` at line 6, Leave the
testing import unchanged; SetEnableCustomCurrency uses testing.T, and its
existing pattern matches the mirrored flatfee service.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@openmeter/billing/charges/flatfee/service/service.go`:
- Around line 86-93: Initialize the service’s custom-currency capability during
New using a production configuration or feature-setting input, instead of
relying on the testing-only setter. Update the service config and constructor
wiring around service and enableCustomCurrency so Create permits supported
custom-currency credit-then-invoice charges in production while preserving the
disabled behavior when the setting is not enabled.

In `@openmeter/billing/charges/service/usagebased_costbasis_test.go`:
- Around line 253-293: Add an immediate defer clock.UnFreeze() after the second
clock.FreezeTime(activationAt) call in the test setup, alongside the existing
freeze for servicePeriodFrom, so each freeze is paired with its own cleanup.

---

Nitpick comments:
In `@openmeter/billing/charges/usagebased/service/service.go`:
- Line 6: Leave the testing import unchanged; SetEnableCustomCurrency uses
testing.T, and its existing pattern matches the mirrored flatfee service.

In `@openmeter/ent/schema/charges.go`:
- Around line 330-335: Update the currency_cost_basis_id field definition in the
charges schema to include Immutable(), matching the set-once treatment of mode,
fiat_currency, currency_id, and manual_rate while preserving its existing
optional, nillable, and PostgreSQL type configuration.

In `@pkg/currencyx/currency.go`:
- Around line 197-199: Update FiatCurrency.GetFiatCode to handle a nil receiver
before dereferencing f.def, returning the appropriate zero or invalid FiatCode
value for nil while preserving the existing ISOCode conversion for non-nil
receivers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 54e3cfdb-9414-43ca-8c40-6dc0fd0b41e1

📥 Commits

Reviewing files that changed from the base of the PR and between b368460 and 7e25c5b.

⛔ Files ignored due to path filters (50)
  • openmeter/ent/db/chargecreditpurchase.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchase/chargecreditpurchase.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchase/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchase_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchase_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis/chargecreditpurchasecostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis_delete.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis_update.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfee.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfee/chargeflatfee.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfee/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfee_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfee_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis/chargeflatfeecostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis_delete.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis_update.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebased.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebased/chargeusagebased.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebased/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebased_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebased_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis/chargeusagebasedcostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis_delete.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis_update.go is excluded by !**/ent/db/**
  • openmeter/ent/db/client.go is excluded by !**/ent/db/**
  • openmeter/ent/db/cursor.go is excluded by !**/ent/db/**
  • openmeter/ent/db/ent.go is excluded by !**/ent/db/**
  • openmeter/ent/db/entmixinaccessor.go is excluded by !**/ent/db/**
  • openmeter/ent/db/expose.go is excluded by !**/ent/db/**
  • openmeter/ent/db/hook/hook.go is excluded by !**/ent/db/**
  • openmeter/ent/db/migrate/schema.go is excluded by !**/ent/db/**
  • openmeter/ent/db/mutation.go is excluded by !**/ent/db/**
  • openmeter/ent/db/paginate.go is excluded by !**/ent/db/**
  • openmeter/ent/db/predicate/predicate.go is excluded by !**/ent/db/**
  • openmeter/ent/db/runtime.go is excluded by !**/ent/db/**
  • openmeter/ent/db/setorclear.go is excluded by !**/ent/db/**
  • openmeter/ent/db/tx.go is excluded by !**/ent/db/**
  • tools/migrate/migrations/atlas.sum is excluded by !**/*.sum, !**/*.sum
📒 Files selected for processing (56)
  • app/common/billing.go
  • app/common/charges.go
  • cmd/billing-worker/wire_gen.go
  • cmd/jobs/internal/wire_gen.go
  • cmd/server/wire_gen.go
  • openmeter/billing/charges/flatfee/adapter.go
  • openmeter/billing/charges/flatfee/adapter/charge.go
  • openmeter/billing/charges/flatfee/adapter/costbasis.go
  • openmeter/billing/charges/flatfee/adapter/intentoverride.go
  • openmeter/billing/charges/flatfee/adapter/mapper.go
  • openmeter/billing/charges/flatfee/charge.go
  • openmeter/billing/charges/flatfee/charge_test.go
  • openmeter/billing/charges/flatfee/service/create.go
  • openmeter/billing/charges/flatfee/service/creditheninvoice.go
  • openmeter/billing/charges/flatfee/service/lineengine.go
  • openmeter/billing/charges/flatfee/service/service.go
  • openmeter/billing/charges/models/costbasis/costbasis.go
  • openmeter/billing/charges/models/costbasis/intent.go
  • openmeter/billing/charges/models/costbasis/intent_test.go
  • openmeter/billing/charges/models/costbasis/model.go
  • openmeter/billing/charges/models/costbasis/resolver.go
  • openmeter/billing/charges/models/costbasis/state.go
  • openmeter/billing/charges/service/base_test.go
  • openmeter/billing/charges/service/flatfee_costbasis_test.go
  • openmeter/billing/charges/service/invoicable_test.go
  • openmeter/billing/charges/service/usagebased_costbasis_test.go
  • openmeter/billing/charges/testutils/service.go
  • openmeter/billing/charges/usagebased/adapter.go
  • openmeter/billing/charges/usagebased/adapter/charge.go
  • openmeter/billing/charges/usagebased/adapter/costbasis.go
  • openmeter/billing/charges/usagebased/adapter/intentoverride.go
  • openmeter/billing/charges/usagebased/adapter/intentoverride_test.go
  • openmeter/billing/charges/usagebased/adapter/mapper.go
  • openmeter/billing/charges/usagebased/charge.go
  • openmeter/billing/charges/usagebased/charge_test.go
  • openmeter/billing/charges/usagebased/service.go
  • openmeter/billing/charges/usagebased/service/create.go
  • openmeter/billing/charges/usagebased/service/creditheninvoice.go
  • openmeter/billing/charges/usagebased/service/service.go
  • openmeter/billing/charges/usagebased/service/statemachine.go
  • openmeter/billing/charges/usagebased/service/triggers.go
  • openmeter/currencies/adapter/currencies.go
  • openmeter/currencies/adapter/currencies_test.go
  • openmeter/currencies/repository.go
  • openmeter/currencies/service.go
  • openmeter/currencies/service/service.go
  • openmeter/ent/schema/charges.go
  • openmeter/ent/schema/chargescreditpurchase.go
  • openmeter/ent/schema/chargesflatfee.go
  • openmeter/ent/schema/chargesusagebased.go
  • openmeter/ledger/customerbalance/testenv_test.go
  • openmeter/server/server_test.go
  • pkg/currencyx/code.go
  • pkg/currencyx/currency.go
  • tools/migrate/migrations/20260722145858_add_charge_cost_basis.down.sql
  • tools/migrate/migrations/20260722145858_add_charge_cost_basis.up.sql
💤 Files with no reviewable changes (1)
  • openmeter/billing/charges/usagebased/adapter/intentoverride_test.go

Comment thread openmeter/billing/charges/flatfee/service/service.go
Comment thread openmeter/billing/charges/service/usagebased_costbasis_test.go
@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Too many files changed for review. (106 files found, 100 file limit)

Bypass the limit by tagging @greptile-apps to review.

@turip

turip commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

Bot review follow-up on the non-actionable notes:

  • currency_cost_basis_id must remain mutable because dynamic resolution populates it after charge creation; marking it immutable would break that flow.
  • The optional nil guard for FiatCurrency.GetFiatCode is not needed in this round because callers operate on validated fiat-currency values.
  • The testing import remains unchanged, as CodeRabbit also noted.

@turip
turip force-pushed the feat/custom-currency-cost-basis-resolution branch from 2b61068 to b1bb8a7 Compare July 23, 2026 04:33

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@openmeter/billing/charges/models/costbasis/intent.go`:
- Around line 30-35: Update Mode.Validate to collect its invalid-mode validation
failure in an errs accumulator and return
models.NewNillableGenericValidationError(errors.Join(errs...)), matching the
validator contract used elsewhere in the file; preserve nil validation for valid
modes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d53e450b-8e17-4e85-bb81-7c0e9665ce34

📥 Commits

Reviewing files that changed from the base of the PR and between 2b61068 and b1bb8a7.

⛔ Files ignored due to path filters (50)
  • openmeter/ent/db/chargecreditpurchase.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchase/chargecreditpurchase.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchase/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchase_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchase_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis/chargecreditpurchasecostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis_delete.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargecreditpurchasecostbasis_update.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfee.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfee/chargeflatfee.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfee/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfee_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfee_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis/chargeflatfeecostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis_delete.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeflatfeecostbasis_update.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebased.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebased/chargeusagebased.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebased/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebased_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebased_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis/chargeusagebasedcostbasis.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis/where.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis_create.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis_delete.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis_query.go is excluded by !**/ent/db/**
  • openmeter/ent/db/chargeusagebasedcostbasis_update.go is excluded by !**/ent/db/**
  • openmeter/ent/db/client.go is excluded by !**/ent/db/**
  • openmeter/ent/db/cursor.go is excluded by !**/ent/db/**
  • openmeter/ent/db/ent.go is excluded by !**/ent/db/**
  • openmeter/ent/db/entmixinaccessor.go is excluded by !**/ent/db/**
  • openmeter/ent/db/expose.go is excluded by !**/ent/db/**
  • openmeter/ent/db/hook/hook.go is excluded by !**/ent/db/**
  • openmeter/ent/db/migrate/schema.go is excluded by !**/ent/db/**
  • openmeter/ent/db/mutation.go is excluded by !**/ent/db/**
  • openmeter/ent/db/paginate.go is excluded by !**/ent/db/**
  • openmeter/ent/db/predicate/predicate.go is excluded by !**/ent/db/**
  • openmeter/ent/db/runtime.go is excluded by !**/ent/db/**
  • openmeter/ent/db/setorclear.go is excluded by !**/ent/db/**
  • openmeter/ent/db/tx.go is excluded by !**/ent/db/**
  • tools/migrate/migrations/atlas.sum is excluded by !**/*.sum, !**/*.sum
📒 Files selected for processing (56)
  • app/common/billing.go
  • app/common/charges.go
  • cmd/billing-worker/wire_gen.go
  • cmd/jobs/internal/wire_gen.go
  • cmd/server/wire_gen.go
  • openmeter/billing/charges/flatfee/adapter.go
  • openmeter/billing/charges/flatfee/adapter/charge.go
  • openmeter/billing/charges/flatfee/adapter/costbasis.go
  • openmeter/billing/charges/flatfee/adapter/intentoverride.go
  • openmeter/billing/charges/flatfee/adapter/mapper.go
  • openmeter/billing/charges/flatfee/charge.go
  • openmeter/billing/charges/flatfee/charge_test.go
  • openmeter/billing/charges/flatfee/service/create.go
  • openmeter/billing/charges/flatfee/service/creditheninvoice.go
  • openmeter/billing/charges/flatfee/service/lineengine.go
  • openmeter/billing/charges/flatfee/service/service.go
  • openmeter/billing/charges/models/costbasis/costbasis.go
  • openmeter/billing/charges/models/costbasis/intent.go
  • openmeter/billing/charges/models/costbasis/intent_test.go
  • openmeter/billing/charges/models/costbasis/model.go
  • openmeter/billing/charges/models/costbasis/resolver.go
  • openmeter/billing/charges/models/costbasis/state.go
  • openmeter/billing/charges/service/base_test.go
  • openmeter/billing/charges/service/flatfee_costbasis_test.go
  • openmeter/billing/charges/service/invoicable_test.go
  • openmeter/billing/charges/service/usagebased_costbasis_test.go
  • openmeter/billing/charges/testutils/service.go
  • openmeter/billing/charges/usagebased/adapter.go
  • openmeter/billing/charges/usagebased/adapter/charge.go
  • openmeter/billing/charges/usagebased/adapter/costbasis.go
  • openmeter/billing/charges/usagebased/adapter/intentoverride.go
  • openmeter/billing/charges/usagebased/adapter/intentoverride_test.go
  • openmeter/billing/charges/usagebased/adapter/mapper.go
  • openmeter/billing/charges/usagebased/charge.go
  • openmeter/billing/charges/usagebased/charge_test.go
  • openmeter/billing/charges/usagebased/service.go
  • openmeter/billing/charges/usagebased/service/create.go
  • openmeter/billing/charges/usagebased/service/creditheninvoice.go
  • openmeter/billing/charges/usagebased/service/service.go
  • openmeter/billing/charges/usagebased/service/statemachine.go
  • openmeter/billing/charges/usagebased/service/triggers.go
  • openmeter/currencies/adapter/currencies.go
  • openmeter/currencies/adapter/currencies_test.go
  • openmeter/currencies/repository.go
  • openmeter/currencies/service.go
  • openmeter/currencies/service/service.go
  • openmeter/ent/schema/charges.go
  • openmeter/ent/schema/chargescreditpurchase.go
  • openmeter/ent/schema/chargesflatfee.go
  • openmeter/ent/schema/chargesusagebased.go
  • openmeter/ledger/customerbalance/testenv_test.go
  • openmeter/server/server_test.go
  • pkg/currencyx/code.go
  • pkg/currencyx/currency.go
  • tools/migrate/migrations/20260722145858_add_charge_cost_basis.down.sql
  • tools/migrate/migrations/20260722145858_add_charge_cost_basis.up.sql
💤 Files with no reviewable changes (1)
  • openmeter/billing/charges/usagebased/adapter/intentoverride_test.go
🚧 Files skipped from review as they are similar to previous changes (51)
  • cmd/billing-worker/wire_gen.go
  • openmeter/server/server_test.go
  • openmeter/billing/charges/models/costbasis/costbasis.go
  • app/common/billing.go
  • pkg/currencyx/currency.go
  • openmeter/billing/charges/models/costbasis/state.go
  • openmeter/billing/charges/models/costbasis/intent_test.go
  • openmeter/ledger/customerbalance/testenv_test.go
  • openmeter/currencies/repository.go
  • openmeter/billing/charges/flatfee/service/lineengine.go
  • cmd/jobs/internal/wire_gen.go
  • openmeter/billing/charges/usagebased/service/creditheninvoice.go
  • openmeter/currencies/service.go
  • openmeter/billing/charges/service/invoicable_test.go
  • openmeter/billing/charges/service/base_test.go
  • cmd/server/wire_gen.go
  • openmeter/billing/charges/usagebased/service.go
  • openmeter/billing/charges/usagebased/adapter.go
  • openmeter/billing/charges/usagebased/service/statemachine.go
  • pkg/currencyx/code.go
  • openmeter/currencies/adapter/currencies_test.go
  • openmeter/ent/schema/chargesusagebased.go
  • openmeter/billing/charges/flatfee/adapter.go
  • openmeter/billing/charges/flatfee/adapter/intentoverride.go
  • openmeter/currencies/service/service.go
  • openmeter/billing/charges/usagebased/service/service.go
  • app/common/charges.go
  • openmeter/billing/charges/flatfee/service/create.go
  • openmeter/billing/charges/flatfee/adapter/mapper.go
  • openmeter/billing/charges/flatfee/charge_test.go
  • openmeter/billing/charges/usagebased/adapter/intentoverride.go
  • openmeter/ent/schema/chargescreditpurchase.go
  • openmeter/billing/charges/usagebased/service/triggers.go
  • openmeter/ent/schema/charges.go
  • openmeter/billing/charges/usagebased/adapter/costbasis.go
  • openmeter/billing/charges/usagebased/adapter/mapper.go
  • openmeter/billing/charges/flatfee/adapter/charge.go
  • openmeter/billing/charges/models/costbasis/resolver.go
  • openmeter/billing/charges/flatfee/service/service.go
  • openmeter/billing/charges/flatfee/service/creditheninvoice.go
  • openmeter/billing/charges/usagebased/adapter/charge.go
  • openmeter/currencies/adapter/currencies.go
  • openmeter/ent/schema/chargesflatfee.go
  • openmeter/billing/charges/flatfee/adapter/costbasis.go
  • openmeter/billing/charges/models/costbasis/model.go
  • openmeter/billing/charges/testutils/service.go
  • openmeter/billing/charges/usagebased/charge.go
  • openmeter/billing/charges/flatfee/charge.go
  • openmeter/billing/charges/service/flatfee_costbasis_test.go
  • openmeter/billing/charges/usagebased/charge_test.go
  • openmeter/billing/charges/service/usagebased_costbasis_test.go

Comment thread openmeter/billing/charges/models/costbasis/intent.go
@turip
turip merged commit 7e5a848 into main Jul 23, 2026
26 checks passed
@turip
turip deleted the feat/custom-currency-cost-basis-resolution branch July 23, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/billing release-note/feature Release note: Exciting New Features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants