Skip to content

feat(themes): add per-theme editors (Subject model) - #42404

Merged
rusackas merged 24 commits into
apache:masterfrom
preset-io:theme-editors-subject-model
Sep 16, 2026
Merged

rusackas merged 24 commits into
apache:masterfrom
preset-io:theme-editors-subject-model

Conversation

@yousoph

@yousoph yousoph commented Jul 24, 2026 •

Copy link
Copy Markdown
Member

SUMMARY

Extends the Subject model / entity editors introduced in #38831 to Themes. Themes previously had no ownership concept and were editable only by admins. This PR adds a per-theme editors list (Subjects) so edit access can be scoped per theme instead of all-or-nothing, following the same editors-only pattern already used by alerts/reports (no viewers for themes).

Key behaviors:

  • A new theme_editors junction table and a Theme.editors relationship (mirrors report_schedule_editors).
  • Theme creation is routed through a new CreateThemeCommand; the creating user is automatically added as an editor.
  • PUT/DELETE/bulk-delete now enforce raise_for_editorship on the theme (admins always pass). System themes and the system default/dark themes keep their existing admin-only protections.
  • Editorship is checked on import overwrite.
  • REST API exposes editors (create/update schemas + list/show columns) and a /api/v1/theme/related/editors endpoint, with a new optional SUBJECTS_RELATED_TYPES_THEMES config to control which subject types appear in the picker (falls back to the global default).
  • Frontend: themes list shows an editors pile and swaps its row action to a read-only view for non-editors; the theme modal gains an editors picker and is read-only for non-editors/system themes.

Backwards compatibility: no feature flag. On upgrade the migration backfills each existing non-system theme's creator as an editor so authors keep edit access; system themes and themes with no creator receive no editors and stay admin-only to edit (an empty editors list means admin-only). Theme visibility is deliberately unchanged: the list endpoint has no new access filter, so every user who can read themes today still can, and themes applied to a dashboard continue to render for anyone who can view that dashboard.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Themes list gains an "Editors" column; the theme modal gains an "Editors" picker.

Before After
Themes list before list after list
Theme modal before modal after modal

TESTING INSTRUCTIONS

  • superset db upgrade creates the theme_editors table (migration f7e8d9c0b1a2).
  • As a non-admin user with can_write on Theme: create a theme → you are automatically its editor and can edit it; you cannot edit a theme you are not an editor of (403); you cannot add yourself as editor via PUT to gain access.
  • As an admin: full CRUD on any theme; system/default themes remain protected.
  • New tests: tests/integration_tests/themes/test_theme_editors.py, tests/unit_tests/migrations/test_add_theme_editors.py, plus ThemeList/ThemeModal jest tests.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags: none
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

Documents the behavior change in UPDATING.md. Builds on #38831.

🤖 Generated with Claude Code

@dosubot dosubot Bot added api Related to the REST API authentication:access-control Rlated to access control change:backend Requires changing the backend change:frontend Requires changing the frontend global:theming Related to theming Superset labels Jul 24, 2026
@github-actions github-actions Bot added risk:db-migration PRs that require a DB migration and removed change:backend Requires changing the backend change:frontend Requires changing the frontend authentication:access-control Rlated to access control global:theming Related to theming Superset labels Jul 24, 2026
@bito-code-review

bito-code-review Bot commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Bito Review Skipped - Source Branch Not Found

Bito didn’t review this change because the pull request is no longer valid. It may have been merged, or the source/target branch may no longer exist.

@yousoph
yousoph marked this pull request as draft July 24, 2026 23:36
@bito-code-review

Copy link
Copy Markdown
Contributor

The migration f7e8d9c0b1a2_add_theme_editors_table intentionally does not perform a backfill of theme creators. As noted in the UPDATING.md documentation, themes previously lacked an owner concept, so the new theme_editors table starts empty. Existing themes are treated as admin-only by default to maintain security, and the system is designed to allow them to remain without editors, similar to legacy or system themes.

UPDATING.md

### Themes support per-theme editors

Themes now carry a list of **editors** (users, roles, or groups). A new
`theme_editors` junction table is created by the migration
`f7e8d9c0b1a2_add_theme_editors_table`. Themes never had owners, so the table
starts empty and no backfill is performed.

@netlify

netlify Bot commented Aug 18, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 8384071
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6aa6cd7c7e5c240008858244
😎 Deploy Preview https://deploy-preview-42404--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov

codecov Bot commented Aug 19, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.65896% with 30 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.18%. Comparing base (8e66145) to head (8384071).
⚠️ Report is 67 commits behind head on master.

