Skip to content

Admin Remove from portal fails silently when user has chat RESTRICT FKs #363

Description

@iPLAYCAFE-dev

Summary

Admin Users → Remove from portal appears to do nothing when the target principal still has chat activity. The mutation fails in the database, the React Query optimistic update rolls back, and no error toast is shown.

Measured root cause

removePortalUser in apps/web/src/lib/server/domains/users/user.service.ts does:

await db.delete(principal).where(eq(principal.id, principalId))

But live schema has ON DELETE RESTRICT on at least:

  • chat_messages.principal_idprincipal
  • conversations.visitor_principal_idprincipal

A portal user who only opened chat (0 posts / 0 comments / 0 votes) can still be undeleteable. Postgres raises a FK violation → wrapped as InternalError('DATABASE_ERROR', …) → client onError restores the list with no UI feedback.

Client gap

useRemovePortalUser (apps/web/src/lib/client/mutations/users.ts) has onError rollback only — no toast.
UsersContainer.handleRemoveUser only clears selection on onSuccess.

Suggested fix

  1. Before deleting the principal (or inside a transaction), detach/delete org-scoped chat residue in a product-safe way or refuse with a typed error the UI can show (e.g. “This user still has conversations”).
  2. Surface mutation failures with a toast / dialog error (don’t fail closed silently).
  3. Align the comment above removePortalUser with actual FK direction (principal.user_id → user CASCADE does not delete the user when the principal is deleted — the newer comment in-tree is correct; the older inline comment next to the delete is misleading).

Repro shape

  1. Create/sign a portal role=user principal.
  2. Start a widget chat so conversations.visitor_principal_id + chat_messages.principal_id point at that principal.
  3. Admin → Users → select user → Remove from portal → confirm.
  4. Observe: modal/selection behavior looks like a no-op; principal remains.

Observed on Quackback v0.13.2 (Rerolla tenant). Happy to share more schema detail if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions