fix duplication

This commit is contained in:
hannathkadher
2025-03-11 13:43:23 +04:00
parent c62c952544
commit f9f9592603
5 changed files with 87 additions and 44 deletions

View File

@ -26,7 +26,7 @@ export class CreateOrphanSpaceHandler
const orphanCommunityName = `${ORPHAN_COMMUNITY_NAME}-${project.name}`; const orphanCommunityName = `${ORPHAN_COMMUNITY_NAME}-${project.name}`;
let orphanCommunity = await this.communityRepository.findOne({ let orphanCommunity = await this.communityRepository.findOne({
where: { name: orphanCommunityName, project }, where: { name: orphanCommunityName, project: { uuid: project.uuid } },
}); });
if (!orphanCommunity) { if (!orphanCommunity) {

View File

@ -14,6 +14,7 @@ import { ModifyAction } from '@app/common/constants/modify-action.enum';
import { NewTagEntity } from '@app/common/modules/tag'; import { NewTagEntity } from '@app/common/modules/tag';
import { ProductEntity } from '@app/common/modules/product/entities'; import { ProductEntity } from '@app/common/modules/product/entities';
import { SpaceRepository } from '@app/common/modules/space'; import { SpaceRepository } from '@app/common/modules/space';
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
import { ProjectEntity } from '@app/common/modules/project/entities'; import { ProjectEntity } from '@app/common/modules/project/entities';
@Injectable() @Injectable()
@ -30,11 +31,10 @@ export class SpaceModelProductAllocationService {
tags: ProcessTagDto[], tags: ProcessTagDto[],
queryRunner?: QueryRunner, queryRunner?: QueryRunner,
modifySubspaceModels?: ModifySubspaceModelDto[], modifySubspaceModels?: ModifySubspaceModelDto[],
spaces?: SpaceEntity[],
): Promise<SpaceModelProductAllocationEntity[]> { ): Promise<SpaceModelProductAllocationEntity[]> {
try { try {
if (!tags.length) { if (!tags.length) return [];
return [];
}
const processedTags = await this.tagService.processTags( const processedTags = await this.tagService.processTags(
tags, tags,
@ -56,7 +56,7 @@ export class SpaceModelProductAllocationService {
SubspaceModelProductAllocationEntity, SubspaceModelProductAllocationEntity,
{ {
where: { where: {
product: tag.product, product: { uuid: tag.product.uuid },
subspaceModel: { spaceModel: { uuid: spaceModel.uuid } }, subspaceModel: { spaceModel: { uuid: spaceModel.uuid } },
tags: { uuid: tag.uuid }, tags: { uuid: tag.uuid },
}, },
@ -81,7 +81,6 @@ export class SpaceModelProductAllocationService {
) )
) { ) {
isTagNeeded = true; isTagNeeded = true;
break; break;
} }
} }
@ -94,9 +93,7 @@ export class SpaceModelProductAllocationService {
spaceModel, spaceModel,
); );
if (hasTags) { if (hasTags) continue;
continue;
}
let allocation = existingAllocations.get(tag.product.uuid); let allocation = existingAllocations.get(tag.product.uuid);
if (!allocation) { if (!allocation) {
@ -123,11 +120,9 @@ export class SpaceModelProductAllocationService {
if (productAllocations.length > 0) { if (productAllocations.length > 0) {
await this.saveAllocations(productAllocations, queryRunner); await this.saveAllocations(productAllocations, queryRunner);
} }
return productAllocations; return productAllocations;
} catch (error) { } catch (error) {
console.error(
`[ERROR] Failed to create product allocations: ${error.message}`,
);
throw this.handleError(error, 'Failed to create product allocations'); throw this.handleError(error, 'Failed to create product allocations');
} }
} }
@ -138,6 +133,7 @@ export class SpaceModelProductAllocationService {
spaceModel: SpaceModelEntity, spaceModel: SpaceModelEntity,
queryRunner: QueryRunner, queryRunner: QueryRunner,
modifySubspaceModels?: ModifySubspaceModelDto[], modifySubspaceModels?: ModifySubspaceModelDto[],
spaces?: SpaceEntity[],
): Promise<void> { ): Promise<void> {
try { try {
const addDtos = dtos.filter((dto) => dto.action === ModifyAction.ADD); const addDtos = dtos.filter((dto) => dto.action === ModifyAction.ADD);
@ -188,8 +184,15 @@ export class SpaceModelProductAllocationService {
spaceModel, spaceModel,
queryRunner, queryRunner,
modifySubspaceModels, modifySubspaceModels,
spaces,
),
this.processDeleteActions(
filteredDtos,
queryRunner,
spaceModel,
project,
spaces,
), ),
this.processDeleteActions(filteredDtos, queryRunner, spaceModel),
]); ]);
} catch (error) { } catch (error) {
throw this.handleError(error, 'Error while updating product allocations'); throw this.handleError(error, 'Error while updating product allocations');
@ -202,6 +205,7 @@ export class SpaceModelProductAllocationService {
spaceModel: SpaceModelEntity, spaceModel: SpaceModelEntity,
queryRunner: QueryRunner, queryRunner: QueryRunner,
modifySubspaceModels?: ModifySubspaceModelDto[], modifySubspaceModels?: ModifySubspaceModelDto[],
spaces?: SpaceEntity[],
): Promise<void> { ): Promise<void> {
const addDtos: ProcessTagDto[] = dtos const addDtos: ProcessTagDto[] = dtos
.filter((dto) => dto.action === ModifyAction.ADD) .filter((dto) => dto.action === ModifyAction.ADD)
@ -218,6 +222,7 @@ export class SpaceModelProductAllocationService {
addDtos, addDtos,
queryRunner, queryRunner,
modifySubspaceModels, modifySubspaceModels,
spaces,
); );
} }
} }
@ -247,11 +252,17 @@ export class SpaceModelProductAllocationService {
): Promise<SpaceModelProductAllocationEntity | null> { ): Promise<SpaceModelProductAllocationEntity | null> {
return queryRunner return queryRunner
? queryRunner.manager.findOne(SpaceModelProductAllocationEntity, { ? queryRunner.manager.findOne(SpaceModelProductAllocationEntity, {
where: { spaceModel, product: product }, where: {
spaceModel: { uuid: spaceModel.uuid },
product: { uuid: product.uuid },
},
relations: ['tags'], relations: ['tags'],
}) })
: this.spaceModelProductAllocationRepository.findOne({ : this.spaceModelProductAllocationRepository.findOne({
where: { spaceModel, product: product }, where: {
spaceModel: { uuid: spaceModel.uuid },
product: { uuid: product.uuid },
},
relations: ['tags'], relations: ['tags'],
}); });
} }
@ -293,6 +304,8 @@ export class SpaceModelProductAllocationService {
dtos: ModifyTagModelDto[], dtos: ModifyTagModelDto[],
queryRunner: QueryRunner, queryRunner: QueryRunner,
spaceModel: SpaceModelEntity, spaceModel: SpaceModelEntity,
project: ProjectEntity,
spaces?: SpaceEntity[],
): Promise<SpaceModelProductAllocationEntity[]> { ): Promise<SpaceModelProductAllocationEntity[]> {
try { try {
if (!dtos || dtos.length === 0) { if (!dtos || dtos.length === 0) {
@ -391,18 +404,18 @@ export class SpaceModelProductAllocationService {
spaceModel: { spaceModel: {
uuid: spaceModel.uuid, uuid: spaceModel.uuid,
}, },
product: tag.product, product: {
uuid: tag.product.uuid,
},
}, },
relations: ['tags'], relations: ['tags'],
}, },
); );
//Flatten all existing tags for this product in the space
const existingTagsForProduct = existingAllocationsForProduct.flatMap( const existingTagsForProduct = existingAllocationsForProduct.flatMap(
(allocation) => allocation.tags, (allocation) => allocation.tags,
); );
// Check if the tag is already assigned to the same product in this space
const isDuplicateTag = existingTagsForProduct.some( const isDuplicateTag = existingTagsForProduct.some(
(existingTag) => existingTag.uuid === tag.uuid, (existingTag) => existingTag.uuid === tag.uuid,
); );

View File

@ -76,7 +76,7 @@ export class SubspaceModelProductAllocationService {
const existingTagInSameSpace = await (queryRunner const existingTagInSameSpace = await (queryRunner
? queryRunner.manager.findOne(SubspaceModelProductAllocationEntity, { ? queryRunner.manager.findOne(SubspaceModelProductAllocationEntity, {
where: { where: {
product: tag.product, product: { uuid: tag.product.uuid },
subspaceModel: { spaceModel: subspaceModel.spaceModel }, subspaceModel: { spaceModel: subspaceModel.spaceModel },
tags: { uuid: tag.uuid }, // Ensure the exact tag is checked tags: { uuid: tag.uuid }, // Ensure the exact tag is checked
}, },
@ -84,7 +84,7 @@ export class SubspaceModelProductAllocationService {
}) })
: this.subspaceModelProductAllocationRepository.findOne({ : this.subspaceModelProductAllocationRepository.findOne({
where: { where: {
product: tag.product, product: { uuid: tag.product.uuid },
subspaceModel: { spaceModel: subspaceModel.spaceModel }, subspaceModel: { spaceModel: subspaceModel.spaceModel },
tags: { uuid: tag.uuid }, tags: { uuid: tag.uuid },
}, },
@ -105,11 +105,17 @@ export class SubspaceModelProductAllocationService {
//Check if there are existing allocations for this product in the subspace //Check if there are existing allocations for this product in the subspace
const existingAllocationsForProduct = await (queryRunner const existingAllocationsForProduct = await (queryRunner
? queryRunner.manager.find(SubspaceModelProductAllocationEntity, { ? queryRunner.manager.find(SubspaceModelProductAllocationEntity, {
where: { subspaceModel, product: tag.product }, where: {
subspaceModel: { uuid: subspaceModel.uuid },
product: { uuid: tag.product.uuid },
},
relations: ['tags'], relations: ['tags'],
}) })
: this.subspaceModelProductAllocationRepository.find({ : this.subspaceModelProductAllocationRepository.find({
where: { subspaceModel, product: tag.product }, where: {
subspaceModel: { uuid: subspaceModel.uuid },
product: { uuid: tag.product.uuid },
},
relations: ['tags'], relations: ['tags'],
})); }));

View File

@ -79,7 +79,12 @@ export class SpaceProductAllocationService {
} }
if (isTagNeeded) { if (isTagNeeded) {
await this.validateTagWithinSpace(queryRunner, tag, space); const isDuplicated = await this.validateTagWithinSpace(
queryRunner,
tag,
space,
);
if (isDuplicated) continue;
let allocation = existingAllocations.get(tag.product.uuid); let allocation = existingAllocations.get(tag.product.uuid);
if (!allocation) { if (!allocation) {
@ -449,29 +454,36 @@ export class SpaceProductAllocationService {
queryRunner: QueryRunner, queryRunner: QueryRunner,
tag: NewTagEntity, tag: NewTagEntity,
space: SpaceEntity, space: SpaceEntity,
) { ): Promise<boolean> {
const existingAllocationsForProduct = await queryRunner.manager.find( const existingAllocationsForProduct = await queryRunner.manager.find(
SpaceProductAllocationEntity, SpaceProductAllocationEntity,
{ {
where: { space, product: tag.product }, where: {
space: {
uuid: space.uuid,
},
product: {
uuid: tag.product.uuid,
},
},
relations: ['tags'], relations: ['tags'],
}, },
); );
if (
!existingAllocationsForProduct ||
existingAllocationsForProduct.length === 0
) {
return false;
}
const existingTagsForProduct = existingAllocationsForProduct.flatMap( const existingTagsForProduct = existingAllocationsForProduct.flatMap(
(allocation) => allocation.tags, (allocation) => allocation.tags || [],
); );
const isDuplicateTag = existingTagsForProduct.some( return existingTagsForProduct.some(
(existingTag) => existingTag.uuid === tag.uuid, (existingTag) => existingTag.uuid === tag.uuid,
); );
if (isDuplicateTag) {
throw new HttpException(
`Tag ${tag.uuid} is already allocated to product ${tag.product.uuid} within this space (${space.uuid}).`,
HttpStatus.BAD_REQUEST,
);
}
} }
private async getAllocationByProduct( private async getAllocationByProduct(
@ -481,11 +493,17 @@ export class SpaceProductAllocationService {
): Promise<SpaceProductAllocationEntity | null> { ): Promise<SpaceProductAllocationEntity | null> {
return queryRunner return queryRunner
? queryRunner.manager.findOne(SpaceProductAllocationEntity, { ? queryRunner.manager.findOne(SpaceProductAllocationEntity, {
where: { space, product: product }, where: {
space: { uuid: space.uuid },
product: { uuid: product.uuid },
},
relations: ['tags'], relations: ['tags'],
}) })
: this.spaceProductAllocationRepository.findOne({ : this.spaceProductAllocationRepository.findOne({
where: { space, product: product }, where: {
space: { uuid: space.uuid },
product: { uuid: product.uuid },
},
relations: ['tags'], relations: ['tags'],
}); });
} }

View File

@ -404,16 +404,16 @@ export class SubspaceProductAllocationService {
const existingTagInSpace = await (queryRunner const existingTagInSpace = await (queryRunner
? queryRunner.manager.findOne(SpaceProductAllocationEntity, { ? queryRunner.manager.findOne(SpaceProductAllocationEntity, {
where: { where: {
product: tag.product, product: { uuid: tag.product.uuid },
space: subspace.space, space: { uuid: subspace.space.uuid },
tags: { uuid: tag.uuid }, tags: { uuid: tag.uuid },
}, },
relations: ['tags'], relations: ['tags'],
}) })
: this.spaceProductAllocationRepository.findOne({ : this.spaceProductAllocationRepository.findOne({
where: { where: {
product: tag.product, product: { uuid: tag.product.uuid },
space: subspace.space, space: { uuid: subspace.space.uuid },
tags: { uuid: tag.uuid }, tags: { uuid: tag.uuid },
}, },
relations: ['tags'], relations: ['tags'],
@ -435,7 +435,7 @@ export class SubspaceProductAllocationService {
const existingTagInSameSpace = await (queryRunner const existingTagInSameSpace = await (queryRunner
? queryRunner.manager.findOne(SubspaceProductAllocationEntity, { ? queryRunner.manager.findOne(SubspaceProductAllocationEntity, {
where: { where: {
product: tag.product, product: { uuid: tag.product.uuid },
subspace: { space: subspace.space }, subspace: { space: subspace.space },
tags: { uuid: tag.uuid }, tags: { uuid: tag.uuid },
}, },
@ -443,7 +443,7 @@ export class SubspaceProductAllocationService {
}) })
: this.subspaceProductAllocationRepository.findOne({ : this.subspaceProductAllocationRepository.findOne({
where: { where: {
product: tag.product, product: { uuid: tag.product.uuid },
subspace: { space: subspace.space }, subspace: { space: subspace.space },
tags: { uuid: tag.uuid }, tags: { uuid: tag.uuid },
}, },
@ -484,11 +484,17 @@ export class SubspaceProductAllocationService {
): Promise<SubspaceProductAllocationEntity | null> { ): Promise<SubspaceProductAllocationEntity | null> {
return queryRunner return queryRunner
? queryRunner.manager.findOne(SubspaceProductAllocationEntity, { ? queryRunner.manager.findOne(SubspaceProductAllocationEntity, {
where: { subspace, product }, where: {
subspace: { uuid: subspace.uuid },
product: { uuid: product.uuid },
},
relations: ['tags'], relations: ['tags'],
}) })
: this.subspaceProductAllocationRepository.findOne({ : this.subspaceProductAllocationRepository.findOne({
where: { subspace, product }, where: {
subspace: { uuid: subspace.uuid },
product: { uuid: product.uuid },
},
relations: ['tags'], relations: ['tags'],
}); });
} }