Files with missing lines Patch % Lines
superset/themes/api.py 68.75% 8 Missing and 2 partials ⚠️
...perset-frontend/src/features/themes/ThemeModal.tsx 86.66% 6 Missing ⚠️
superset/commands/theme/import_themes.py 64.28% 2 Missing and 3 partials ⚠️
superset/mcp_service/theme/tool/create_theme.py 44.44% 5 Missing ⚠️
superset/commands/theme/create.py 92.30% 1 Missing and 1 partial ⚠️
superset/commands/theme/update.py 81.81% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #42404      +/-   ##
==========================================
+ Coverage   80.17%   80.18%   +0.01%     
==========================================
  Files        2925     2926       +1     
  Lines      172670   172808     +138     
  Branches    40087    40131      +44     
==========================================
+ Hits       138440   138570     +130     
+ Misses      31633    31628       -5     
- Partials     2597     2610      +13     
Flag Coverage Δ
hive 37.35% <46.95%> (+0.01%) ⬆️
javascript 75.66% <89.65%> (-0.01%) ⬇️
mysql 56.89% <78.26%> (+0.02%) ⬆️
postgres 56.91% <78.26%> (+0.02%) ⬆️
presto 39.23% <46.95%> (+0.01%) ⬆️
python 84.58% <79.13%> (+0.02%) ⬆️
sqlite 56.61% <78.26%> (+0.02%) ⬆️
unit 75.90% <58.26%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@yousoph yousoph added the 🎪 ⚡ showtime-trigger-start Create new ephemeral environment for this PR label Aug 19, 2026
@github-actions github-actions Bot added 🎪 30ea099 🚦 building and removed 🎪 ⚡ showtime-trigger-start Create new ephemeral environment for this PR labels Aug 19, 2026
yousoph and others added 19 commits September 9, 2026 17:23
Backfill each non-system theme's creator as an editor so existing theme
authors keep edit access after upgrade (empty editors = admin-only would
otherwise regress non-admin authors). System themes and null-creator
themes are skipped.

Also fix a ThemeModal save-payload type, a mypy Optional return in the
integration test, and update the theme API column-set and update-command
unit tests for the new editors field / editorship check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Re-point down_revision to the current single migration head so the branch
does not introduce a second alembic head after syncing with master.
…format

Add admin login to the command-level theme-deletion integration tests now
that delete enforces editorship; update the migration revision-chain test
for the rebased down_revision; ruff-format the migration.
Mirror CreateThemeCommand and the dashboard/chart/dataset importers so a
non-admin who imports a new theme can still edit/delete it (the new
editorship checks require editorship, which import previously never set).
Editor add/remove now marks the modal dirty, so closing without saving
triggers the discard confirmation instead of silently dropping editor
changes (previously only theme_name/json_data were compared).
POST /api/v1/theme/ built the Theme row directly instead of going
through CreateThemeCommand, so the creator was never added as an
editor. That left the assertion in
test_create_theme_adds_creator_as_editor failing before the test's
own cleanup ran, which in turn left the theme_writer fixture's user
and role dangling and broke every sibling test in the class (FK
violation deleting the user, then duplicate ab_user_role rows on
subsequent setups).

Also fixes the list/show columns (missing "editors"), the related/editors
endpoint (missing allowed_rel_fields/filters wiring), PUT silently
dropping the "editors" payload, and PUT/DELETE not translating
ThemeForbiddenError into a 403. Fixes a pre-existing unit test that
only worked by accident because a Mock's unconfigured .editors
attribute happened not to be exercised until CreateThemeCommand was
wired up correctly.
Master gained migration 39097d124752 (add_reason_to_purge_audit_log)
with the same down_revision this branch's migration was cut from,
producing two Alembic heads. Re-point down_revision to the new head
so the branch merges into a single linear chain.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The migration was rebased onto 39097d124752 in a prior commit, but the
test's revision-chain assertion still expected the old down_revision,
failing unit-tests CI on every run.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ose extra_editors

The MCP create_theme tool created themes directly via ThemeDAO, bypassing
CreateThemeCommand's editor-seeding step, so themes created through MCP
left the creating user without edit access afterward. Route it through
the same command the REST API uses.

Also surface extra_editors on the theme GET/GET-list responses (matching
dashboards/charts) and return 403 instead of an unhandled error when a
non-editor attempts a bulk delete.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…in RBAC test

