Skip to content

chore: allow enabling credit then invoice seperately#4136

Merged
turip merged 1 commit intomainfrom
chore/allow-enabling-credit-then-invoice-seperately
Apr 14, 2026
Merged

chore: allow enabling credit then invoice seperately#4136
turip merged 1 commit intomainfrom
chore/allow-enabling-credit-then-invoice-seperately

Conversation

@turip
Copy link
Copy Markdown
Member

@turip turip commented Apr 14, 2026

Overview

Allow controling credit_then_invoice seperately of credit_only. If disabled credit_then_invoice falls back to invoice only.

Notes for reviewer

Summary by CodeRabbit

  • New Features

    • Introduced new enable_credit_then_invoice configuration option to enable an alternative billing settlement mode that processes credit operations alongside invoice generation.
  • Chores

    • Updated configuration schema and service initialization to support the new billing settlement mode.
    • Added the new feature flag across all environment configuration files.
  • Tests

    • Added test coverage for credit-then-invoice settlement mode behavior with various configurations.

@turip turip requested a review from a team as a code owner April 14, 2026 07:27
@turip turip added the release-note/feature Release note: Exciting New Features label Apr 14, 2026
@turip turip requested review from GAlexIHU and tothandras April 14, 2026 07:27
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 14, 2026

📝 Walkthrough

Walkthrough

The PR introduces an EnableCreditThenInvoice feature flag across the billing and credits configuration layers. The flag is added to CreditsConfiguration, threaded through dependency injection into the subscription sync service and reconciler, and used by the patch collection router to conditionally handle credit-then-invoice settlement mode behavior.

Changes

Cohort / File(s) Summary
Configuration Layer
app/config/credits.go, app/config/config_test.go, config.example.yaml, e2e/config.yaml
Added EnableCreditThenInvoice boolean field to CreditsConfiguration with default value false, updated test expectations, and populated example/e2e configuration files.
Dependency Injection & Wiring
app/common/billing.go, cmd/billing-worker/wire_gen.go, cmd/jobs/internal/wire_gen.go
Updated NewBillingSubscriptionSyncService to accept creditsConfig parameter and forwarded it through generated wire code in both worker and jobs commands.
Service & Reconciler Configuration
openmeter/billing/worker/subscriptionsync/service/service.go, openmeter/billing/worker/subscriptionsync/service/reconciler/reconciler.go
Added EnableCreditThenInvoice to FeatureFlags and Config structures, with validation requiring ChargesService when flag is enabled. Updated reconciler instantiation to propagate the flag.
Patch Collection Router Logic
openmeter/billing/worker/subscriptionsync/service/reconciler/patch.go, openmeter/billing/worker/subscriptionsync/service/reconciler/patch_test.go
Refactored newPatchCollectionRouter to accept a config object with capacity, invoices, and feature flags; added conditional logic to bypass credit-then-invoice behavior when disabled or credits disabled. Comprehensive table-driven test added covering various settlement mode and feature flag combinations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

release-note/misc, area/billing

Suggested reviewers

  • tothandras
  • GAlexIHU
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: adding a new configuration flag to control credit-then-invoice behavior independently from the existing credits feature.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 chore/allow-enabling-credit-then-invoice-seperately

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
openmeter/billing/worker/subscriptionsync/service/reconciler/patch_test.go (1)

34-86: Consider adding one more matrix case for flag precedence.

This suite is strong already. I’d just add the credits disabled + CTI enabled combo to lock in the !creditsEnabled short-circuit path explicitly for CreditThenInvoiceSettlementMode.

Suggested test case addition
 		{
+			name:                    "credit then invoice with credits disabled falls back to invoice lines",
+			settlementMode:          productcatalog.CreditThenInvoiceSettlementMode,
+			enableCredits:           false,
+			enableCreditThenInvoice: true,
+			rateCard:                usageRateCard,
+			expectedCollection:      &lineInvoicePatchCollection{},
+		},
+		{
 			name:                    "credit then invoice enabled flat fee uses flat fee charges",
 			settlementMode:          productcatalog.CreditThenInvoiceSettlementMode,
 			enableCredits:           true,

As per coding guidelines "**/*_test.go: Make sure the tests are comprehensive and cover the changes."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openmeter/billing/worker/subscriptionsync/service/reconciler/patch_test.go`
around lines 34 - 86, Add a test case to the testCases slice in patch_test.go
that covers the "credits disabled + CreditThenInvoice enabled" precedence:
create an entry with settlementMode set to
productcatalog.CreditThenInvoiceSettlementMode, enableCredits: false,
enableCreditThenInvoice: true, pick any rateCard (e.g., flatRateCard) and set
expectedCollection to &lineInvoicePatchCollection{} to assert the !enableCredits
short-circuit; insert it alongside the other cases in the testCases slice so the
suite explicitly validates that CreditThenInvoice does not enable credits when
enableCredits is false.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@openmeter/billing/worker/subscriptionsync/service/reconciler/patch.go`:
- Around line 75-77: The current validation in the reconciler erroneously treats
a zero capacity as invalid (if c.capacity <= 0) which makes legitimate no-op
reconciliations fail; update the check in the function containing the "if
c.capacity <= 0" guard to only reject negative capacities (e.g., use c.capacity
< 0) or remove the check so zero is accepted, and keep the error message/context
tied to the same symbol (c.capacity) so callers still get an error for truly
invalid negative values.

---

Nitpick comments:
In `@openmeter/billing/worker/subscriptionsync/service/reconciler/patch_test.go`:
- Around line 34-86: Add a test case to the testCases slice in patch_test.go
that covers the "credits disabled + CreditThenInvoice enabled" precedence:
create an entry with settlementMode set to
productcatalog.CreditThenInvoiceSettlementMode, enableCredits: false,
enableCreditThenInvoice: true, pick any rateCard (e.g., flatRateCard) and set
expectedCollection to &lineInvoicePatchCollection{} to assert the !enableCredits
short-circuit; insert it alongside the other cases in the testCases slice so the
suite explicitly validates that CreditThenInvoice does not enable credits when
enableCredits is false.
🪄 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: 9c4072fd-1b50-4b75-a12c-d00447cf1661

📥 Commits

Reviewing files that changed from the base of the PR and between f9b89ed and cc971a1.

📒 Files selected for processing (11)
  • app/common/billing.go
  • app/config/config_test.go
  • app/config/credits.go
  • cmd/billing-worker/wire_gen.go
  • cmd/jobs/internal/wire_gen.go
  • config.example.yaml
  • e2e/config.yaml
  • openmeter/billing/worker/subscriptionsync/service/reconciler/patch.go
  • openmeter/billing/worker/subscriptionsync/service/reconciler/patch_test.go
  • openmeter/billing/worker/subscriptionsync/service/reconciler/reconciler.go
  • openmeter/billing/worker/subscriptionsync/service/service.go

@turip turip merged commit ebedbbe into main Apr 14, 2026
28 of 30 checks passed
@turip turip deleted the chore/allow-enabling-credit-then-invoice-seperately branch April 14, 2026 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note/feature Release note: Exciting New Features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants