Skip to content

Commit

Permalink
Change projects/id response (#190)
Browse files Browse the repository at this point in the history
  • Loading branch information
catalin-oancea authored Dec 19, 2024
1 parent 90c96f9 commit 1fb4958
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 6 deletions.
93 changes: 93 additions & 0 deletions api/src/modules/projects/projects-scorecard.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ import { Repository, SelectQueryBuilder } from 'typeorm';
import { z } from 'zod';
import { getProjectsQuerySchema } from '@shared/contracts/projects.contract';
import { ProjectScorecardView } from '@shared/entities/project-scorecard.view';
import { ProjectScorecardDto } from '@shared/dtos/projects/project-scorecard.dto';
import { ECOSYSTEM } from '@shared/entities/ecosystem.enum';
import {
ACTIVITY,
RESTORATION_ACTIVITY_SUBTYPE,
} from '@shared/entities/activity.enum';
import {
PROJECT_PRICE_TYPE,
PROJECT_SIZE_FILTER,
} from '@shared/entities/projects.entity';
import { PROJECT_SCORE } from '@shared/entities/project-score.enum';

export type ProjectFetchSpecificacion = z.infer<typeof getProjectsQuerySchema>;

Expand Down Expand Up @@ -68,4 +79,86 @@ export class ProjectsScorecardService extends AppBaseService<

return query;
}

adaptDbViewToApiView(dbView: ProjectScorecardView): ProjectScorecardDto {
return {
id: dbView.id,
countryCode: dbView.countryCode,
ecosystem: dbView.ecosystem as ECOSYSTEM,
activity: dbView.activity as ACTIVITY,
activitySubtype: dbView.activitySubtype as RESTORATION_ACTIVITY_SUBTYPE,
projectName: dbView.projectName,
abatementPotential: dbView.abatementPotential,
projectSize: dbView.projectSize,
initialPriceAssumption: dbView.initialPriceAssumption,
projectSizeFilter: dbView.projectSizeFilter as PROJECT_SIZE_FILTER,
priceType: dbView.priceType as PROJECT_PRICE_TYPE,
scoreCardRating: dbView.scoreCardRating as PROJECT_SCORE,
scorecard: {
financialFeasibility: dbView.financialFeasibility as PROJECT_SCORE,
legalFeasibility: dbView.legalFeasibility as PROJECT_SCORE,
implementationFeasibility:
dbView.implementationFeasibility as PROJECT_SCORE,
socialFeasibility: dbView.socialFeasibility as PROJECT_SCORE,
securityRating: dbView.securityRating as PROJECT_SCORE,
availabilityOfExperiencedLabor:
dbView.availabilityOfExperiencedLabor as PROJECT_SCORE,
availabilityOfAlternatingFunding:
dbView.availabilityOfAlternatingFunding as PROJECT_SCORE,
coastalProtectionBenefits:
dbView.coastalProtectionBenefits as PROJECT_SCORE,
biodiversityBenefit: dbView.biodiversityBenefit as PROJECT_SCORE,
},
projectCost: {
total: {
totalCost: dbView.totalCost,
capex: dbView.capex,
opex: dbView.opex,
costPerTCO2e: dbView.costPerTCO2e,
feasibilityAnalysis: dbView.feasibilityAnalysis,
conservationPlanning: dbView.conservationPlanning,
dataCollection: dbView.dataCollection,
communityRepresentation: dbView.communityRepresentation,
blueCarbonProjectPlanning: dbView.blueCarbonProjectPlanning,
establishingCarbonRights: dbView.establishingCarbonRights,
validation: dbView.validation,
implementationLabor: dbView.implementationLabor,
monitoring: dbView.monitoring,
maintenance: dbView.maintenance,
monitoringMaintenance: dbView.monitoringMaintenance,
communityBenefit: dbView.communityBenefit,
carbonStandardFees: dbView.carbonStandardFees,
baselineReassessment: dbView.baselineReassessment,
mrv: dbView.mrv,
longTermProjectOperating: dbView.longTermProjectOperating,
totalRevenue: dbView.totalRevenue,
},
npv: {
totalCost: dbView.totalCostNPV,
capex: dbView.capexNPV,
opex: dbView.opexNPV,
costPerTCO2e: dbView.costPerTCO2eNPV,
feasibilityAnalysis: dbView.feasibilityAnalysisNPV,
conservationPlanning: dbView.conservationPlanningNPV,
dataCollection: dbView.dataCollectionNPV,
communityRepresentation: dbView.communityRepresentationNPV,
blueCarbonProjectPlanning: dbView.blueCarbonProjectPlanningNPV,
establishingCarbonRights: dbView.establishingCarbonRightsNPV,
validation: dbView.validationNPV,
implementationLabor: dbView.implementationLaborNPV,
monitoring: dbView.monitoringNPV,
maintenance: dbView.maintenanceNPV,
monitoringMaintenance: dbView.monitoringMaintenanceMPV,
communityBenefit: dbView.communityBenefitNPV,
carbonStandardFees: dbView.carbonStandardFeesNPV,
baselineReassessment: dbView.baselineReassessmentNPV,
mrv: dbView.mrvNPV,
longTermProjectOperating: dbView.longTermProjectOperatingNPV,
totalRevenue: dbView.totalRevenueNPV,
},
},
leftoverAfterOpex: dbView.leftoverAfterOpex,
creditsIssued: dbView.creditsIssued,
};
}
}
6 changes: 4 additions & 2 deletions api/src/modules/projects/projects.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ export class ProjectsController {
async getProject(): ControllerResponse {
return tsRestHandler(
projectsContract.getProject,
async ({ params: { id }, query }) => {
const data = await this.projectsScorecardService.getById(id, query);
async ({ params: { id } }) => {
const project = await this.projectsScorecardService.getById(id);
const data =
this.projectsScorecardService.adaptDbViewToApiView(project);
return { body: { data }, status: HttpStatus.OK };
},
);
Expand Down
5 changes: 3 additions & 2 deletions api/test/integration/projects/projects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,9 @@ describe('Projects', () => {

expect(response.status).toBe(HttpStatus.OK);
expect(response.body.data.projectName).toBe(project.projectName);
expect(response.body.data.feasibilityAnalysisNPV).toBeDefined();
expect(response.body.data.socialFeasibility).toBeDefined();
expect(response.body.data.scorecard).toBeDefined();
expect(response.body.data.projectCost.total).toBeDefined();
expect(response.body.data.projectCost.npv).toBeDefined();
});

test('Should return a 400 if project does not exist', async () => {
Expand Down
4 changes: 2 additions & 2 deletions shared/contracts/projects.contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { generateEntityQuerySchema } from "@shared/schemas/query-param.schema";
import { BaseEntity } from "typeorm";
import { ProjectScorecardView } from "@shared/entities/project-scorecard.view";
import { PaginatedProjectsWithMaximums } from "@shared/dtos/projects/projects.dto";
import { ProjectScorecardDto } from "@shared/dtos/projects/project-scorecard.dto";

const contract = initContract();

Expand Down Expand Up @@ -59,9 +60,8 @@ export const projectsContract = contract.router({
id: z.coerce.string().uuid(),
}),
responses: {
200: contract.type<ApiResponse<ProjectScorecardView>>(),
200: contract.type<ApiResponse<ProjectScorecardDto>>(),
},
query: projectScorecardQuerySchema,
},
getProjectCountries: {
method: "GET",
Expand Down
88 changes: 88 additions & 0 deletions shared/dtos/projects/project-scorecard.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import {
ACTIVITY,
RESTORATION_ACTIVITY_SUBTYPE,
} from "@shared/entities/activity.enum";
import { ECOSYSTEM } from "@shared/entities/ecosystem.enum";
import { PROJECT_SCORE } from "@shared/entities/project-score.enum";
import {
PROJECT_PRICE_TYPE,
PROJECT_SIZE_FILTER,
} from "@shared/entities/projects.entity";

export class ProjectScorecardDto {
id: string;
countryCode: string;
ecosystem: ECOSYSTEM;
activity: ACTIVITY;
activitySubtype: RESTORATION_ACTIVITY_SUBTYPE;
projectName: string;

abatementPotential: number;
projectSize: number;
initialPriceAssumption: number;
projectSizeFilter: PROJECT_SIZE_FILTER;
priceType: PROJECT_PRICE_TYPE;

scoreCardRating: PROJECT_SCORE;
scorecard: {
financialFeasibility: PROJECT_SCORE;
legalFeasibility: PROJECT_SCORE;
implementationFeasibility: PROJECT_SCORE;
socialFeasibility: PROJECT_SCORE;
securityRating: PROJECT_SCORE;
availabilityOfExperiencedLabor: PROJECT_SCORE;
availabilityOfAlternatingFunding: PROJECT_SCORE;
coastalProtectionBenefits: PROJECT_SCORE;
biodiversityBenefit: PROJECT_SCORE;
};
projectCost: {
total: {
totalCost: number;
capex: number;
opex: number;
costPerTCO2e: number;
feasibilityAnalysis: number;
conservationPlanning: number;
dataCollection: number;
communityRepresentation: number;
blueCarbonProjectPlanning: number;
establishingCarbonRights: number;
validation: number;
implementationLabor: number;
monitoring: number;
maintenance: number;
monitoringMaintenance: number;
communityBenefit: number;
carbonStandardFees: number;
baselineReassessment: number;
mrv: number;
longTermProjectOperating: number;
totalRevenue: number;
};
npv: {
totalCost: number;
capex: number;
opex: number;
costPerTCO2e: number;
feasibilityAnalysis: number;
conservationPlanning: number;
dataCollection: number;
communityRepresentation: number;
blueCarbonProjectPlanning: number;
establishingCarbonRights: number;
validation: number;
implementationLabor: number;
monitoring: number;
maintenance: number;
monitoringMaintenance: number;
communityBenefit: number;
carbonStandardFees: number;
baselineReassessment: number;
mrv: number;
longTermProjectOperating: number;
totalRevenue: number;
};
};
leftoverAfterOpex: number;
creditsIssued: number;
}

0 comments on commit 1fb4958

Please sign in to comment.