Project 1 - Admin Panel
Admin Panel - Roles & Permissions
The app has three roles: user, instructor, and admin. Access control is enforced in middleware, server actions, and API routes.
Roles
| Role | Description |
|---|---|
| user | Default for new signups. Can enroll in courses, view their progress, orders, invoices, and chat. |
| instructor | Can create and manage their own courses (modules, chapters), view enrollments, and chat with students. |
| admin | Full access: manage all users, roles, courses, categories, blogs, events, invoices, accounting, media, and chat. |
Database
- Enum type
user_rolewith valuesuser,instructor,admin. user_profileshas arolecolumn (defaultuser).- Only admins should be allowed to change roles (enforced in app code and, if applicable, DB policies).
Assigning roles
- Signup: New users get
userby default. Admins can assign a different role during registration if the flow supports it. - After signup: Use the admin “Manage roles” (or equivalent) UI, or call the role-update API/server action that checks admin and updates
user_profiles.role.
Using roles in code
Server components / pages
Protect pages by requiring a role (e.g. redirect if not allowed):
import { requireAdmin } from '@/lib/auth/middleware'
export default async function AdminPage() {
await requireAdmin()
return <div>Admin content</div>
}
Server actions
Check role before performing sensitive actions:
'use server'
import { isAdmin } from '@/lib/auth/roles'
export async function deleteUser(userId: string) {
if (!(await isAdmin())) return { success: false, error: 'Unauthorized' }
// ... delete user
}
Client components
Get role on the server and pass as a prop so the client can show/hide UI (authorization still enforced on server):
// Server
const role = await getCurrentUserRole()
return <ClientComponent userRole={role} />
// Client
{userRole === 'admin' && <AdminButton />}
Key files
- Role helpers:
src/lib/auth/roles.tsgetCurrentUserProfile(),getCurrentUserRole(),hasRole(),isAdmin(),isInstructor(),isUser(),hasAnyRole(),isAdminOrInstructor()updateUserRole(userId, newRole)(admin only),getAllUsersWithRoles()(admin only)
- Middleware:
src/lib/auth/middleware.tsrequireRole(role),requireAdmin(),requireInstructor(),requireAdminOrInstructor(),requireAuth()
- Types:
src/lib/auth/types.ts– e.g.UserRole,USER_ROLES
Security
- Always enforce roles on the server; client checks are for UX only.
- Prefer least privilege: default new users to
user. - Consider logging role changes for auditing.
See Features for what each role can do in the UI (courses, blogs, chat, etc.).