SPEC 019 — Admin Panel
1. Feature Purpose
The Admin Panel provides site-level administrators with tools to manage users, view platform statistics, and enforce domain/email blacklists. Unlike organization-level roles (SPEC 012), admin access is granted through theGlobalRolesUsers table and operates across all organizations on the platform. This is the control plane for platform operators to monitor health, manage abuse, and support users.
2. Current State (Verified)
2.1 Global Role System
2.2 User Management
2.3 Site Statistics
2.4 Blacklists
2.5 Frontend
3. Data Model
GlobalRolesUsers
DomainBlacklists
EmailBlacklists
4. API Endpoints
All “Admin” auth endpoints require the requesting user to have an entry in
GlobalRolesUsers with an appropriate admin role.
5. Frontend Components
Frontend Behavior
- Route guard — Admin routes are protected by a global role check; non-admins see a 403 page or are redirected.
- Search — User management supports real-time search by email, username, or user ID with debounced API calls.
- Bulk actions — User list supports multi-select for bulk enable/disable operations.
- Statistics refresh — Dashboard stats auto-refresh on a 60-second interval while the page is visible.
- Confirmation modals — Destructive actions (disable user, delete blacklist entry) require confirmation before execution.
6. Business Rules
- Global role separation — Admin access is completely separate from organization-level roles. Being an org admin does not grant platform admin access.
- GlobalRolesUsers is the single source of truth — All admin middleware checks this table; there is no fallback to environment variables or hardcoded user IDs.
- Domain blacklist enforcement — During registration and team invitation, the email domain is checked against
DomainBlacklists; matching domains are rejected with a generic error (no leak of blacklist existence). - Email blacklist enforcement — Specific email addresses in
EmailBlacklistsare blocked from registration and invitation with the same generic error. - Blacklist is case-insensitive — Domain comparison is lowercase; email comparison uses
citextfor case-insensitive matching. - User disable vs delete — Disabling a user (
enabled = false) blocks login but preserves data. Deletion removes the account and is irreversible. - Audit trail — Blacklist entries record
createdByto track which admin added them. - Self-protection — Admins cannot disable or delete their own account through the admin panel.
- No self-promotion — Adding entries to
GlobalRolesUsersis restricted to existing admins or direct database access; there is no self-service admin promotion endpoint. - Statistics are real-time — Stats endpoints run live aggregation queries; no materialized views or caches are used.
7. Acceptance Criteria
- Only users with a
GlobalRolesUsersentry can access admin endpoints and routes - Non-admin users receive 403 on admin API calls and are redirected on frontend
- Admin dashboard displays correct counts for users, organizations, and active sessions
- User management table supports pagination and search by email/username
- Admin can disable a user account; disabled user cannot log in
- Admin can re-enable a disabled user account
- Admin cannot disable their own account
- Admin can add a domain to the blacklist; new registrations from that domain are blocked
- Admin can add a specific email to the blacklist; that email cannot register or be invited
- Blacklist checks are case-insensitive
- Blacklist rejections show generic error messages (no information leak)
- Admin can remove blacklist entries; previously blocked domains/emails can register again
- Organization browser displays all organizations with summary information
- Destructive actions require confirmation modal