Miguel engine v2 - #5836
Draft
brunomiguelpinto wants to merge 57 commits into
Draft
Conversation
brunomiguelpinto
force-pushed
the
miguel-engine-v2
branch
from
July 8, 2026 15:36
3f2633a to
7d5eaa7
Compare
brunomiguelpinto
changed the base branch from
api-v2-foundation
to
products-and-plans-subscription-runtime
July 8, 2026 15:58
brunomiguelpinto
force-pushed
the
miguel-engine-v2
branch
from
July 9, 2026 13:42
7d5eaa7 to
a565f36
Compare
brunomiguelpinto
force-pushed
the
miguel-engine-v2
branch
from
July 10, 2026 13:38
a565f36 to
8ba76e1
Compare
## Context Billing cycle specs should use FactoryBot setup instead of constructing records directly. ## Description Add a billing cycle factory with the required associations and default period values. Update the process service spec to create its pending cycle through the factory while preserving explicit pricing references for the override scenario.
Rate phase overrides can be edited after subscriptions exist, including pricing properties. Billing cycles must keep the effective pricing data selected at scheduling time so later override edits do not change already scheduled fees. Add stored rate properties to billing cycles and populate them from the effective rate or override when cycles are scheduled. Use the stored properties during processing and final cycle creation, and update specs to cover snapshot behavior.
## Context The cycles preview endpoint reported a calendar next billing date even when no billable cycle existed in the requested range because rates were not yet available. ## Description Return only the cycles payload when no cycle can be generated, and cover future-dated rate windows so clients do not receive a misleading next billing date.
## Context Backdated advance activations could schedule billing cycles with billing_at set to the historical period boundary. That timestamp then flowed into invoice creation and produced a backdated invoice issuing date. ## Description Clamp billing cycle billing_at to the current time when the billing boundary is in the past, while preserving future billing boundaries. Add scheduler specs for past and future advance periods.
## Context Subscription rate card termination needs to create the final arrears billing cycle directly so the clock processor can pick up pending cycles later. Regular scheduling should only generate cycles for rate cards whose billing clock is due. ## Description Add a due_for_range scope based on next_billing_at and use it from the billing cycle scheduler. Move final arrears cycle creation into SubscriptionRateCards::TerminateService using the existing billing period date service, while advance termination only sets ended_at. Update the related scheduler, model, and termination specs.
## Context Advance subscription rate cards are credited on termination based on the paid period that contains the termination date. The credit path should use the same period and rate resolution as billing cycle scheduling instead of a standalone rate resolver or direct boundary calculation. ## Description Use BillingPeriods::DatesService to resolve advance periods for unused credit calculation and expose the consumed ratio on each period. Remove the unused ResolveRateService and add coverage for split-rate periods so credits use the period-specific ratio.
## Context Arrears termination uses the current item clock as the date range end so the existing date service can emit the open cycle before it is clamped to the termination instant. ## Description Add an inline comment documenting why SubscriptionRateCards::TerminateService passes next_billing_at as the range end when resolving termination periods.
## Context Billing period ratios need the same anchor date that generated each cycle. Realigned billing anchors can differ from the subscription rate card anchor after interval changes. ## Description Store the generated cycle anchor date on DatesService cycles and pass it to ratio calculation so backdated advance stub periods use the correct generated boundaries.
## Context Billing period cycles exposed billing interval and anchor values that were only needed while building periods and computing ratios. ## Description Remove the internal billing interval and anchor fields from cycle and period value objects. Keep boundary lookup state private to the dates service and update the related spec expectations.
## Context Manual product-catalog billing can optionally terminate subscriptions before billing them inline. ## Description Terminate subscriptions at the current time when manual billing runs with termination enabled. Update the service spec to freeze time and assert the deterministic termination timestamp.
## Context Manual product-catalog billing and termination are separate API actions. The bill path no longer needs to accept or execute a termination option. ## Description Remove termination handling from the manual bill endpoint and service. Add request coverage for the terminate action, including applied rate cards, credit notes, current-time fallback, permissions, and not-found behavior.
## Context V2 product-catalog subscription termination needs request coverage for the real service behavior, including arrears final billing cycles and advance credit notes. ## Description Parse the termination timestamp before calling the termination service and add request specs that exercise monthly arrears, phased arrears, and billed advance termination scenarios.
Charge model services used to receive different chargeable records and a separate properties hash. This made the pricing boundary depend on ActiveRecord models and duplicated how charge model inputs were passed around. Introduce ChargeModels::ChargeableData as the normalized input for charge model calculations. Build it with ChargeModels::ChargeableData.from_charge(charge) for usage charges and ChargeModels::ChargeableData.from_fixed_charge(fixed_charge) for fixed charges. Pass ChargeableData to ChargeModels::Factory and charge model services instead of passing raw charge objects and separate properties. When charge filter properties must override the charge properties, use .with(properties:) on the data object before invoking the factory or service. Update charge model callers, pay-in-advance pricing, projections, and specs to use the normalized chargeable data boundary.
## Context Fixed-product billing cycles could only price standard rate properties directly, so graduated and volume rate models resolved their ranges but produced zero-amount fees. ## Description Price billing cycles through the charge model factory using PricingStructure data from the resolved cycle. Preserve charge model amount details on the fee and add regression coverage for tiered fixed-product rates.
Billing cycle fee processing needs to preserve the pricing unit selected during scheduling so retries and processing do not resolve pricing configuration again. Add an optional pricing unit association to billing cycles and persist it from the scheduler. Move billing cycle fee computation under BillingCycles::Fees, split amount conversion into a dedicated service, and use the stored pricing unit when building fee pricing unit usage.
## Context Billing cycle product fees must honor rate minimum amounts so fixed product subscriptions are not finalized below their configured floor. ## Description Add billing cycle minimum amount resolution and return base and true-up amount payloads from the billing cycle fee amount service. Decorate an optional linked true-up fee in the compute service and persist both fees during cycle processing, including pricing unit and prorated minimum scenarios.
Billing cycle fee computation should not rebuild billing calendar boundaries when the scheduler already resolves each cycle period. Persist the proration ratio on billing cycles, compute the value in the billing period date services, and make fee amount calculation read it from the billing cycle. Keep advance unused-credit calculations on a separate consumed ratio so termination refunds continue to use elapsed-period semantics.
Termination billing needs periods that overlap the termination window instead of extending the regular arrears lookup to the next billing date. Route termination date generation through a dedicated billing period service selected by DatesService options. Generate overlapping periods from the provided termination range, clamp the final period in the date layer, and let rate card termination persist all generated billing cycles without local period math.
## Context Billing cycle invoice generation needs to separate invoices by all grouping dimensions that affect invoice content and payment handling. ## Description Use billing cycle data when grouping and creating invoices, including cycle currency, cycle-level consolidation, purchase order numbers, billing entity, payment method, and local billing date. Persist zero-amount finalization transitions and avoid setting legacy charge date ranges on new billing cycle invoice subscriptions. Add focused specs for invoice grouping, purchase order numbers, payment method combinations, consolidation, and zero-amount finalization behavior.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Roadmap Task
👉 https://getlago.canny.io/feature-requests/p/{{FEATURE_SLUG}}
Context
Include relevant motivation and context.
Description
Describe your changes in detail.
List any dependencies that are required.