Add memberRole field to BaseAccessLevelType GraphQL type
## Context
| | |
|---|---|
| **Phase** | 3 of 6 |
| **Parallel with** | https://gitlab.com/gitlab-org/gitlab/-/work_items/594880+ <br> https://gitlab.com/gitlab-org/gitlab/-/work_items/594881+ <br> https://gitlab.com/gitlab-org/gitlab/-/work_items/594882+ <br> https://gitlab.com/gitlab-org/gitlab/-/work_items/594883+ |
| **Blocked by** | https://gitlab.com/gitlab-org/gitlab/-/work_items/594877+ <br> https://gitlab.com/gitlab-org/gitlab/-/work_items/594878+ <br> https://gitlab.com/gitlab-org/gitlab/-/work_items/594879+ |
| **Unblocks** | https://gitlab.com/gitlab-org/gitlab/-/work_items/594889+ |
## Summary
Add a `memberRole` field to the `BaseAccessLevelType` GraphQL type so that custom role data is exposed when querying branch protection access levels via GraphQL.
## Background
The GraphQL type `Types::BranchProtections::BaseAccessLevelType` (in `app/graphql/types/branch_protections/base_access_level_type.rb`) is prepended by `EE::Types::BranchProtections::BaseAccessLevelType` (in `ee/app/graphql/ee/types/branch_protections/base_access_level_type.rb`). The EE version currently adds `user` and `group` fields. A `memberRole` field needs to be added similarly.
This type is used by `MergeAccessLevelType`, `PushAccessLevelType`, and `UnprotectAccessLevelType` (all inherit from `BaseAccessLevelType`), so the field will automatically be available on all three.
## Relevant files
- `ee/app/graphql/ee/types/branch_protections/base_access_level_type.rb` — add field here
- `app/graphql/types/branch_protections/base_access_level_type.rb` — CE base
- Check if `Types::MemberRoles::MemberRoleType` exists; if not, it needs to be created or a minimal version added
## Changes required
### Check for existing `MemberRoleType`
Search for `Types::MemberRoles::MemberRoleType` or similar in `ee/app/graphql/types/`. If it exists, use it. If not, create a minimal type:
```ruby
# ee/app/graphql/types/member_roles/member_role_type.rb
module Types
module MemberRoles
class MemberRoleType < BaseObject
graphql_name 'MemberRole'
description 'Represents a custom member role.'
authorize :read_member_role
field :id, ::Types::GlobalIDType[::MemberRole], null: false,
description: 'Global ID of the custom role.'
field :name, GraphQL::Types::String, null: false,
description: 'Name of the custom role.'
field :base_access_level, Types::AccessLevelType, null: false,
description: 'Base access level of the custom role.'
end
end
end
```
### `ee/app/graphql/ee/types/branch_protections/base_access_level_type.rb`
```ruby
module EE
module Types
module BranchProtections
module BaseAccessLevelType
extend ActiveSupport::Concern
prepended do
field :user,
::Types::AccessLevels::UserType,
null: true,
description: 'User associated with the access level.'
field :group,
::Types::AccessLevels::GroupType,
null: true,
description: 'Group associated with the access level.'
field :member_role,
::Types::MemberRoles::MemberRoleType,
null: true,
description: 'Custom role associated with the access level.'
end
end
end
end
end
```
## GraphQL query example
```graphql
query {
project(fullPath: "mygroup/myproject") {
branchRules {
nodes {
branchProtection {
mergeAccessLevels {
nodes {
accessLevel
accessLevelDescription
memberRole {
id
name
baseAccessLevel
}
}
}
}
}
}
}
}
```
## Testing
- GraphQL type spec: resolver returns `member_role` object when access level has `member_role_id` set
- GraphQL type spec: resolver returns `null` for `memberRole` when `member_role_id` is nil
- Verify authorization: user must have appropriate permissions to read the member role via this field
## Dependencies
- Issue 3 (EE concern) — `belongs_to :member_role` must exist on the access level models
## Labels
issue