Sync contract_overages_allowed flag from Zuora to GitLab.com for Restricted Access enforcement
## Summary
For self-managed instances, the `contract_overages_allowed` flag from Zuora is already synced via the license and can be checked using `License.current.contract_overages_allowed?`. However, for GitLab.com (SaaS), this sync was never implemented.
To support the [Restricted Access rollout plan](https://gitlab.com/groups/gitlab-org/-/epics/18788), we need to sync the `contract_overages_allowed__c` custom field from Zuora subscriptions to GitLab.com namespaces.
## Background
- The `contract_overages_allowed__c` field exists in Zuora and is synced to CustomersDot's `License` model
- For self-managed, this value is already available in the license file
- For SaaS, we need to implement a sync mechanism to the `GitlabSubscription` model
- This flag will be used to enforce Restricted Access (Block Seat Overages) based on subscription settings
Related discussions:
- https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/11378#note_2880830722
- https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/11378#note_2867023069
## Proposal
Implement a sync mechanism similar to how the auto-renew flag is currently handled:
1. When `contract_overages_allowed__c` is updated in Zuora, trigger a callout to CustomersDot
2. CustomersDot updates its local subscription record
3. CustomersDot invokes the [Update Subscription API](https://docs.gitlab.com/development/internal_api/gitlab_subscriptions/#update-a-subscription) to update GitLab.com
4. GitLab.com updates the `GitlabSubscription` record with the new flag value
```mermaid
sequenceDiagram
actor TM as GitLab Team Member
participant Z as Zuora
participant CD as CDot
participant GL as GitLab.com
TM->>Z: Update contract_overages_allowed__c<br/>for subscription
activate Z
Z->>CD: Trigger callout<br/>(flag update notification)
deactivate Z
activate CD
CD->>CD: Update local<br/>subscription record
CD->>GL: Invoke Update Subscription API<br/>(update overage flag)
activate GL
GL->>GL: Update GitlabSubscription<br/>record
GL-->>CD: Success response
deactivate GL
deactivate CD
Note over GL: GitlabSubscription now stores<br/>contract_overages_allowed flag<br/>(used to determine restricted access)
```
## Possible values
* In Zuora: `Yes`, `No` and `nil`
* Default is `Yes`
* `nil` when no value is selected
* In CustomersDot: true, false and nil
* `true` for `Yes` and for `nil`
* `false` for `No`
* `nil` when no subscription is assigned to the order
* In GitLab: `true`, `false` and `nil`
* `nil` also when the subscription gets created before the subscription in Zuora or CDot gets created
## Implementation Tasks
- [x] Add `contract_overages_allowed` column to `gitlab_subscriptions` table in GitLab.com
- [x] Update the [Update Subscription API](https://docs.gitlab.com/development/internal_api/gitlab_subscriptions/#update-a-subscription) to accept the `contract_overages_allowed` parameter
- [x] Update CustomersDot to send the `contract_overages_allowed` value when calling the Update Subscription API
- [x] Set up Zuora callout to trigger CustomersDot updates when `contract_overages_allowed__c` changes
- [x] Add tests for the sync mechanism
- [ ] Document the new field and sync behavior
## Rollout Plan Alignment
This implementation supports the [Restricted Access rollout plan](https://gitlab.com/groups/gitlab-org/-/epics/18788) by:
1. Allowing business logic to set default values based on customer type (e.g., self-service vs sales-assisted)
2. Enabling sales-controlled opt-outs through SFDC approval processes
3. Supporting phased rollout to specific customer cohorts (QSR customers first)
Eventually, the default value for new subscriptions should be set to `false` (overages not allowed) as part of Phase 1 of the RA rollout.
## Related Issues
- https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/11378 - Change Column Default for contract_overages_allowed
epic