feat(charges): add backend customer charge overrides - #4884
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
| {Name: "amount_before_proration", Type: field.TypeOther, SchemaType: map[string]string{"postgres": "numeric"}}, | ||
| {Name: "amount_after_proration", Type: field.TypeOther, SchemaType: map[string]string{"postgres": "numeric"}}, | ||
| {Name: "status_detailed", Type: field.TypeEnum, Enums: []string{"created", "active", "active.realization.started", "active.realization.waiting_for_collection", "active.realization.processing", "active.realization.issuing", "active.realization.zero_fiat_amount_overage_completed", "active.realization.completed", "active.awaiting_payment_settlement", "final", "deleted"}}, | ||
| {Name: "status_detailed", Type: field.TypeEnum, Enums: []string{"created", "active", "active.clear_override", "active.realization.started", "active.realization.waiting_for_collection", "active.realization.processing", "active.realization.issuing", "active.realization.zero_fiat_amount_overage_completed", "active.realization.completed", "active.awaiting_payment_settlement", "final", "deleted", "deleted.clear_override"}}, |
There was a problem hiding this comment.
Missing detailed-status migration
When clearing an override transitions a flat-fee or usage-based charge through active.clear_override or deleted.clear_override, the adapters persist a value that the committed database migration history does not add to the existing status_detailed constraint, causing deployed databases to reject the update and the clear operation to fail.
Knowledge Base Used: Data layer: ent schema, migrations, and generated client
Prompt To Fix With AI
This is a comment left during a code review.
Path: openmeter/ent/db/migrate/schema.go
Line: 2207
Comment:
**Missing detailed-status migration**
When clearing an override transitions a flat-fee or usage-based charge through `active.clear_override` or `deleted.clear_override`, the adapters persist a value that the committed database migration history does not add to the existing `status_detailed` constraint, causing deployed databases to reject the update and the clear operation to fail.
**Knowledge Base Used:** [Data layer: ent schema, migrations, and generated client](https://app.greptile.com/openmeter/-/custom-context/knowledge-base/openmeterio/openmeter/-/docs/data-layer.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Summary
PaymentAdjustmentNoneand map it to the existing no-credit-refund/no-invoice-refund deletion policyLifecycle behavior
active.clear_overridecleanup and returns in the restoredcreated,active, orfinalstatedeleted.clear_overrideand returns in the normaldeletedstatePaymentAdjustmentNonepreserves already-realized credit, invoice, and payment historyCoverage
Validation
go test ./openmeter/billing/charges ./openmeter/billing/charges/meta ./openmeter/billing/charges/statemachine ./openmeter/billing/charges/flatfee/service ./openmeter/billing/charges/usagebased/service -count=1POSTGRES_HOST=127.0.0.1 go test ./openmeter/billing/charges/service -run 'TestCustomerChargeAPI' -count=1Follow-up: patch advancement sequencing
The implementation currently makes the shared
ApplyPatchcallAdvanceUntilStateStablebefore the charge service applies accumulated invoice patches. The review discussion identified this as a real sequencing regression rather than only stale test expectations:final, marking its run immutable and breaking the existing shrink-then-extend workflowcreatedtoactivebefore replacement gathering work has been appliedThe likely follow-up design is a service-owned advancement loop that treats every transition as a complete step:
A separate policy decision remains: whether every patch requests synchronous stabilization or only operations such as clear override. If mutable shrink-then-extend must keep using the same realization, ordinary shrink cannot be advanced to stability synchronously. This follow-up is intentionally left for a dedicated change.
Known broader-suite failures related to this follow-up are currently in the immutable-proration and custom-currency zero-fiat shrink/extend scenarios in
invoicable_test.go.Greptile Summary
The PR adds customer-managed override snapshots and deletion operations for flat-fee and usage-based charges, preserving subscription-owned base intent.
Confidence Score: 4/5
The PR should not merge until a migration allows the new clear-override detailed status values in existing databases.
Override clearing persists active.clear_override or deleted.clear_override, but the committed migration history does not update the database constraints to accept those values.
Files Needing Attention: openmeter/ent/db/migrate/schema.go and tools/migrate/migrations/
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR API[Customer clear override] --> Patch[ClearOverride patch] Patch --> State{Hidden base state} State -->|Live| ActiveClear[active.clear_override] State -->|Deleted| DeletedClear[deleted.clear_override] ActiveClear --> Persist[Persist status_detailed] DeletedClear --> Persist Persist --> DB[(PostgreSQL)] DB -->|Migration lacks new values| Error[Constraint rejection]Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "feat(charges): add backend charge overri..." | Re-trigger Greptile
Context used: