From 1403a670e3768793e83d0bdb9ddd3b36166338a5 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Tue, 11 Mar 2025 22:11:25 +0400 Subject: [PATCH 1/4] added validation for space model --- src/space/services/space-validation.service.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/space/services/space-validation.service.ts b/src/space/services/space-validation.service.ts index f8db191..dff32f8 100644 --- a/src/space/services/space-validation.service.ts +++ b/src/space/services/space-validation.service.ts @@ -45,14 +45,15 @@ export class ValidationService { await this.communityService.validateProject(projectUuid); const spaces = await this.spaceRepository.find({ where: { uuid: In(spacesUuids), disabled: false }, - relations: ['devices', 'subspaces', 'productAllocations'], + relations: ['devices', 'subspaces', 'productAllocations', 'spaceModel'], }); const hasInvalidSpaces = spaces.some( (space) => space.devices.length > 0 || space.subspaces.length > 0 || - space.productAllocations.length > 0, + space.productAllocations.length > 0 || + space.spaceModel, ); if (hasInvalidSpaces) { From 5c47a3195f6ebc6931a953261d5443aa3e15c7a6 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Tue, 11 Mar 2025 22:29:01 +0400 Subject: [PATCH 2/4] fixed delete propagation --- src/space-model/handlers/propate-subspace-handler.ts | 11 +++++++++++ .../propogate-space-model-deletion.handler.ts | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/src/space-model/handlers/propate-subspace-handler.ts b/src/space-model/handlers/propate-subspace-handler.ts index d8be419..9da7980 100644 --- a/src/space-model/handlers/propate-subspace-handler.ts +++ b/src/space-model/handlers/propate-subspace-handler.ts @@ -49,6 +49,8 @@ export class PropogateUpdateSpaceModelHandler await this.addSubspaceModel(subspaceModel, spaces); } else if (subspaceModel.action === ModifyAction.DELETE) { await this.deleteSubspaceModel(subspaceModel, spaces); + } else if (subspaceModel.action === ModifyAction.UPDATE) { + await this.updateSubspaceModel(subspaceModel); } } } @@ -152,6 +154,15 @@ export class PropogateUpdateSpaceModelHandler } } + async updateSubspaceModel(subspaceModel: ISingleSubspaceModel) { + return this.subspaceRepository.update( + { + subSpaceModel: { uuid: subspaceModel.subspaceModel.uuid }, + disabled: false, + }, + { subspaceName: subspaceModel.subspaceModel.subspaceName }, + ); + } async updateSubspaceModels( subspaceModels: UpdatedSubspaceModelPayload[], queryRunner: QueryRunner, diff --git a/src/space-model/handlers/propogate-space-model-deletion.handler.ts b/src/space-model/handlers/propogate-space-model-deletion.handler.ts index 318635e..1686435 100644 --- a/src/space-model/handlers/propogate-space-model-deletion.handler.ts +++ b/src/space-model/handlers/propogate-space-model-deletion.handler.ts @@ -36,6 +36,13 @@ export class PropogateDeleteSpaceModelHandler for (const space of spaces) { try { + await queryRunner.manager.update( + this.spaceRepository.target, + { uuid: space.uuid }, + { + spaceModel: null, + }, + ); await this.spaceService.unlinkSpaceFromModel(space, queryRunner); } catch (innerError) { this.logger.error( From 67a78dbdfd9188939542c1882912331946c3e108 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Tue, 11 Mar 2025 22:31:14 +0400 Subject: [PATCH 3/4] error --- .../handlers/propate-subspace-handler.ts | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/space-model/handlers/propate-subspace-handler.ts b/src/space-model/handlers/propate-subspace-handler.ts index 9da7980..9b3aad2 100644 --- a/src/space-model/handlers/propate-subspace-handler.ts +++ b/src/space-model/handlers/propate-subspace-handler.ts @@ -40,18 +40,21 @@ export class PropogateUpdateSpaceModelHandler async execute(command: PropogateUpdateSpaceModelCommand): Promise { const { subspaceModels, spaces } = command.param; + try { + if (!subspaceModels || subspaceModels.length === 0) return; + if (!spaces || spaces.length === 0) return; - if (!subspaceModels || subspaceModels.length === 0) return; - if (!spaces || spaces.length === 0) return; - - for (const subspaceModel of subspaceModels) { - if (subspaceModel.action === ModifyAction.ADD) { - await this.addSubspaceModel(subspaceModel, spaces); - } else if (subspaceModel.action === ModifyAction.DELETE) { - await this.deleteSubspaceModel(subspaceModel, spaces); - } else if (subspaceModel.action === ModifyAction.UPDATE) { - await this.updateSubspaceModel(subspaceModel); + for (const subspaceModel of subspaceModels) { + if (subspaceModel.action === ModifyAction.ADD) { + await this.addSubspaceModel(subspaceModel, spaces); + } else if (subspaceModel.action === ModifyAction.DELETE) { + await this.deleteSubspaceModel(subspaceModel, spaces); + } else if (subspaceModel.action === ModifyAction.UPDATE) { + await this.updateSubspaceModel(subspaceModel); + } } + } catch (error) { + console.error(`Error processing subspaceModel updates`, error); } } From 1ce2f3c3ccb14025c354876f6d09d039b7195c70 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Wed, 12 Mar 2025 01:36:10 +0400 Subject: [PATCH 4/4] fix issues --- .../handlers/propate-subspace-handler.ts | 14 +-- .../services/space-model.service.ts | 7 +- ...bspace-model-product-allocation.service.ts | 2 +- .../subspace/subspace-model.service.ts | 15 ++-- .../services/space-validation.service.ts | 35 ++++++-- src/space/services/space.service.ts | 40 ++++++--- .../services/subspace/subspace.service.ts | 87 ++++++++++--------- 7 files changed, 122 insertions(+), 78 deletions(-) diff --git a/src/space-model/handlers/propate-subspace-handler.ts b/src/space-model/handlers/propate-subspace-handler.ts index 9b3aad2..c44f621 100644 --- a/src/space-model/handlers/propate-subspace-handler.ts +++ b/src/space-model/handlers/propate-subspace-handler.ts @@ -13,8 +13,7 @@ import { SubspaceModelProductAllocationRepoitory, TagModel, } from '@app/common/modules/space-model'; -import { DataSource, In, QueryRunner } from 'typeorm'; -import { SubSpaceService } from 'src/space/services'; +import { In, QueryRunner } from 'typeorm'; import { TagService } from 'src/space/services/tag'; import { ISingleSubspaceModel, @@ -30,8 +29,6 @@ export class PropogateUpdateSpaceModelHandler constructor( private readonly spaceRepository: SpaceRepository, private readonly subspaceRepository: SubspaceRepository, - private readonly dataSource: DataSource, - private readonly subSpaceService: SubSpaceService, private readonly tagService: TagService, private readonly subspaceModelProductRepository: SubspaceModelProductAllocationRepoitory, private readonly subspaceProductRepository: SubspaceProductAllocationRepository, @@ -111,7 +108,9 @@ export class PropogateUpdateSpaceModelHandler ], }); - if (!subspaces.length) return; + if (!subspaces.length) { + return; + } const allocationUuidsToRemove = subspaces.flatMap((subspace) => subspace.productAllocations.map((allocation) => allocation.uuid), @@ -127,7 +126,10 @@ export class PropogateUpdateSpaceModelHandler ); const relocatedAllocations = subspaceModel.relocatedAllocations || []; - if (!relocatedAllocations.length) return; + + if (!relocatedAllocations.length) { + return; + } for (const space of spaces) { for (const { allocation, tags = [] } of relocatedAllocations) { diff --git a/src/space-model/services/space-model.service.ts b/src/space-model/services/space-model.service.ts index c770a56..ae2a1fa 100644 --- a/src/space-model/services/space-model.service.ts +++ b/src/space-model/services/space-model.service.ts @@ -440,11 +440,12 @@ export class SpaceModelService { queryRunner?: QueryRunner, // Make queryRunner optional ): Promise { try { - space.spaceModel = spaceModel; if (queryRunner) { - await queryRunner.manager.save(SpaceEntity, space); + await queryRunner.manager.update(SpaceEntity, space.uuid, { + spaceModel, + }); } else { - await this.spaceRepository.save(space); + await this.spaceRepository.update(space.uuid, { spaceModel }); } const spaceProductAllocations = spaceModel.productAllocations.map( (modelAllocation) => diff --git a/src/space-model/services/subspace/subspace-model-product-allocation.service.ts b/src/space-model/services/subspace/subspace-model-product-allocation.service.ts index 0efc8fa..280a7d8 100644 --- a/src/space-model/services/subspace/subspace-model-product-allocation.service.ts +++ b/src/space-model/services/subspace/subspace-model-product-allocation.service.ts @@ -281,7 +281,7 @@ export class SubspaceModelProductAllocationService { queryRunner: QueryRunner, spaceModel: SpaceModelEntity, spaceTagUpdateDtos?: ModifyTagModelDto[], - ) { + ): Promise { const spaceAllocationToExclude: SpaceModelProductAllocationEntity[] = []; const updatedAllocations: IUpdatedAllocations[] = []; diff --git a/src/space-model/services/subspace/subspace-model.service.ts b/src/space-model/services/subspace/subspace-model.service.ts index 82905ee..e5fa6c1 100644 --- a/src/space-model/services/subspace/subspace-model.service.ts +++ b/src/space-model/services/subspace/subspace-model.service.ts @@ -145,13 +145,14 @@ export class SubSpaceModelService { ); const combineModels = [...createdSubspaces, ...updatedSubspaces]; - await this.productAllocationService.updateAllocations( - combineModels, - projectUuid, - queryRunner, - spaceModel, - spaceTagUpdateDtos, - ); + const updatedAllocations = + await this.productAllocationService.updateAllocations( + combineModels, + projectUuid, + queryRunner, + spaceModel, + spaceTagUpdateDtos, + ); const deletedSubspaces = await this.deleteSubspaceModels( deleteDtos, diff --git a/src/space/services/space-validation.service.ts b/src/space/services/space-validation.service.ts index dff32f8..e134b5d 100644 --- a/src/space/services/space-validation.service.ts +++ b/src/space/services/space-validation.service.ts @@ -177,17 +177,36 @@ export class ValidationService { } async validateSpaceModel(spaceModelUuid: string): Promise { - const spaceModel = await this.spaceModelRepository.findOne({ - where: { uuid: spaceModelUuid }, - relations: [ + const queryBuilder = this.spaceModelRepository + .createQueryBuilder('spaceModel') + .leftJoinAndSelect( + 'spaceModel.subspaceModels', 'subspaceModels', + 'subspaceModels.disabled = :disabled', + { disabled: false }, + ) + .leftJoinAndSelect( 'subspaceModels.productAllocations', - 'subspaceModels.productAllocations.tags', - 'subspaceModels.productAllocations.product', + 'subspaceProductAllocations', + ) + .leftJoinAndSelect( + 'subspaceProductAllocations.tags', + 'subspaceAllocationTags', + ) + .leftJoinAndSelect( + 'subspaceProductAllocations.product', + 'subspaceAllocationProduct', + ) + .leftJoinAndSelect('spaceModel.productAllocations', 'productAllocations') + .leftJoinAndSelect( 'productAllocations.product', - 'productAllocations.tags', - ], - }); + 'productAllocationProduct', + ) + .leftJoinAndSelect('productAllocations.tags', 'productAllocationTags') + .andWhere('spaceModel.disabled = :disabled', { disabled: false }) + .where('spaceModel.uuid = :uuid', { uuid: spaceModelUuid }); + + const spaceModel = await queryBuilder.getOne(); if (!spaceModel) { throw new HttpException( diff --git a/src/space/services/space.service.ts b/src/space/services/space.service.ts index 202b935..e27d43b 100644 --- a/src/space/services/space.service.ts +++ b/src/space/services/space.service.ts @@ -427,6 +427,8 @@ export class SpaceService { const { communityUuid, spaceUuid, projectUuid } = params; const queryRunner = this.dataSource.createQueryRunner(); + const hasSubspace = updateSpaceDto.subspace?.length > 0; + const hasTags = updateSpaceDto.tags?.length > 0; try { await queryRunner.connect(); @@ -450,11 +452,19 @@ export class SpaceService { } if (space.spaceModel && !updateSpaceDto.spaceModelUuid) { - space.spaceModel = null; + await queryRunner.manager.update(SpaceEntity, space.uuid, { + spaceModel: null, + }); await this.unlinkSpaceFromModel(space, queryRunner); } - this.updateSpaceProperties(space, updateSpaceDto); + await this.updateSpaceProperties(space, updateSpaceDto, queryRunner); + + if (hasSubspace || hasTags) { + await queryRunner.manager.update(SpaceEntity, space.uuid, { + spaceModel: null, + }); + } if (updateSpaceDto.spaceModelUuid) { const spaceModel = await this.validationService.validateSpaceModel( @@ -478,6 +488,7 @@ export class SpaceService { project, queryRunner, ); + await this.spaceModelService.linkToSpace( space, spaceModel, @@ -485,14 +496,9 @@ export class SpaceService { ); } } - - const hasSubspace = updateSpaceDto.subspace?.length > 0; - if (hasSubspace) { - space.spaceModel = null; await this.subSpaceService.unlinkModels(space.subspaces, queryRunner); } - await queryRunner.manager.save(space); if (hasSubspace) { await this.subSpaceService.modifySubSpace( @@ -513,6 +519,7 @@ export class SpaceService { updateSpaceDto.subspace, ); } + await queryRunner.commitTransaction(); return new SuccessResponseDto({ @@ -560,16 +567,23 @@ export class SpaceService { } } - private updateSpaceProperties( + private async updateSpaceProperties( space: SpaceEntity, updateSpaceDto: UpdateSpaceDto, - ): void { + queryRunner: QueryRunner, + ): Promise { const { spaceName, x, y, icon } = updateSpaceDto; - if (spaceName) space.spaceName = spaceName; - if (x) space.x = x; - if (y) space.y = y; - if (icon) space.icon = icon; + const updateFields: Partial = {}; + + if (spaceName) updateFields.spaceName = spaceName; + if (x !== undefined) updateFields.x = x; + if (y !== undefined) updateFields.y = y; + if (icon) updateFields.icon = icon; + + if (Object.keys(updateFields).length > 0) { + await queryRunner.manager.update(SpaceEntity, space.uuid, updateFields); + } } async getSpacesHierarchyForSpace( diff --git a/src/space/services/subspace/subspace.service.ts b/src/space/services/subspace/subspace.service.ts index 44c9d53..1d8c2b7 100644 --- a/src/space/services/subspace/subspace.service.ts +++ b/src/space/services/subspace/subspace.service.ts @@ -327,51 +327,58 @@ export class SubSpaceService { if (!subspaceDtos || subspaceDtos.length === 0) { return; } - const addedSubspaces = []; - const updatedSubspaces = []; + try { + const addedSubspaces = []; + const updatedSubspaces = []; - for (const subspace of subspaceDtos) { - switch (subspace.action) { - case ModifyAction.ADD: - const addedSubspace = await this.handleAddAction( - subspace, - space, - queryRunner, - ); - if (addedSubspace) addedSubspaces.push(addedSubspace); + for (const subspace of subspaceDtos) { + switch (subspace.action) { + case ModifyAction.ADD: + const addedSubspace = await this.handleAddAction( + subspace, + space, + queryRunner, + ); + if (addedSubspace) addedSubspaces.push(addedSubspace); - break; - case ModifyAction.UPDATE: - const updatedSubspace = await this.handleUpdateAction( - subspace, - queryRunner, - ); - if (updatedSubspace) { - updatedSubspaces.push(updatedSubspace); - } - break; - case ModifyAction.DELETE: - await this.handleDeleteAction(subspace, queryRunner); - break; - default: - throw new HttpException( - `Invalid action "${subspace.action}".`, - HttpStatus.BAD_REQUEST, - ); + break; + case ModifyAction.UPDATE: + const updatedSubspace = await this.handleUpdateAction( + subspace, + queryRunner, + ); + if (updatedSubspace) { + updatedSubspaces.push(updatedSubspace); + } + break; + case ModifyAction.DELETE: + await this.handleDeleteAction(subspace, queryRunner); + break; + default: + throw new HttpException( + `Invalid action "${subspace.action}".`, + HttpStatus.BAD_REQUEST, + ); + } } - } - const combinedSubspaces = [...addedSubspaces, ...updatedSubspaces].filter( - (subspace) => subspace !== undefined, - ); + const combinedSubspaces = [...addedSubspaces, ...updatedSubspaces].filter( + (subspace) => subspace !== undefined, + ); - if (combinedSubspaces.length > 0) { - await this.subspaceProductAllocationService.updateSubspaceProductAllocations( - combinedSubspaces, - projectUuid, - queryRunner, - space, - spaceTagUpdateDtos, + if (combinedSubspaces.length > 0) { + await this.subspaceProductAllocationService.updateSubspaceProductAllocations( + combinedSubspaces, + projectUuid, + queryRunner, + space, + spaceTagUpdateDtos, + ); + } + } catch (error) { + throw new HttpException( + `An error occurred while modifying subspaces: ${error.message}`, + HttpStatus.INTERNAL_SERVER_ERROR, ); } }