feat(billing): CreateInvoicePendingLines charges support#4508
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds ChargeService.CreatePendingInvoiceLines and a charge-backed pending-invoice-line implementation (validation, intent mapping, transactional charge creation, optional invoice-now, reordering), integrates pending-line results into Create(), wires a ChargeService into the HTTP handler, and conditionally routes pending-line requests based on credits and feature flags. ChangesCharge-backed pending invoice lines
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
openmeter/billing/charges/service/pendinglines_test.go (1)
181-240: ⚡ Quick winAdd assertions for the remaining input policy branches.
Nice coverage overall. One small gap: this test block doesn’t yet assert rejection for
line.ChargeID != nilandline.Engine != ""(except the invoice-engine normalization case). Adding those two cases would lock down all validation rules invalidateChargePendingInvoiceLinesInput.As per coding guidelines, “Make sure the tests are comprehensive and cover the changes.”
🤖 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/service/pendinglines_test.go` around lines 181 - 240, The test TestCreatePendingInvoiceLinesRejectsNonManualInput currently checks managed-by and subscription branches but misses the branches where a line has ChargeID set and where Engine is non-empty; add two sub-cases that build a billing.GatheringLine (using billing.NewFlatFeeGatheringLine) with (1) ChargeID non-nil and (2) Engine set to a non-empty string, then call s.Charges.CreatePendingInvoiceLines with those lines (CreatePendingInvoiceLinesInput) and assert an error is returned and the error message contains the expected validation text (matching the messages produced by validateChargePendingInvoiceLinesInput for "charge id is not allowed" and "engine is not allowed" or equivalent).Source: Coding guidelines
openmeter/billing/httpdriver/invoiceline.go (1)
134-169: 💤 Low valueConsider adding doc comments for the decision logic.
The conditional routing logic is solid and handles all the edge cases nicely! The fallback to
falsewhen feature evaluation fails is a safe default.Since the decision involves multiple config flags and feature gating, a brief doc comment on
shouldCreatePendingLinesWithChargesexplaining the precedence (credits config → feature gate presence → feature flag evaluation) would help future maintainers quickly understand the flow.🤖 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/httpdriver/invoiceline.go` around lines 134 - 169, Add a short doc comment above shouldCreatePendingLinesWithCharges describing the decision precedence: check for presence of h.chargeService first, then h.credits.Enabled and h.credits.EnableCreditThenInvoice, then presence of h.featureGate, then empty h.credits.FeatureFlag, and finally the feature flag evaluation via h.featureGate.EvaluateBool; mention that failures default to false and that createPendingInvoiceLines delegates to chargeService when this returns true to clarify overall routing.
🤖 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/service/create.go`:
- Around line 439-446: The current loop uses index-based correlation between
result.Lines and lines which can mis-map when ordering or membership differs;
instead build a lookup map from the input slice (e.g., for each entry in lines
create map[bypassLineID] = true using the input's LineID and
BypassCollectionAlignment flag) and then iterate result.Lines and check the map
by result line.ID before appending to out.collectionAlignmentBypassedLines (use
invoicePendingLinesInput with CustomerID and LineID). This replaces the idx <
len(lines) check and ensures mapping by line ID rather than by index.
---
Nitpick comments:
In `@openmeter/billing/charges/service/pendinglines_test.go`:
- Around line 181-240: The test
TestCreatePendingInvoiceLinesRejectsNonManualInput currently checks managed-by
and subscription branches but misses the branches where a line has ChargeID set
and where Engine is non-empty; add two sub-cases that build a
billing.GatheringLine (using billing.NewFlatFeeGatheringLine) with (1) ChargeID
non-nil and (2) Engine set to a non-empty string, then call
s.Charges.CreatePendingInvoiceLines with those lines
(CreatePendingInvoiceLinesInput) and assert an error is returned and the error
message contains the expected validation text (matching the messages produced by
validateChargePendingInvoiceLinesInput for "charge id is not allowed" and
"engine is not allowed" or equivalent).
In `@openmeter/billing/httpdriver/invoiceline.go`:
- Around line 134-169: Add a short doc comment above
shouldCreatePendingLinesWithCharges describing the decision precedence: check
for presence of h.chargeService first, then h.credits.Enabled and
h.credits.EnableCreditThenInvoice, then presence of h.featureGate, then empty
h.credits.FeatureFlag, and finally the feature flag evaluation via
h.featureGate.EvaluateBool; mention that failures default to false and that
createPendingInvoiceLines delegates to chargeService when this returns true to
clarify overall routing.
🪄 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: 929631ed-517f-4b47-a220-edc85efe5396
📒 Files selected for processing (9)
openmeter/billing/charges/service.goopenmeter/billing/charges/service/create.goopenmeter/billing/charges/service/pendinglines.goopenmeter/billing/charges/service/pendinglines_test.goopenmeter/billing/httpdriver/handler.goopenmeter/billing/httpdriver/invoiceline.goopenmeter/billing/httpdriver/pendinglines_test.goopenmeter/server/router/router.goopenmeter/server/server_test.go
d2c8a57 to
fe894f7
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
openmeter/billing/httpdriver/pendinglines_test.go (1)
26-135: ⚡ Quick winConsider adding a test case for non-nil
featureGatewith emptyFeatureFlag.Your test suite covers most branches, but there's one path in
shouldCreatePendingLinesWithChargeswherefeatureGateis non-nil yetFeatureFlagis an empty string—this should returntruewithout calling the gate. Adding this case would give you complete branch coverage of the routing logic.🧪 Suggested test case
{ + name: "non-nil feature gate with empty flag uses charges", + handler: handler{ + chargeService: nonNilChargeService{}, + credits: config.CreditsConfiguration{ + Enabled: true, + EnableCreditThenInvoice: true, + FeatureFlag: "", + }, + featureGate: staticFeatureGate{}, + }, + expected: true, + }, + { name: "feature gate error is returned",🤖 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/httpdriver/pendinglines_test.go` around lines 26 - 135, Add a test case in TestShouldCreatePendingLinesWithCharges that covers the branch where handler.featureGate is non-nil but credits.FeatureFlag is an empty string: create a handler with chargeService nonNilChargeService, credits.FeatureFlag set to "" (and Enabled/EnableCreditThenInvoice true), featureGate set to a non-nil staticFeatureGate (either enabled or disabled), and assert expected == true and no error; this verifies shouldCreatePendingLinesWithCharges returns true without invoking the gate.
🤖 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.
Nitpick comments:
In `@openmeter/billing/httpdriver/pendinglines_test.go`:
- Around line 26-135: Add a test case in TestShouldCreatePendingLinesWithCharges
that covers the branch where handler.featureGate is non-nil but
credits.FeatureFlag is an empty string: create a handler with chargeService
nonNilChargeService, credits.FeatureFlag set to "" (and
Enabled/EnableCreditThenInvoice true), featureGate set to a non-nil
staticFeatureGate (either enabled or disabled), and assert expected == true and
no error; this verifies shouldCreatePendingLinesWithCharges returns true without
invoking the gate.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 60c7987c-9b84-4f6c-9bdf-b5347e84d079
📒 Files selected for processing (9)
openmeter/billing/charges/service.goopenmeter/billing/charges/service/create.goopenmeter/billing/charges/service/pendinglines.goopenmeter/billing/charges/service/pendinglines_test.goopenmeter/billing/httpdriver/handler.goopenmeter/billing/httpdriver/invoiceline.goopenmeter/billing/httpdriver/pendinglines_test.goopenmeter/server/router/router.goopenmeter/server/server_test.go
🚧 Files skipped from review as they are similar to previous changes (8)
- openmeter/server/server_test.go
- openmeter/server/router/router.go
- openmeter/billing/httpdriver/invoiceline.go
- openmeter/billing/charges/service.go
- openmeter/billing/httpdriver/handler.go
- openmeter/billing/charges/service/pendinglines_test.go
- openmeter/billing/charges/service/pendinglines.go
- openmeter/billing/charges/service/create.go
Greptile SummaryThis PR adds a charge-backed path for
Confidence Score: 5/5Safe to merge. The charge-backed flow is atomic, the previous index-based ordering bug is properly fixed with charge ID correlation, and all new code paths have integration test coverage. The refactor correctly delegates to a private openmeter/billing/charges/service/pendinglines.go — the price-type switch default case. Important Files Changed
|
6f5e588 to
68922ae
Compare
There was a problem hiding this comment.
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/httpdriver/invoiceline.go`:
- Around line 160-165: The code currently calls h.featureGate.Enabled(namespace,
flag) without checking h.featureGate for nil, which causes a panic; update the
logic in invoiceline.go so that if h.featureGate is nil it returns true (per the
"nil feature gate uses charges" test) instead of calling Enabled. Specifically,
when computing flag via h.featureGate.Flags.Credits(), keep that guarded, but
add an early nil check for h.featureGate and return true, otherwise call
h.featureGate.Enabled(namespace, flag); reference the h.featureGate field, the
Enabled method, and the Flags.Credits() call to locate the change.
🪄 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: c6b2d375-3ced-4014-ad89-7af4a3fa9120
📒 Files selected for processing (3)
openmeter/billing/httpdriver/handler.goopenmeter/billing/httpdriver/invoiceline.goopenmeter/billing/httpdriver/pendinglines_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
- openmeter/billing/httpdriver/handler.go
- openmeter/billing/httpdriver/pendinglines_test.go
5ba09a7 to
9ea35b0
Compare
b02334c to
acd4b55
Compare
Summary by CodeRabbit
New Features
Reliability
Tests