The create_theme tool no longer imports db directly since it now
routes through CreateThemeCommand, so the RBAC control test's
patch.object(create_theme_module.db.session, "commit") broke with
AttributeError. Patch superset.db.session.commit directly instead,
matching the convention used by other command-based MCP tool tests.
The API already attached extra_editors (editorship granted via
EXTRA_EDITORS_RESOLVER) to theme GET responses, matching charts/dashboards,
but ThemeModal only checked the persisted editors list when deciding
read-only state. A user granted editorship solely through the resolver could
update the theme via the API yet was shown a read-only modal.

Also adds regression coverage confirming the MCP create_theme tool persists
through CreateThemeCommand (its editor-seeding step) rather than bypassing
it, matching the REST create path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ThemeModal already factors extra_editors (editorship granted via
EXTRA_EDITORS_RESOLVER) into its read-only check, and the API already
attaches extra_editors to each row in the theme list response, but the
list-row action still checked only the persisted editors list. A user
granted editorship solely through the resolver could update the theme
via the API yet saw a read-only 'View' action.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A migration landed on master with the same down_revision this
branch's add_theme_editors_table migration was cut from, producing
two Alembic heads. Add a no-op merge revision joining them.
…ns note

Restore .github/workflows to the merge-base state so the PR no longer
rolls back action pins, the ubuntu-slim runners, and the liccheck
pkg_resources shim (the cause of the python-dependency-liccheck failure).

Reword the UPDATING.md entry: themes were never admin-only to edit, since
Theme is in GAMMA_READ_ONLY_MODEL_VIEWS and Alpha holds can_write. The
change this PR introduces is tightening update/delete to editors or Admins.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The related/editors endpoint used the base related-field serialization,
returning the raw Subject<...> str() with no label, type, or active
fields. Add the same text_field_rel_fields, extra_fields_rel_fields, and
order_rel_fields config used by the dashboard/chart editors endpoints so
the theme editor picker gets proper labels/icons and can filter out
inactive subjects. Adds a response-shape test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A force-push to this branch dropped the merge migration that had
previously joined the task_dependencies and theme_editors Alembic
heads, leaving two divergent heads again. Add a fresh no-op merge
revision joining them.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The Theme REST API gained an `editors` field on post/put plus a 403
response, but the committed spec was never regenerated to match.
@bito-code-review

Copy link
Copy Markdown
Contributor

AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers an incremental AI Review.

  • /review full - Manually triggers a full AI Review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

…editorship

The ThemeList Delete row action was gated purely on the blanket Theme:can_write
permission, so a non-editor saw an enabled Delete icon for themes they could
not actually delete (the server-side raise_for_editorship check correctly
blocked the request, but the UI was misleading). Similarly, the Edit row
action's edit/view toggle didn't account for the admin-only restriction on
the active system default/dark theme slot, so a non-admin editor saw an
editable icon for a theme they could not actually save.

Both actions now share a single per-row guard that mirrors the server's
UpdateThemeCommand/DeleteThemeCommand checks: editorship (or admin) for
regular themes, admin-only for the active system default/dark theme.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@bito-code-review

bito-code-review Bot commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Agent Run #56fd90

