Skip to content

feat(BA-5737): add RBAC-enforced VFolder create mutations#11139

Merged
fregataa merged 16 commits into
mainfrom
feature/BA-5737-project-vfolder-mutations
Apr 23, 2026
Merged

feat(BA-5737): add RBAC-enforced VFolder create mutations#11139
fregataa merged 16 commits into
mainfrom
feature/BA-5737-project-vfolder-mutations

Conversation

@fregataa
Copy link
Copy Markdown
Member

@fregataa fregataa commented Apr 16, 2026

Summary

  • Add createProjectVFolderInProject GraphQL mutations so project admin flows have a consistent project-scoped mutation surface alongside the existing projectVfolders query.

Test plan

  • pants fmt :: && pants fix :: && pants lint --changed-since=origin/main — green
  • Manual verification with live server after CI green

Resolves BA-5737


📚 Documentation preview 📚: https://sorna--11139.org.readthedocs.build/en/11139/


📚 Documentation preview 📚: https://sorna-ko--11139.org.readthedocs.build/ko/11139/

Copilot AI review requested due to automatic review settings April 16, 2026 05:39
@github-actions github-actions Bot added size:XL 500~ LoC comp:manager Related to Manager component labels Apr 16, 2026
fregataa added a commit that referenced this pull request Apr 16, 2026
@github-actions github-actions Bot added the area:docs Documentations label Apr 16, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a project-scoped mutation surface for vfolder v2 so project admin flows can create/delete vfolders via PROJECT-scoped RBAC (consistent with the existing projectVfolders query).

Changes:

  • Introduce PROJECT-scoped vfolder actions (Create/Delete/BulkDelete*InProject) and wire them through ScopeActionProcessor using scope RBAC validators.
  • Expose new GraphQL mutations (createProjectVfolderV2, deleteProjectVfolderV2, bulkDeleteProjectVfoldersV2) backed by the new adapter methods.
  • Add unit/component test coverage for delete/bulk-delete project-scoped paths and service routing.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/unit/manager/services/vfolder/test_vfolder_in_project_service.py Unit tests for service delegation and project membership checks.
tests/component/vfolder_v2/test_vfolder_project_mutations.py Component tests exercising RBAC + service behavior for project-scoped deletes.
src/ai/backend/manager/services/vfolder/services/vfolder.py Adds create_in_project, delete_in_project, bulk_delete_in_project service methods.
src/ai/backend/manager/services/vfolder/processors/vfolder.py Registers new PROJECT-scoped action processors and supported action specs.
src/ai/backend/manager/services/vfolder/actions/vfolder_in_project.py New PROJECT-scoped action/result dataclasses for create/delete/bulk-delete.
src/ai/backend/manager/api/gql/vfolder_v2/resolver/mutation.py Adds new GraphQL mutations for project-scoped create/delete/bulk-delete.
src/ai/backend/manager/api/gql/vfolder_v2/resolver/init.py Exports the new mutation resolvers.
src/ai/backend/manager/api/gql/vfolder_v2/init.py Re-exports new vfolder v2 mutations for schema wiring.
src/ai/backend/manager/api/gql/schema.py Adds new mutation fields to the GraphQL Mutation type.
src/ai/backend/manager/api/adapters/vfolder.py Adds adapter entrypoints that dispatch project-scoped actions to processors.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ai/backend/manager/api/gql/vfolder_v2/resolver/mutation.py
Comment thread src/ai/backend/manager/services/vfolder/services/vfolder.py Outdated
Comment thread src/ai/backend/manager/services/vfolder/services/vfolder.py Outdated
Comment thread src/ai/backend/manager/services/vfolder/services/vfolder.py Outdated
fregataa added a commit that referenced this pull request Apr 16, 2026
@fregataa fregataa force-pushed the feature/BA-5737-project-vfolder-mutations branch from c8a7a42 to 14fd0ed Compare April 16, 2026 06:19
Comment thread docs/manager/graphql-reference/supergraph.graphql Outdated
@jopemachine
Copy link
Copy Markdown
Member

I remembered there was a discussion about not using VFolderV2 in GraphQL because it would interfere with the agentic workflow.

Comment thread tests/unit/manager/services/vfolder/test_vfolder_in_project_service.py Outdated
@fregataa fregataa marked this pull request as draft April 16, 2026 07:48
@fregataa fregataa force-pushed the feature/BA-5737-project-vfolder-mutations branch from e2e94f0 to 6021bea Compare April 16, 2026 08:32
@github-actions github-actions Bot added comp:client Related to Client component comp:cli Related to CLI component labels Apr 16, 2026
fregataa added a commit that referenced this pull request Apr 16, 2026
@fregataa fregataa force-pushed the feature/BA-5737-project-vfolder-mutations branch from 6021bea to 82bb6c1 Compare April 16, 2026 08:35
@fregataa fregataa requested a review from yomybaby April 16, 2026 08:37
@fregataa fregataa force-pushed the feature/BA-5737-project-vfolder-mutations branch 2 times, most recently from cb815be to eb22e8e Compare April 16, 2026 09:23
fregataa added a commit that referenced this pull request Apr 16, 2026
@fregataa fregataa force-pushed the feature/BA-5737-project-vfolder-mutations branch from 638554d to 3de71a7 Compare April 16, 2026 11:15
fregataa added a commit that referenced this pull request Apr 16, 2026
@fregataa fregataa force-pushed the feature/BA-5737-project-vfolder-mutations branch 2 times, most recently from a95a4d9 to 9e1e8e9 Compare April 16, 2026 12:31
Comment thread src/ai/backend/manager/services/vfolder/services/vfolder.py
@fregataa fregataa force-pushed the feature/BA-5737-project-vfolder-mutations branch 2 times, most recently from 5f76a19 to 2e5bb7c Compare April 16, 2026 12:59
fregataa and others added 9 commits April 22, 2026 22:17
Co-authored-by: octodog <mu001@lablup.com>
…icated input type

