Deleting a location must not destroy its alert history #134
Labels
No labels
area:ai
area:ci-cd
area:notifications
area:observability
area:public-pages
backlog
bug
duplicate
enhancement
help wanted
invalid
question
type:decision
type:feature
type:infra
type:maintenance
type:security
v1.0.1
v1.1.0
v1.2.0
v1.3.0
v2.0.0
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/WeatherBot#134
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent: #22.
Location.sent_alertsis declaredcascade="all, delete-orphan"(app/models/location.py:99-101), andSentAlert.location_idisondelete="CASCADE". Deleting a location hard-deletes its entire alert history.nws_alert_snapshots,public_alert_pages, andspc_outlook_impact_locationscascade onlocation_idthe same way.That is defensible behaviour today. It is a trap for a release whose entire premise is that history is worth keeping: one accidental delete silently destroys the record the Explorer exists to show, with no warning and no recovery.
Tasks
deleted_at), or detach history (ON DELETE SET NULLplus denormalized location name/coords on the history rows so an orphaned event still renders).visible_location_filterkeys offLocation.owner_id, so orphaned history needs an explicit visibility rule — this is the part most likely to be got wrong.Picking this up. Model decision: soft-delete (
locations.deleted_at), not detach-history.Rationale: soft-delete keeps every FK, join, and — decisively — the existing three-tier visibility semantics intact:
owner_idandlocation_memberssurvive, sovisible_location_filter/can_view_location_with_dbkeep working unchanged for historical events, which the issue correctly flags as "the part most likely to be got wrong" under the detach model. Detach would need nullablelocation_idacross five history tables, denormalized name/coords, and a brand-new visibility rule for orphaned rows. Survey of the codebase shows the soft-delete cost is small: nearly all active-location surfaces already filterLocation.enabled == True, which the soft-delete path forces off.Scope
locations.deleted_at(nullable, tz-aware).DELETE /api/locations/{id}becomes soft-delete: setsdeleted_at,enabled=False,public_enabled=False; row and all history retained.?purge=true(admin-only) keeps the old cascade for genuine removal.GET /api/locations/{id}/delete-preview: counts of retained history (alerts, derived events, snapshots) to power the UI warning.replace=truesoft-deletes instead of hard-deleting; re-importing a soft-deleted location revives it (deleted_atcleared). Export excludes deleted.deleted_at IS NULLguards whereenableddoesn't already cover them (per-location interactive endpoints 404 on deleted; background jobs skip deleted; the correlation full rebuild deliberately still includes deleted locations so their history keeps deriving).