From f1e1044bb21a203b5f89a8555a4696e5c91edf62 Mon Sep 17 00:00:00 2001 From: Mrika Llabani Date: Fri, 10 Nov 2023 08:21:36 +0100 Subject: [PATCH] N21-1319 schoolexternaltool metadata --- .../school-external-tool-metadata.response.ts | 11 +++ .../controller/tool-school.controller.ts | 22 ++++++ .../domain/school-external-tool-metadata.ts | 9 +++ .../school-external-tool-metadata.mapper.ts | 14 ++++ .../school-external-tool-metadata.service.ts | 78 +++++++++++++++++++ .../uc/school-external-tool.uc.ts | 19 +++++ .../school-external-tool.repo.ts | 5 ++ 7 files changed, 158 insertions(+) create mode 100644 apps/server/src/modules/tool/school-external-tool/controller/dto/school-external-tool-metadata.response.ts create mode 100644 apps/server/src/modules/tool/school-external-tool/domain/school-external-tool-metadata.ts create mode 100644 apps/server/src/modules/tool/school-external-tool/mapper/school-external-tool-metadata.mapper.ts create mode 100644 apps/server/src/modules/tool/school-external-tool/service/school-external-tool-metadata.service.ts diff --git a/apps/server/src/modules/tool/school-external-tool/controller/dto/school-external-tool-metadata.response.ts b/apps/server/src/modules/tool/school-external-tool/controller/dto/school-external-tool-metadata.response.ts new file mode 100644 index 00000000000..59cbdc91152 --- /dev/null +++ b/apps/server/src/modules/tool/school-external-tool/controller/dto/school-external-tool-metadata.response.ts @@ -0,0 +1,11 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { ToolContextType } from '../../../common/enum'; + +export class SchoolExternalToolMetadataResponse { + @ApiProperty() + contextExternalToolCountPerContext: Map; + + constructor(schoolExternalToolMetadataResponse: SchoolExternalToolMetadataResponse) { + this.contextExternalToolCountPerContext = schoolExternalToolMetadataResponse.contextExternalToolCountPerContext; + } +} diff --git a/apps/server/src/modules/tool/school-external-tool/controller/tool-school.controller.ts b/apps/server/src/modules/tool/school-external-tool/controller/tool-school.controller.ts index 79d6f789443..9a4cdac32b9 100644 --- a/apps/server/src/modules/tool/school-external-tool/controller/tool-school.controller.ts +++ b/apps/server/src/modules/tool/school-external-tool/controller/tool-school.controller.ts @@ -14,8 +14,10 @@ import { Body, Controller, Delete, Get, Param, Post, Query, Put, HttpCode, HttpS import { ValidationError } from '@shared/common'; import { LegacyLogger } from '@src/core/logger'; import { Authenticate, CurrentUser, ICurrentUser } from '@modules/authentication'; +import { SchoolExternalToolMetadata } from '../domain/school-external-tool-metadata'; import { SchoolExternalToolRequestMapper, SchoolExternalToolResponseMapper } from '../mapper'; import { ExternalToolSearchListResponse } from '../../external-tool/controller/dto'; +import { SchoolExternalToolMetadataMapper } from '../mapper/school-external-tool-metadata.mapper'; import { SchoolExternalToolIdParams, SchoolExternalToolPostParams, @@ -26,6 +28,7 @@ import { import { SchoolExternalToolDto } from '../uc/dto/school-external-tool.types'; import { SchoolExternalToolUc } from '../uc'; import { SchoolExternalTool } from '../domain'; +import { SchoolExternalToolMetadataResponse } from './dto/school-external-tool-metadata.response'; @ApiTags('Tool') @Authenticate('jwt') @@ -136,4 +139,23 @@ export class ToolSchoolController { return response; } + + @Get('/:schoolExternalToolId/metadata') + @ApiOperation({ summary: 'Gets the metadata of an school external tool.' }) + @ApiOkResponse({ + description: 'Metadata of school external tool fetched successfully.', + }) + @ApiUnauthorizedResponse({ description: 'User is not logged in.' }) + async getMetaDataForExternalTool( + @CurrentUser() currentUser: ICurrentUser, + @Param() params: SchoolExternalToolIdParams + ): Promise { + const schoolExternalToolMetadata: SchoolExternalToolMetadata = + await this.schoolExternalToolUc.getMetadataForSchoolExternalTool(currentUser.userId, params.schoolExternalToolId); + + const mapped: SchoolExternalToolMetadataResponse = + SchoolExternalToolMetadataMapper.mapToSchoolExternalToolMetadataResponse(schoolExternalToolMetadata); + + return mapped; + } } diff --git a/apps/server/src/modules/tool/school-external-tool/domain/school-external-tool-metadata.ts b/apps/server/src/modules/tool/school-external-tool/domain/school-external-tool-metadata.ts new file mode 100644 index 00000000000..ec03f944360 --- /dev/null +++ b/apps/server/src/modules/tool/school-external-tool/domain/school-external-tool-metadata.ts @@ -0,0 +1,9 @@ +import { ToolContextType } from '../../common/enum'; + +export class SchoolExternalToolMetadata { + contextExternalToolCountPerContext: Map; + + constructor(schoolExternalToolMetadata: SchoolExternalToolMetadata) { + this.contextExternalToolCountPerContext = schoolExternalToolMetadata.contextExternalToolCountPerContext; + } +} diff --git a/apps/server/src/modules/tool/school-external-tool/mapper/school-external-tool-metadata.mapper.ts b/apps/server/src/modules/tool/school-external-tool/mapper/school-external-tool-metadata.mapper.ts new file mode 100644 index 00000000000..ef397dbe0f5 --- /dev/null +++ b/apps/server/src/modules/tool/school-external-tool/mapper/school-external-tool-metadata.mapper.ts @@ -0,0 +1,14 @@ +import { SchoolExternalToolMetadataResponse } from '../controller/dto/school-external-tool-metadata.response'; +import { SchoolExternalToolMetadata } from '../domain/school-external-tool-metadata'; + +export class SchoolExternalToolMetadataMapper { + static mapToSchoolExternalToolMetadataResponse( + schoolExternalToolMetadata: SchoolExternalToolMetadata + ): SchoolExternalToolMetadataResponse { + const externalToolMetadataResponse: SchoolExternalToolMetadataResponse = new SchoolExternalToolMetadataResponse({ + contextExternalToolCountPerContext: schoolExternalToolMetadata.contextExternalToolCountPerContext, + }); + + return externalToolMetadataResponse; + } +} diff --git a/apps/server/src/modules/tool/school-external-tool/service/school-external-tool-metadata.service.ts b/apps/server/src/modules/tool/school-external-tool/service/school-external-tool-metadata.service.ts new file mode 100644 index 00000000000..d4de0f42ed2 --- /dev/null +++ b/apps/server/src/modules/tool/school-external-tool/service/school-external-tool-metadata.service.ts @@ -0,0 +1,78 @@ +import { Injectable } from '@nestjs/common'; +import { EntityId } from '@shared/domain'; +import { ContextExternalToolRepo, ExternalToolRepo, SchoolExternalToolRepo } from '@shared/repo'; +import { Logger } from '../../../../core/logger'; +import { ToolContextType } from '../../common/enum'; +import { SchoolExternalToolMetadata } from '../domain/school-external-tool-metadata'; + +@Injectable() +export class SchoolExternalToolMetadataService { + constructor( + private readonly logger: Logger, + private readonly externalToolRepo: ExternalToolRepo, + private readonly schoolToolRepo: SchoolExternalToolRepo, + private readonly contextToolRepo: ContextExternalToolRepo + ) {} + + async getMetadata(schoolExternalToolId: EntityId) { + const toolCountPerContext: { ToolContextType; number }[] = await Promise.all( + // Context Course + Object.values(ToolContextType).map( + async ( + contextType: ToolContextType + ): Promise<{ + ToolContextType; + number; + }> => { + const countPerContext: number = + await this.contextToolRepo.countContextExternalToolsBySchoolToolIdAndContextType( + contextType, + schoolExternalToolId + ); + return { ToolContextType: contextType, number: countPerContext }; + } + ) + ); + + const schoolExternaltoolMetadata = this.createSchoolExternalToolMetadata(toolCountPerContext); + + /* const contextExternalToolMetadata: Map = new Map( + toolCountPerContext.map((contextExternalToolCountPerSchool: { ToolContextType; number }) => [ + contextExternalToolCountPerSchool.ToolContextType, + contextExternalToolCountPerSchool.number, + ]) + ); + + const externaltoolMetadata: ExternalToolMetadata = new ExternalToolMetadata({ + schoolExternalToolCount, + contextExternalToolCountPerContext: contextExternalToolMetadata, + }); + + */ + + return schoolExternaltoolMetadata; + } + + private createContextExternalToolMetaData( + toolCountPerContext: { ToolContextType; number }[] + ): Map { + const contextExternalToolMetadata: Map = new Map( + toolCountPerContext.map((contextExternalToolCountPerSchool: { ToolContextType; number }) => [ + contextExternalToolCountPerSchool.ToolContextType, + contextExternalToolCountPerSchool.number, + ]) + ); + + return contextExternalToolMetadata; + } + + private createSchoolExternalToolMetadata( + contextExternalToolCountPerContext: { ToolContextType; number }[] + ): SchoolExternalToolMetadata { + const schoolExternaltoolMetadata: SchoolExternalToolMetadata = new SchoolExternalToolMetadata({ + contextExternalToolCountPerContext: this.createContextExternalToolMetaData(contextExternalToolCountPerContext), + }); + + return schoolExternaltoolMetadata; + } +} diff --git a/apps/server/src/modules/tool/school-external-tool/uc/school-external-tool.uc.ts b/apps/server/src/modules/tool/school-external-tool/uc/school-external-tool.uc.ts index d7adf3f4937..e5d05409d3b 100644 --- a/apps/server/src/modules/tool/school-external-tool/uc/school-external-tool.uc.ts +++ b/apps/server/src/modules/tool/school-external-tool/uc/school-external-tool.uc.ts @@ -4,7 +4,9 @@ import { AuthorizationContext, AuthorizationContextBuilder } from '@modules/auth import { ToolPermissionHelper } from '../../common/uc/tool-permission-helper'; import { ContextExternalToolService } from '../../context-external-tool/service'; import { SchoolExternalTool } from '../domain'; +import { SchoolExternalToolMetadata } from '../domain/school-external-tool-metadata'; import { SchoolExternalToolService, SchoolExternalToolValidationService } from '../service'; +import { SchoolExternalToolMetadataService } from '../service/school-external-tool-metadata.service'; import { SchoolExternalToolDto, SchoolExternalToolQueryInput } from './dto/school-external-tool.types'; @Injectable() @@ -13,6 +15,7 @@ export class SchoolExternalToolUc { private readonly schoolExternalToolService: SchoolExternalToolService, private readonly contextExternalToolService: ContextExternalToolService, private readonly schoolExternalToolValidationService: SchoolExternalToolValidationService, + private readonly schoolexternaltoolMetadataService: SchoolExternalToolMetadataService, private readonly toolPermissionHelper: ToolPermissionHelper ) {} @@ -95,4 +98,20 @@ export class SchoolExternalToolUc { const saved = await this.schoolExternalToolService.saveSchoolExternalTool(updated); return saved; } + + async getMetadataForSchoolExternalTool( + userId: EntityId, + schoolExternalToolId: EntityId + ): Promise { + const schoolExternalTool: SchoolExternalTool = await this.schoolExternalToolService.findById(schoolExternalToolId); + + const context: AuthorizationContext = AuthorizationContextBuilder.read([Permission.SCHOOL_TOOL_ADMIN]); + await this.toolPermissionHelper.ensureSchoolPermissions(userId, schoolExternalTool, context); + + const metadata: SchoolExternalToolMetadata = await this.schoolexternaltoolMetadataService.getMetadata( + schoolExternalToolId + ); + + return metadata; + } } diff --git a/apps/server/src/shared/repo/schoolexternaltool/school-external-tool.repo.ts b/apps/server/src/shared/repo/schoolexternaltool/school-external-tool.repo.ts index 64f55c715e8..978193b54c0 100644 --- a/apps/server/src/shared/repo/schoolexternaltool/school-external-tool.repo.ts +++ b/apps/server/src/shared/repo/schoolexternaltool/school-external-tool.repo.ts @@ -38,6 +38,11 @@ export class SchoolExternalToolRepo extends BaseDORepo< return domainObjects; } + async countSchoolExternalToolsByExternalToolId(toolId: string): Promise { + const schoolExternalToolCount: number = await this._em.count(this.entityName, { tool: toolId }); + return schoolExternalToolCount; + } + async findBySchoolId(schoolId: string): Promise { const entities: SchoolExternalToolEntity[] = await this._em.find(this.entityName, { school: schoolId }); const domainObjects: SchoolExternalTool[] = entities.map((entity: SchoolExternalToolEntity): SchoolExternalTool => {