Actionable Suggestions - 0
Additional Suggestions - 14
  • superset/commands/theme/import_themes.py - 1
    • Overwrite gate blocks creator · Line 75-83
      `is_editor()` (manager.py:5798) only checks the `editors` relationship and `EXTRA_EDITORS_RESOLVER`, not `created_by`/`changed_by`. Pre-existing themes were never seeded into `editors` (old code only set `created_by`), so their original creator is now blocked from overwriting despite holding `can_write`. Consider `and existing.created_by != user` in the gate.
  • superset/migrations/versions/2026-07-24_00-00_f7e8d9c0b1a2_add_theme_editors_table.py - 1
    • Missing theme_id index · Line 61-61
      The junction table only has a composite UniqueConstraint on (subject_id, theme_id). The `Theme.editors` relationship (secondary="theme_editors") queries by `theme_id` alone, which cannot use that index (leading column is subject_id), so every editors lookup is a full table scan. Add `create_index(THEME_EDITORS, "ix_theme_editors_theme_id", ["theme_id"])` in `upgrade()`, matching the subjects migration's resource-column index precedent.
  • superset-frontend/src/pages/ThemeList/index.tsx - 1
    • Modal/list gating mismatch · Line 544-552
      The list now shows a read-only 'View' action for protected system themes (is_system_default/is_system_dark) to non-admin editors via `canManageTheme`, but `handleThemeEdit` still opens `ThemeModal`, whose `isReadOnly` only checks `isSystemTheme` and editorship. A non-admin editor gets an editable modal for a theme the server will reject. Mirror this gating in `ThemeModal`.
  • superset/themes/api.py - 1
    • Duplicated extra_editors logic · Line 190-206
      `pre_get`/`pre_get_list` duplicate the `extra_editors` attachment logic already present in `charts/api.py` (and dashboards). If the resolver contract or response shape changes, these copies can drift independently. Consider extracting a shared helper (e.g. in `security/manager.py`) and reusing it from both APIs.
  • superset/commands/theme/delete.py - 1
    • Missing security gate tests · Line 68-72
      The new per-theme editorship gate (lines 68-72) has no test coverage, unlike the analogous `UpdateThemeCommand` gate which is tested. Add a `DeleteThemeCommand` test asserting a non-editor raises `ThemeForbiddenError` and an editor/admin passes, so this security behavior is locked in.
  • superset/mcp_service/theme/tool/create_theme.py - 1
    • Unreachable error handler · Line 142-148
      The `except ThemeInvalidError` branch appears unreachable: `CreateThemeRequest` only accepts `theme_name`/`json_data`, and `CreateThemeCommand.validate()` raises `ThemeInvalidError` only via `populate_subjects`, which needs `editors` IDs in the payload. With `default_to_user=True` and no `editors`, it returns the current user's subject and never raises. Consider removing the dead branch or adding a comment explaining when it can fire.
  • superset-frontend/src/features/themes/ThemeModal.test.tsx - 2
    • Unasserted preselection claim · Line 408-434
      The test name claims the current user is preselected, but no assertion verifies it. `getByText('Editors')` only checks the label, and the enabled 'Add' button does not prove preselection (editors are optional per `validate()`). Add an assertion for the preselected editor (e.g. 'Admin User') so a regression in the `currentUserEditor` init logic is caught.
    • Empty-editors path untested · Line 436-464
      In edit mode the modal fetches the resource via `fetchResource(theme.id)` and overrides `currentTheme` from the fetched `resource` (ThemeModal.tsx lines 445, 470-482). The `beforeEach` mock returns `mockTheme`, which has `editors: [{id:1,label:'Admin User'}]`, so the passed `themeWithoutEditors` is discarded and the empty-editors path is never actually tested. Ensure the fetch mock for `*/api/v1/theme/1` returns the empty-editors theme (e.g. register the override so it takes precedence over the beforeEach route) so the intended path is exercised.
  • superset/commands/theme/exceptions.py - 1
    • Unused exception class · Line 42-43
      `ThemeUpdateFailedError` is defined but never referenced anywhere in the repo. `UpdateThemeCommand.run` uses `reraise=Exception` (update.py:47), so this class is dead code introduced by the diff. Remove it (and the `UpdateFailedError` import) or use it in the update command's `@transaction` decorator.
  • superset-frontend/src/features/themes/ThemeModal.tsx - 1
    • Redundant effect dependency · Line 490-490
      `validate()` (lines 410-424) only reads `theme_name`, `json_data`, `isReadOnly`, and `validation.hasErrors` — it never references `editors`. Adding `currentTheme.editors?.length` to this effect's deps makes `validate()`/`setDisableSave` re-run on every editors change with no output change. Drop this dependency.
  • superset/config.py - 1
    • Missing docs for new config · Line 3189-3189
      The new `SUBJECTS_RELATED_TYPES_THEMES` key is wired to `subject_type_filter("SUBJECTS_RELATED_TYPES_THEMES")` in `superset/themes/api.py` and noted in UPDATING.md, but the per-entity override list in `docs/admin_docs/security/security.mdx` (lines 191-196) omits it. Add a bullet so admins can discover the theme picker override.
  • tests/integration_tests/themes/test_theme_editors.py - 1
    • Unused fixture · Line 234-234
      `test_related_editors_endpoint` logs in as `ADMIN_USERNAME` and never references the writer user, yet it pulls in the `theme_writer` fixture, which creates an unused user and role (and a `Subject` via `_user_subject` in other tests). The fixture is unnecessary here and adds setup/teardown work.
  • tests/unit_tests/themes/commands_test.py - 1
    • Inconsistent patch target · Line 61-61
      For consistency with the other tests in this file (`test_validate_system_default_theme_blocks_non_admin`, `test_validate_system_default_theme_allows_admin`), patch the module-level `superset.commands.theme.update.security_manager.raise_for_editorship` rather than the top-level `superset.security_manager` LocalProxy attribute. The top-level target requires an active app context to resolve `appbuilder.sm` at patch time and diverges from the file's established pattern for the same dependency.
  • superset-frontend/src/pages/ThemeList/ThemeList.test.tsx - 1
    • Misleading test name · Line 378-378
      The test name says it 'hides the edit and delete actions', but line 405 asserts the edit button is present with `aria-label='View'` — it is rendered read-only, not hidden. Rename to avoid misleading a future maintainer about the expected DOM.
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset-frontend/src/features/themes/ThemeModal.tsx - 1
Review Details
  • Files reviewed - 27 · Commit Range: 15556aa..fd1392b
    • superset-frontend/src/features/themes/ThemeModal.test.tsx
    • superset-frontend/src/features/themes/ThemeModal.tsx
    • superset-frontend/src/features/themes/types.ts
    • superset-frontend/src/pages/ThemeList/ThemeList.test.tsx
    • superset-frontend/src/pages/ThemeList/index.tsx
    • superset/commands/theme/create.py
    • superset/commands/theme/delete.py
    • superset/commands/theme/exceptions.py
    • superset/commands/theme/import_themes.py
    • superset/commands/theme/update.py
    • superset/config.py
    • superset/mcp_service/theme/tool/create_theme.py
    • superset/migrations/versions/2026-07-24_00-00_f7e8d9c0b1a2_add_theme_editors_table.py
    • superset/migrations/versions/2026-09-04_19-03_aa5fa339627c_merge_add_theme_editors_table_with_.py
    • superset/migrations/versions/2026-09-09_00-00_0884f655c0a6_merge_task_dependencies_with_theme_.py
    • superset/models/core.py
    • superset/subjects/models.py
    • superset/themes/api.py
    • superset/themes/schemas.py
    • tests/integration_tests/dashboards/test_theme_integration.py
    • tests/integration_tests/themes/api_tests.py
    • tests/integration_tests/themes/test_theme_editors.py
    • tests/unit_tests/mcp_service/test_rbac_tool_enforcement.py
    • tests/unit_tests/mcp_service/theme/tool/test_create_theme.py
    • tests/unit_tests/migrations/test_add_theme_editors.py
    • tests/unit_tests/themes/api_test.py
    • tests/unit_tests/themes/commands_test.py
  • Files skipped - 2
    • UPDATING.md - Reason: Filter setting
    • docs/static/resources/openapi.json - Reason: Filter setting
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers an incremental AI Review.

  • /review full - Manually triggers a full AI Review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Comment thread superset-frontend/src/features/themes/ThemeModal.tsx Outdated
