lablup / lablup/backend.ai-webui
Adapt RBAC admin pages to the 26.9.0 role-scope and permission-bit schema (backend #14445-#14494)
- Dominant language
- TypeScript
- Stars
- 133
- Forks
- 81
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 355
Description
## Background
`data/schema.graphql` was last synced on 2026-08-25 (#8609). Since then the manager's RBAC GraphQL surface changed in a series of breaking PRs on `lablup/backend.ai` (all merged, targeting 26.9.0). The RBAC admin pages in WebUI still query the old shape and will fail against a 26.9.0 manager once the schema is synced.
Backend PRs (cumulative, must be handled together):
- #14445 (BA-7730) a role owns exactly one scope: `Role.scopeType` / `Role.scopeId` / `Role.scope: EntityNode`; `CreateRoleInput.scope: ScopeInput` (the `scopes` list is deprecated)
- #14446 (BA-7731) responses carry the role's scope and the permission's bit
- #14469 (BA-7732) `scopeType` / `scopeId` / `scope` dropped from `Permission`, `PermissionFilter`, `PermissionNestedFilter`, `CreatePermissionInput`, `UpdatePermissionInput`
- #14476 (BA-7797) `RBACElementType` enum removed; scope/entity types are plain `String` (`RBACElementTypeFilter` -> `StringFilter`, `RoleMappedScopeNestedFilter.scopeId` -> `UUIDFilter`)
- #14478 (BA-7796) `Query.adminEntities`, `Role.scopes`, `EntityRef`, `EntityRefEdge`, `EntityConnection`, `EntityFilter`, `EntityOrderBy`, `EntityOrderField` removed; `AuditLogV2.entity` and `EntityLabel.entity` added
- #14494 (BA-7812) `operation: OperationType` -> `permission: PermissionBit` on `Permission`, `RolePermissionPreset`, `RolePermissionPresetEntryInput`, `CreatePermissionInput`, `UpdatePermissionInput`, `OperationInfo.requiredPermission`, the failure-info types; `OperationTypeFilter` -> `PermissionBitFilter`; `RolePermissionPresetOrderField.OPERATION` -> `PERMISSION`; `OperationType` and the `GRANT_*` values are gone (`PermissionBit` = `READ` / `UPDATE` / `CREATE` / `SOFT_DELETE` / `HARD_DELETE`)
The REST changes in #14494 (`CreatePermissionRequest` scope removal, `soft-delete` -> `soft_delete`) do not affect WebUI: no REST RBAC call exists in the client.
## Scope of work
1. Sync `data/schema.graphql` to the 26.9.0 manager and run `pnpm relay`.
1. `react/src/components/LegacyCreatePermissionModal.tsx`: drop the `OperationType` import and the `GRANT_*` delegate group; select and send `permission` instead of `operation`; remove the scope selectors from the create/update input.
1. `react/src/components/RoleScopePermissionEditModal.tsx`: drop the delegate (`GRANT_*`) column group and its label helper; `operation` -> `permission` in the fragments and in the bulk add/remove entries; move `RoleScopePermissionEditModal_scopesFragment` from `EntityRef` onto `Role` and rewrite the EntityRef-based display-name helpers.
1. `react/src/components/ScopedRolePermissionCard.tsx`: replace the paginated, filterable `adminRole.scopes(...)` query and the `EntityFilter` property filter with the single `scopeType` / `scopeId` / `scope { ... `} selection on `Role`; `permissions` node selects `entityType permission` (no `scopeId`).
1. `react/src/components/LegacyRolePermissionTab.tsx`: `adminPermissions` selection keeps only `entityType permission`; remove the scope columns, the `scopeType` / `scopeId` filter properties, and the local `operation: string` types.
1. `react/src/components/LegacyRoleScopeTab.tsx`: the tab is a paginated `Role.scopes` list and no longer has a query to run. Remove it (or reduce it to a single-scope display) and drop its registration on the role detail page.
1. `react/src/components/RoleNodes.tsx`: `scopes(first: 3) { count edges `} -> single `scopeType scopeId scope { ... `}; the scope column shows one scope.
1. `react/src/components/RoleAssignmentTab.tsx`: `firstScope: scopes(first: 1)` and the `.edges[0].node` read -> `scopeType scopeId`.
1. `react/src/hooks/useCurrentUserProjectRoles.ts`: `role { scopes(first: 1) `} and the edges loop -> `role { scopeType scopeId `}; remove `satisfies RBACElementType`.
1. `react/src/components/RoleFormModal.tsx`: send a single `scope` instead of the `scopes` Form.List; `requiredPermission` is now `PermissionBit`.
1. `react/src/pages/RBACManagementPage.tsx`: confirm the `mappedScope.scopeType` / `mappedScope.scopeId` filter properties against the new `StringFilter` / `UUIDFilter` shapes.
1. Every remaining `RBACElementType` reference (five files) and the `GRANT_*` fixtures in `react/src/helper/rbacGrantState.test.ts` and `rbacPermissionDiff.test.ts`; update the `rbacGrantState.ts` doc comment.
1. Decide the compatibility policy: the change is breaking, so either gate the new shape behind a 26.9.0 feature flag in `packages/backend.ai-client/src/client.ts` or accept that the RBAC pages require a 26.9.0 manager.
Optional follow-up: `AuditLogV2.entity` / `EntityLabel.entity` are new and could replace hand-built entity links in the audit log later; not required here.
## Acceptance
- `bash scripts/verify.sh` passes after the schema sync.
- RBAC role list, role detail (permissions, assignment), create/edit role, and the permission edit modal work against a 26.9.0 manager.
- Compiled Relay documents on the RBAC pages stay under the new manager limits (`MAX_QUERY_DEPTH = 20`, `MAX_ALIAS_COUNT = 20`, backend #14483); the current maximum is 15 aliases on `LegacyRolePermissionTabQuery`.
JIRA Issue: FR-3905
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.