import { Controller, Get, Post, Patch, Delete, Param, Body, UseGuards, } from '@nestjs/common'; import { JwtAuthGuard } from '../auth/jwt-auth.guard'; import { TenantId } from '../tenant/tenant.decorator'; import { TenantDatabaseService } from '../tenant/tenant-database.service'; import { Role } from '../models/role.model'; @Controller('setup/roles') @UseGuards(JwtAuthGuard) export class SetupRolesController { constructor(private tenantDbService: TenantDatabaseService) {} @Get() async getRoles(@TenantId() tenantId: string) { const resolvedTenantId = await this.tenantDbService.resolveTenantId(tenantId); const knex = await this.tenantDbService.getTenantKnexById(resolvedTenantId); return await Role.query(knex).select('*').orderBy('name', 'asc'); } @Get(':id') async getRole( @TenantId() tenantId: string, @Param('id') id: string, ) { const resolvedTenantId = await this.tenantDbService.resolveTenantId(tenantId); const knex = await this.tenantDbService.getTenantKnexById(resolvedTenantId); return await Role.query(knex).findById(id).withGraphFetched('users'); } @Post() async createRole( @TenantId() tenantId: string, @Body() data: { name: string; description?: string; guardName?: string }, ) { const resolvedTenantId = await this.tenantDbService.resolveTenantId(tenantId); const knex = await this.tenantDbService.getTenantKnexById(resolvedTenantId); const role = await Role.query(knex).insert({ name: data.name, description: data.description, guardName: data.guardName || 'tenant', }); return role; } @Patch(':id') async updateRole( @TenantId() tenantId: string, @Param('id') id: string, @Body() data: { name?: string; description?: string; guardName?: string }, ) { const resolvedTenantId = await this.tenantDbService.resolveTenantId(tenantId); const knex = await this.tenantDbService.getTenantKnexById(resolvedTenantId); const updateData: any = {}; if (data.name) updateData.name = data.name; if (data.description !== undefined) updateData.description = data.description; if (data.guardName) updateData.guardName = data.guardName; const role = await Role.query(knex).patchAndFetchById(id, updateData); return role; } @Delete(':id') async deleteRole( @TenantId() tenantId: string, @Param('id') id: string, ) { const resolvedTenantId = await this.tenantDbService.resolveTenantId(tenantId); const knex = await this.tenantDbService.getTenantKnexById(resolvedTenantId); // Delete role user assignments first await knex('user_roles').where({ roleId: id }).delete(); // Delete role permissions await knex('role_permissions').where({ roleId: id }).delete(); await knex('role_object_permissions').where({ roleId: id }).delete(); // Delete the role await Role.query(knex).deleteById(id); return { success: true }; } @Post(':roleId/users') async addUserToRole( @TenantId() tenantId: string, @Param('roleId') roleId: string, @Body() data: { userId: string }, ) { const resolvedTenantId = await this.tenantDbService.resolveTenantId(tenantId); const knex = await this.tenantDbService.getTenantKnexById(resolvedTenantId); // Check if assignment already exists const existing = await knex('user_roles') .where({ userId: data.userId, roleId }) .first(); if (existing) { return { success: true, message: 'User already assigned' }; } await knex('user_roles').insert({ id: knex.raw('(UUID())'), userId: data.userId, roleId, created_at: knex.fn.now(), updated_at: knex.fn.now(), }); return { success: true }; } @Delete(':roleId/users/:userId') async removeUserFromRole( @TenantId() tenantId: string, @Param('roleId') roleId: string, @Param('userId') userId: string, ) { const resolvedTenantId = await this.tenantDbService.resolveTenantId(tenantId); const knex = await this.tenantDbService.getTenantKnexById(resolvedTenantId); await knex('user_roles') .where({ userId, roleId }) .delete(); return { success: true }; } }