import { Response } from 'express'; import { AuthenticatedRequest } from '../types'; import * as roleService from '../services/role.service'; import { CreateRoleInput, UpdateRoleInput } from '../validators/role.validator'; /** * GET /roles * List all roles (all authenticated users) */ export async function getAllRoles( _req: AuthenticatedRequest, res: Response ): Promise { try { const roles = await roleService.getAll(); res.status(200).json({ success: true, message: 'Roles retrieved successfully', data: roles, }); } catch (error) { const message = error instanceof Error ? error.message : 'Failed to retrieve roles'; res.status(500).json({ success: false, error: message, }); } } /** * GET /roles/:id * Get a single role by ID with user count (all authenticated users) */ export async function getRoleById( req: AuthenticatedRequest, res: Response ): Promise { try { const roleId = req.params.id; const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; if (!uuidRegex.test(roleId)) { res.status(400).json({ success: false, error: 'Invalid role ID', }); return; } const role = await roleService.getById(roleId); if (!role) { res.status(404).json({ success: false, error: 'Role not found', }); return; } res.status(200).json({ success: true, message: 'Role retrieved successfully', data: role, }); } catch (error) { const message = error instanceof Error ? error.message : 'Failed to retrieve role'; res.status(500).json({ success: false, error: message, }); } } /** * POST /roles * Create a new role (admin only) */ export async function createRole( req: AuthenticatedRequest, res: Response ): Promise { try { const data = req.body as CreateRoleInput; const role = await roleService.create({ name: data.name, description: data.description, permissions: data.permissions as Record | undefined, }); res.status(201).json({ success: true, message: 'Role created successfully', data: role, }); } catch (error) { const message = error instanceof Error ? error.message : 'Failed to create role'; if (message === 'Role name already exists') { res.status(409).json({ success: false, error: message, }); return; } res.status(500).json({ success: false, error: message, }); } } /** * PUT /roles/:id * Update a role (admin only) */ export async function updateRole( req: AuthenticatedRequest, res: Response ): Promise { try { const roleId = req.params.id; const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; if (!uuidRegex.test(roleId)) { res.status(400).json({ success: false, error: 'Invalid role ID', }); return; } const data = req.body as UpdateRoleInput; const role = await roleService.update(roleId, { name: data.name, description: data.description, permissions: data.permissions as Record | undefined, }); if (!role) { res.status(404).json({ success: false, error: 'Role not found', }); return; } res.status(200).json({ success: true, message: 'Role updated successfully', data: role, }); } catch (error) { const message = error instanceof Error ? error.message : 'Failed to update role'; if (message === 'Role name already exists') { res.status(409).json({ success: false, error: message, }); return; } res.status(500).json({ success: false, error: message, }); } } /** * DELETE /roles/:id * Delete a role (admin only, only if no users assigned) */ export async function deleteRole( req: AuthenticatedRequest, res: Response ): Promise { try { const roleId = req.params.id; const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; if (!uuidRegex.test(roleId)) { res.status(400).json({ success: false, error: 'Invalid role ID', }); return; } const deleted = await roleService.deleteRole(roleId); if (!deleted) { res.status(404).json({ success: false, error: 'Role not found', }); return; } res.status(200).json({ success: true, message: 'Role deleted successfully', }); } catch (error) { const message = error instanceof Error ? error.message : 'Failed to delete role'; // Handle case where users are assigned to the role if (message.includes('Cannot delete role')) { res.status(409).json({ success: false, error: message, }); return; } res.status(500).json({ success: false, error: message, }); } }