Skip to content

feat(BA-5829): AppConfigFragment + AppConfig GraphQL#11285

Draft
jopemachine wants to merge 13 commits intoBA-5836from
BA-5829
Draft

feat(BA-5829): AppConfigFragment + AppConfig GraphQL#11285
jopemachine wants to merge 13 commits intoBA-5836from
BA-5829

Conversation

@jopemachine
Copy link
Copy Markdown
Member

@jopemachine jopemachine commented Apr 24, 2026

📚 Stacked PRs

This PR is part of a 10-PR stack delivering BEP-1052. Merge in order:

  1. ⬇️ chore(BA-5822): drop legacy AppConfig layer (preparation for BEP-1052) #11265chore(BA-5822): drop legacy AppConfig layer
  2. ⬇️ feat(BA-5814): AppConfigPolicy foundation (data / repository / service / adapter, bulk-aware) #11266feat(BA-5814): AppConfigPolicy foundation
  3. ⬇️ feat(BA-5815): AppConfigPolicy GraphQL #11269feat(BA-5815): AppConfigPolicy GraphQL
  4. ⬇️ feat(BA-5844): AppConfigPolicy REST v2 surface #11312feat(BA-5844): AppConfigPolicy REST v2
  5. ⬇️ feat(BA-5827): AppConfigFragment foundation (DB + repository + errors) #11282feat(BA-5827): AppConfigFragment foundation
  6. ⬇️ feat(BA-5836): AppConfigFragment service vertical (service / DTO / adapter) #11296feat(BA-5836): AppConfigFragment service vertical
  7. 👉 feat(BA-5829): AppConfigFragment + AppConfig GraphQL #11285feat(BA-5829): AppConfigFragment + AppConfig GraphQL ← you are here
  8. ⬇️ feat(BA-5830): AppConfigFragment + AppConfig REST v2 #11286feat(BA-5830): AppConfigFragment + AppConfig REST v2
  9. ⬇️ feat(BA-5832): AppConfig v2 SDK + CLI (BEP-1052) #11295feat(BA-5832): AppConfig v2 SDK + CLI
  10. ⬇️ feat(BA-5837): ValkeyCache for AppConfigFragment merged-view reads #11298feat(BA-5837): ValkeyCache for AppConfigFragment merged-view reads

CI on intermediate PRs may show test churn since each one only lands a slice of the new layer. The full picture is guaranteed to build at the tip (#11298).

Summary

Wires the AppConfigFragment domain and the merged AppConfig view (BEP-1052 §2 / §5) into the GQL layer. Bulk service / adapter foundation lives in #11282; this PR adds (a) the merged-view service / adapter surface and (b) the GraphQL exposure on top.

Service / processor (additions only — bulk lands in #11282):

  • Merged-view actions: getUserAppConfig, searchUserAppConfigs, adminSearchAppConfigs
  • Service methods + processor wiring + supported_actions for the three actions

Adapter (additions only — admin bulk lands in #11282):

  • Merged-view: getUserAppConfig / myAppConfigs / adminSearchAppConfigs / publicAppConfigFragments (my_* resolves the user via current_user() inside the adapter)
  • myBulkCreate / myBulkUpdate — payloads carry AppConfigNode

DTOs (common/dto/manager/v2/app_config/, new package):

  • AppConfigNode, GetUserAppConfigInput / Payload, SearchAppConfigsInput / Payload, SearchMyAppConfigsInput
  • BulkCreate / UpdateMyAppConfigFragmentsPayload (placed here because they carry AppConfigNode)

GraphQL:

  • app_config package — AppConfigGQL + root resolvers myAppConfigs / adminAppConfigs / publicAppConfigFragments / getUserAppConfig
  • app_config_fragment package — scope-bound + admin queries; bulk-only mutations (admin + my variants); AppConfigFragmentGQL + AppConfigScopeTypeGQL + filter / order / key inputs
  • DataLoader: app_config_fragment_loader for N+1 batching
  • schema.py: registers the new root queries / mutations

Resolves BA-5829.


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


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

@github-actions github-actions Bot added size:XL 500~ LoC comp:manager Related to Manager component comp:common Related to Common component labels Apr 24, 2026
jopemachine added a commit that referenced this pull request Apr 24, 2026
jopemachine added a commit that referenced this pull request Apr 24, 2026
Mounts the Fragment adapter as REST v2 under `/v2/app-config-fragments`
(BEP-1052 §4). Shares v2 DTOs with the GraphQL surface added in
BA-5829 (#11285).

Endpoints:
- `POST /v2/app-config-fragments/get`                              — auth_required (body-carried natural key)
- `POST /v2/app-config-fragments/{scope_type}/{scope_id}/search`   — auth_required (scoped)
- `POST /v2/app-config-fragments/search`                           — superadmin_required (cross-scope)
- `POST /v2/app-config-fragments`                                  — superadmin_required (create)
- `POST /v2/app-config-fragments/update`                           — superadmin_required
- `POST /v2/app-config-fragments/purge`                            — superadmin_required

Scoped search uses the project's `{scope_type}/{scope_id}` nested
URL convention; `get` takes the three-part natural key via the body
since a three-field path segment is noisier than a body DTO.

Adds:
- `api/rest/v2/app_config_fragment/handler.V2AppConfigFragmentHandler`
  + `registry.register_v2_app_config_fragment_routes`.
- `AppConfigFragmentScopePathParam` in the shared path-params module.
- Handler instantiation + sub-registry wiring in `rest/v2/tree.py`.

The scope handler converts the DTO `AppConfigScopeType` to the
data-layer enum so the adapter signature stays data-typed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread src/ai/backend/manager/api/adapters/app_config_fragment.py Outdated
jopemachine added a commit that referenced this pull request Apr 24, 2026
Mounts the Fragment adapter as REST v2 under `/v2/app-config-fragments`
(BEP-1052 §4). Shares v2 DTOs with the GraphQL surface added in
BA-5829 (#11285).

Endpoints:
- `POST /v2/app-config-fragments/get`                              — auth_required (body-carried natural key)
- `POST /v2/app-config-fragments/{scope_type}/{scope_id}/search`   — auth_required (scoped)
- `POST /v2/app-config-fragments/search`                           — superadmin_required (cross-scope)
- `POST /v2/app-config-fragments`                                  — superadmin_required (create)
- `POST /v2/app-config-fragments/update`                           — superadmin_required
- `POST /v2/app-config-fragments/purge`                            — superadmin_required

Scoped search uses the project's `{scope_type}/{scope_id}` nested
URL convention; `get` takes the three-part natural key via the body
since a three-field path segment is noisier than a body DTO.

Adds:
- `api/rest/v2/app_config_fragment/handler.V2AppConfigFragmentHandler`
  + `registry.register_v2_app_config_fragment_routes`.
- `AppConfigFragmentScopePathParam` in the shared path-params module.
- Handler instantiation + sub-registry wiring in `rest/v2/tree.py`.

The scope handler converts the DTO `AppConfigScopeType` to the
data-layer enum so the adapter signature stays data-typed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jopemachine added a commit that referenced this pull request Apr 24, 2026
…052 §5)

Mounts the merged-view `AppConfig` surface as REST v2 under
`/v2/app-configs/...`. Shares v2 DTOs and the adapter with the
GraphQL layer added in BA-5829 (#11285). Handler reuses the Fragment
adapter because the merged-view methods live on
`AppConfigFragmentAdapter`.

Endpoints:
- `GET  /v2/app-configs/my/{name}`          — auth (self-service single)
- `POST /v2/app-configs/my/search`          — auth (self-service paginated)
- `POST /v2/app-configs/search`             — superadmin (cross-user)
- `GET  /v2/app-configs/{user_id}/{name}`   — superadmin (read one user's view)

Adds:
- `api/rest/v2/app_config/handler.V2AppConfigHandler` with `my_get` /
  `my_search` / `admin_get` / `admin_search`.
- `api/rest/v2/app_config/registry.register_v2_app_config_routes`.
- `AppConfigMyNamePathParam` + `AppConfigUserNamePathParam` in the
  shared path-params module.
- Handler instantiation + sub-registry wiring in `rest/v2/tree.py`
  (handler takes `adapters.app_config_fragment` — annotated for the
  reviewer).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jopemachine added a commit that referenced this pull request Apr 24, 2026
Mounts the Fragment adapter as REST v2 under `/v2/app-config-fragments`
(BEP-1052 §4). Shares v2 DTOs with the GraphQL surface added in
BA-5829 (#11285).

Endpoints:
- `POST /v2/app-config-fragments/get`                              — auth_required (body-carried natural key)
- `POST /v2/app-config-fragments/{scope_type}/{scope_id}/search`   — auth_required (scoped)
- `POST /v2/app-config-fragments/search`                           — superadmin_required (cross-scope)
- `POST /v2/app-config-fragments`                                  — superadmin_required (create)
- `POST /v2/app-config-fragments/update`                           — superadmin_required
- `POST /v2/app-config-fragments/purge`                            — superadmin_required

Scoped search uses the project's `{scope_type}/{scope_id}` nested
URL convention; `get` takes the three-part natural key via the body
since a three-field path segment is noisier than a body DTO.

Adds:
- `api/rest/v2/app_config_fragment/handler.V2AppConfigFragmentHandler`
  + `registry.register_v2_app_config_fragment_routes`.
- `AppConfigFragmentScopePathParam` in the shared path-params module.
- Handler instantiation + sub-registry wiring in `rest/v2/tree.py`.

The scope handler converts the DTO `AppConfigScopeType` to the
data-layer enum so the adapter signature stays data-typed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jopemachine added a commit that referenced this pull request Apr 24, 2026
…052 §5)

Mounts the merged-view `AppConfig` surface as REST v2 under
`/v2/app-configs/...`. Shares v2 DTOs and the adapter with the
GraphQL layer added in BA-5829 (#11285). Handler reuses the Fragment
adapter because the merged-view methods live on
`AppConfigFragmentAdapter`.

Endpoints:
- `GET  /v2/app-configs/my/{name}`          — auth (self-service single)
- `POST /v2/app-configs/my/search`          — auth (self-service paginated)
- `POST /v2/app-configs/search`             — superadmin (cross-user)
- `GET  /v2/app-configs/{user_id}/{name}`   — superadmin (read one user's view)

Adds:
- `api/rest/v2/app_config/handler.V2AppConfigHandler` with `my_get` /
  `my_search` / `admin_get` / `admin_search`.
- `api/rest/v2/app_config/registry.register_v2_app_config_routes`.
- `AppConfigMyNamePathParam` + `AppConfigUserNamePathParam` in the
  shared path-params module.
- Handler instantiation + sub-registry wiring in `rest/v2/tree.py`
  (handler takes `adapters.app_config_fragment` — annotated for the
  reviewer).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jopemachine added a commit that referenced this pull request Apr 24, 2026
…P-1052 §3)

Replaces the single-item `create` / `update` / `purge` endpoints with
bulk equivalents per BEP-1052 §3 (all writes are bulk; pass a
one-element array for a single write).

New REST routes on `/v2/app-config-fragments/`:
- `POST /bulk-create`        — superadmin (admin, any scope)
- `POST /bulk-update`        — superadmin
- `POST /bulk-purge`         — superadmin
- `POST /my/bulk-create`     — auth (USER scope, current_user)
- `POST /my/bulk-update`     — auth (USER scope, current_user)

Removed: `POST /`, `POST /update`, `POST /purge` — replaced by the
bulk variants above. Reads are unchanged (`POST /get`,
`POST /{scope_type}/{scope_id}/search`, `POST /search`).

Handler methods updated to accept the v2 Bulk* DTOs added in
BA-5829 (#11285) and return the Bulk*Payload DTOs. `my_bulk_*`
resolves the caller via the adapter's `current_user()` call so the
REST handler itself stays auth-agnostic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jopemachine added a commit that referenced this pull request Apr 25, 2026
jopemachine added a commit that referenced this pull request Apr 25, 2026
Mounts the Fragment adapter as REST v2 under `/v2/app-config-fragments`
(BEP-1052 §4). Shares v2 DTOs with the GraphQL surface added in
BA-5829 (#11285).

Endpoints:
- `POST /v2/app-config-fragments/get`                              — auth_required (body-carried natural key)
- `POST /v2/app-config-fragments/{scope_type}/{scope_id}/search`   — auth_required (scoped)
- `POST /v2/app-config-fragments/search`                           — superadmin_required (cross-scope)
- `POST /v2/app-config-fragments`                                  — superadmin_required (create)
- `POST /v2/app-config-fragments/update`                           — superadmin_required
- `POST /v2/app-config-fragments/purge`                            — superadmin_required

Scoped search uses the project's `{scope_type}/{scope_id}` nested
URL convention; `get` takes the three-part natural key via the body
since a three-field path segment is noisier than a body DTO.

Adds:
- `api/rest/v2/app_config_fragment/handler.V2AppConfigFragmentHandler`
  + `registry.register_v2_app_config_fragment_routes`.
- `AppConfigFragmentScopePathParam` in the shared path-params module.
- Handler instantiation + sub-registry wiring in `rest/v2/tree.py`.

The scope handler converts the DTO `AppConfigScopeType` to the
data-layer enum so the adapter signature stays data-typed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jopemachine added a commit that referenced this pull request Apr 25, 2026
…052 §5)

Mounts the merged-view `AppConfig` surface as REST v2 under
`/v2/app-configs/...`. Shares v2 DTOs and the adapter with the
GraphQL layer added in BA-5829 (#11285). Handler reuses the Fragment
adapter because the merged-view methods live on
`AppConfigFragmentAdapter`.

Endpoints:
- `GET  /v2/app-configs/my/{name}`          — auth (self-service single)
- `POST /v2/app-configs/my/search`          — auth (self-service paginated)
- `POST /v2/app-configs/search`             — superadmin (cross-user)
- `GET  /v2/app-configs/{user_id}/{name}`   — superadmin (read one user's view)

Adds:
- `api/rest/v2/app_config/handler.V2AppConfigHandler` with `my_get` /
  `my_search` / `admin_get` / `admin_search`.
- `api/rest/v2/app_config/registry.register_v2_app_config_routes`.
- `AppConfigMyNamePathParam` + `AppConfigUserNamePathParam` in the
  shared path-params module.
- Handler instantiation + sub-registry wiring in `rest/v2/tree.py`
  (handler takes `adapters.app_config_fragment` — annotated for the
  reviewer).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jopemachine added a commit that referenced this pull request Apr 25, 2026
…P-1052 §3)

Replaces the single-item `create` / `update` / `purge` endpoints with
bulk equivalents per BEP-1052 §3 (all writes are bulk; pass a
one-element array for a single write).

New REST routes on `/v2/app-config-fragments/`:
- `POST /bulk-create`        — superadmin (admin, any scope)
- `POST /bulk-update`        — superadmin
- `POST /bulk-purge`         — superadmin
- `POST /my/bulk-create`     — auth (USER scope, current_user)
- `POST /my/bulk-update`     — auth (USER scope, current_user)

Removed: `POST /`, `POST /update`, `POST /purge` — replaced by the
bulk variants above. Reads are unchanged (`POST /get`,
`POST /{scope_type}/{scope_id}/search`, `POST /search`).

Handler methods updated to accept the v2 Bulk* DTOs added in
BA-5829 (#11285) and return the Bulk*Payload DTOs. `my_bulk_*`
resolves the caller via the adapter's `current_user()` call so the
REST handler itself stays auth-agnostic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jopemachine added a commit that referenced this pull request Apr 25, 2026
@jopemachine jopemachine changed the title feat(BA-5829): AppConfigFragment Strawberry GraphQL (queries + mutations) feat(BA-5829): AppConfigFragment + AppConfig GraphQL Apr 25, 2026
jopemachine added a commit that referenced this pull request Apr 25, 2026
@github-actions github-actions Bot added the area:docs Documentations label Apr 25, 2026
jopemachine added a commit that referenced this pull request Apr 25, 2026
jopemachine added a commit that referenced this pull request Apr 25, 2026
…drop scoped GQL root

Per review on PR #11285:

- Split the merged-view (AppConfig, BEP-1052 §5) surface and the
  self-service `my_bulk_*` writes out of `AppConfigFragmentAdapter`
  into a new `AppConfigAdapter`. Each adapter now handles a single
  domain DTO surface, matching the project convention. Both adapters
  share the same `app_config_fragment` service processors —
  splitting only the transport layer.
- Drop the `scoped_app_config_fragments` GQL root resolver. BEP-1052
  exposes the scope-bound list as child fields on
  `DomainV2.appConfigFragments` / `UserV2.appConfigFragments`, not as
  a root field. The scope-bound REST endpoint
  `POST /v2/app-config-fragments/{scope_type}/{scope_id}/search`
  continues to use `AppConfigFragmentAdapter.search()` directly.
- Update the GQL resolvers (`my_app_configs`, `admin_app_configs`,
  `bulk_create_my_app_config_fragments`,
  `bulk_update_my_app_config_fragments`) to call the new
  `info.context.adapters.app_config` adapter.
- Wire the new `app_config` field through `Adapters.__init__` and
  `Adapters.create()`.
- DataLoader now uses `AppConfigFragmentFilter(id=UUIDFilter(...))`
  per the new filter shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jopemachine added a commit that referenced this pull request Apr 25, 2026
… import

Per #11285 review:

- Strip the BEP-1052 §X annotations from descriptions, comments, and
  docstrings — the BEP number doesn't help future readers and clutters
  the schema.
- Move `BulkCreate/UpdateMyAppConfigFragmentsPayloadGQL` from
  `app_config_fragment/types/bulk_payloads.py` into
  `app_config/types/bulk_payloads.py`. They referenced `AppConfigGQL`
  while `AppConfigGQL` already references `AppConfigFragmentGQL`, so
  splitting them keeps the import direction one-way and resolves the
  `tests/component/user/test_keypair_ops.py` collection error reported
  by `test-component`.
- Drop unused `# type: ignore[misc]` on `gql_mutation` decorators
  (the helper preserves the wrapped function's signature, so mypy no
  longer treats the result as untyped).
Comment thread src/ai/backend/common/dto/manager/v2/app_config/request.py
Comment thread src/ai/backend/manager/api/gql/app_config_fragment/types/filters.py
jopemachine added a commit that referenced this pull request Apr 26, 2026
jopemachine added a commit that referenced this pull request Apr 26, 2026
…drop scoped GQL root

Per review on PR #11285:

- Split the merged-view (AppConfig, BEP-1052 §5) surface and the
  self-service `my_bulk_*` writes out of `AppConfigFragmentAdapter`
  into a new `AppConfigAdapter`. Each adapter now handles a single
  domain DTO surface, matching the project convention. Both adapters
  share the same `app_config_fragment` service processors —
  splitting only the transport layer.
- Drop the `scoped_app_config_fragments` GQL root resolver. BEP-1052
  exposes the scope-bound list as child fields on
  `DomainV2.appConfigFragments` / `UserV2.appConfigFragments`, not as
  a root field. The scope-bound REST endpoint
  `POST /v2/app-config-fragments/{scope_type}/{scope_id}/search`
  continues to use `AppConfigFragmentAdapter.search()` directly.
- Update the GQL resolvers (`my_app_configs`, `admin_app_configs`,
  `bulk_create_my_app_config_fragments`,
  `bulk_update_my_app_config_fragments`) to call the new
  `info.context.adapters.app_config` adapter.
- Wire the new `app_config` field through `Adapters.__init__` and
  `Adapters.create()`.
- DataLoader now uses `AppConfigFragmentFilter(id=UUIDFilter(...))`
  per the new filter shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jopemachine added a commit that referenced this pull request Apr 26, 2026
… import

Per #11285 review:

- Strip the BEP-1052 §X annotations from descriptions, comments, and
  docstrings — the BEP number doesn't help future readers and clutters
  the schema.
- Move `BulkCreate/UpdateMyAppConfigFragmentsPayloadGQL` from
  `app_config_fragment/types/bulk_payloads.py` into
  `app_config/types/bulk_payloads.py`. They referenced `AppConfigGQL`
  while `AppConfigGQL` already references `AppConfigFragmentGQL`, so
  splitting them keeps the import direction one-way and resolves the
  `tests/component/user/test_keypair_ops.py` collection error reported
  by `test-component`.
- Drop unused `# type: ignore[misc]` on `gql_mutation` decorators
  (the helper preserves the wrapped function's signature, so mypy no
  longer treats the result as untyped).
jopemachine added a commit that referenced this pull request Apr 26, 2026
…drop scoped GQL root

Per review on PR #11285:

- Split the merged-view (AppConfig, BEP-1052 §5) surface and the
  self-service `my_bulk_*` writes out of `AppConfigFragmentAdapter`
  into a new `AppConfigAdapter`. Each adapter now handles a single
  domain DTO surface, matching the project convention. Both adapters
  share the same `app_config_fragment` service processors —
  splitting only the transport layer.
- Drop the `scoped_app_config_fragments` GQL root resolver. BEP-1052
  exposes the scope-bound list as child fields on
  `DomainV2.appConfigFragments` / `UserV2.appConfigFragments`, not as
  a root field. The scope-bound REST endpoint
  `POST /v2/app-config-fragments/{scope_type}/{scope_id}/search`
  continues to use `AppConfigFragmentAdapter.search()` directly.
- Update the GQL resolvers (`my_app_configs`, `admin_app_configs`,
  `bulk_create_my_app_config_fragments`,
  `bulk_update_my_app_config_fragments`) to call the new
  `info.context.adapters.app_config` adapter.
- Wire the new `app_config` field through `Adapters.__init__` and
  `Adapters.create()`.
- DataLoader now uses `AppConfigFragmentFilter(id=UUIDFilter(...))`
  per the new filter shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jopemachine and others added 13 commits April 27, 2026 11:40
Adds the GraphQL exposure for AppConfigFragment and the merged
AppConfig view (BEP-1052 §2 / §5).

Service / processor additions (only what the GQL layer needs that is
not already in BA-5827):
- Merged-view actions: get_user_app_config, search_user_app_configs,
  admin_search_app_configs (single-row + paginated reads of the
  computed AppConfig view).
- Service methods + processor wiring + supported_actions for those
  three actions.

Adapter additions:
- Merged-view methods: get_user_app_config / my_app_configs /
  admin_search_app_configs / public_app_config_fragments. `my_*`
  pulls the user from current_user() inside the adapter.
- Bulk-only `my` mutations: my_bulk_create / my_bulk_update —
  bulk admin variants are wired in BA-5827 already.

DTO additions:
- common/dto/manager/v2/app_config/* — AppConfigNode,
  GetUserAppConfigInput / Payload, SearchAppConfigsInput / Payload,
  SearchMyAppConfigsInput, BulkCreate/UpdateMyAppConfigFragmentsPayload
  (the my-bulk payloads live here because they carry AppConfigNode).

GraphQL:
- app_config package: AppConfigGQL, my/admin/public root resolvers.
- app_config_fragment package: scope-bound + admin queries, bulk-only
  mutations (admin + my variants), AppConfigFragmentGQL +
  AppConfigScopeTypeGQL + filter/order/key inputs.
- DataLoader: app_config_fragment_loader for N+1 batching.
- schema.py: register the new root queries / mutations.

Resolves BA-5829.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…drop scoped GQL root

Per review on PR #11285:

- Split the merged-view (AppConfig, BEP-1052 §5) surface and the
  self-service `my_bulk_*` writes out of `AppConfigFragmentAdapter`
  into a new `AppConfigAdapter`. Each adapter now handles a single
  domain DTO surface, matching the project convention. Both adapters
  share the same `app_config_fragment` service processors —
  splitting only the transport layer.
- Drop the `scoped_app_config_fragments` GQL root resolver. BEP-1052
  exposes the scope-bound list as child fields on
  `DomainV2.appConfigFragments` / `UserV2.appConfigFragments`, not as
  a root field. The scope-bound REST endpoint
  `POST /v2/app-config-fragments/{scope_type}/{scope_id}/search`
  continues to use `AppConfigFragmentAdapter.search()` directly.
- Update the GQL resolvers (`my_app_configs`, `admin_app_configs`,
  `bulk_create_my_app_config_fragments`,
  `bulk_update_my_app_config_fragments`) to call the new
  `info.context.adapters.app_config` adapter.
- Wire the new `app_config` field through `Adapters.__init__` and
  `Adapters.create()`.
- DataLoader now uses `AppConfigFragmentFilter(id=UUIDFilter(...))`
  per the new filter shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… import

Per #11285 review:

- Strip the BEP-1052 §X annotations from descriptions, comments, and
  docstrings — the BEP number doesn't help future readers and clutters
  the schema.
- Move `BulkCreate/UpdateMyAppConfigFragmentsPayloadGQL` from
  `app_config_fragment/types/bulk_payloads.py` into
  `app_config/types/bulk_payloads.py`. They referenced `AppConfigGQL`
  while `AppConfigGQL` already references `AppConfigFragmentGQL`, so
  splitting them keeps the import direction one-way and resolves the
  `tests/component/user/test_keypair_ops.py` collection error reported
  by `test-component`.
- Drop unused `# type: ignore[misc]` on `gql_mutation` decorators
  (the helper preserves the wrapped function's signature, so mypy no
  longer treats the result as untyped).
`app_config/types/node.py` imports `AppConfigFragmentGQL` (AppConfig's
`fragments` field), which loads `app_config_fragment/__init__.py`.
That used to eagerly re-export the mutation resolvers, which then
imported back from `app_config.types.bulk_payloads` -> `node` (still
mid-load) -> ImportError.

Three small surgeries break the cycle:

- `app_config_fragment/__init__.py` no longer re-exports its resolver
  symbols; `schema.py` now imports them straight from the resolver
  submodules.
- `app_config/types/__init__.py` no longer re-exports the My-bulk
  payload GQL types, so loading the package no longer drags in
  `bulk_payloads.py` before `node.py` finishes.
- `mutation.py` imports the My-bulk payload types from the
  `bulk_payloads` submodule directly.

`tests/component/user/test_keypair_ops.py` collection (and the
`api-updated` schema-dump step) used to fail because of this cycle.
Strawberry's schema builder can't resolve `dict[str, Any]` to a GraphQL
output/input type and fails the manager startup with `AppConfigFragment
fields cannot be resolved. Unexpected type 'dict[str, typing.Any]'`.
Switch the three opaque payload fields (`AppConfigGQL.config`,
`AppConfigFragmentGQL.extra_config`, and the bulk-input
`extra_config`) to `strawberry.scalars.JSON`, matching how
`service_catalog`, `agent`, `deployment`, and `notification` already
expose JSON-shaped fields.
`gql_enum(...)` returns a wrapped enum class, which Strawberry registers
under `"AppConfigScopeType"`. Other GQL modules use the bare DTO enum as
a field annotation, and Strawberry auto-registers that under the same
name on first encounter — failing the schema build with `Type
AppConfigScopeType is defined multiple times`.

Drop the explicit registration and let Strawberry auto-register from
field references; re-export the GQL alias as a plain rebind so existing
`AppConfigScopeTypeGQL` imports keep working.
The Fragment + AppConfig GraphQL types added in this PR were never
reflected in the committed dump — the live manager schema and the
docs were out of sync. Re-running `dump-gql-schema` +
`generate-supergraph` from this branch lands the new types
(`AppConfigFragment`, `AppConfig`, `myAppConfigs`,
`adminBulkCreate/Update/PurgeAppConfigFragments`, etc.) in the same
PR that introduces them on the Python side.
…mp filters/orders

- Propagate the `bulk_create_my` / `bulk_update_my` → `my_bulk_create`
  / `my_bulk_update` rename through the merged-view adapter, GQL
  resolvers, GQL types, and DTOs (now `MyBulkCreate*` / `MyBulkUpdate*`
  consistently).
- Add `created_at` / `updated_at` filter fields to `AppConfigFilter`
  and corresponding `CREATED_AT` / `UPDATED_AT` enum values to
  `AppConfigOrderField` so callers can filter / order merged AppConfigs
  on timestamp boundaries.
- Add `UPDATED_AT` to `AppConfigFragmentOrderFieldGQL` (paired with the
  existing DTO enum).
- Refresh the GraphQL schema dump (v2 + supergraph) to match.

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

Carry the BA-5827 column rename through:
- AppConfigFragment GQL Node and bulk-input field names
- AppConfigAdapter merged-view + my_bulk pass-through
- The GraphQL schema dump (v2 + supergraph)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pulls in id-keyed Policy GQL surface (AdminAppConfigPolicyCreateItemInput
/ AdminAppConfigPolicyUpdateItemInput / purgedIds) propagated from
PR #11269.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:docs Documentations 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.

1 participant