screentinker/server
ScreenTinker 05f9c20ecf fix(admin): user deletion failed with FOREIGN KEY constraint (#18)
DELETE /api/auth/users/:id ran a bare `DELETE FROM users`, but 23 columns
reference users(id) and only 4 cascade, so with foreign_keys=ON the delete
fails the moment the user is referenced anywhere - and a real user always is
(owns an org, created a workspace, has login activity). Reproduces on a fresh
DB, exactly as reported.

The schema also lacks cascades from workspaces -> tenant resources, so the DB
can't clean up on its own. New lib/user-deletion.js resolves every reference in
one transaction (defer_foreign_keys=ON for forgiving order; table-existence
guard for resilience):
  - Refuse (409) if the user OWNS an organization that has other members -
    don't nuke a shared tenant; transfer ownership first.
  - Hard-delete the organizations they SOLELY own (workspaces + all contents).
  - In orgs they don't own, PRESERVE resources: SET NULL the nullable
    creator/inviter columns, and reassign the NOT NULL legacy creator user_id to
    the resource's org owner (fallback: the acting admin).
  - Memberships (organization_members/workspace_members/team_members/
    content_folders) cascade on the user delete; pending invites they sent and
    legacy teams they own are removed.

The handler now 404s an unknown id and 409s the shared-org case.

Tests (node:test): reproduces the FK failure, then verifies provisioned-member
delete (resources preserved + unlinked/reassigned), solo-org-owner cascade,
shared-org refusal (409), self-delete 400, non-superadmin 403, unknown 404.
Full suite 22/22. Verified end-to-end on a copy of a real DB: deleted a user
owning 2 solo orgs, foreign_key_check clean.

Closes #18.
2026-06-08 10:51:32 -05:00
..
config fix: log real client IPs through Cloudflare instead of CF edge 2026-05-07 15:26:37 -05:00
db feat(admin): admin-provisioned user creation + first-login gate (#10) 2026-06-05 11:03:56 -05:00
lib fix(admin): user deletion failed with FOREIGN KEY constraint (#18) 2026-06-08 10:51:32 -05:00
middleware feat(admin): admin-provisioned user creation + first-login gate (#10) 2026-06-05 11:03:56 -05:00
player security(widgets): add sandbox="allow-scripts" to widget iframes 2026-05-28 12:28:34 -05:00
routes fix(admin): user deletion failed with FOREIGN KEY constraint (#18) 2026-06-08 10:51:32 -05:00
services feat(signup): T+3 activation nudge for users with zero paired screens 2026-05-30 20:28:24 -05:00
test fix(admin): user deletion failed with FOREIGN KEY constraint (#18) 2026-06-08 10:51:32 -05:00
ws fix(proof-of-play): throttle play_logs writes to prevent runaway bloat 2026-06-02 09:52:22 -05:00
.gitignore feat(email): Microsoft Graph send + alert spam protection + preferences UI 2026-05-12 18:16:40 -05:00
config.js feat(signup): optional org-on-create for self-service signups (#12) 2026-06-05 11:16:27 -05:00
package-lock.json feat(email): Microsoft Graph send + alert spam protection + preferences UI 2026-05-12 18:16:40 -05:00
package.json test(admin): node:test coverage for Add User + role gating 2026-06-05 11:23:06 -05:00
server.js feat(admin): admin-provisioned user creation + first-login gate (#10) 2026-06-05 11:03:56 -05:00