Resolves a UPDATING.md ordering conflict by keeping both this
branch's and master's changelog entries. Verified the theme_editors
migration chain still resolves to a single Alembic head
(0884f655c0a6) after the merge.
…admins

ThemeModal only checked the blanket is_system flag to decide read-only
state, so a non-admin editor of a regular theme that had been promoted
to the active system-default/dark slot saw Save enabled and got a 403
from UpdateThemeCommand.validate() on submit, which enforces
admin-only on is_system_default/is_system_dark independently of
is_system. Mirror that guard in the modal and adjust the read-only
notice text so it doesn't claim the user isn't an editor when they are
one.
@sadpandajoe

Copy link
Copy Markdown
Member

Re: the "Additional Suggestions" from the 2026-09-11 review run (0 actionable, 14 additional) — the modal/list gating mismatch is now fixed (same defect independently flagged by a human reviewer, see the ThemeModal.tsx fix in the latest commits). Disposition on the other three:

  • import_themes.py overwrite-gate edge case — real edge case (a pre-existing theme's original created_by isn't seeded into editors under the old code, so re-import overwrite could be blocked despite can_write), but it's a narrow migration-era edge case, not a regression introduced by this PR's happy path. Leaving as a follow-up rather than growing this PR further.
  • Missing ix_theme_editors_theme_id index — valid perf suggestion for the theme_editors junction table, but not correctness-blocking; deferring to a follow-up perf pass.
  • Duplicated extra_editors logic vs. charts/dashboards APIs — valid DRY suggestion, but a refactor of shared logic across resource types is out of scope for this bug-fix-sized PR.

Not blocking merge on these three; happy to file follow-up issues if maintainers want them tracked separately.

@rusackas

Copy link
Copy Markdown
Member

Your call on fix here vs merge/follow-up @sadpandajoe - looks good enough to me, but happy to push some commits, or open a follow-up PR ¯\_(ツ)_/¯

@rusackas

Copy link
Copy Markdown
Member

Merging this, thanks for the thorough writeup @yousoph, and for the careful triage on those three @sadpandajoe. Opening a follow-up PR for them now rather than letting them go untracked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Related to the REST API change:backend Requires changing the backend change:frontend Requires changing the frontend doc Namespace | Anything related to documentation global:theming Related to theming Superset risk:db-migration PRs that require a DB migration size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants