Skip to content

Commit

Permalink
IMN-675-676-677-678 risk analysis (#838)
Browse files Browse the repository at this point in the history
  • Loading branch information
Viktor-K authored Aug 9, 2024
1 parent 0e3bb77 commit 56546d4
Show file tree
Hide file tree
Showing 8 changed files with 450 additions and 158 deletions.
366 changes: 241 additions & 125 deletions packages/api-clients/open-api/bffApi.yml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,11 @@ export function toBffCatalogApiEserviceRiskAnalysis(
)
.reduce((answers: bffApi.RiskAnalysisForm["answers"], answer) => {
const key = answer.key;
if (answers[key] && answer.value) {
if (!answers[key]) {
answers[key] = [];
}

if (answer.value) {
answers[key] = [...answers[key], answer.value];
} else {
answers[key] = [];
Expand Down
24 changes: 24 additions & 0 deletions packages/bff/src/model/domain/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export const errorCodes = {
eserviceDescriptorNotFound: "0013",
purposeDraftVersionNotFound: "0014",
invalidRiskAnalysisContentType: "0015",
missingInterface: "0016",
eserviceRiskNotFound: "0017",
};

export type ErrorCodes = keyof typeof errorCodes;
Expand Down Expand Up @@ -158,3 +160,25 @@ export function invalidRiskAnalysisContentType(
title: "Invalid Risk Analysis content type",
});
}

export function missingInterface(
eserviceId: string,
descriptorId: string
): ApiError<ErrorCodes> {
return new ApiError({
detail: `Missing interface for Eservice ${eserviceId} and descriptor ${descriptorId}`,
code: "missingInterface",
title: "Missing interface",
});
}

export function eserviceRiskNotFound(
eserviceId: string,
riskAnalysisId: string
): ApiError<ErrorCodes> {
return new ApiError({
detail: `"RiskAnalysis ${riskAnalysisId} not found in Eservice ${eserviceId}"`,
code: "eserviceRiskNotFound",
title: "Risk analysis not found",
});
}
14 changes: 0 additions & 14 deletions packages/bff/src/model/modelMappingUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { catalogApi, tenantApi } from "pagopa-interop-api-clients";
import { catalogApiDescriptorState } from "./api/apiTypes.js";
import { catalogProcessApiEServiceDescriptorCertifiedAttributesSatisfied } from "./validators.js";

/*
This file contains commons utility functions
Expand Down Expand Up @@ -37,16 +36,3 @@ export function getTenantEmail(
(m) => m.kind === tenantApi.MailKind.Values.CONTACT_EMAIL
);
}

export function hasCertifiedAttributes(
descriptor: catalogApi.EServiceDescriptor | undefined,
requesterTenant: tenantApi.Tenant
): boolean {
return (
descriptor !== undefined &&
catalogProcessApiEServiceDescriptorCertifiedAttributesSatisfied(
descriptor,
requesterTenant
)
);
}
101 changes: 91 additions & 10 deletions packages/bff/src/routers/catalogRouter.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import { ZodiosEndpointDefinitions } from "@zodios/core";
import { ZodiosRouter } from "@zodios/express";
import { bffApi } from "pagopa-interop-api-clients";
import {
ExpressContext,
ZodiosContext,
zodiosValidationErrorToApiProblem,
} from "pagopa-interop-commons";
import { bffApi } from "pagopa-interop-api-clients";
import { unsafeBrandId } from "pagopa-interop-models";
import { PagoPAInteropBeClients } from "../providers/clientProvider.js";
import { catalogServiceBuilder } from "../services/catalogService.js";
import { toEserviceCatalogProcessQueryParams } from "../model/api/converters/catalogClientApiConverter.js";
import { makeApiProblem } from "../model/domain/errors.js";
import { PagoPAInteropBeClients } from "../providers/clientProvider.js";
import { catalogServiceBuilder } from "../services/catalogService.js";
import { fromBffAppContext } from "../utilities/context.js";
import {
bffGetCatalogErrorMapper,
emptyErrorMapper,
} from "../utilities/errorMappers.js";
import { fromBffAppContext } from "../utilities/context.js";

const catalogRouter = (
ctx: ZodiosContext,
Expand Down Expand Up @@ -219,9 +219,26 @@ const catalogRouter = (
res.status(501).send()
)
.put("/eservices/:eServiceId", async (_req, res) => res.status(501).send())
.post("/eservices/:eServiceId/riskAnalysis", async (_req, res) =>
res.status(501).send()
)
.post("/eservices/:eServiceId/riskAnalysis", async (req, res) => {
const ctx = fromBffAppContext(req.ctx, req.headers);
try {
await catalogService.addRiskAnalysisToEService(
unsafeBrandId(req.params.eServiceId),
req.body,
ctx
);

return res.status(204).send();
} catch (error) {
const errorRes = makeApiProblem(
error,
bffGetCatalogErrorMapper,
ctx.logger,
`Error inserting risk analysis ${req.body.name} to eservice ${req.params.eServiceId} from catalog`
);
return res.status(errorRes.status).json(errorRes).end();
}
})
.post("/eservices/:eServiceId/update", async (req, res) => {
const ctx = fromBffAppContext(req.ctx, req.headers);
try {
Expand All @@ -243,16 +260,80 @@ const catalogRouter = (
})
.get(
"/eservices/:eServiceId/riskAnalysis/:riskAnalysisId",
async (_req, res) => res.status(501).send()
async (req, res) => {
const ctx = fromBffAppContext(req.ctx, req.headers);
try {
const riskAnalysis = await catalogService.getEServiceRiskAnalysis(
unsafeBrandId(req.params.eServiceId),
unsafeBrandId(req.params.riskAnalysisId),
ctx
);

return res.status(200).json(riskAnalysis).send();
} catch (error) {
const errorRes = makeApiProblem(
error,
bffGetCatalogErrorMapper,
ctx.logger,
`Error retrieving risk analysis ${req.params.riskAnalysisId} to eservice ${req.params.eServiceId} from catalog`
);
return res.status(errorRes.status).json(errorRes).end();
}
}
)
.post(
"/eservices/:eServiceId/riskAnalysis/:riskAnalysisId",
async (_req, res) => res.status(501).send()
async (req, res) => {
const ctx = fromBffAppContext(req.ctx, req.headers);
try {
await catalogService.updateEServiceRiskAnalysis(
unsafeBrandId(req.params.eServiceId),
unsafeBrandId(req.params.riskAnalysisId),
req.body,
ctx
);
return res.status(204).send();
} catch (error) {
const errorRes = makeApiProblem(
error,
bffGetCatalogErrorMapper,
ctx.logger,
`Error updating risk analysis ${req.params.riskAnalysisId} to eservice ${req.params.eServiceId} from catalog`
);
return res.status(errorRes.status).json(errorRes).end();
}
}
)
.delete(
"/eservices/:eServiceId/riskAnalysis/:riskAnalysisId",
async (req, res) => {
const ctx = fromBffAppContext(req.ctx, req.headers);
try {
await catalogService.deleteEServiceRiskAnalysis(
unsafeBrandId(req.params.eServiceId),
unsafeBrandId(req.params.riskAnalysisId),
ctx
);
return res.status(204).send();
} catch (error) {
const errorRes = makeApiProblem(
error,
bffGetCatalogErrorMapper,
ctx.logger,
`Error deleting risk analysis ${req.params.riskAnalysisId} to eservice ${req.params.eServiceId} from catalog`
);
return res.status(errorRes.status).json(errorRes).end();
}
}
)
.get(
"/export/eservices/:eserviceId/descriptors/:descriptorId",
async (_req, res) => res.status(501).send()
);
)
.get("/import/eservices/presignedUrl", async (_req, res) =>
res.status(501).send()
)
.post("/import/eservices", async (_req, res) => res.status(501).send());

return catalogRouter;
};
Expand Down
7 changes: 2 additions & 5 deletions packages/bff/src/routers/clientRouter.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ZodiosEndpointDefinitions } from "@zodios/core";
import { ZodiosRouter } from "@zodios/express";
import { bffApi } from "pagopa-interop-api-clients";
import {
ExpressContext,
ZodiosContext,
zodiosValidationErrorToApiProblem,
} from "pagopa-interop-commons";
import { bffApi } from "pagopa-interop-api-clients";

const clientRouter = (
ctx: ZodiosContext
Expand Down Expand Up @@ -47,10 +47,7 @@ const clientRouter = (
res.status(501).send()
)
.post("/clientsConsumer", async (_req, res) => res.status(501).send())
.post("/clientsApi", async (_req, res) => res.status(501).send())
.get("/clients/:clientId/users/:userId/keys", async (_req, res) =>
res.status(501).send()
);
.post("/clientsApi", async (_req, res) => res.status(501).send());

return clientRouter;
};
Expand Down
84 changes: 82 additions & 2 deletions packages/bff/src/services/catalogService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import {
WithLogger,
formatDateyyyyMMddThhmmss,
} from "pagopa-interop-commons";
import { DescriptorId, EServiceId } from "pagopa-interop-models";
import {
DescriptorId,
EServiceId,
RiskAnalysisId,
} from "pagopa-interop-models";
import {
toBffCatalogApiDescriptorAttributes,
toBffCatalogApiDescriptorDoc,
Expand All @@ -16,7 +20,10 @@ import {
toBffCatalogDescriptorEService,
} from "../model/api/converters/catalogClientApiConverter.js";

import { eserviceDescriptorNotFound } from "../model/domain/errors.js";
import {
eserviceDescriptorNotFound,
eserviceRiskNotFound,
} from "../model/domain/errors.js";
import { getLatestActiveDescriptor } from "../model/modelMappingUtils.js";
import { assertRequesterIsProducer } from "../model/validators.js";
import {
Expand Down Expand Up @@ -118,6 +125,20 @@ export const retrieveEserviceDescriptor = (
return descriptor;
};

const retrieveRiskAnalysis = (
eservice: catalogApi.EService,
riskAnalysisId: string
): catalogApi.EServiceRiskAnalysis => {
const riskAnalysis = eservice.riskAnalysis.find(
(ra) => ra.id === riskAnalysisId
);

if (!riskAnalysis) {
throw eserviceRiskNotFound(eservice.id, riskAnalysisId);
}
return riskAnalysis;
};

const getAttributeIds = (
descriptor: catalogApi.EServiceDescriptor
): string[] => [
Expand Down Expand Up @@ -490,5 +511,64 @@ export function catalogServiceBuilder(
file: Buffer.from(buildCsv(consumers)),
};
},
updateEServiceRiskAnalysis: async (
eserviceId: EServiceId,
riskAnalysisId: RiskAnalysisId,
riskAnalysisSeed: bffApi.EServiceRiskAnalysisSeed,
context: WithLogger<BffAppContext>
): Promise<void> =>
await catalogProcessClient.updateRiskAnalysis(riskAnalysisSeed, {
headers: context.headers,
params: {
eServiceId: eserviceId,
riskAnalysisId,
},
}),
deleteEServiceRiskAnalysis: async (
eserviceId: EServiceId,
riskAnalysisId: RiskAnalysisId,
context: WithLogger<BffAppContext>
): Promise<void> =>
await catalogProcessClient.deleteRiskAnalysis(undefined, {
headers: context.headers,
params: {
eServiceId: eserviceId,
riskAnalysisId,
},
}),
addRiskAnalysisToEService: async (
eserviceId: EServiceId,
riskAnalysisSeed: bffApi.EServiceRiskAnalysisSeed,
context: WithLogger<BffAppContext>
): Promise<void> =>
await catalogProcessClient.createRiskAnalysis(
{
name: riskAnalysisSeed.name,
riskAnalysisForm: riskAnalysisSeed.riskAnalysisForm,
},
{
headers: context.headers,
params: {
eServiceId: eserviceId,
},
}
),
getEServiceRiskAnalysis: async (
eserviceId: EServiceId,
riskAnalysisId: RiskAnalysisId,
context: WithLogger<BffAppContext>
): Promise<bffApi.EServiceRiskAnalysis> => {
const eservice: catalogApi.EService =
await catalogProcessClient.getEServiceById({
params: {
eServiceId: eserviceId,
},
headers: context.headers,
});

const riskAnalysis = retrieveRiskAnalysis(eservice, riskAnalysisId);

return toBffCatalogApiEserviceRiskAnalysis(riskAnalysis);
},
};
}
6 changes: 5 additions & 1 deletion packages/bff/src/utilities/errorMappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ const {

export const bffGetCatalogErrorMapper = (error: ApiError<ErrorCodes>): number =>
match(error.code)
.with("descriptorNotFound", () => HTTP_STATUS_NOT_FOUND)
.with(
"descriptorNotFound",
"eserviceRiskNotFound",
() => HTTP_STATUS_NOT_FOUND
)
.with("invalidEserviceRequester", () => HTTP_STATUS_FORBIDDEN)
.otherwise(() => HTTP_STATUS_INTERNAL_SERVER_ERROR);

Expand Down

0 comments on commit 56546d4

Please sign in to comment.