Sum all credit grants of an Orbit trial
What does this MR do and why?
When Sales adds credits to an Orbit trial, CustomersDot records each grant as its own trial entry. GitLab read only the first entry, so the Orbit settings page showed the first grant's credits, and the trial dates and state followed that grant. A new trial that Sales starts after an earlier trial ended also showed as ended.
- The current trial is the set of grants with the latest expiry. CustomersDot gives all active grants of a trial the same expiry, so grants that expire earlier belong to an earlier trial.
- The credit total is the sum of the current trial's grants, and the start date is its earliest grant.
- The end date and the active or ended state come from the current trial. A self-serve trial has one grant, so nothing changes for it.
References
Closes https://gitlab.com/gitlab-org/gitlab/-/work_items/635709
Screenshots or screen recordings
E2E run against the local CustomersDot, with the grants written to the group's Orbit trial wallet. Before: master. After: this branch.
| Before | After | |
|---|---|---|
| Grants of 50, 10, 10 and 10 credits (the issue's wallet) | ![]() |
![]() |
| An earlier trial of 50 credits expired, then Sales started a new trial with 10 credits | ![]() |
![]() |
| Wallet | Before | After |
|---|---|---|
| 50 + 10 + 10 + 10, one trial | trial with 50 credits | trial with 80 credits |
| Earlier trial of 50 expired, new trial of 10 | trial ended, Orbit paused | trial with 10 credits, active |
| 50 + 10, all expired | trial ended | trial ended |
| One grant of 100 | trial with 100 credits | trial with 100 credits |
The hourly ended-trials cron now keeps Orbit on for the new trial, and still turns it off when all grants have expired.
Regression: all 29 scenarios of the Orbit monetization E2E factory pass on this branch, the same as on master. After the current-trial change, the trial scenarios (start, end, and sales-assisted, on GitLab.com and Self-Managed) pass again.
How to set up and validate locally
-
In a Rails console, parse a CustomersDot payload with an expired trial and a new trial:
payload = { 'trial_info' => { 'orbit' => { 'current_balance' => '10.0', 'trials' => [ { 'starts_at' => 2.months.ago.iso8601, 'expires_at' => 1.month.ago.iso8601, 'initial_credit_amount' => '50.0' }, { 'starts_at' => 1.day.ago.iso8601, 'expires_at' => 1.month.from_now.iso8601, 'initial_credit_amount' => '10.0' } ] } } } trial = Gitlab::SubscriptionPortal::Client.send(:parse_product_trial, :orbit, payload) [trial.state, trial.credits_total, trial.trial_expires_at] # => [:trial, 10.0, <one month from now>]
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.



