Add the Orbit billing account for top-level groups
What does this MR do and why?
Adds the Orbit billing account, the one place that decides Orbit access and trials for a top-level group. Policies, services, workers and GraphQL ask Billing.account_for(group) for access and trial decisions, so the license, promo gate, add-on and trial facts stay inside the account. Only the batch checks of OrbitLicense over many top-level groups still read the promo gate. The next MR adds the instance account for GitLab Self-Managed and GitLab Dedicated on the same rules.
GitLab.com behavior does not change, with two small fixes:
- When the Orbit trial is off for the group (the
orbit_trialflag), turning Orbit on asks for a purchase, not a trial, with the new turn-on denial reasonPURCHASE_REQUIRED. trial.offershows only to users who can start the trial.
GitLab Self-Managed behavior does not change: the instance license still decides.
For the analytics instrumentation review: the Snowplow category of orbit_trial_started, orbit_trial_start_failed and orbit_trial_ended changes to Analytics::Orbit::Billing::GroupAccount. No Service Ping metric uses these events, and nothing in the repository filters them by category.
Related to https://gitlab.com/gitlab-org/orbit/knowledge-graph/-/work_items/1385
References
- Stack, part 1 of 2. Next: !261678 (merged) (the self-managed instance trial)
- Epic: https://gitlab.com/groups/gitlab-org/-/epics/21198
- Conflicts with !261155 (merged). The MR that merges second moves the
ToggleNamespaceService#enable_namespacechange intoAccount#record_turned_on, and theStartTrialServicechange intoGroupAccount#after_trial_started.
Screenshots or screen recordings
No UI change.
How to set up and validate locally
On a GitLab.com GDK, as the Owner of a top-level group with Orbit, run this query in GraphiQL. Expect the same state as on master:
{ group(fullPath: "my-group") { orbitAccess { state reason turnOnDenialReason trial { state } } } }