Platform admin
Users (incl. delete)
/admin/users lists every user account on the platform โ
super-admins, customers, and members invited into any workspace. The
page supports search by name/email, role promotion, BYOK per-user
overrides, edit, impersonate, and (since v1.1) delete.
Delete
Super-admin only. Click the Delete button on any user row (the button is hidden on your own row). A confirm dialog spells out the consequence โ they lose access to every workspace and the row is soft-deleted for audit.
Safety rails
The controller refuses four cases:
- Self-delete โ you cannot delete the account you are signed into. Would lock you out of admin.
- Last super-admin โ defence-in-depth check; the controller refuses if the target is a super-admin and no other live super-admin exists.
-
Workspace owner โ if the user still owns one or
more workspaces, the delete returns an error toast naming the
count. Transfer ownership at
/admin/workspaces/{id}first (or via the workspace's own Members & roles page) and retry. -
Non-super-admin actor โ the route is in the
platform-admin group; a customer hitting
DELETE /admin/users/{id}directly returns 404 to hide the endpoint's existence.
What soft-delete touches
-
users.deleted_atis set to the current timestamp. Subsequent reads via Eloquent's default scope exclude the row. -
All
workspace_userspivot rows for the user are deleted so a re-invited account doesn't collide on the unique composite key. -
Foreign-key references in
conversations,leads,audit_logs, and other tables with auser_idcolumn are left intact โ soft-delete preserves the row, so those joins keep working. -
An
AuditLogentry withaction=platform_user.deletedis written under the acting admin's default workspace, including the deleted email + role for forensic recovery.
Customer-initiated deletion (different code path)
When a customer deletes their own account from
/settings/profile, the row is
hard-deleted via forceDelete() โ a
customer-initiated deletion is treated as a GDPR right-to-erasure
request, so the data goes away for real. Only the platform-admin
delete is soft.
Restoring a soft-deleted user
There is no admin UI for restore yet. To bring back a soft-deleted account run:
php artisan tinker --execute 'App\Models\User::withTrashed()->where("email","x@y.com")->first()->restore();'
The user's workspace memberships are NOT restored โ they need a
fresh invitation. If the original workspace is gone too,
default_workspace_id will be stale and the next visit
redirects them through the standard onboarding flow.