Skip to content

feat(soft-delete): gate soft delete behind a temporary SOFT_DELETE release toggle#41166

Open
mikebridge wants to merge 1 commit into
apache:masterfrom
mikebridge:sc-111230-soft-delete-gate
Open

feat(soft-delete): gate soft delete behind a temporary SOFT_DELETE release toggle#41166
mikebridge wants to merge 1 commit into
apache:masterfrom
mikebridge:sc-111230-soft-delete-gate

Conversation

@mikebridge

@mikebridge mikebridge commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

Adds a temporary rollout / kill-switch feature flag — SOFT_DELETE (default off) — so the soft-delete substrate can ship dark and be activated per-deploy once validated, separating deploy from release for a behavior change with cross-entity blast radius (DELETE semantics + read-path visibility filtering).

This is deployment scaffolding, not a permanent toggle: it is removed once soft delete is stable, leaving the unconditional "always active once deployed" end state. Until an operator opts in, existing deployments retain byte-for-byte legacy DELETE (hard-delete) behavior.

Two gate points, both no-op to legacy behavior when off:

  • BaseDAO.delete() routes to soft_delete() only when the flag is on; otherwise hard_delete().
  • The do_orm_execute visibility listener attaches no deleted_at IS NULL criteria when off.

Both the write path and the read path gate on the same flag, so they cannot diverge. Restore needs no explicit gate — with the flag off no row carries deleted_at, so a restore call has nothing to act on. The flag docstring documents the kill-switch semantics (flipping off after rows are soft-deleted resurrects them — emergency stop, not a clean rollback) and that the import pipeline's existing-row detection is gated transitively via the listener.

The deleted_at migration (from the substrate PRs) stays un-gated (additive). Removal of this flag + its two gate points is a small follow-up once soaked.

THIS IS A RELEASE TOGGLE, NOT A FEATURE FLAG

A common and reasonable objection is "feature flags that change functionality are a maintenance hazard." That objection is about long-lived flags — permanent configuration surface that parameterizes product behavior, branches the test matrix indefinitely, and accumulates as config sprawl. This flag is a different category.

In the Continuous Delivery taxonomy this is a Release Toggle: a transitory toggle whose only job is to decouple deploy from release so a not-yet-validated change can land on master and ship dark, then be switched on once trusted — and then deleted. It is not a Permission/Experiment/Ops toggle that lives forever.

Why the distinction matters here:

Long-lived feature flag (the thing people are wary of) This flag (release toggle)
Lifespan Indefinite Removed after the change soaks
Purpose Permanently parameterize behavior / experiment per tenant De-risk rollout of one high-blast-radius change
End state Both branches maintained forever Single unconditional code path; flag + both gate points deleted
Test matrix Permanent fork Temporary; off-path is the existing legacy behavior

So the change is deliberately scoped as scaffolding with a removal plan, default off, both gate points keyed to the same flag so the write and read paths can't diverge. It exists to make a behavior change with cross-entity reach safe to deploy continuously — not to add a permanent toggle to the product.

TESTING INSTRUCTIONS

Unit tests cover both flag states (default-off and on):

pytest tests/unit_tests/daos/test_base_dao_soft_delete.py \
       tests/unit_tests/models/test_soft_delete_mixin.py
  • With FEATURE_FLAGS = {"SOFT_DELETE": False} (default): a DELETE on a SoftDeleteMixin model hard-deletes, and the read-path listener does not hide soft-deleted rows.
  • With SOFT_DELETE on: DELETE soft-deletes and the listener filters soft-deleted rows out of reads (existing substrate behavior).

ADDITIONAL INFORMATION

  • Required feature flags: SOFT_DELETE (default off; temporary rollout/kill-switch — to be removed after stabilization)
  • Has associated issue:
  • Changes UI
  • Includes DB Migration
  • Introduces new feature or API
  • Removes existing feature or API

@bito-code-review

bito-code-review Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #0cc334

Actionable Suggestions - 0
Filtered by Review Rules

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

  • tests/unit_tests/models/test_soft_delete_mixin.py - 2
Review Details
  • Files reviewed - 5 · Commit Range: e7edbc6..e7edbc6
    • superset/config.py
    • superset/daos/base.py
    • superset/models/helpers.py
    • tests/unit_tests/daos/test_base_dao_soft_delete.py
    • tests/unit_tests/models/test_soft_delete_mixin.py
  • Files skipped - 1
    • docs/static/feature-flags.json - Reason: Filter setting
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

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

  • /review - 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

@netlify

netlify Bot commented Jun 17, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 0b47f63
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a33004a60434600094d5f80
😎 Deploy Preview https://deploy-preview-41166--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.

@mikebridge mikebridge force-pushed the sc-111230-soft-delete-gate branch 2 times, most recently from 3318c24 to 71bc1f2 Compare June 17, 2026 17:27
@github-actions github-actions Bot added the doc Namespace | Anything related to documentation label Jun 17, 2026
@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 64.30%. Comparing base (a19093e) to head (0b47f63).

Files with missing lines Patch % Lines
superset/daos/base.py 50.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #41166      +/-   ##
==========================================
- Coverage   64.31%   64.30%   -0.01%     
==========================================
  Files        2652     2652              
  Lines      144807   144808       +1     
  Branches    33423    33423              
==========================================
- Hits        93126    93119       -7     
- Misses      50013    50021       +8     
  Partials     1668     1668              
Flag Coverage Δ
hive 39.32% <66.66%> (-0.01%) ⬇️
mysql 58.04% <66.66%> (-0.02%) ⬇️
postgres 58.10% <66.66%> (-0.02%) ⬇️
presto 40.89% <66.66%> (-0.01%) ⬇️
python 59.55% <66.66%> (-0.02%) ⬇️
sqlite 57.77% <66.66%> (-0.02%) ⬇️
unit 100.00% <ø> (ø)

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.

Adds a temporary rollout / kill-switch feature flag (`SOFT_DELETE`,
default off) so the soft-delete substrate can ship dark and be activated
per-deploy once validated — separating deploy from release for a
behavior change with cross-entity blast radius.

This is deployment scaffolding, not a permanent toggle: it is removed
once soft delete is stable, leaving the unconditional "always active"
end state. Until an operator opts in, deployments retain legacy DELETE
(hard-delete) behavior.

Two gate points (both no-op to legacy behavior when off):
- `BaseDAO.delete()` routes to soft_delete only when the flag is on;
  otherwise hard_delete.
- The `do_orm_execute` visibility listener attaches no criteria when off.

Both write- and read-path gate on the same flag, so they cannot diverge.
Restore needs no explicit gate: with the flag off no row carries
`deleted_at`, so a restore call has nothing to act on. The flag docstring
documents the kill-switch semantics (flipping off after rows are
soft-deleted resurrects them — emergency stop, not a clean rollback) and
that the import pipeline's existing-row detection is gated transitively
via the listener.

The `deleted_at` migration stays un-gated (additive). Existing
soft-delete unit tests are updated to enable the flag; new tests pin the
gate-off path: a mixin model hard-deletes and the listener does not
filter.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mikebridge mikebridge force-pushed the sc-111230-soft-delete-gate branch from 71bc1f2 to 0b47f63 Compare June 17, 2026 20:15
@bito-code-review

bito-code-review Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #dc874c

Actionable Suggestions - 0
Review Details
  • Files reviewed - 5 · Commit Range: 0b47f63..0b47f63
    • superset/config.py
    • superset/daos/base.py
    • superset/models/helpers.py
    • tests/unit_tests/daos/test_base_dao_soft_delete.py
    • tests/unit_tests/models/test_soft_delete_mixin.py
  • Files skipped - 1
    • docs/static/feature-flags.json - Reason: Filter setting
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

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

  • /review - 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

@richardfogaca richardfogaca self-requested a review June 17, 2026 21:38
@mikebridge mikebridge changed the title feat(soft-delete): gate soft delete behind a temporary SOFT_DELETE flag feat(soft-delete): gate soft delete behind a temporary SOFT_DELETE release toggle Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc Namespace | Anything related to documentation size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants