Skip to main content

SPEC 019 — Admin Panel

FieldValue
StatusDRAFT
PriorityP1 — Core Product
Backendequa-server/modules/admin/
Frontendequa-web/src/modules/admin/

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 the GlobalRolesUsers 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

DetailValue
EntityGlobalRolesUsers — maps users to site-level roles
Role fieldrole (GlobalRole integer enum)
GuardMiddleware checks GlobalRolesUsers before allowing admin endpoint access
ScopeAdmin privileges are platform-wide, not scoped to any organization

2.2 User Management

DetailValue
CapabilitiesList all users, search by email, enable/disable accounts, view user details
Backendequa-server/modules/admin/ handles user queries and mutations
Endpointsequa-server/modules/api/src/endpoints/admin-endpoints.ts

2.3 Site Statistics

DetailValue
MetricsTotal users, organizations, active sessions, recent sign-ups, storage usage
SourceAggregation queries against Users, Organizations, Sessions tables
DisplayDashboard cards and charts on the admin frontend

2.4 Blacklists

DetailValue
Domain blacklistDomainBlacklists — blocks registration from specific email domains
Email blacklistEmailBlacklists — blocks specific email addresses
EnforcementChecked during registration and invitation flows

2.5 Frontend

ComponentPath
Admin moduleequa-web/src/modules/admin/
DashboardAdmin landing page with stats cards
User managementSearchable user table with action menus

3. Data Model

GlobalRolesUsers

ColumnTypeConstraints
useruuidPK, FK → Users
roleintegerNOT NULL — GlobalRole enum value

DomainBlacklists

ColumnTypeConstraints
iduuidPK
domainvarcharUNIQUE, NOT NULL — e.g. spam-domain.com
reasonvarcharnullable
createdByuuidFK → Users
createdAttimestampDEFAULT now()

EmailBlacklists

ColumnTypeConstraints
iduuidPK
emailcitextUNIQUE, NOT NULL
reasonvarcharnullable
createdByuuidFK → Users
createdAttimestampDEFAULT now()

4. API Endpoints

MethodPathAuthDescription
GET/api/v1/admin/statsAdminPlatform-wide statistics (users, orgs, sessions, storage)
GET/api/v1/admin/usersAdminPaginated user list with search and filters
GET/api/v1/admin/users/:userIdAdminSingle user detail (orgs, sessions, activity)
PUT/api/v1/admin/users/:userIdAdminUpdate user (enable/disable, modify fields)
DELETE/api/v1/admin/users/:userIdAdminSoft-delete or permanently remove a user account
GET/api/v1/admin/organizationsAdminPaginated organization list
GET/api/v1/admin/blacklists/domainsAdminList domain blacklist entries
POST/api/v1/admin/blacklists/domainsAdminAdd a domain to the blacklist
DELETE/api/v1/admin/blacklists/domains/:idAdminRemove a domain from the blacklist
GET/api/v1/admin/blacklists/emailsAdminList email blacklist entries
POST/api/v1/admin/blacklists/emailsAdminAdd an email to the blacklist
DELETE/api/v1/admin/blacklists/emails/:idAdminRemove an email from the blacklist
All “Admin” auth endpoints require the requesting user to have an entry in GlobalRolesUsers with an appropriate admin role.

5. Frontend Components

ComponentPathDescription
AdminDashboardadmin/AdminDashboard.tsxLanding page with statistics cards (users, orgs, sessions, storage)
UserManagementadmin/UserManagement.tsxSearchable, paginated user table with inline actions
UserDetailadmin/UserDetail.tsxFull user profile view with organization memberships and session history
DomainBlacklistadmin/DomainBlacklist.tsxCRUD table for blocked domains
EmailBlacklistadmin/EmailBlacklist.tsxCRUD table for blocked email addresses
OrgBrowseradmin/OrgBrowser.tsxPaginated organization list with summary stats

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

  1. Global role separation — Admin access is completely separate from organization-level roles. Being an org admin does not grant platform admin access.
  2. GlobalRolesUsers is the single source of truth — All admin middleware checks this table; there is no fallback to environment variables or hardcoded user IDs.
  3. 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).
  4. Email blacklist enforcement — Specific email addresses in EmailBlacklists are blocked from registration and invitation with the same generic error.
  5. Blacklist is case-insensitive — Domain comparison is lowercase; email comparison uses citext for case-insensitive matching.
  6. User disable vs delete — Disabling a user (enabled = false) blocks login but preserves data. Deletion removes the account and is irreversible.
  7. Audit trail — Blacklist entries record createdBy to track which admin added them.
  8. Self-protection — Admins cannot disable or delete their own account through the admin panel.
  9. No self-promotion — Adding entries to GlobalRolesUsers is restricted to existing admins or direct database access; there is no self-service admin promotion endpoint.
  10. Statistics are real-time — Stats endpoints run live aggregation queries; no materialized views or caches are used.

7. Acceptance Criteria

  • Only users with a GlobalRolesUsers entry 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

8. Risks

RiskImpactMitigation
Privilege escalation via direct DB insert into GlobalRolesUsersUnauthorized admin accessRestrict DB write access; audit GlobalRolesUsers changes
Admin account compromiseFull platform controlRequire 2FA for admin accounts; log all admin actions
Real-time stats queries on large datasetsSlow dashboard load, DB strainAdd query timeouts; consider materialized views if scale demands
Blacklist bypass via email aliases (e.g. user+tag@domain.com)Blocked users re-registerNormalize emails (strip + aliases) before blacklist check
Accidental user deletionIrreversible data lossImplement soft-delete with grace period before hard purge
No rate limiting on admin endpointsAbuse by compromised admin sessionAdd rate limiting; log and alert on unusual admin activity patterns
Blacklist reason field is optionalPoor audit trail for why domains/emails were blockedConsider making reason required or defaulting to a standard message
Self-protection rule bypass via APIAdmin disables own account, locks themselves outServer-side check preventing self-targeting on disable/delete endpoints