Expose non-billable usage on the personal credits dashboard API

What does this MR do and why?

The personal GitLab Credits dashboard (User settings > GitLab Credits, GitLab.com only) reads billable usage only, so a user's Orbit promotional usage is invisible there, while the group dashboard's Total usage card already counts it. CustomersDot exposes a per-user nonBillableUsage field since https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/17539 (deployed). This MR reads it and exposes it on currentUser.creditsUsage.

  • SubscriptionUsageClient#get_non_billable_usage_for_user_id: a new request for the user's nonBillableUsage, with the same NON_BILLABLE_USAGE_UNAVAILABLE handling and ClickHouse read timeout as the subscription-level get_non_billable_usage. It is a separate request from the daily usage because CustomersDot answers a ClickHouse failure on that field with an error, which would otherwise fail the billable series too.
  • CreditsUsage#non_billable_usage: builds the per-product, per-skip-reason entries scoped to the user. Returns nil (not []) when CustomersDot can't read the data, so the API can tell "none" from "unknown".
  • GitlabSubscriptionUserCreditsUsageNonBillableUsage: a new GraphQL type that authorizes read_user, like the other self-view types, with productId, skipReason, totalCreditsUsed and dailyUsage.
  • nonBillableUsage field on GitlabSubscriptionUserCreditsUsage, nullable.
  • Specs and regenerated GraphQL docs.

This is change B of the plan in #633154 (comment 4099136079). The frontend (C) follows in a separate MR on top of this branch. No existing field changes meaning: creditsUsed and dailyUsage stay billable-only.

References

Screenshots or screen recordings

Screenshot_2026-10-28_at_09.32.40

How to set up and validate locally

  1. Set up GDK in SaaS mode with a local CustomersDot, as in "How to set up and validate locally" in !260725 (merged).

  2. In CustomersDot, seed billable and non-billable usage for one user of a subscription and run enrichment, for example:

    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
  3. As that user, run this query in /-/graphql-explorer:

    query {
      currentUser {
        creditsUsage(namespacePath: "<group-path>") {
          creditsUsed
          dailyUsage { date creditsUsed }
          nonBillableUsage {
            productId
            skipReason
            totalCreditsUsed
            dailyUsage { date creditsUsed }
          }
        }
      }
    }
  4. creditsUsed and dailyUsage are unchanged (billable only); nonBillableUsage lists the skipped usage per product and skip reason.

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.

Edited by Sheldon Led

Merge request reports

Loading
Loading