Introduce CreateVFolderInProjectInput (DTO + GQL) without project_id
field, since project_id is passed as a separate mutation argument
matching the existing project-scoped pattern. Resolves PR review
feedback about duplicate project_id in input and mutation args.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: octodog <mu001@lablup.com>
- Use VFolderUsageModeGQL / VFolderMountPermissionGQL enums in the
  CreateVFolderInProjectInputGQL type instead of raw `str`.
- Extract shared creation steps into private VFolderService helpers
  (_load_user, _check_user_role_for_group, _check_ownership_allowed,
  _check_name_uniqueness, _do_create_vfolder) so create_v2 and
  create_in_project compose them differently.
- Fix gaps in create_in_project that were not present in create_v2:
  missing name uniqueness check, missing allowed_vfolder_types check,
  and creator field storing `str(user_uuid)` instead of `user.email`.
- Add component RBAC denial test for POST /v2/vfolders/projects/{id}.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: octodog <mu001@lablup.com>
…pers

Add _resolve_host, _check_name_parameter, _resolve_project_info,
_check_user_vfolder_quota, _check_group_vfolder_quota,
_determine_ownership, and _check_model_store_usage_mode. Both
create_v2 and create_in_project now compose the shared pieces they
need. _determine_ownership stays exclusive to create_v2 since
create_in_project is always group-owned and intentionally skips the
legacy UserRole gate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Align with the TerminateSessionsInProjectInput precedent: the *InProject
input DTO carries project_id as a field, and the adapter takes a single
DTO (no separate project_id parameter). GQL mutation drops the standalone
projectId argument; REST handler overrides body.project_id with the URL
path segment so the URL remains authoritative.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes the _do_create_vfolder helper and the two dead-code try/excepts
it wrapped. aiohttp.ClientResponseError never escapes StorageProxyHTTPClient
(non-2xx is translated to BackendAIError subclasses before returning), and
sa_exc.DataError is unreachable given upstream Pydantic input validation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fregataa fregataa force-pushed the feature/BA-5737-project-vfolder-mutations branch from b731e45 to 35d630d Compare April 22, 2026 13:49
Promotes the ad-hoc (uuid, int, int, ProjectType) tuple returned by
VfolderRepository.get_group_resource_info into a frozen dataclass in
data/group/types.py so the type crosses the repo→service boundary
self-describing. Drops the service-local wrapper and its tuple unpacking.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fregataa fregataa requested review from seedspirit and removed request for seedspirit April 22, 2026 14:07
fregataa and others added 4 commits April 22, 2026 23:33
Renames CreateVFolderInProjectInput to scope-agnostic CreateVFolderInScopeInput
and drops its project_id field. The owning scope is now supplied by the
transport layer — a path segment for REST (/v2/vfolders/projects/{project_id}/create)
and a separate mutation argument for GraphQL (createVFolderInProject(projectId, input)).
This keeps the body reusable if other scope types (user, domain) gain their own
scoped-create endpoints later, mirrors the existing scoped-search URL pattern
/v2/{entity}/{scope_type}/{scope_id}/{action}, and makes the RBAC scope visible
at the router level for audit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds test_superadmin_succeeds and test_regular_user_with_permission_succeeds
to exercise the happy path through ScopeActionProcessor RBAC. The regular-user
case seeds a Role with PROJECT-scoped VFOLDER:CREATE and asserts the service
completes end-to-end. Fixes the stale endpoint-path docstring now that the
route carries a /create suffix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The repo mock previously returned a raw tuple; switch to a ProjectResourceInfo
instance so the tests track the new repo return type.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: octodog <mu001@lablup.com>
@fregataa fregataa requested a review from seedspirit April 22, 2026 15:27
Comment thread src/ai/backend/manager/data/group/types.py Outdated
Comment thread src/ai/backend/manager/data/group/types.py
Comment thread src/ai/backend/manager/api/adapters/vfolder.py
Align field names with the class name and type: group_uuid -> project_id,
group_type -> project_type.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fregataa fregataa requested a review from jopemachine April 23, 2026 07:32
result = await self._adapter.restore(path.parsed.vfolder_id)
return APIResponse.build(status_code=HTTPStatus.OK, response_model=result)

async def project_create(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the intent to follow the convention, but project_create keeps reading as if it creates a project itself.
Would it be better to align it as something like create_in_project?

@fregataa fregataa merged commit f78dae0 into main Apr 23, 2026
33 checks passed
@fregataa fregataa deleted the feature/BA-5737-project-vfolder-mutations branch April 23, 2026 10:37
jopemachine pushed a commit that referenced this pull request Apr 24, 2026
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: octodog <mu001@lablup.com>
seedspirit pushed a commit that referenced this pull request Apr 24, 2026
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: octodog <mu001@lablup.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:docs Documentations comp:cli Related to CLI component comp:client Related to Client component comp:common Related to Common component comp:manager Related to Manager component size:XL 500~ LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants