From 83e1212083f6da92e9c0375decb184a3b63ed743 Mon Sep 17 00:00:00 2001 From: andrea rota Date: Mon, 9 Oct 2023 13:25:23 +0100 Subject: [PATCH] group project BLM-related endpoints within their own controller and OpenAPI category --- .../projects/projects.blm.controller.ts | 127 ++++++++++++++++++ .../modules/projects/projects.controller.ts | 96 +------------ .../src/modules/projects/projects.module.ts | 2 + 3 files changed, 130 insertions(+), 95 deletions(-) create mode 100644 api/apps/api/src/modules/projects/projects.blm.controller.ts diff --git a/api/apps/api/src/modules/projects/projects.blm.controller.ts b/api/apps/api/src/modules/projects/projects.blm.controller.ts new file mode 100644 index 0000000000..fddd51af63 --- /dev/null +++ b/api/apps/api/src/modules/projects/projects.blm.controller.ts @@ -0,0 +1,127 @@ +import { + BadRequestException, + Body, + Controller, ForbiddenException, + Get, InternalServerErrorException, + NotFoundException, + Param, Patch, Req, UseGuards +} from '@nestjs/common'; + +import { projectResource } from './project.api.entity'; +import { + ApiBearerAuth, ApiOkResponse, + ApiOperation, + ApiParam, ApiTags +} from '@nestjs/swagger'; +import { apiGlobalPrefixes } from '@marxan-api/api.config'; +import { JwtAuthGuard } from '@marxan-api/guards/jwt-auth.guard'; + +import { RequestWithAuthenticatedUser } from '@marxan-api/app.controller'; +import { + ProjectsService +} from './projects.service'; +import { isLeft } from 'fp-ts/Either'; +import { inlineJobTag } from '@marxan-api/dto/inline-job-tag'; +import { UpdateProjectBlmRangeDTO } from '@marxan-api/modules/projects/dto/update-project-blm-range.dto'; +import { invalidRange } from '@marxan-api/modules/projects/blm'; +import { + planningUnitAreaNotFound, + updateFailure, +} from '@marxan-api/modules/projects/blm/change-project-blm-range.command'; +import { ProjectBlmValuesResponseDto } from '@marxan-api/modules/projects/dto/project-blm-values-response.dto'; +import { forbiddenError } from '@marxan-api/modules/access-control'; +import { + projectNotFound as blmProjectNotFound, + unknownError as blmUnknownError, +} from '../blm'; +import { + ImplementsAcl +} from '@marxan-api/decorators/acl.decorator'; + +@UseGuards(JwtAuthGuard) +@ApiBearerAuth() +@ApiTags('Project - BLM') +@Controller(`${apiGlobalPrefixes.v1}/projects`) +export class ProjectBLMController { + constructor( + private readonly projectsService: ProjectsService, + ) {} + + @ImplementsAcl() + @ApiOperation({ + description: 'Updates the project BLM range and calculate its values', + }) + @ApiParam({ + name: 'id', + description: 'ID of the Project', + }) + @ApiOkResponse({ type: ProjectBlmValuesResponseDto }) + @ApiTags(inlineJobTag) + @Patch(':id/calibration') + async updateBlmRange( + @Param('id') id: string, + @Body() { range }: UpdateProjectBlmRangeDTO, + @Req() req: RequestWithAuthenticatedUser, + ): Promise { + const result = await this.projectsService.updateBlmValues( + id, + req.user.id, + range, + ); + + if (isLeft(result)) { + switch (result.left) { + case invalidRange: + throw new BadRequestException(`Invalid range: ${range}`); + case planningUnitAreaNotFound: + throw new NotFoundException( + `Could not find project BLM values for project with ID: ${id}`, + ); + case updateFailure: + throw new InternalServerErrorException( + `Could not update with range ${range} project BLM values for project with ID: ${id}`, + ); + case forbiddenError: + throw new ForbiddenException(); + default: + throw new InternalServerErrorException(); + } + } + + return result.right; + } + + @ImplementsAcl() + @ApiOperation({ + description: 'Shows the project BLM values of a project', + }) + @ApiParam({ + name: 'id', + description: 'ID of the Project', + }) + @ApiOkResponse({ type: ProjectBlmValuesResponseDto }) + @ApiTags(inlineJobTag) + @Get(':id/calibration') + async getProjectBlmValues( + @Param('id') id: string, + @Req() req: RequestWithAuthenticatedUser, + ): Promise { + const result = await this.projectsService.findProjectBlm(id, req.user.id); + + if (isLeft(result)) + switch (result.left) { + case blmProjectNotFound: + throw new NotFoundException( + `Could not find project BLM values for project with ID: ${id}`, + ); + case forbiddenError: + throw new ForbiddenException(); + case blmUnknownError: + throw new InternalServerErrorException(); + default: + const _exhaustiveCheck: never = result.left; + throw _exhaustiveCheck; + } + return result.right; + } +} diff --git a/api/apps/api/src/modules/projects/projects.controller.ts b/api/apps/api/src/modules/projects/projects.controller.ts index ed961ab27f..78ffb1e139 100644 --- a/api/apps/api/src/modules/projects/projects.controller.ts +++ b/api/apps/api/src/modules/projects/projects.controller.ts @@ -1,14 +1,11 @@ import { - BadRequestException, Body, Controller, Delete, ForbiddenException, Get, Header, - InternalServerErrorException, - NotFoundException, - Param, ParseUUIDPipe, + InternalServerErrorException, Param, ParseUUIDPipe, Patch, Post, Req, @@ -37,19 +34,6 @@ import { ProjectJobsStatusDto } from './dto/project-jobs-status.dto'; import { JobStatusSerializer } from './dto/job-status.serializer'; import { isLeft } from 'fp-ts/Either'; import { asyncJobTag } from '@marxan-api/dto/async-job-tag'; -import { inlineJobTag } from '@marxan-api/dto/inline-job-tag'; -import { UpdateProjectBlmRangeDTO } from '@marxan-api/modules/projects/dto/update-project-blm-range.dto'; -import { invalidRange } from '@marxan-api/modules/projects/blm'; -import { - planningUnitAreaNotFound, - updateFailure, -} from '@marxan-api/modules/projects/blm/change-project-blm-range.command'; -import { ProjectBlmValuesResponseDto } from '@marxan-api/modules/projects/dto/project-blm-values-response.dto'; -import { forbiddenError } from '@marxan-api/modules/access-control'; -import { - projectNotFound as blmProjectNotFound, - unknownError as blmUnknownError, -} from '../blm'; import { Response } from 'express'; import { ImplementsAcl, @@ -160,84 +144,6 @@ export class ProjectsController { return this.jobsStatusSerializer.serialize(projectId, projectWithScenarios); } - @ImplementsAcl() - @ApiOperation({ - description: 'Updates the project BLM range and calculate its values', - }) - @ApiParam({ - name: 'id', - description: 'ID of the Project', - }) - @ApiOkResponse({ type: ProjectBlmValuesResponseDto }) - @ApiTags(inlineJobTag) - @Patch(':id/calibration') - async updateBlmRange( - @Param('id') id: string, - @Body() { range }: UpdateProjectBlmRangeDTO, - @Req() req: RequestWithAuthenticatedUser, - ): Promise { - const result = await this.projectsService.updateBlmValues( - id, - req.user.id, - range, - ); - - if (isLeft(result)) { - switch (result.left) { - case invalidRange: - throw new BadRequestException(`Invalid range: ${range}`); - case planningUnitAreaNotFound: - throw new NotFoundException( - `Could not find project BLM values for project with ID: ${id}`, - ); - case updateFailure: - throw new InternalServerErrorException( - `Could not update with range ${range} project BLM values for project with ID: ${id}`, - ); - case forbiddenError: - throw new ForbiddenException(); - default: - throw new InternalServerErrorException(); - } - } - - return result.right; - } - - @ImplementsAcl() - @ApiOperation({ - description: 'Shows the project BLM values of a project', - }) - @ApiParam({ - name: 'id', - description: 'ID of the Project', - }) - @ApiOkResponse({ type: ProjectBlmValuesResponseDto }) - @ApiTags(inlineJobTag) - @Get(':id/calibration') - async getProjectBlmValues( - @Param('id') id: string, - @Req() req: RequestWithAuthenticatedUser, - ): Promise { - const result = await this.projectsService.findProjectBlm(id, req.user.id); - - if (isLeft(result)) - switch (result.left) { - case blmProjectNotFound: - throw new NotFoundException( - `Could not find project BLM values for project with ID: ${id}`, - ); - case forbiddenError: - throw new ForbiddenException(); - case blmUnknownError: - throw new InternalServerErrorException(); - default: - const _exhaustiveCheck: never = result.left; - throw _exhaustiveCheck; - } - return result.right; - } - @ImplementsAcl() @ApiOperation({ description: diff --git a/api/apps/api/src/modules/projects/projects.module.ts b/api/apps/api/src/modules/projects/projects.module.ts index 719d142488..3e3538018a 100644 --- a/api/apps/api/src/modules/projects/projects.module.ts +++ b/api/apps/api/src/modules/projects/projects.module.ts @@ -59,6 +59,7 @@ import { LegacyProjectsController } from './projects.legacy-projects.controller' import { ProjectFeaturesController } from './projects.project-features.controller'; import { ProjectCloningController } from './projects.cloning.controller'; import { ProjectPlanningAreaAndGridController } from './projects.planning-area-and-grid.controller'; +import { ProjectBLMController } from './projects.blm.controller'; @Module({ imports: [ @@ -125,6 +126,7 @@ import { ProjectPlanningAreaAndGridController } from './projects.planning-area-a LegacyProjectsController, ProjectsController, ProjectsListingController, + ProjectBLMController, ProjectCloningController, ProjectCostSurfaceController, ProjectDetailsController,