import { Controller, UseGuards, HttpCode, HttpStatus, Get, Post, BadRequestException, Put, Param, Delete, ParseIntPipe, Inject, Logger, LoggerService, Body } from '@nestjs/common' import { AuthGuard } from '@nestjs/passport' import { ApiTags, ApiOperation, ApiOkResponse, ApiBearerAuth, ApiInternalServerErrorResponse, ApiBody, ApiCreatedResponse, ApiBadRequestResponse, ApiForbiddenResponse } from '@nestjs/swagger' import { ERRORS, POSTGRES } from '../constants' import { RoleService } from '../repositories' import { Role, DefaultRole } from '../models/role' import { Roles, RolesGuard } from '../auth' @ApiBearerAuth() @ApiTags('Roles') @UseGuards(AuthGuard(), RolesGuard) @Roles(DefaultRole.Admin) @Controller('/api/roles') export class RoleController { constructor( private readonly roleService: RoleService, @Inject(Logger) private readonly logger: LoggerService ) { } @ApiOperation({ summary: 'Get the list of roles' }) @ApiOkResponse({ description: 'Role list' }) @ApiInternalServerErrorResponse({ description: 'Internal Server Error' }) @ApiForbiddenResponse({ description: 'You do not have the necessary role to perform this action' }) @Get() @HttpCode(HttpStatus.OK) async findAll(): Promise<Role[]> { return await this.roleService.findAll() } @ApiOperation({ summary: 'Create a new role' }) @ApiBody({ type: Role, description: 'Role information' }) @ApiCreatedResponse({ description: 'The role was created successfully' }) @ApiBadRequestResponse({ description: 'The role could not be created' }) @ApiForbiddenResponse({ description: 'You do not have the necessary role to perform this action' }) @Post() @HttpCode(HttpStatus.CREATED) async addRole( @Body() role: Role ): Promise<void> { try { await this.roleService.addRole(role) } catch (error) { /** * Validate database exceptions */ switch(error.code) { case POSTGRES.UNIQUE_VIOLATION: throw new BadRequestException(ERRORS.UNIQUE_VIOLATION) default: this.logger.error(error.message, 'ADD_ROLE') throw new BadRequestException(error.message) } } } @ApiOperation({ summary: 'Update a role' }) @ApiBody({ type: Role, description: 'Role information' }) @ApiOkResponse({ description: 'The role was updated successfully' }) @ApiBadRequestResponse({ description: 'The role could not be updated' }) @ApiForbiddenResponse({ description: 'You do not have the necessary role to perform this action' }) @Put() @HttpCode(HttpStatus.OK) async updateRole( @Body() role: Role ): Promise<void> { try { await this.roleService.updateRole(role) } catch (error) { /** * Validate database exceptions */ switch(error.code) { case POSTGRES.UNIQUE_VIOLATION: throw new BadRequestException(ERRORS.UNIQUE_VIOLATION) default: this.logger.error(error.message, 'UPDATE_ROLE') throw new BadRequestException(error.message) } } } @ApiOperation({ summary: 'Delete a role' }) @ApiOkResponse({ description: 'Role deleted' }) @ApiBadRequestResponse({ description: 'The role could not be deleted' }) @ApiForbiddenResponse({ description: 'You do not have the necessary role to perform this action' }) @Delete(':id') @HttpCode(HttpStatus.OK) async delete( @Param('id', ParseIntPipe) id: number ): Promise<void> { if (id === DefaultRole.User) { throw new BadRequestException(ERRORS.ROLE_USER_DELETION) } else if (id === DefaultRole.Admin) { throw new BadRequestException(ERRORS.ROLE_ADMIN_DELETION) } try { await this.roleService.delete(id) } catch (error) { this.logger.error(error.message, 'DELETE_ROLE') throw new BadRequestException(error.message) } } }