From 6e92a290f17ee79d2d015eb89938cbcb672e2b77 Mon Sep 17 00:00:00 2001 From: Clara Jordan Date: Mon, 19 Sep 2022 20:58:54 +0100 Subject: [PATCH] Add governingEntities to flowObjects response --- .../flow-object/flow-object-service.ts | 11 ++++ src/domain-services/flow/graphql/types.ts | 4 ++ .../governing-entity-service.ts | 51 +++++++++++++++++++ .../governing-entity/graphql/resolver.ts | 21 ++++++++ .../governing-entity/graphql/types.ts | 12 +++++ 5 files changed, 99 insertions(+) create mode 100644 src/domain-services/governing-entity/governing-entity-service.ts create mode 100644 src/domain-services/governing-entity/graphql/resolver.ts create mode 100644 src/domain-services/governing-entity/graphql/types.ts diff --git a/src/domain-services/flow-object/flow-object-service.ts b/src/domain-services/flow-object/flow-object-service.ts index 68fe44b5..293ec0df 100644 --- a/src/domain-services/flow-object/flow-object-service.ts +++ b/src/domain-services/flow-object/flow-object-service.ts @@ -5,6 +5,7 @@ import { groupBy } from 'lodash'; import { Service } from 'typedi'; import Context from '../Context'; import { GlobalClusterService } from '../global-cluster/global-cluster-service'; +import { GoverningEntityService } from '../governing-entity/governing-entity-service'; import { LocationService } from '../location/location-service'; import { OrganizationService } from '../organization/organization-service'; import { PlanService } from '../plans/plan-service'; @@ -15,6 +16,7 @@ import { UsageYearService } from '../usage-year/usage-year-service'; export class FlowObjectService { constructor( private globalClusterService: GlobalClusterService, + private governingEntityService: GoverningEntityService, private locationService: LocationService, private projectService: ProjectService, private planService: PlanService, @@ -49,6 +51,15 @@ export class FlowObjectService { ), ]; } + if (type === 'governingEntity') { + return [ + 'governingEntities', + await this.governingEntityService.findByIds( + context.models, + flowObjects.map((fo) => fo.objectID) + ), + ]; + } if (type === 'location') { return [ 'locations', diff --git a/src/domain-services/flow/graphql/types.ts b/src/domain-services/flow/graphql/types.ts index cb0d6bdd..934a8103 100644 --- a/src/domain-services/flow/graphql/types.ts +++ b/src/domain-services/flow/graphql/types.ts @@ -2,6 +2,7 @@ import { Brand } from '@unocha/hpc-api-core/src/util/types'; import { Field, ID, ObjectType } from 'type-graphql'; import { BaseTypeWithSoftDelete } from '../../base-types'; import GlobalCluster from '../../global-cluster/graphql/types'; +import GoverningEntity from '../../governing-entity/graphql/types'; import Location from '../../location/graphql/types'; import Organization from '../../organization/graphql/types'; import Plan from '../../plans/graphql/types'; @@ -13,6 +14,9 @@ export class FlowObjectsGroupedByType { @Field(() => [GlobalCluster], { nullable: true }) globalClusters: GlobalCluster[]; + @Field(() => [GoverningEntity], { nullable: true }) + governingEntities: GoverningEntity[]; + @Field(() => [Location], { nullable: true }) locations: Location[]; diff --git a/src/domain-services/governing-entity/governing-entity-service.ts b/src/domain-services/governing-entity/governing-entity-service.ts new file mode 100644 index 00000000..7f830925 --- /dev/null +++ b/src/domain-services/governing-entity/governing-entity-service.ts @@ -0,0 +1,51 @@ +import { GoverningEntityId } from '@unocha/hpc-api-core/src/db/models/governingEntity'; +import { Database } from '@unocha/hpc-api-core/src/db/type'; +import { InstanceDataOfModel } from '@unocha/hpc-api-core/src/db/util/raw-model'; +import { createBrandedValue } from '@unocha/hpc-api-core/src/util/types'; +import { Service } from 'typedi'; + +@Service() +export class GoverningEntityService { + async findById( + models: Database, + id: number + ): Promise> { + const governingEntity = await models.governingEntity.get( + createBrandedValue(id) + ); + + if (!governingEntity) { + throw new Error(`Governing entity with ID ${id} does not exist`); + } + + return governingEntity; + } + + async findByIds( + models: Database, + ids: number[] + ): Promise<{ id: GoverningEntityId; name?: string | null }[]> { + const governingEntities = await models.governingEntity.find({ + where: { + id: { + [models.Op.IN]: ids.map((id) => createBrandedValue(id)), + }, + }, + }); + + const currentGoverningEntityVersions = + await models.governingEntityVersion.find({ + where: { + governingEntityId: { + [models.Op.IN]: governingEntities.map((p) => p.id), + }, + currentVersion: true, + }, + }); + + return currentGoverningEntityVersions.map((gev) => ({ + id: gev.governingEntityId, + name: gev.name, + })); + } +} diff --git a/src/domain-services/governing-entity/graphql/resolver.ts b/src/domain-services/governing-entity/graphql/resolver.ts new file mode 100644 index 00000000..c1b2fa86 --- /dev/null +++ b/src/domain-services/governing-entity/graphql/resolver.ts @@ -0,0 +1,21 @@ +import { Database } from '@unocha/hpc-api-core/src/db/type'; +import { InstanceDataOfModel } from '@unocha/hpc-api-core/src/db/util/raw-model'; +import { Arg, Ctx, Query, Resolver } from 'type-graphql'; +import { Service } from 'typedi'; +import Context from '../../Context'; +import { GoverningEntityService } from '../governing-entity-service'; +import GoverningEntity from './types'; + +@Service() +@Resolver(GoverningEntity) +export default class GoverningEntityResolver { + constructor(private fieldClusterService: GoverningEntityService) {} + + @Query(() => GoverningEntity) + async fieldCluster( + @Arg('id') id: number, + @Ctx() context: Context + ): Promise> { + return await this.fieldClusterService.findById(context.models, id); + } +} diff --git a/src/domain-services/governing-entity/graphql/types.ts b/src/domain-services/governing-entity/graphql/types.ts new file mode 100644 index 00000000..992777bd --- /dev/null +++ b/src/domain-services/governing-entity/graphql/types.ts @@ -0,0 +1,12 @@ +import { Brand } from '@unocha/hpc-api-core/src/util/types'; +import { Field, ID, ObjectType } from 'type-graphql'; +import { BaseType } from '../../base-types'; + +@ObjectType() +export default class GoverningEntity extends BaseType { + @Field(() => ID) + id: Brand; + + @Field({ nullable: true }) + name?: string; +}