Staff Dashboard Implementation Plan

🎯 Overview

A secure, enterprise-grade staff dashboard for managing Clerk users and system administration, accessible only to authorized @do.dev staff members.

🔒 Security Architecture

Defense in Depth (4 Layers)

  1. Layer 1: Next.js Middleware

    • Protects all /staff/* routes
    • Checks authentication, email domain, and staff access
    • Redirects unauthorized users before page render
  2. Layer 2: Layout Server Component

    • Server-side verification in /staff/layout.tsx
    • Double-checks credentials at page level
    • Returns 404 for unauthorized (don't reveal dashboard exists)
  3. Layer 3: Convex Functions

    • Every staff query/mutation calls requireStaffAccess()
    • Validates JWT claims for staffDashboardAccess
    • Independent of Next.js layer
  4. Layer 4: Client Components

    • UI-level hiding of sensitive elements
    • Already authorized at this point (UX only)

Access Requirements (BOTH must be true)

  • ✅ User email ends with @do.dev
  • user.privateMetadata.staffDashboardAccess === true

📊 Data Architecture

Clerk Integration

Private Metadata Storage:

user.privateMetadata = {
  staffDashboardAccess: boolean
}

JWT Claims Configuration:

  • Configure Clerk JWT template to include staffDashboardAccess in claims
  • Enables Convex to check access without additional API calls

Convex Database Schema

staffAuditLogs table:

{
  _id: Id<"staffAuditLogs">,
  _creationTime: number,
  staffUserId: string,        // Clerk user ID
  staffUserEmail: string,
  action: string,             // "view_user", "grant_staff_access", etc.
  targetUserId?: string,      // If action involves another user
  details: object,            // JSON details of the action
  ipAddress?: string,
  userAgent?: string
}

userProfiles table:

{
  _id: Id<"userProfiles">,
  _creationTime: number,
  clerkUserId: string,
  lastActive?: number,
  notes?: string,             // Staff notes about user
  tags?: string[],            // Admin tags
  customData?: object
}

🗂️ File Structure

apps/homepage-web/
├── app/
│   ├── staff/                          # Staff-only routes
│   │   ├── layout.tsx                  # Staff layout with auth check
│   │   ├── page.tsx                    # Dashboard overview
│   │   ├── users/
│   │   │   ├── page.tsx                # User list
│   │   │   └── [userId]/
│   │   │       └── page.tsx            # User detail page
│   │   ├── audit-logs/
│   │   │   └── page.tsx                # Audit log viewer
│   │   └── settings/
│   │       └── page.tsx                # Staff settings
│   └── middleware.ts                   # Update for /staff protection
├── components/
│   └── staff/                          # Staff-only components
│       ├── StaffSidebar.tsx
│       ├── StaffHeader.tsx
│       ├── UserTable.tsx
│       ├── UserCard.tsx
│       ├── AuditLogTable.tsx
│       ├── StatCard.tsx
│       └── ConfirmationDialog.tsx
├── lib/
│   ├── auth/
│   │   └── staff-auth.ts               # Staff authorization utilities
│   └── errors/
│       └── staff-errors.ts             # Error handling
├── convex/
│   ├── schema.ts                       # Update with staff tables
│   ├── _helpers/
│   │   └── staffAuth.ts                # Convex staff auth helper
│   └── staff/                          # Staff-only functions
│       ├── dashboard.ts                # Dashboard queries
│       ├── users.ts                    # User management queries/mutations
│       └── auditLogs.ts                # Audit log queries
└── scripts/
    └── grant-staff-access.ts           # Initial setup script

🚀 Implementation Phases

Phase 1: Foundation (Security First)

Priority: CRITICAL

  1. Create Convex schema for audit logs and user profiles
  2. Implement lib/auth/staff-auth.ts utilities
  3. Create Convex requireStaffAccess() helper
  4. Create scripts/grant-staff-access.ts for initial setup
  5. Set up error handling utilities

Deliverables:

  • ✅ Convex schema deployed
  • ✅ Auth utilities tested
  • ✅ First staff member granted access

Phase 2: Route Protection

Priority: HIGH

  1. Update middleware.ts to protect /staff routes
  2. Create app/staff/layout.tsx with server-side auth
  3. Create basic unauthorized/404 pages

Deliverables:

  • ✅ All /staff routes protected
  • ✅ Unauthorized users blocked
  • ✅ Proper error pages

Phase 3: Core UI

Priority: HIGH

  1. Build staff dashboard overview page
  2. Create Convex queries for dashboard stats
  3. Build user list UI with table, search, filters
  4. Create user detail page
  5. Implement basic navigation

Deliverables:

  • ✅ Functional dashboard overview
  • ✅ User list with search
  • ✅ User detail views
  • ✅ Navigation working

Phase 4: Advanced Features

Priority: MEDIUM

  1. Create Convex mutations for user operations
  2. Implement audit log viewer
  3. Add confirmation dialogs for destructive actions
  4. Build staff member management UI

Deliverables:

  • ✅ User management operations
  • ✅ Audit trail viewer
  • ✅ Safety confirmations
  • ✅ Staff access control

Phase 5: Security Hardening

Priority: HIGH

  1. Comprehensive error handling
  2. Security testing checklist
  3. Rate limiting on write operations
  4. Loading states and optimistic updates

Deliverables:

  • ✅ All security tests pass
  • ✅ Error handling comprehensive
  • ✅ Production ready

🎨 UI/UX Design

Dashboard Overview Sections

  1. Key Metrics Cards:

    • Total Users
    • Active Users (24h/7d/30d)
    • Staff Users
    • New Users (today/week/month)
  2. Recent Activity Feed:

    • Last 10 user signups
    • Recent staff actions
    • User profile updates
  3. Quick Actions:

    • Search user
    • View audit logs
    • Add staff member

User Management Features

  • List all users with pagination
  • Search by email, name, user ID
  • Filter by status (active, banned, etc.)
  • View user metadata and settings
  • Grant/revoke staff access
  • Add staff notes
  • View activity history

Component Design Principles

  • Use ShadCN UI components for consistency
  • Warning colors (amber/orange) for admin actions
  • Clear confirmation dialogs for dangerous operations
  • Real-time updates via Convex reactivity
  • Responsive design (desktop-first for staff tools)

🔧 Configuration Requirements

Clerk Setup

  1. JWT Template Configuration (CRITICAL):

    Dashboard → JWT Templates → Create/Edit "convex"
    
    Claims:
    {
      "staffDashboardAccess": "{{user.private_metadata.staffDashboardAccess}}"
    }
  2. Initial Staff User:

    pnpm tsx scripts/grant-staff-access.ts user@do.dev

Convex Deployment

# Deploy schema changes
pnpm convex:deploy

# Verify deployment
npx convex dev

✅ Security Testing Checklist

Authentication Tests

  • Unauthenticated user blocked from /staff routes
  • Authenticated non-@do.dev user blocked
  • Authenticated @do.dev user without flag blocked
  • Only authorized users can access dashboard

Authorization Tests

  • Middleware blocks before page render
  • Layout performs server-side check
  • Convex functions reject unauthorized
  • User losing access mid-session is blocked

Edge Cases

  • Email domain change → immediate denial
  • User modifying own staff access → rejected
  • Expired token → forced re-auth
  • Invalid user ID → proper error

Audit Trail

  • All staff actions logged
  • Failed access attempts logged
  • Logs immutable by staff
  • Sufficient context for investigation

Data Privacy

  • privateMetadata never exposed to client
  • Sensitive data not in error messages
  • Dashboard hidden from normal users

🚨 Critical Security Notes

  1. Never expose staff dashboard existence to unauthorized users

    • Return 404, not "unauthorized"
    • No hints in client-side code
    • No analytics tracking for unauthorized attempts
  2. Prevent self-modification

    • Staff cannot grant/revoke own staff access
    • Requires another staff member
  3. Audit everything

    • Every read operation logs to audit trail
    • Include IP, user agent, timestamp
    • Store before/after state for changes
  4. Rate limiting

    • Implement rate limits on write operations
    • Prevent abuse even from authorized staff

📝 Operations to Implement

Read Operations (Queries)

  • List all users with pagination
  • Search users by email/name
  • Get user details
  • Get user sessions
  • View audit logs with filters
  • Dashboard statistics

Write Operations (Mutations)

  • Update user metadata
  • Grant/revoke staff access (with reason)
  • Ban/unban users
  • Delete users (double confirmation)
  • Add staff notes to users

Operations NOT to Implement

  • Password reset (users do this themselves)
  • Email verification bypass
  • Direct session manipulation

🔍 Error Handling Strategy

Error Types

export class StaffAuthError extends Error {
  code: "NO_AUTH" | "INVALID_DOMAIN" | "NO_STAFF_ACCESS" | "REVOKED"
}

Error Responses

  • Authentication errors → redirect to home
  • Authorization errors → log and show 404
  • Clerk API errors → retry with exponential backoff
  • Convex errors → show user-friendly message
  • All errors logged to audit trail

📈 Success Metrics

  • ✅ Zero unauthorized access to staff routes
  • ✅ 100% audit coverage of staff actions
  • ✅ <100ms auth check overhead
  • ✅ All security tests passing
  • ✅ Comprehensive error handling

🎓 Next Steps

  1. Review and approve this plan
  2. Configure Clerk JWT template
  3. Begin Phase 1 implementation
  4. Test each phase thoroughly
  5. Deploy to production with monitoring

Estimated Total Development Time: 7-11 hours Priority: HIGH (Security-critical feature) Status: Ready for implementation

On this page