diff --git a/packages/api-clients/open-api/bffApi.yml b/packages/api-clients/open-api/bffApi.yml index fb66f6d2e7..8d165bf5f8 100644 --- a/packages/api-clients/open-api/bffApi.yml +++ b/packages/api-clients/open-api/bffApi.yml @@ -4405,6 +4405,11 @@ paths: format: uuid default: [] explode: false + - in: query + name: delegated + description: if true only delegated e-services will be returned, if false only non-delegated e-services will be returned, if not present all e-services will be returned + schema: + type: boolean - in: query name: offset required: true diff --git a/packages/api-clients/open-api/catalogApi.yml b/packages/api-clients/open-api/catalogApi.yml index c834ab2a60..0c52acbd08 100644 --- a/packages/api-clients/open-api/catalogApi.yml +++ b/packages/api-clients/open-api/catalogApi.yml @@ -95,6 +95,11 @@ paths: description: mode schema: $ref: "#/components/schemas/EServiceMode" + - in: query + name: delegated + description: if true only delegated e-services will be returned, if false only non-delegated e-services will be returned, if not present all e-services will be returned + schema: + type: boolean - in: query name: offset required: true diff --git a/packages/backend-for-frontend/src/routers/catalogRouter.ts b/packages/backend-for-frontend/src/routers/catalogRouter.ts index a223b08493..a0779aaaa7 100644 --- a/packages/backend-for-frontend/src/routers/catalogRouter.ts +++ b/packages/backend-for-frontend/src/routers/catalogRouter.ts @@ -79,6 +79,7 @@ const catalogRouter = ( const response = await catalogService.getProducerEServices( req.query.q, req.query.consumersIds, + req.query.delegated, req.query.offset, req.query.limit, ctx diff --git a/packages/backend-for-frontend/src/services/catalogService.ts b/packages/backend-for-frontend/src/services/catalogService.ts index 81de1f0a4b..8cec70eb07 100644 --- a/packages/backend-for-frontend/src/services/catalogService.ts +++ b/packages/backend-for-frontend/src/services/catalogService.ts @@ -429,6 +429,7 @@ export function catalogServiceBuilder( getProducerEServices: async ( eserviceName: string | undefined, consumersIds: string[], + delegated: boolean | undefined, offset: number, limit: number, { headers, authData, logger }: WithLogger @@ -454,6 +455,7 @@ export function catalogServiceBuilder( queries: { name: eserviceName, producersIds: producerId, + delegated, offset, limit, }, @@ -479,6 +481,7 @@ export function catalogServiceBuilder( name: eserviceName, eservicesIds: eserviceIds, producersIds: producerId, + delegated, offset, limit, }, diff --git a/packages/catalog-process/src/model/domain/models.ts b/packages/catalog-process/src/model/domain/models.ts index 3e87abb3fe..6e4b215458 100644 --- a/packages/catalog-process/src/model/domain/models.ts +++ b/packages/catalog-process/src/model/domain/models.ts @@ -21,6 +21,7 @@ export type ApiGetEServicesFilters = { agreementStates: AgreementState[]; name?: string; mode?: EServiceMode; + delegated?: boolean; }; export type EServiceDocument = { diff --git a/packages/catalog-process/src/routers/EServiceRouter.ts b/packages/catalog-process/src/routers/EServiceRouter.ts index acb8732a56..015b266b1e 100644 --- a/packages/catalog-process/src/routers/EServiceRouter.ts +++ b/packages/catalog-process/src/routers/EServiceRouter.ts @@ -112,6 +112,7 @@ const eservicesRouter = ( states, agreementStates, mode, + delegated, offset, limit, } = req.query; @@ -128,6 +129,7 @@ const eservicesRouter = ( ), name, mode: mode ? apiEServiceModeToEServiceMode(mode) : undefined, + delegated, }, offset, limit, diff --git a/packages/catalog-process/src/services/readModelService.ts b/packages/catalog-process/src/services/readModelService.ts index 645213edb5..4b0e9a8105 100644 --- a/packages/catalog-process/src/services/readModelService.ts +++ b/packages/catalog-process/src/services/readModelService.ts @@ -119,6 +119,7 @@ export function readModelServiceBuilder( name, attributesIds, mode, + delegated, } = filters; const ids = await match(agreementStates.length) .with(0, () => eservicesIds) @@ -165,7 +166,7 @@ export function readModelServiceBuilder( ); const delegationLookup = - producersIds.length > 0 + producersIds.length > 0 || delegated !== undefined ? [ { $lookup: { @@ -261,19 +262,29 @@ export function readModelServiceBuilder( ? { "data.mode": { $eq: mode } } : {}; + const delegatedFilter: ReadModelFilter = match(delegated) + .with(true, () => ({ + "delegation.data.state": { + $in: [delegationState.active, delegationState.waitingForApproval], + }, + })) + .with(false, () => ({ + "delegation.data.state": { + $nin: [delegationState.active, delegationState.waitingForApproval], + }, + })) + .otherwise(() => ({})); + const aggregationPipeline = [ ...delegationLookup, - { - $match: { - ...nameFilter, - ...idsFilter, - ...producersIdsFilter, - ...descriptorsStateFilter, - ...attributesFilter, - ...visibilityFilter, - ...modeFilter, - } satisfies ReadModelFilter, - }, + { $match: nameFilter }, + { $match: idsFilter }, + { $match: producersIdsFilter }, + { $match: descriptorsStateFilter }, + { $match: attributesFilter }, + { $match: visibilityFilter }, + { $match: modeFilter }, + { $match: delegatedFilter }, { $project: { data: 1, diff --git a/packages/catalog-process/test/getEservices.test.ts b/packages/catalog-process/test/getEservices.test.ts index 25ebcd46e1..eaed920272 100644 --- a/packages/catalog-process/test/getEservices.test.ts +++ b/packages/catalog-process/test/getEservices.test.ts @@ -341,6 +341,95 @@ describe("get eservices", () => { eservice5, ]); }); + it("should get the eServices if they exist (parameters: delegated = true)", async () => { + const delegatedOrganization1 = generateId(); + const delegatedOrganization2 = generateId(); + + await addOneDelegation({ + ...getMockDelegationProducer(), + eserviceId: eservice4.id, + delegateId: delegatedOrganization1, + state: delegationState.active, + }); + + await addOneDelegation({ + ...getMockDelegationProducer(), + eserviceId: eservice5.id, + delegateId: delegatedOrganization2, + state: delegationState.waitingForApproval, + }); + + await addOneDelegation({ + ...getMockDelegationProducer(), + eserviceId: eservice6.id, + delegateId: delegatedOrganization2, + state: delegationState.rejected, + }); + + const result = await catalogService.getEServices( + getMockAuthData(), + { + eservicesIds: [], + producersIds: [], + states: [], + agreementStates: [], + attributesIds: [], + delegated: true, + }, + 0, + 50, + genericLogger + ); + expect(result.totalCount).toBe(2); + expect(result.results).toEqual([eservice4, eservice5]); + }); + it("should get the eServices if they exist (parameters: delegated = false)", async () => { + const delegatedOrganization1 = generateId(); + const delegatedOrganization2 = generateId(); + + await addOneDelegation({ + ...getMockDelegationProducer(), + eserviceId: eservice4.id, + delegateId: delegatedOrganization1, + state: delegationState.active, + }); + + await addOneDelegation({ + ...getMockDelegationProducer(), + eserviceId: eservice5.id, + delegateId: delegatedOrganization2, + state: delegationState.waitingForApproval, + }); + + await addOneDelegation({ + ...getMockDelegationProducer(), + eserviceId: eservice6.id, + delegateId: delegatedOrganization2, + state: delegationState.rejected, + }); + + const result = await catalogService.getEServices( + getMockAuthData(), + { + eservicesIds: [], + producersIds: [], + states: [], + agreementStates: [], + attributesIds: [], + delegated: false, + }, + 0, + 50, + genericLogger + ); + expect(result.totalCount).toBe(4); + expect(result.results).toEqual([ + eservice1, + eservice2, + eservice3, + eservice6, + ]); + }); it("should get the eServices if they exist (parameters: statestates, name)", async () => { const result = await catalogService.getEServices( getMockAuthData(organizationId3), @@ -658,6 +747,42 @@ describe("get eservices", () => { }); }); + it("should get the eServices if they exist (parameters: producersIds, mode, delegated = true)", async () => { + await addOneDelegation({ + ...getMockDelegationProducer(), + eserviceId: eservice4.id, + delegateId: organizationId3, + state: delegationState.active, + }); + + await addOneDelegation({ + ...getMockDelegationProducer(), + eserviceId: eservice5.id, + delegateId: organizationId3, + state: delegationState.revoked, + }); + + const result = await catalogService.getEServices( + getMockAuthData(), + { + eservicesIds: [], + producersIds: [organizationId2], + states: [], + agreementStates: [], + attributesIds: [], + mode: eserviceMode.deliver, + delegated: true, + }, + 0, + 50, + genericLogger + ); + expect(result).toEqual({ + totalCount: 1, + results: [eservice4], + }); + }); + it("should get the eServices, including the ones with an active delegation, if they exist (parameters: producersIds, mode)", async () => { const delegatedOrganization1: TenantId = generateId(); const delegatedOrganization2: TenantId = generateId();