SEP-1825: Let an app declare its own settings class without editing core or migrations - #1360
Open
peter-o-addo wants to merge 11 commits into
Open
SEP-1825: Let an app declare its own settings class without editing core or migrations#1360peter-o-addo wants to merge 11 commits into
peter-o-addo wants to merge 11 commits into
Conversation
…ALLOWED_KEYS parity
peter-o-addo
marked this pull request as ready for review
August 18, 2026 08:56
peter-o-addo
requested review from
a team,
marcuscruz-percona,
maxbube and
yyyyyyyan
as code owners
August 18, 2026 08:56
Contributor
Author
1. GET
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR removes the tight coupling between “settings class identifiers” and a shared SettingClassEnum/DB CHECK constraint by shifting the public API to identify settings classes by Pydantic __name__ strings, while persisting override rows under a derived storage token (historically the enum member name). This enables SEP apps to declare app-owned settings classes without edits to core enums or per-track migrations.
Changes:
- Replace enum-centric settings-class handling with string/class-name identifiers across settings override runtime, policy gates, and APIs.
- Drop the
settingoverride.setting_classCHECK constraint on SEP/Tasks/Inventory migration tracks (with shared idempotent Alembic helpers) and adjust tests accordingly. - Regenerate frontend OpenAPI specs/types to widen
SettingClasstostringand document the change via a changelog fragment.
Reviewed changes
Copilot reviewed 55 out of 58 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/sidecar/test_embedded_settings.py | Updates allowlist reachability test to treat setting classes as strings. |
| tests/app/tasks/migrations/test_setting_class_enum.py | Reworks migration tests to cover CHECK-drop behavior and downgrade cleanup. |
| tests/app/sep/test_settings_override_worker.py | Updates worker override wiring tests for string-based app-owned class IDs. |
| tests/app/sep/test_settings_override_integration.py | Updates integration expectations for app-owned class identifiers and storage tokens. |
| tests/app/sep/test_main.py | Adjusts main proxy-map tests to use class-name identifiers for app-owned classes. |
| tests/app/sep/migrations/test_alembic_integration.py | Adds SEP-track CHECK-drop/downgrade assertions. |
| tests/app/sep/apps/report/test_config.py | Asserts report proxy uses class-name identifier, not enum member. |
| tests/app/sep/apps/framework/test_registry.py | Updates app-owned settings registry tests for string identifiers. |
| tests/app/sep/apps/alerts/test_config.py | Asserts alerts proxy uses class-name identifier and avoids collisions. |
| tests/app/sep/api/routes/test_settings.py | Updates settings admin route tests for string-based class identifiers (404 on storage tokens). |
| tests/app/sep/api/routes/test_settings_proxy.py | Updates proxy route ordering/contents assertions for string-based identifiers. |
| tests/app/sep/api/routes/test_settings_export.py | Updates export tests to use class-name identifiers in exported blocks. |
| tests/app/migrations/test_shared_postgres_settingoverride.py | Updates shared-DB migration tests for CHECK-drop and VARCHAR length behavior. |
| tests/app/core/settings_override/test_proxy.py | Updates proxy tests to store class identifiers as strings. |
| tests/app/core/settings_override/test_policy.py | Updates allowlist/policy tests to key by class-name strings and cover unregistered names. |
| tests/app/core/settings_override/test_policy_gates.py | Adds coverage ensuring app-owned/unregistered classes honor allowlist by name. |
| tests/app/core/settings_override/test_models.py | Adds tests pinning storage-token derivation (setting_class_token). |
| tests/app/core/settings_override/test_manager.py | Asserts persisted override rows store the storage token (e.g. SEP_SETTINGS). |
| tests/app/core/settings_override/test_lifecycle.py | Adds coverage for refresh behavior when override rows reference an unwired class. |
| tests/app/core/settings_override/api/test_app_owned_groups.py | Updates API grouping/metadata tests for string-based setting class IDs. |
| tests/app/core/db/test_utils.py | Adds compare-type tests for TypeDecorator(String(255)) equivalence. |
| frontend/packages/api/src/hooks/useSettings.ts | Widens SettingClass typing to plain string and updates docs comment. |
| frontend/packages/api/src/generated/tasks.ts | Regenerated Tasks client types: removes SettingClassEnum, uses string. |
| frontend/packages/api/src/generated/sep.ts | Regenerated SEP client types: removes SettingClassEnum, uses string. |
| frontend/packages/api/src/generated/inventory.ts | Regenerated Inventory client types: removes SettingClassEnum, uses string. |
| frontend/packages/api/specs/tasks.json | Regenerated Tasks OpenAPI spec to remove SettingClassEnum and use string. |
| frontend/packages/api/specs/sep.json | Regenerated SEP OpenAPI spec to remove SettingClassEnum and use string. |
| frontend/packages/api/specs/inventory.json | Regenerated Inventory OpenAPI spec to remove SettingClassEnum and use string. |
| changelog.d/SEP-1825.changed.md | Documents the settings-class identifier change for operators. |
| app/tasks/migrations/versions/2026_08_17_2210-7d2e869ac188_drop_setting_class_check_constraint.py | Tasks-track migration to drop the CHECK using shared Alembic ops. |
| app/tasks/migrations/versions/2026_08_13_2143-a19da5cf0bca_add_taskhistory_log_state_capture_status.py | Repoints Tasks migration chain to bypass a removed enum-extension revision. |
| app/tasks/migrations/versions/2026_08_12_1200-e2f3a4b5c6d7_extend_setting_class_enum_health_report.py | Deleted obsolete Tasks enum-extension migration. |
| app/tasks/migrations/env.py | Prevents Alembic logging config from disabling existing loggers. |
| app/sep/migrations/versions/2026_08_17_2210-74720aeda25b_drop_setting_class_check_constraint.py | SEP-track migration to drop the CHECK using shared Alembic ops. |
| app/sep/migrations/versions/2026_08_12_1200-d1e2f3a4b5c6_extend_setting_class_enum_health_report.py | Deleted obsolete SEP enum-extension migration. |
| app/sep/main.py | Updates callback registry typing and wires app-owned class callback by class name. |
| app/sep/apps/report/config.py | Keys report settings proxy by class __name__. |
| app/sep/apps/report/app_owned_settings.py | Declares report app-owned settings using class __name__. |
| app/sep/apps/framework/registry.py | Updates app-owned settings-class collection to dedupe by string identifier. |
| app/sep/apps/alerts/config.py | Keys alerts settings proxy by class __name__. |
| app/sep/apps/alerts/app_owned_settings.py | Declares alerts app-owned settings using class __name__. |
| app/sep/api/routes/settings.py | Updates export/list logic to treat setting-class identifiers as strings. |
| app/inventory/migrations/versions/2026_08_17_2210-a38607bba456_drop_setting_class_check_constraint.py | Inventory-track migration to drop the CHECK using shared Alembic ops. |
| app/inventory/migrations/versions/2026_08_12_1200-f3a4b5c6d7e8_extend_setting_class_enum_health_report.py | Deleted obsolete Inventory enum-extension migration. |
| app/inventory/migrations/env.py | Prevents Alembic logging config from disabling existing loggers. |
| app/core/settings_override/registry.py | Switches policy gating to key off class-name strings rather than enum membership. |
| app/core/settings_override/proxy.py | Updates proxy to accept setting_class: str. |
| app/core/settings_override/policy.py | Updates allowlist functions to accept setting_class: str. |
| app/core/settings_override/models.py | Introduces setting_class_token(), stores setting_class as string with enum-name compatibility. |
| app/core/settings_override/lifecycle.py | Updates registry/callback typing and log messages for string identifiers. |
| app/core/settings_override/constants.py | Adds the pre-SEP-1825 CHECK member list for downgrade restoration. |
| app/core/settings_override/cache.py | Filters override rows by derived storage token (not enum value) and logs using class-name. |
| app/core/settings_override/api/routes.py | Makes API path params strings and persists rows using derived storage tokens. |
| app/core/settings_override/api/models.py | Updates response models to use setting_class: str. |
| app/core/settings_override/api/export.py | Updates export helper to accept string setting-class identifiers. |
| app/core/settings_override/alembic_ops.py | Adds shared, idempotent Alembic helpers to drop/restore the CHECK across tracks. |
| app/core/settings_override/init.py | Re-exports setting_class_token and updates imports. |
| app/core/db/utils.py | Adds check_constraint_name() and extends compare_type() to handle TypeDecorator(String). |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+412
to
+415
| constraints = _check_constraints_for_column(bind, table_name, column_name) | ||
| if not constraints: | ||
| return None | ||
| return constraints[0].get("name") |
Comment on lines
16
to
21
| """add taskhistory_log_state capture_status | ||
|
|
||
| Revision ID: a19da5cf0bca | ||
| Revises: e2f3a4b5c6d7 | ||
| Revises: 6a19d56d7985 | ||
| Create Date: 2026-08-13 21:43:58.711511 | ||
|
|
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.
Summary
Let an app declare its own settings class without editing
SettingClassEnumor adding CHECK-constraint migrations, by storingsetting_classas a derived string and identifying classes by Pydantic__name__on the API.app/core/settings_override/models.py: addsetting_class_token(), persistsetting_classas a plain string, and keep enum-member name binding compatibleapp/core/settings_override/{cache.py,api/routes.py,policy.py,registry.py,api/models.py,api/export.py,proxy.py,lifecycle.py}: switch settings-class handling from enum-centric to string/class-name-centric across runtime, API, and policyapp/sep/{api/routes/settings.py,apps/framework/registry.py,apps/alerts/{app_owned_settings.py,config.py},apps/report/{app_owned_settings.py,config.py},main.py}: wire app-owned classes by__name__and keep callback/proxy wiring alignedapp/core/settings_override/{alembic_ops.py,constants.py},app/core/db/utils.py,app/{sep,tasks,inventory}/migrations/env.py: add shared migration helpers and keep autogenerate clean for the string-backedsetting_classsettingoverride.setting_classCHECK on all tracks, remove obsolete health-report enum-extension revisions, and re-point child revisionsfrontend/packages/api/specs/{sep,tasks,inventory}.json,frontend/packages/api/src/generated/{sep,tasks,inventory}.ts,frontend/packages/api/src/hooks/useSettings.ts: regenerate API types/specs and widenSettingClasstostringchangelog.d/SEP-1825.changed.md: document the settings-class identifier change for operatorsTested
Checklist
make test)make run-pre-commit)make makemigrations)changelog.d/if the change is user-facing (make changelog-add), or confirmed N/A (internal-only change, or a same-release-cycle fix for an unreleased sibling ticket)