chore(BA-5822): drop legacy AppConfig layer (preparation for BEP-1052)#11265
Draft
jopemachine wants to merge 7 commits intomainfrom
Draft
chore(BA-5822): drop legacy AppConfig layer (preparation for BEP-1052)#11265jopemachine wants to merge 7 commits intomainfrom
jopemachine wants to merge 7 commits intomainfrom
Conversation
This was referenced Apr 24, 2026
Removes the existing AppConfig data / repository / service / GQL / REST layer and the underlying `app_configs` table. The replacement (`app_config_fragments` + `app_config_policies`) lands on top in the next stacked PR — the new shape is incompatible with the old (different scope enum, different unique key) so no in-place data migration is attempted. - Migration: DROP TABLE app_configs + DROP TYPE app_config_scope_type; downgrade recreates the predecessor table without data. - Delete models/, data/, repositories/, services/, api/gql/app_config.py, api/rest/v2/app_config/, api/adapters/app_config.py, and the matching unit tests. - Update wiring: remove app_config from services factory/processors, repositories container, adapters registry, and the REST v2 tree. - Drop 11 GQL fields/mutations from schema.py and the AppConfig union member from EntityNode. EntityType.APP_CONFIG / RBACElementType.APP_CONFIG enum entries are left in place — DB rows may still reference the literal value, so they will be cleaned up separately when the new RBAC integration lands. Resolves BA-5822.
Co-authored-by: octodog <mu001@lablup.com>
Resolves BA-5822.
…n head origin/main has progressed past ad7acfe8aa1c since this migration landed; chain `84d5c6daf8cc` after the current main head `ce69b746304e` so the alembic chain stays linear (single head). No schema change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends the legacy-AppConfig drop to the client side: - `client/v2/domains_v2/app_config.py` — `V2AppConfigClient` with `upsert_domain_config` / `delete_user_config` / etc. is removed alongside its `v2_registry` `@cached_property` wiring. - `client/cli/v2/app_config/` — legacy `./bai app-config get-domain`, `upsert-user`, etc. are removed from the CLI tree. - `common/dto/manager/v2/app_config/` — legacy DTO module (`UpsertDomainConfigInput`, `DeleteUserConfigPayload`, ...) is deleted. Per #11295 review: BEP-1052's new SDK / CLI / DTO surfaces will land in their own PRs and should not also have to repeal the legacy versions there.
jopemachine
added a commit
that referenced
this pull request
Apr 25, 2026
…ew reads Re-introduces a Valkey-backed cache layer for the merged AppConfig view, replacing the cache source that was dropped together with the legacy `app_configs` table in #11265 (BA-5822). The hot path — `AppConfigFragmentRepository.app_config(user_id, name)` — is the WebUI bootstrap loop (BEP-1052 §6) and was previously a DB hit per request. Mirrors the legacy `AppConfigCacheSource` shape on top of the `(user, name)`-keyed merged view: - `cache_source/cache_source.py`: - `get_merged_config(user_id, name)` cache-aside read keyed by `app_config:merged:{user_id}:{name}` - `set_merged_config(merged, domain_name=...)` writes the deep-merged payload + indexes the cache key in `app_config:user_keys:{user_id}` and the user in `app_config:domain_users:{domain_name}` so invalidation runs without `SCAN` - `invalidate_for_scope(scope_type, scope_id)`: - `USER`: drop the user's per-name set - `DOMAIN` / `DOMAIN_USER_DEFAULTS`: cascade through every member of the domain user set - `PUBLIC`: rely on TTL (broad invalidation TBD) - `invalidate_for_user(user_id)` convenience for self-service writes - `db_source.user_domain_name(user_id)` single-column lookup so the cache layer can tag merged-view entries with their owning domain - `AppConfigFragmentRepository.app_config(...)` is now cache-aside (cache hit returns the cached payload + fresh DB fragments; cache miss writes through) - `AppConfigFragmentAdminRepository.{create,update,purge}` invalidate the affected scope after the DB write - `repositories.py` builds the cache source from `args.valkey_stat_client` and threads it into both repos - All cache calls pass through `suppress_with_log` — cache failures log a warning and fall through to the DB
jopemachine
added a commit
that referenced
this pull request
Apr 25, 2026
…ew reads Re-introduces a Valkey-backed cache layer for the merged AppConfig view, replacing the cache source that was dropped together with the legacy `app_configs` table in #11265 (BA-5822). The hot path — `AppConfigFragmentRepository.app_config(user_id, name)` — is the WebUI bootstrap loop (BEP-1052 §6) and was previously a DB hit per request. Mirrors the legacy `AppConfigCacheSource` shape on top of the `(user, name)`-keyed merged view: - `cache_source/cache_source.py`: - `get_merged_config(user_id, name)` cache-aside read keyed by `app_config:merged:{user_id}:{name}` - `set_merged_config(merged, domain_name=...)` writes the deep-merged payload + indexes the cache key in `app_config:user_keys:{user_id}` and the user in `app_config:domain_users:{domain_name}` so invalidation runs without `SCAN` - `invalidate_for_scope(scope_type, scope_id)`: - `USER`: drop the user's per-name set - `DOMAIN` / `DOMAIN_USER_DEFAULTS`: cascade through every member of the domain user set - `PUBLIC`: rely on TTL (broad invalidation TBD) - `invalidate_for_user(user_id)` convenience for self-service writes - `db_source.user_domain_name(user_id)` single-column lookup so the cache layer can tag merged-view entries with their owning domain - `AppConfigFragmentRepository.app_config(...)` is now cache-aside (cache hit returns the cached payload + fresh DB fragments; cache miss writes through) - `AppConfigFragmentAdminRepository.{create,update,purge}` invalidate the affected scope after the DB write - `repositories.py` builds the cache source from `args.valkey_stat_client` and threads it into both repos - All cache calls pass through `suppress_with_log` — cache failures log a warning and fall through to the DB
jopemachine
added a commit
that referenced
this pull request
Apr 25, 2026
…ew reads Re-introduces a Valkey-backed cache layer for the merged AppConfig view, replacing the cache source that was dropped together with the legacy `app_configs` table in #11265 (BA-5822). The hot path — `AppConfigFragmentRepository.app_config(user_id, name)` — is the WebUI bootstrap loop (BEP-1052 §6) and was previously a DB hit per request. Mirrors the legacy `AppConfigCacheSource` shape on top of the `(user, name)`-keyed merged view: - `cache_source/cache_source.py`: - `get_merged_config(user_id, name)` cache-aside read keyed by `app_config:merged:{user_id}:{name}` - `set_merged_config(merged, domain_name=...)` writes the deep-merged payload + indexes the cache key in `app_config:user_keys:{user_id}` and the user in `app_config:domain_users:{domain_name}` so invalidation runs without `SCAN` - `invalidate_for_scope(scope_type, scope_id)`: - `USER`: drop the user's per-name set - `DOMAIN` / `DOMAIN_USER_DEFAULTS`: cascade through every member of the domain user set - `PUBLIC`: rely on TTL (broad invalidation TBD) - `invalidate_for_user(user_id)` convenience for self-service writes - `db_source.user_domain_name(user_id)` single-column lookup so the cache layer can tag merged-view entries with their owning domain - `AppConfigFragmentRepository.app_config(...)` is now cache-aside (cache hit returns the cached payload + fresh DB fragments; cache miss writes through) - `AppConfigFragmentAdminRepository.{create,update,purge}` invalidate the affected scope after the DB write - `repositories.py` builds the cache source from `args.valkey_stat_client` and threads it into both repos - All cache calls pass through `suppress_with_log` — cache failures log a warning and fall through to the DB
jopemachine
added a commit
that referenced
this pull request
Apr 26, 2026
…ew reads Re-introduces a Valkey-backed cache layer for the merged AppConfig view, replacing the cache source that was dropped together with the legacy `app_configs` table in #11265 (BA-5822). The hot path — `AppConfigFragmentRepository.app_config(user_id, name)` — is the WebUI bootstrap loop (BEP-1052 §6) and was previously a DB hit per request. Mirrors the legacy `AppConfigCacheSource` shape on top of the `(user, name)`-keyed merged view: - `cache_source/cache_source.py`: - `get_merged_config(user_id, name)` cache-aside read keyed by `app_config:merged:{user_id}:{name}` - `set_merged_config(merged, domain_name=...)` writes the deep-merged payload + indexes the cache key in `app_config:user_keys:{user_id}` and the user in `app_config:domain_users:{domain_name}` so invalidation runs without `SCAN` - `invalidate_for_scope(scope_type, scope_id)`: - `USER`: drop the user's per-name set - `DOMAIN` / `DOMAIN_USER_DEFAULTS`: cascade through every member of the domain user set - `PUBLIC`: rely on TTL (broad invalidation TBD) - `invalidate_for_user(user_id)` convenience for self-service writes - `db_source.user_domain_name(user_id)` single-column lookup so the cache layer can tag merged-view entries with their owning domain - `AppConfigFragmentRepository.app_config(...)` is now cache-aside (cache hit returns the cached payload + fresh DB fragments; cache miss writes through) - `AppConfigFragmentAdminRepository.{create,update,purge}` invalidate the affected scope after the DB write - `repositories.py` builds the cache source from `args.valkey_stat_client` and threads it into both repos - All cache calls pass through `suppress_with_log` — cache failures log a warning and fall through to the DB
jopemachine
added a commit
that referenced
this pull request
Apr 26, 2026
…ew reads Re-introduces a Valkey-backed cache layer for the merged AppConfig view, replacing the cache source that was dropped together with the legacy `app_configs` table in #11265 (BA-5822). The hot path — `AppConfigFragmentRepository.app_config(user_id, name)` — is the WebUI bootstrap loop (BEP-1052 §6) and was previously a DB hit per request. Mirrors the legacy `AppConfigCacheSource` shape on top of the `(user, name)`-keyed merged view: - `cache_source/cache_source.py`: - `get_merged_config(user_id, name)` cache-aside read keyed by `app_config:merged:{user_id}:{name}` - `set_merged_config(merged, domain_name=...)` writes the deep-merged payload + indexes the cache key in `app_config:user_keys:{user_id}` and the user in `app_config:domain_users:{domain_name}` so invalidation runs without `SCAN` - `invalidate_for_scope(scope_type, scope_id)`: - `USER`: drop the user's per-name set - `DOMAIN` / `DOMAIN_USER_DEFAULTS`: cascade through every member of the domain user set - `PUBLIC`: rely on TTL (broad invalidation TBD) - `invalidate_for_user(user_id)` convenience for self-service writes - `db_source.user_domain_name(user_id)` single-column lookup so the cache layer can tag merged-view entries with their owning domain - `AppConfigFragmentRepository.app_config(...)` is now cache-aside (cache hit returns the cached payload + fresh DB fragments; cache miss writes through) - `AppConfigFragmentAdminRepository.{create,update,purge}` invalidate the affected scope after the DB write - `repositories.py` builds the cache source from `args.valkey_stat_client` and threads it into both repos - All cache calls pass through `suppress_with_log` — cache failures log a warning and fall through to the DB
jopemachine
added a commit
that referenced
this pull request
Apr 26, 2026
…ew reads Re-introduces a Valkey-backed cache layer for the merged AppConfig view, replacing the cache source that was dropped together with the legacy `app_configs` table in #11265 (BA-5822). The hot path — `AppConfigFragmentRepository.app_config(user_id, name)` — is the WebUI bootstrap loop (BEP-1052 §6) and was previously a DB hit per request. Mirrors the legacy `AppConfigCacheSource` shape on top of the `(user, name)`-keyed merged view: - `cache_source/cache_source.py`: - `get_merged_config(user_id, name)` cache-aside read keyed by `app_config:merged:{user_id}:{name}` - `set_merged_config(merged, domain_name=...)` writes the deep-merged payload + indexes the cache key in `app_config:user_keys:{user_id}` and the user in `app_config:domain_users:{domain_name}` so invalidation runs without `SCAN` - `invalidate_for_scope(scope_type, scope_id)`: - `USER`: drop the user's per-name set - `DOMAIN` / `DOMAIN_USER_DEFAULTS`: cascade through every member of the domain user set - `PUBLIC`: rely on TTL (broad invalidation TBD) - `invalidate_for_user(user_id)` convenience for self-service writes - `db_source.user_domain_name(user_id)` single-column lookup so the cache layer can tag merged-view entries with their owning domain - `AppConfigFragmentRepository.app_config(...)` is now cache-aside (cache hit returns the cached payload + fresh DB fragments; cache miss writes through) - `AppConfigFragmentAdminRepository.{create,update,purge}` invalidate the affected scope after the DB write - `repositories.py` builds the cache source from `args.valkey_stat_client` and threads it into both repos - All cache calls pass through `suppress_with_log` — cache failures log a warning and fall through to the DB
3 tasks
jopemachine
added a commit
that referenced
this pull request
Apr 26, 2026
…ew reads Re-introduces a Valkey-backed cache layer for the merged AppConfig view, replacing the cache source that was dropped together with the legacy `app_configs` table in #11265 (BA-5822). The hot path — `AppConfigFragmentRepository.app_config(user_id, name)` — is the WebUI bootstrap loop (BEP-1052 §6) and was previously a DB hit per request. Mirrors the legacy `AppConfigCacheSource` shape on top of the `(user, name)`-keyed merged view: - `cache_source/cache_source.py`: - `get_merged_config(user_id, name)` cache-aside read keyed by `app_config:merged:{user_id}:{name}` - `set_merged_config(merged, domain_name=...)` writes the deep-merged payload + indexes the cache key in `app_config:user_keys:{user_id}` and the user in `app_config:domain_users:{domain_name}` so invalidation runs without `SCAN` - `invalidate_for_scope(scope_type, scope_id)`: - `USER`: drop the user's per-name set - `DOMAIN` / `DOMAIN_USER_DEFAULTS`: cascade through every member of the domain user set - `PUBLIC`: rely on TTL (broad invalidation TBD) - `invalidate_for_user(user_id)` convenience for self-service writes - `db_source.user_domain_name(user_id)` single-column lookup so the cache layer can tag merged-view entries with their owning domain - `AppConfigFragmentRepository.app_config(...)` is now cache-aside (cache hit returns the cached payload + fresh DB fragments; cache miss writes through) - `AppConfigFragmentAdminRepository.{create,update,purge}` invalidate the affected scope after the DB write - `repositories.py` builds the cache source from `args.valkey_stat_client` and threads it into both repos - All cache calls pass through `suppress_with_log` — cache failures log a warning and fall through to the DB
jopemachine
added a commit
that referenced
this pull request
Apr 27, 2026
…ew reads Re-introduces a Valkey-backed cache layer for the merged AppConfig view, replacing the cache source that was dropped together with the legacy `app_configs` table in #11265 (BA-5822). The hot path — `AppConfigFragmentRepository.app_config(user_id, name)` — is the WebUI bootstrap loop (BEP-1052 §6) and was previously a DB hit per request. Mirrors the legacy `AppConfigCacheSource` shape on top of the `(user, name)`-keyed merged view: - `cache_source/cache_source.py`: - `get_merged_config(user_id, name)` cache-aside read keyed by `app_config:merged:{user_id}:{name}` - `set_merged_config(merged, domain_name=...)` writes the deep-merged payload + indexes the cache key in `app_config:user_keys:{user_id}` and the user in `app_config:domain_users:{domain_name}` so invalidation runs without `SCAN` - `invalidate_for_scope(scope_type, scope_id)`: - `USER`: drop the user's per-name set - `DOMAIN` / `DOMAIN_USER_DEFAULTS`: cascade through every member of the domain user set - `PUBLIC`: rely on TTL (broad invalidation TBD) - `invalidate_for_user(user_id)` convenience for self-service writes - `db_source.user_domain_name(user_id)` single-column lookup so the cache layer can tag merged-view entries with their owning domain - `AppConfigFragmentRepository.app_config(...)` is now cache-aside (cache hit returns the cached payload + fresh DB fragments; cache miss writes through) - `AppConfigFragmentAdminRepository.{create,update,purge}` invalidate the affected scope after the DB write - `repositories.py` builds the cache source from `args.valkey_stat_client` and threads it into both repos - All cache calls pass through `suppress_with_log` — cache failures log a warning and fall through to the DB
The implementation never shipped `user_writable` (admin / my-path gating now hangs entirely off `scope_sources`). Remove the field from the proposed Policy table, repository signatures, GraphQL schema, and scenario walkthroughs so the proposal matches the code.
jopemachine
added a commit
that referenced
this pull request
Apr 27, 2026
…ew reads Re-introduces a Valkey-backed cache layer for the merged AppConfig view, replacing the cache source that was dropped together with the legacy `app_configs` table in #11265 (BA-5822). The hot path — `AppConfigFragmentRepository.app_config(user_id, name)` — is the WebUI bootstrap loop (BEP-1052 §6) and was previously a DB hit per request. Mirrors the legacy `AppConfigCacheSource` shape on top of the `(user, name)`-keyed merged view: - `cache_source/cache_source.py`: - `get_merged_config(user_id, name)` cache-aside read keyed by `app_config:merged:{user_id}:{name}` - `set_merged_config(merged, domain_name=...)` writes the deep-merged payload + indexes the cache key in `app_config:user_keys:{user_id}` and the user in `app_config:domain_users:{domain_name}` so invalidation runs without `SCAN` - `invalidate_for_scope(scope_type, scope_id)`: - `USER`: drop the user's per-name set - `DOMAIN` / `DOMAIN_USER_DEFAULTS`: cascade through every member of the domain user set - `PUBLIC`: rely on TTL (broad invalidation TBD) - `invalidate_for_user(user_id)` convenience for self-service writes - `db_source.user_domain_name(user_id)` single-column lookup so the cache layer can tag merged-view entries with their owning domain - `AppConfigFragmentRepository.app_config(...)` is now cache-aside (cache hit returns the cached payload + fresh DB fragments; cache miss writes through) - `AppConfigFragmentAdminRepository.{create,update,purge}` invalidate the affected scope after the DB write - `repositories.py` builds the cache source from `args.valkey_stat_client` and threads it into both repos - All cache calls pass through `suppress_with_log` — cache failures log a warning and fall through to the DB
jopemachine
added a commit
that referenced
this pull request
Apr 27, 2026
…ew reads Re-introduces a Valkey-backed cache layer for the merged AppConfig view, replacing the cache source that was dropped together with the legacy `app_configs` table in #11265 (BA-5822). The hot path — `AppConfigFragmentRepository.app_config(user_id, name)` — is the WebUI bootstrap loop (BEP-1052 §6) and was previously a DB hit per request. Mirrors the legacy `AppConfigCacheSource` shape on top of the `(user, name)`-keyed merged view: - `cache_source/cache_source.py`: - `get_merged_config(user_id, name)` cache-aside read keyed by `app_config:merged:{user_id}:{name}` - `set_merged_config(merged, domain_name=...)` writes the deep-merged payload + indexes the cache key in `app_config:user_keys:{user_id}` and the user in `app_config:domain_users:{domain_name}` so invalidation runs without `SCAN` - `invalidate_for_scope(scope_type, scope_id)`: - `USER`: drop the user's per-name set - `DOMAIN` / `DOMAIN_USER_DEFAULTS`: cascade through every member of the domain user set - `PUBLIC`: rely on TTL (broad invalidation TBD) - `invalidate_for_user(user_id)` convenience for self-service writes - `db_source.user_domain_name(user_id)` single-column lookup so the cache layer can tag merged-view entries with their owning domain - `AppConfigFragmentRepository.app_config(...)` is now cache-aside (cache hit returns the cached payload + fresh DB fragments; cache miss writes through) - `AppConfigFragmentAdminRepository.{create,update,purge}` invalidate the affected scope after the DB write - `repositories.py` builds the cache source from `args.valkey_stat_client` and threads it into both repos - All cache calls pass through `suppress_with_log` — cache failures log a warning and fall through to the DB
jopemachine
added a commit
that referenced
this pull request
Apr 27, 2026
…ew reads Re-introduces a Valkey-backed cache layer for the merged AppConfig view, replacing the cache source that was dropped together with the legacy `app_configs` table in #11265 (BA-5822). The hot path — `AppConfigFragmentRepository.app_config(user_id, name)` — is the WebUI bootstrap loop (BEP-1052 §6) and was previously a DB hit per request. Mirrors the legacy `AppConfigCacheSource` shape on top of the `(user, name)`-keyed merged view: - `cache_source/cache_source.py`: - `get_merged_config(user_id, name)` cache-aside read keyed by `app_config:merged:{user_id}:{name}` - `set_merged_config(merged, domain_name=...)` writes the deep-merged payload + indexes the cache key in `app_config:user_keys:{user_id}` and the user in `app_config:domain_users:{domain_name}` so invalidation runs without `SCAN` - `invalidate_for_scope(scope_type, scope_id)`: - `USER`: drop the user's per-name set - `DOMAIN` / `DOMAIN_USER_DEFAULTS`: cascade through every member of the domain user set - `PUBLIC`: rely on TTL (broad invalidation TBD) - `invalidate_for_user(user_id)` convenience for self-service writes - `db_source.user_domain_name(user_id)` single-column lookup so the cache layer can tag merged-view entries with their owning domain - `AppConfigFragmentRepository.app_config(...)` is now cache-aside (cache hit returns the cached payload + fresh DB fragments; cache miss writes through) - `AppConfigFragmentAdminRepository.{create,update,purge}` invalidate the affected scope after the DB write - `repositories.py` builds the cache source from `args.valkey_stat_client` and threads it into both repos - All cache calls pass through `suppress_with_log` — cache failures log a warning and fall through to the DB
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📚 Stacked PRs
This PR is part of a 10-PR stack delivering BEP-1052. Merge in order:
chore(BA-5822): drop legacy AppConfig layer← you are herefeat(BA-5814): AppConfigPolicy foundationfeat(BA-5815): AppConfigPolicy GraphQLfeat(BA-5844): AppConfigPolicy REST v2feat(BA-5827): AppConfigFragment foundationfeat(BA-5836): AppConfigFragment service verticalfeat(BA-5829): AppConfigFragment + AppConfig GraphQLfeat(BA-5830): AppConfigFragment + AppConfig REST v2feat(BA-5832): AppConfig v2 SDK + CLIfeat(BA-5837): ValkeyCache for AppConfigFragment merged-view readsCI 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
app_configsand its enum type; downgrade recreates the predecessor table without data restoration.EntityType.APP_CONFIG/RBACElementType.APP_CONFIGenum entries are intentionally left in place — DB rows may still reference the literal value, and the cleanup belongs with the new RBAC integration in a later issue.Resolves BA-5822.
📚 Documentation preview 📚: https://sorna--11265.org.readthedocs.build/en/11265/
📚 Documentation preview 📚: https://sorna-ko--11265.org.readthedocs.build/ko/11265/