Access Requirements
Requires
moderator or admin role to access /admin/usersUser List View
The main user management page displays all platform users with:- Statistics cards: Total users, hidden count, banned count, and elevated roles (admins/moderators)
- Search: Filter by display name or username (case-insensitive)
- Tab filters: All, Active, Hidden, Banned
- Pagination: 20 users per page
- Avatar and display name (obfuscated for privacy)
- Username (if set)
- Clerk ID (obfuscated, click to reveal)
- Role badge (
user,moderator, oradmin) - Status badge (Active, Hidden, or Banned)
- Country code and account age
- Quick action buttons
Privacy Features
Personally identifiable information (PII) is automatically obfuscated in the list view. Click to reveal specific fields as needed. This protects user privacy during live streaming or screen sharing.
User Detail View
Navigate to/admin/users/[id] to view comprehensive user details:
Profile Information
- Display name, username, Clerk ID
- Country and region (ISO codes)
- Experience level
- Bio and social links (GitHub, Twitter, website, Twitch)
- Account creation date
Moderation History
If a user is banned or hidden, the status panel displays:- Action timestamp
- Name of admin/moderator who performed the action
- Ban reason (if provided)
Activity
- Event Registrations: Shows registered events with team preference and commitment level
- Projects: Lists all projects created by the user (with links if slug exists)
Moderation Actions
Hide User
Permission: Moderators and admins Soft-hides a user profile from public view without blocking authentication:- Sets
hiddenAttimestamp andhiddenByactor ID - User can still sign in but profile is filtered from public queries
- Cannot hide super-admins (defined in
ADMIN_USER_IDSenv var) - Logs action to
adminAuditLogtable
- Cannot hide users who are already hidden
- Cannot hide super-admins
Unhide User
Permission: Moderators and admins Reverts a hide action:- Clears
hiddenAtandhiddenByfields - Restores profile to public queries
- Logs action to audit log
Ban User
Permission: Moderators and admins (with restrictions) Permanently blocks a user from accessing the platform:- Sets
bannedAt,bannedBy, and optionalbanReason - Calls
clerk.users.banUser(clerkId)to disable authentication - Banned users are redirected to
/bannedpage by middleware - Logs action with reason to audit log
Moderators cannot ban users with
admin role. Only admins can ban other admins.- Cannot ban super-admins
- Cannot ban yourself
- Cannot ban already-banned users
Unban User
Permission: Admin only Reverts a ban and restores full account access:- Clears
bannedAt,bannedBy,banReason,hiddenAt, andhiddenBy - Calls
clerk.users.unbanUser(clerkId)to restore authentication - Logs action to audit log
Unbanning also clears any hidden status to ensure full restoration.
Delete User
Permission: Admin only Cascading deletion order (seelib/db/delete-profile.ts):
- Team invites (sent and received)
- Project memberships
- Event registrations
- Event projects
- Projects (owned)
- Profile record
- Logs to audit log with deleted user metadata (since target profile no longer exists)
- Calls
clerk.users.deleteUser(clerkId)to remove from Clerk
- Cannot delete super-admins
- Cannot delete yourself
Implementation Details
Database Schema
Relevantprofiles table columns (from lib/db/schema.ts:77-105):
Server Actions
All moderation actions are defined inapp/admin/users/actions.ts:
hideUser(lines 36-74)unhideUser(lines 76-111)banUser(lines 113-182)unbanUser(lines 184-237)deleteUser(lines 239-309)
- Verifies actor permissions via
isModerator(userId)orisAdmin(userId) - Validates target user state and super-admin checks
- Performs database updates
- Syncs with Clerk (non-blocking — DB is source of truth)
- Logs to
adminAuditLog - Revalidates
/admin/userspath - Returns
{ success: true }or{ success: false, error: string }
Queries
User management queries are inlib/admin/queries.ts:
getAdminUserList()(lines 144-163): Returns all profiles ordered by creation dategetAdminUserDetail(profileId)(lines 165-204): Returns profile with relations (projects, registrations) and moderator namesgetAdminUserStats()(lines 241-265): Returns counts for total, hidden, banned, and elevated users
Client Components
AdminUsersClient (app/admin/users/admin-users-client.tsx):
- Client-side search and filtering state
- Obfuscated field rendering for PII protection
- Action buttons conditional on user status and current role
- Real-time role badge and status indicators
app/admin/users/[id]/user-detail-actions.tsx):
- Renders action buttons based on current moderation state
- Shows unban button only to admins
- Confirmation dialogs for destructive actions
Role Permissions Matrix
| Action | User | Moderator | Admin |
|---|---|---|---|
| View user list | No | Yes | Yes |
| View user detail | No | Yes | Yes |
| Hide user | No | Yes | Yes |
| Unhide user | No | Yes | Yes |
| Ban user (user role) | No | Yes | Yes |
| Ban admin | No | No | Yes |
| Unban user | No | No | Yes |
| Delete user | No | No | Yes |
Best Practices
- Always provide a ban reason to document moderation decisions
- Use hide instead of ban for temporary visibility restrictions
- Check audit log before reversing another moderator’s actions
- Verify super-admin status before attempting admin-level actions (system will prevent, but awareness helps)
- Review user activity (registrations, projects) before deletion to assess impact