Skip to content

Replace org_must_have_owner trigger with app-level check#58

Merged
jgpruitt merged 1 commit intomainfrom
me0/fix-org-delete
Apr 28, 2026
Merged

Replace org_must_have_owner trigger with app-level check#58
jgpruitt merged 1 commit intomainfrom
me0/fix-org-delete

Conversation

@jgpruitt
Copy link
Copy Markdown
Collaborator

The BEFORE DELETE/UPDATE trigger on org_member fired during the cascade from delete from org, blocking deletion of any org you owned. The trigger was designed for member-management (preventing the last owner from being removed) but couldn't distinguish that from a cascading org delete.

Now removeMember and updateRole enforce the invariant in the application layer, where the cascade path skips the check entirely. The check uses select ... for update on the remaining owner rows to close the race the trigger already had: two concurrent owner removals could each see the other as still present and proceed, leaving the org with zero owners. With the row locks, the second transaction blocks on the first and observes the post-commit count.

Migration 008 drops the trigger and helper function. Adds a regression test verifying deleteOrg cascades cleanly when the deleting user is the sole owner.

The BEFORE DELETE/UPDATE trigger on org_member fired during the cascade
from `delete from org`, blocking deletion of any org you owned. The
trigger was designed for member-management (preventing the last owner
from being removed) but couldn't distinguish that from a cascading org
delete.

Now removeMember and updateRole enforce the invariant in the
application layer, where the cascade path skips the check entirely.
The check uses `select ... for update` on the remaining owner rows
to close the race the trigger already had: two concurrent owner
removals could each see the other as still present and proceed,
leaving the org with zero owners. With the row locks, the second
transaction blocks on the first and observes the post-commit count.

Migration 008 drops the trigger and helper function. Adds a regression
test verifying `deleteOrg` cascades cleanly when the deleting user
is the sole owner.
@jgpruitt jgpruitt merged commit fba1639 into main Apr 28, 2026
3 checks passed
@jgpruitt jgpruitt deleted the me0/fix-org-delete branch April 28, 2026 20:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant