Accept username in BudgetCapUserOverrideInput
What does this MR do and why?
Backend for the bulk CSV import of per-user credit cap overrides. Admins paste username, cap, enabled lines, so the upsertUserBudgetCapOverrides mutation needs to accept usernames, not only global IDs.
BudgetCapUserOverrideInput:userIdbecomes optional and a newusernameargument is added. Exactly one of the two must be set on each override (validates exactly_one_of). Blank usernames are rejected.UpsertUserOverridesmutation: usernames are resolved to user IDs with a single case-insensitiveUser.by_usernamelookup before forwarding to CustomersDot. If any username cannot be resolved, the whole batch is rejected withUsers not found: <usernames>, mirroring the existing behavior for unknown user IDs. Namespace membership validation applies to username-resolved users as well.usernameis markedexperiment: { milestone: '19.5' }. The UI that uses it is gated behind thecredit_caps_bulk_updatefeature flag introduced in !257651 (merged), so the backend does not check the flag itself.- GraphQL docs and introspection schemas regenerated.
No CustomersDot changes are needed. Email support is deferred to a follow-up, per the parent issue.
Implementation status
Part of https://gitlab.com/gitlab-org/gitlab/-/work_items/630981
| Piece | Work item | MR | Status |
|---|---|---|---|
Feature flag credit_caps_bulk_update + scaffold button |
https://gitlab.com/gitlab-org/gitlab/-/work_items/630982 | !257651 (merged) | |
BE: username on BudgetCapUserOverrideInput |
https://gitlab.com/gitlab-org/gitlab/-/work_items/630983 | !258407 (merged) | |
| FE: bulk update overrides modal | https://gitlab.com/gitlab-org/gitlab/-/work_items/630982 | !257948 (merged) | |
| FE: CSV parser | https://gitlab.com/gitlab-org/gitlab/-/work_items/630984 | !258244 (merged) | |
| FE: integrate modal with BE | https://gitlab.com/gitlab-org/gitlab/-/work_items/630985 | !258465 (merged) | |
| FE: CSV parser improvements (follow-up) | https://gitlab.com/gitlab-org/gitlab/-/work_items/631895 | !259381 (merged) | |
| Documentation update | https://gitlab.com/gitlab-org/gitlab/-/work_items/632125 | !259654 (merged) | |
| Feature flag rollout | https://gitlab.com/gitlab-org/gitlab/-/work_items/631018 |
References
- Task: https://gitlab.com/gitlab-org/gitlab/-/work_items/630983
- Parent issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/630981
- Epic: https://gitlab.com/groups/gitlab-org/-/work_items/23579
- Feature flag scaffold: !257651 (merged)
- PoC: !257323 (closed)
Screenshots or screen recordings
How to set up and validate locally
-
Make sure you have a top-level group where you are an owner and a member user in it, or use an admin in admin mode for instance scope.
-
Open GraphiQL at
http://localhost:3000/-/graphql-explorerand run (adjustnamespacePathandusername):mutation { upsertUserBudgetCapOverrides(input: { namespacePath: "your-group" overrides: [ { username: "some-member", cap: 100, enabled: true } ] }) { userOverrides { user { id username } cap capEnabled } errors } } -
Expected: the override is resolved to the user and forwarded to CustomersDot (locally this will most likely surface a CDot connection error in
errors, which is expected without a CDot setup; the important part is that noUsers not founderror is raised). -
Try an unknown username: you get
Users not found: <username>and CDot is not called. -
Try an override with both
userIdandusername, or with neither: you getOne and only one of [userId, username] arguments is required.
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.