Refactor RolesController and RolesService to include restaurant-specific handling by adding RestId parameter to relevant methods; remove optional restaurant ID properties from DTOs for cleaner design; implement soft delete logic in remove method to ensure proper role management.
This commit is contained in:
@@ -12,10 +12,6 @@ export class CreateRoleDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
title!: string;
|
title!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: 'Restaurant id (optional)', required: false })
|
|
||||||
@IsOptional()
|
|
||||||
@IsString()
|
|
||||||
restId?: string;
|
|
||||||
|
|
||||||
@ApiProperty({ description: 'List of permission IDs', isArray: true, required: false })
|
@ApiProperty({ description: 'List of permission IDs', isArray: true, required: false })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ export class FindRolesDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
name?: string;
|
name?: string;
|
||||||
|
|
||||||
@ApiProperty({ description: 'Restaurant id filter', required: false })
|
|
||||||
@IsOptional()
|
|
||||||
@IsString()
|
|
||||||
restId?: string;
|
|
||||||
|
|
||||||
@ApiProperty({ description: 'Page number', required: false, default: 1 })
|
@ApiProperty({ description: 'Page number', required: false, default: 1 })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@Type(() => Number)
|
@Type(() => Number)
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// role-permission.entity.ts (pivot)
|
|
||||||
import { Entity, ManyToOne } from '@mikro-orm/core';
|
import { Entity, ManyToOne } from '@mikro-orm/core';
|
||||||
import { Role } from './role.entity';
|
import { Role } from './role.entity';
|
||||||
import { Permission } from './permission.entity';
|
import { Permission } from './permission.entity';
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { EntityManager } from '@mikro-orm/postgresql';
|
|||||||
import { CreateRoleDto } from '../dto/create-role.dto';
|
import { CreateRoleDto } from '../dto/create-role.dto';
|
||||||
import { UpdateRoleDto } from '../dto/update-role.dto';
|
import { UpdateRoleDto } from '../dto/update-role.dto';
|
||||||
import { FindRolesDto } from '../dto/find-roles.dto';
|
import { FindRolesDto } from '../dto/find-roles.dto';
|
||||||
|
import { RolePermission } from '../entities/rolePermission.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RolesService {
|
export class RolesService {
|
||||||
@@ -19,8 +20,8 @@ export class RolesService {
|
|||||||
private readonly em: EntityManager,
|
private readonly em: EntityManager,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async create(dto: CreateRoleDto) {
|
async create(restId: string, dto: CreateRoleDto) {
|
||||||
const { name, title, restId, permissionIds } = dto;
|
const { name, title, permissionIds } = dto;
|
||||||
|
|
||||||
// Check if role already exists
|
// Check if role already exists
|
||||||
const existing = await this.roleRepository.findOne({ name, restaurant: restId ? { id: restId } : null });
|
const existing = await this.roleRepository.findOne({ name, restaurant: restId ? { id: restId } : null });
|
||||||
@@ -55,8 +56,8 @@ export class RolesService {
|
|||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAll(dto: FindRolesDto) {
|
async findAll(restId: string, dto: FindRolesDto) {
|
||||||
const { name, restId, page = 1, limit = 20 } = dto;
|
const { name, page = 1, limit = 20 } = dto;
|
||||||
const offset = (page - 1) * limit;
|
const offset = (page - 1) * limit;
|
||||||
|
|
||||||
// Build query dynamically
|
// Build query dynamically
|
||||||
@@ -86,16 +87,22 @@ export class RolesService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async findOne(id: string) {
|
async findOne(restId: string, id: string) {
|
||||||
const role = await this.roleRepository.findOne({ id }, { populate: ['permissions', 'restaurant'] });
|
const role = await this.roleRepository.findOne(
|
||||||
|
{ id, restaurant: { id: restId } },
|
||||||
|
{ populate: ['permissions', 'restaurant'] },
|
||||||
|
);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
throw new NotFoundException('Role not found');
|
throw new NotFoundException('Role not found');
|
||||||
}
|
}
|
||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(id: string, dto: UpdateRoleDto) {
|
async update(restId: string, id: string, dto: UpdateRoleDto) {
|
||||||
const role = await this.roleRepository.findOne({ id });
|
const role = await this.roleRepository.findOne(
|
||||||
|
{ id, restaurant: { id: restId } },
|
||||||
|
{ populate: ['permissions', 'restaurant'] },
|
||||||
|
);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
throw new NotFoundException('Role not found');
|
throw new NotFoundException('Role not found');
|
||||||
}
|
}
|
||||||
@@ -122,13 +129,23 @@ export class RolesService {
|
|||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
|
|
||||||
async remove(id: string) {
|
async remove(restId: string, id: string) {
|
||||||
const role = await this.roleRepository.findOne({ id });
|
const role = await this.roleRepository.findOne(
|
||||||
|
{ id, restaurant: { id: restId } },
|
||||||
|
{ populate: ['permissions', 'restaurant'] },
|
||||||
|
);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
throw new NotFoundException('Role not found');
|
throw new NotFoundException('Role not found');
|
||||||
}
|
}
|
||||||
|
if (!role.admins.isEmpty()) {
|
||||||
|
throw new BadRequestException('Role has admins');
|
||||||
|
}
|
||||||
|
|
||||||
await this.roleRepository.nativeUpdate({ id }, { deletedAt: new Date() });
|
// Hard delete pivot table entries (role_permissions) before soft deleting the role
|
||||||
return { message: 'Role deleted successfully' };
|
await this.em.nativeDelete(RolePermission, { role: { id: role.id } });
|
||||||
|
|
||||||
|
// Soft delete the role
|
||||||
|
role.deletedAt = new Date();
|
||||||
|
return this.em.persistAndFlush(role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { UpdateRoleDto } from './dto/update-role.dto';
|
|||||||
import { FindRolesDto } from './dto/find-roles.dto';
|
import { FindRolesDto } from './dto/find-roles.dto';
|
||||||
import { AdminAuthGuard } from '../auth/guards/adminAuth.guard';
|
import { AdminAuthGuard } from '../auth/guards/adminAuth.guard';
|
||||||
import { Permissions } from '../auth/decorators/permissions.decorator';
|
import { Permissions } from '../auth/decorators/permissions.decorator';
|
||||||
|
import { RestId } from 'src/common/decorators';
|
||||||
|
|
||||||
@UseGuards(AdminAuthGuard)
|
@UseGuards(AdminAuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@@ -21,14 +22,14 @@ export class RolesController {
|
|||||||
@Get()
|
@Get()
|
||||||
@ApiOperation({ summary: 'Get all roles with pagination and filters' })
|
@ApiOperation({ summary: 'Get all roles with pagination and filters' })
|
||||||
@ApiResponse({ status: 200, description: 'Roles retrieved successfully' })
|
@ApiResponse({ status: 200, description: 'Roles retrieved successfully' })
|
||||||
async findAll(@Query() dto: FindRolesDto) {
|
findAll(@Query() dto: FindRolesDto, @RestId() restId: string) {
|
||||||
return this.roleService.findAll(dto);
|
return this.roleService.findAll(restId, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('permissions')
|
@Get('permissions')
|
||||||
@ApiOperation({ summary: 'Get all permissions' })
|
@ApiOperation({ summary: 'Get all permissions' })
|
||||||
@ApiResponse({ status: 200, description: 'Permissions retrieved successfully' })
|
@ApiResponse({ status: 200, description: 'Permissions retrieved successfully' })
|
||||||
async findAllPermissions() {
|
findAllPermissions() {
|
||||||
return this.permissionService.findAll();
|
return this.permissionService.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,16 +38,16 @@ export class RolesController {
|
|||||||
@ApiOperation({ summary: 'Create a new role' })
|
@ApiOperation({ summary: 'Create a new role' })
|
||||||
@ApiBody({ type: CreateRoleDto })
|
@ApiBody({ type: CreateRoleDto })
|
||||||
@ApiResponse({ status: 201, description: 'Role created successfully' })
|
@ApiResponse({ status: 201, description: 'Role created successfully' })
|
||||||
async create(@Body() dto: CreateRoleDto) {
|
create(@Body() dto: CreateRoleDto, @RestId() restId: string) {
|
||||||
return this.roleService.create(dto);
|
return this.roleService.create(restId, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@ApiOperation({ summary: 'Get a specific role by ID' })
|
@ApiOperation({ summary: 'Get a specific role by ID' })
|
||||||
@ApiResponse({ status: 200, description: 'Role retrieved successfully' })
|
@ApiResponse({ status: 200, description: 'Role retrieved successfully' })
|
||||||
@ApiResponse({ status: 404, description: 'Role not found' })
|
@ApiResponse({ status: 404, description: 'Role not found' })
|
||||||
async findOne(@Param('id') id: string) {
|
findOne(@Param('id') id: string, @RestId() restId: string) {
|
||||||
return this.roleService.findOne(id);
|
return this.roleService.findOne(restId, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(':id')
|
@Patch(':id')
|
||||||
@@ -54,15 +55,15 @@ export class RolesController {
|
|||||||
@ApiBody({ type: UpdateRoleDto })
|
@ApiBody({ type: UpdateRoleDto })
|
||||||
@ApiResponse({ status: 200, description: 'Role updated successfully' })
|
@ApiResponse({ status: 200, description: 'Role updated successfully' })
|
||||||
@ApiResponse({ status: 404, description: 'Role not found' })
|
@ApiResponse({ status: 404, description: 'Role not found' })
|
||||||
async update(@Param('id') id: string, @Body() dto: UpdateRoleDto) {
|
update(@Param('id') id: string, @Body() dto: UpdateRoleDto, @RestId() restId: string) {
|
||||||
return this.roleService.update(id, dto);
|
return this.roleService.update(restId, id, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@ApiOperation({ summary: 'Delete a role' })
|
@ApiOperation({ summary: 'Delete a role' })
|
||||||
@ApiResponse({ status: 200, description: 'Role deleted successfully' })
|
@ApiResponse({ status: 200, description: 'Role deleted successfully' })
|
||||||
@ApiResponse({ status: 404, description: 'Role not found' })
|
@ApiResponse({ status: 404, description: 'Role not found' })
|
||||||
async remove(@Param('id') id: string) {
|
remove(@Param('id') id: string, @RestId() restId: string) {
|
||||||
return this.roleService.remove(id);
|
return this.roleService.remove(restId, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user