Codex 5.3 Refactor Note: Canonical refactor plan: docs/CODEX-5.3-REFACTOR-PLAN.md. This document is retained for historical and implementation context during the refactor.
W4 Quick Reference Guide
Access the Interface
URL: http://localhost:3000/admin/users
Required Role: ADMIN
Test User: admin@example.com / admin123
Main Features at a Glance
1. Search Users
Type in search box → Searches by name or email (real-time)
2. Filter Users
Role: All | ADMIN | HR | MANAGER | SMO
Status: All | ACTIVE | DISABLED | PENDING_INVITE
Last Login: All | Last 7 days | Last 30 days | Never
3. View User Details
Click any row in the table → Details load in right panel
Shows: Profile info + Access controls + Recent activity
4. Change User Role
1. Select user in table
2. In right panel, change Role dropdown
3. Confirm in modal dialog
4. Role updates + Audit logged
5. Disable/Enable Account
1. Select user in table
2. In right panel, toggle "Account Active"
3. Confirm in modal dialog
4. Status updates + Audit logged
Note: Cannot disable own account (guardrail)
6. Force Password Reset
1. Select user in table
2. In right panel, toggle "Force Password Reset"
3. Confirm in modal dialog
4. Flag set + Audit logged
Note: User sees reset prompt on next login (future feature)
7. Resend Setup Invite
1. Select PENDING_INVITE user
2. Click "Resend Setup" in right panel
3. Confirm in modal dialog
4. New invite link displays (copy to send)
5. Audit logged
8. Review Audit Log
1. Select user in table
2. Scroll to "Recent Activity" section
3. Last 10 events shown
4. Click "View Full Audit Log" for complete history
API Endpoints (For Integration/Testing)
List Users
curl -X GET "http://localhost:3000/api/users?q=john&role=HR&status=ACTIVE&page=1"
Get User Detail
curl -X GET "http://localhost:3000/api/users/{userId}"
Update User Settings
curl -X PATCH "http://localhost:3000/api/users/{userId}" \
-H "Content-Type: application/json" \
-d '{"isActive": false, "forcePasswordReset": true}'
Change Role
curl -X PUT "http://localhost:3000/api/users/{userId}/role" \
-H "Content-Type: application/json" \
-d '{"role": "MANAGER"}'
Resend Invite
curl -X POST "http://localhost:3000/api/users/{userId}/resend-setup"
Get Audit Preview
curl -X GET "http://localhost:3000/api/admin/audit?userId={userId}&limit=10"
Common Tasks
Task: Promote HR to Manager
- Search for the user
- Click row to select
- Change role dropdown from HR → MANAGER
- Click "Confirm" in modal
- Done! Audit event logged automatically
Task: Lock Account Temporarily
- Find the user
- Toggle "Account Active" OFF
- Click "Disable" to confirm
- User status changes to DISABLED
- They cannot log in until re-enabled
Task: Send New Invite to Pending User
- Filter by Status: PENDING_INVITE
- Click user to select
- Click "Resend Setup" button
- Click "Resend" to confirm
- Copy the invite link provided
- Send to user (via email/message)
Troubleshooting
Problem: "Cannot disable your own account"
- Solution: You're trying to disable yourself. Select a different user.
Problem: "Cannot remove your own admin role"
- Solution: Cannot change your own role to non-ADMIN. Change another admin's role instead.
Problem: "User is not PENDING_INVITE"
- Solution: The user doesn't have a pending invite. Only PENDING_INVITE users can receive new invites.
Problem: No results showing
- Cause: May be filtered out by current filters. Reset filters to see all users.
Problem: User appears in list but can't open detail
- Cause: User was deleted between loading list and selection. Refresh the page.
Testing Steps
Quick 5-Minute Test
- ✅ Navigate to
/admin/users - ✅ Search for a user (e.g., "hr@")
- ✅ Click to select → details load
- ✅ Change role → confirm → see toast
- ✅ Check Recent Activity for audit log
Full Test (10 minutes)
- ✅ Test each filter individually
- ✅ Test search with partial text
- ✅ Test multiple filters together
- ✅ Change role (not self)
- ✅ Toggle account active
- ✅ Set force password reset
- ✅ Try self-disable (should error)
- ✅ Try self-demotion (should error)
- ✅ Verify audit logs appear
- ✅ Check toast notifications
Database Queries (Admin Only)
View Recent User Changes
SELECT eventType, "userId", details, "createdAt"
FROM "AuditLog"
WHERE "userId" = 'user-id-here'
ORDER BY "createdAt" DESC
LIMIT 20;
Find All Disabled Accounts
SELECT id, email, fullName, status
FROM "User"
WHERE status = 'DISABLED';
Find Users Who Need Password Reset
SELECT id, email, fullName
FROM "User"
WHERE "forcePasswordReset" = true;
Check Last Login Activity
SELECT id, email, "lastLoginAt"
FROM "User"
ORDER BY "lastLoginAt" DESC
LIMIT 10;
File Locations
| Component | File |
|---|---|
| Main Page | src/app/admin/users/page.tsx |
| Table Panel | src/app/admin/users/_components/UsersTable.tsx |
| Detail Panel | src/app/admin/users/_components/UserDetail.tsx |
| List API | src/app/api/users/route.ts |
| Detail/Update API | src/app/api/users/[id]/route.ts |
| Role Change API | src/app/api/users/[id]/role/route.ts |
| Resend Invite API | src/app/api/users/[id]/resend-setup/route.ts |
| Audit API | src/app/api/admin/audit/route.ts |
| Schema | prisma/schema.prisma |
| Full Docs | docs/W4-ADMIN-USERS-IMPLEMENTATION.md |
Key Differences from Other Screens
vs. W1 (Login)
- W4 is admin-only (W1 is public)
- W4 has complex forms (W1 has single login)
- W4 has guardrails (W1 is simpler)
vs. W2 (Request Access)
- W4 is internal (W2 is public)
- W4 manages existing users (W2 creates requests)
- W4 has live changes (W2 is one-time submission)
vs. W3 (Access Requests)
- W4 manages all users (W3 only approval flow)
- W4 has 3-panel detail (W3 has 2-panel approval)
- W4 is ongoing management (W3 is workflow)
Next: Integration Tips
When integrating with other systems:
- Email System: Hook
POST /resend-setupto send emails - Notification System: Listen to audit events, send alerts
- Reporting: Query AuditLog for compliance reports
- Dashboard: Use GET
/api/usersto show user count/health - Webhooks: Post audit events to external systems
Performance Notes
- Lists default to 20 users per page
- Search is debounced (300ms) to reduce API calls
- Audit preview shows 10 events (configurable)
- Status filters reduce results immediately
- Consider adding pagination controls for large user bases
Last Updated: January 23, 2025
Status: Production Ready
Version: W4 1.0