Add includeNonBillable to the subscription usage events API
What does this MR do and why?
The user drill-down on the GitLab Credits dashboard lists billable events only, so once the user's total credits used card counts non-billable usage (!265553 (merged)), the event log adds up to less than the card, and promotional usage leaves no trace there.
CustomersDot now takes an opt-in includeNonBillable argument on events and usedFlowTypes and reports billable and skipReason per event (https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/17693). This MR is the backend half of consuming it:
- GraphQL:
GitlabSubscriptionUsageUser.eventsand.usedFlowTypestakeincludeNonBillable: Boolean = false.GitlabSubscriptionUsageUserEventgetsbillable: BooleanandskipReason: String, both null unless the argument is set. Without the argument every query is unchanged, so existing API consumers see no change. - Client: new
GET_USER_EVENTS_WITH_NON_BILLABLE_QUERYandGET_USED_FLOW_TYPES_WITH_NON_BILLABLE_QUERY, used only when the argument is set. While CustomersDot hasn't deployed the argument (or the two event fields), the client retries with the billable-only query, the same fallback pattern asentityTypeandnonBillableCreditsUsed. - Complexity: CustomersDot caps license-key (self-managed) requests at a query complexity of 200. GitLab's events query sits at 171; the two new fields over a 20-row page add 40. The opt-in query therefore leaves out the deprecated
eventType(superseded byflowType, https://gitlab.com/gitlab-org/gitlab/-/work_items/581215), landing at 191. GitLab'seventTypefield is documented as null whenincludeNonBillableis true. Measured withGraphQL::Analysis::QueryComplexityagainst the CustomersDot schema. - Specs, GraphQL docs and introspection schema.
Frontend (badge on non-billable rows, filter including non-billable flows) is in !265821 (merged), stacked on this branch. Split on purpose: GitLab.com deploys are rolling, and this change adds a GraphQL argument, which @gl_introduced can't cover at all.
This is change G2 of the plan in #633154 (comment 4099142904).
References
- Tracked in https://gitlab.com/gitlab-org/gitlab/-/work_items/636698
- Related to #633154 (closed)
- Plan: #633154 (comment 4099142904)
- CustomersDot (G1): https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/17693
- Frontend half (G3): !265821 (merged)
- Usage by user (E1/E2): !265548 (merged), !265553 (merged)
Screenshots or screen recordings
How to set up and validate locally
-
Check out https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/17693 in your local CustomersDot. Without it, the client falls back to the billable-only queries and
billable/skipReasonare null. -
Set up GDK in SaaS mode with that CustomersDot, as in "How to set up and validate locally" in !260725 (merged).
-
In CustomersDot, seed billable and non-billable Orbit usage for one user and enrich:
bin/populate_usage_data -r 20 --realm SaaS --root-namespace-id <id> --user-id <user_id> --feature-qualified-name orbit_mcp --team-member --skip-reason promo bin/populate_usage_data -r 20 --realm SaaS --root-namespace-id <id> --user-id <user_id> --feature-qualified-name orbit_rest -
In
/-/graphql-explorer, as a group owner:query { subscriptionUsage(namespacePath: "<group-path>") { usersUsage { users(username: "<username>") { nodes { usedFlowTypes { id } allFlowTypes: usedFlowTypes(includeNonBillable: true) { id } events(first: 20) { nodes { flowType billable skipReason } } allEvents: events(includeNonBillable: true, first: 20) { nodes { flowType eventType billable skipReason } } } } } } } -
eventsandusedFlowTypesare unchanged (billable only,billable/skipReasonnull).allEventsinterleavesorbit_mcprows withbillable: false, skipReason: "promo"andeventType: null;allFlowTypesaddsorbit_mcp.
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.
