🟡 Priority: High
Difficulty: Hard
Estimated Effort: 4-5 days
Relevant Files: src/routes/, src/controllers/, src/middleware/, prisma/schema.prisma
Labels: enhancement, priority:high, admin
Requirements
-
Admin User Model
- Add an
AdminUser model to Prisma:
model AdminUser {
id String @id @default(uuid())
email String @unique
password String // bcrypt hashed
role String @default("VIEWER") // VIEWER, MODERATOR, ADMIN, SUPER_ADMIN
lastLogin DateTime?
createdAt DateTime @default(now())
}
- Seed a default SUPER_ADMIN account on first deployment
-
Authentication
POST /admin/login — email + password, returns a JWT with { adminId, role, exp }
- JWT secret must be separate from any other secret in the system
- Token expiry: 1 hour for VIEWER, 4 hours for ADMIN/SUPER_ADMIN
- Refresh tokens with 7-day expiry stored in Redis
-
RBAC Middleware
- Create
src/middleware/rbac.middleware.ts
- Define permissions:
VIEWER: read-only access to dashboards and reports
MODERATOR: can flag/unflag users, resolve disputes
ADMIN: can manage groups, trigger payouts, view financials
SUPER_ADMIN: can manage admin users, rotate encryption keys, access audit logs
- Middleware checks
req.admin.role against required permission for each route
-
Dashboard Endpoints
GET /admin/dashboard/stats — total users, active groups, total contributions, total payouts (last 24h, 7d, 30d)
GET /admin/users?page=1&limit=20&search=phone — paginated user list with search
GET /admin/users/:id — user detail with wallet info (public key only), group memberships, contribution history
GET /admin/groups?page=1&limit=20&status=active — paginated group list
GET /admin/groups/:id — group detail with members, contributions, payout history
GET /admin/transactions?page=1&limit=50&status=failed — transaction log with filters
POST /admin/groups/:id/trigger-payout — manually trigger a payout (ADMIN only)
POST /admin/users/:id/flag — flag a user for review (MODERATOR+)
-
Audit Logging
- Every admin action must be logged in an
AdminAuditLog table:
model AdminAuditLog {
id String @id @default(uuid())
adminId String
action String
target String // e.g., "user:abc123" or "group:def456"
metadata Json?
ip String
createdAt DateTime @default(now())
}
- Audit logs are append-only (no updates or deletes)
-
Testing
- Unit test: RBAC middleware correctly blocks unauthorized access
- Unit test: JWT validation works for valid/expired/tampered tokens
- Integration test: full login → access dashboard → trigger payout flow
- Test: VIEWER cannot trigger payouts, ADMIN can
- Target: >85% coverage on admin module
🟡 Priority: High
Difficulty: Hard
Estimated Effort: 4-5 days
Relevant Files:
src/routes/,src/controllers/,src/middleware/,prisma/schema.prismaLabels:
enhancement,priority:high,adminRequirements
Admin User Model
AdminUsermodel to Prisma:Authentication
POST /admin/login— email + password, returns a JWT with{ adminId, role, exp }RBAC Middleware
src/middleware/rbac.middleware.tsVIEWER: read-only access to dashboards and reportsMODERATOR: can flag/unflag users, resolve disputesADMIN: can manage groups, trigger payouts, view financialsSUPER_ADMIN: can manage admin users, rotate encryption keys, access audit logsreq.admin.roleagainst required permission for each routeDashboard Endpoints
GET /admin/dashboard/stats— total users, active groups, total contributions, total payouts (last 24h, 7d, 30d)GET /admin/users?page=1&limit=20&search=phone— paginated user list with searchGET /admin/users/:id— user detail with wallet info (public key only), group memberships, contribution historyGET /admin/groups?page=1&limit=20&status=active— paginated group listGET /admin/groups/:id— group detail with members, contributions, payout historyGET /admin/transactions?page=1&limit=50&status=failed— transaction log with filtersPOST /admin/groups/:id/trigger-payout— manually trigger a payout (ADMIN only)POST /admin/users/:id/flag— flag a user for review (MODERATOR+)Audit Logging
AdminAuditLogtable:Testing