Skip to content

Commit

Permalink
group project BLM-related endpoints within their own controller and O…
Browse files Browse the repository at this point in the history
…penAPI category
  • Loading branch information
hotzevzl committed Oct 9, 2023
1 parent ffcb734 commit 83e1212
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 95 deletions.
127 changes: 127 additions & 0 deletions api/apps/api/src/modules/projects/projects.blm.controller.ts
Original file line number Diff line number Diff line change
@@ -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<ProjectBlmValuesResponseDto> {
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<ProjectBlmValuesResponseDto> {
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;
}
}
96 changes: 1 addition & 95 deletions api/apps/api/src/modules/projects/projects.controller.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import {
BadRequestException,
Body,
Controller,
Delete,
ForbiddenException,
Get,
Header,
InternalServerErrorException,
NotFoundException,
Param, ParseUUIDPipe,
InternalServerErrorException, Param, ParseUUIDPipe,
Patch,
Post,
Req,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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<ProjectBlmValuesResponseDto> {
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<ProjectBlmValuesResponseDto> {
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:
Expand Down
2 changes: 2 additions & 0 deletions api/apps/api/src/modules/projects/projects.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: [
Expand Down Expand Up @@ -125,6 +126,7 @@ import { ProjectPlanningAreaAndGridController } from './projects.planning-area-a
LegacyProjectsController,
ProjectsController,
ProjectsListingController,
ProjectBLMController,
ProjectCloningController,
ProjectCostSurfaceController,
ProjectDetailsController,
Expand Down

0 comments on commit 83e1212

Please sign in to comment.