# Adding a MANAGER Role - Complete Example ## 1. Update Types ```typescript // src/shared/types/index.ts export enum UserRole { SYSTEM_ADMIN = 'SYSTEM_ADMIN', BUSINESS_OWNER = 'BUSINESS_OWNER', MANAGER = 'MANAGER', // ← NEW STAFF = 'STAFF', AUDITOR = 'AUDITOR', } ``` ## 2. Update Role Constants ```typescript // src/shared/constants/roles.ts export const ROLE_HIERARCHY = { [UserRole.SYSTEM_ADMIN]: 4, [UserRole.BUSINESS_OWNER]: 3, [UserRole.MANAGER]: 2.5, // ← NEW (between business owner and staff) [UserRole.STAFF]: 2, [UserRole.AUDITOR]: 1, }; export const ROLE_PERMISSIONS = { // ... existing roles [UserRole.MANAGER]: [ 'manage_team_receipts', 'view_team_reports', 'verify_receipts', 'manage_staff_schedules', // ← NEW PERMISSIONS ], }; ``` ## 3. Update Database Schema ```prisma // prisma/schema.prisma enum UserRole { SYSTEM_ADMIN BUSINESS_OWNER MANAGER // ← ADD STAFF AUDITOR } ``` ## 4. Add Manager-Specific Endpoints ```typescript // src/features/users/users.controller.ts @Get('my-team') @Roles(UserRole.MANAGER, UserRole.BUSINESS_OWNER, UserRole.SYSTEM_ADMIN) @ApiOperation({ summary: 'Get team members (Manager access)' }) async getMyTeam(@CurrentUser() user: any) { return this.usersService.getTeamByManager(user.id); } @Post('assign-staff') @Roles(UserRole.MANAGER, UserRole.BUSINESS_OWNER) @ApiOperation({ summary: 'Assign staff to manager' }) async assignStaff(@Body() assignDto: AssignStaffDto) { return this.usersService.assignStaffToManager(assignDto); } ``` ## 5. Update Service Logic ```typescript // src/features/users/users.service.ts async getUsers(currentUserId: string, currentUserRole: UserRole) { // ... existing logic if (currentUserRole === UserRole.MANAGER) { // Managers see their assigned team const teamMembers = await this.supabaseDb.getUsersByManager(currentUserId); const currentUser = await this.supabaseDb.findUserById(currentUserId); return currentUser ? [currentUser, ...teamMembers] : teamMembers; } // ... rest of logic } async getTeamByManager(managerId: string): Promise { return this.supabaseDb.findUsers({ manager_id: managerId, is_active: true }); } ``` ## 6. Database Migration ```sql -- Add new role to enum ALTER TYPE "UserRole" ADD VALUE 'MANAGER'; -- Add manager_id column to users table (optional) ALTER TABLE users ADD COLUMN manager_id UUID REFERENCES users(id); -- Create index for manager relationships CREATE INDEX idx_users_manager_id ON users(manager_id); ``` ## 7. Update DTOs ```typescript // src/features/users/dto/user.dto.ts export class CreateStaffDto { @ApiProperty({ description: 'Staff role', enum: [UserRole.STAFF, UserRole.AUDITOR, UserRole.MANAGER], // ← ADD MANAGER example: UserRole.STAFF, }) @IsEnum([UserRole.STAFF, UserRole.AUDITOR, UserRole.MANAGER]) role: UserRole.STAFF | UserRole.AUDITOR | UserRole.MANAGER; @ApiPropertyOptional({ description: 'Manager ID (for staff assignments)', }) @IsOptional() @IsUUID() managerId?: string; } ``` ## Result: Fully Functional Manager Role - ✅ Hierarchical permissions (can access staff endpoints) - ✅ Manager-specific endpoints - ✅ Team management capabilities - ✅ Database relationships - ✅ Type safety maintained - ✅ API documentation updated