Skip to content

chore(BA-5822): drop legacy AppConfig layer (preparation for BEP-1052)#11265

Draft
jopemachine wants to merge 7 commits intomainfrom
BA-5822
Draft

chore(BA-5822): drop legacy AppConfig layer (preparation for BEP-1052)#11265
jopemachine wants to merge 7 commits intomainfrom
BA-5822

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 ← you are here
  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
  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

  • Removes the existing AppConfig data / repository / service / GQL / REST layer to clear room for the BEP-1052 redesign.
  • Migration drops app_configs and its enum type; downgrade recreates the predecessor table without data restoration.
  • Wiring updates: services factory/processors, repositories container, adapters registry, REST v2 tree, GraphQL schema (-11 fields/mutations), and the EntityNode union.
  • EntityType.APP_CONFIG / RBACElementType.APP_CONFIG enum 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/

jopemachine and others added 3 commits April 25, 2026 13:49
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>
…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.
@github-actions github-actions Bot added comp:client Related to Client component comp:common Related to Common component comp:cli Related to CLI component labels Apr 25, 2026
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
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
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 require:db-migration Automatically set when alembic migrations are added or updated size:XL 500~ LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant