mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-07-10 07:07:21 +00:00

* task: add getCommunitiesV2 * task: update getOneSpace API to match revamp structure * refactor: implement modifications to pace management APIs * refactor: remove space link
250 lines
7.7 KiB
TypeScript
250 lines
7.7 KiB
TypeScript
import { SpaceProductAllocationRepository } from '@app/common/modules/space';
|
|
import { SubspaceProductAllocationEntity } from '@app/common/modules/space/entities/subspace/subspace-product-allocation.entity';
|
|
import { SubspaceEntity } from '@app/common/modules/space/entities/subspace/subspace.entity';
|
|
import { SubspaceProductAllocationRepository } from '@app/common/modules/space/repositories/subspace.repository';
|
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
|
import { UpdateSubspaceDto } from 'src/space/dtos';
|
|
import { TagService as NewTagService } from 'src/tags/services';
|
|
import { In, Not, QueryRunner } from 'typeorm';
|
|
|
|
@Injectable()
|
|
export class SubspaceProductAllocationService {
|
|
constructor(
|
|
private readonly tagService: NewTagService,
|
|
|
|
private readonly spaceProductAllocationRepository: SpaceProductAllocationRepository,
|
|
private readonly subspaceProductAllocationRepository: SubspaceProductAllocationRepository,
|
|
) {}
|
|
|
|
async createProductAllocations(
|
|
subspace: SubspaceEntity,
|
|
allocationsData: { product: string; tag: string }[],
|
|
queryRunner?: QueryRunner,
|
|
// spaceAllocationsToExclude?: SpaceProductAllocationEntity[],
|
|
): Promise<void> {
|
|
try {
|
|
if (!allocationsData.length) return;
|
|
|
|
const allocations: SubspaceProductAllocationEntity[] = [];
|
|
|
|
for (const allocationData of allocationsData) {
|
|
// await this.validateTagWithinSubspace(
|
|
// queryRunner,
|
|
// allocationData.tag,
|
|
// subspace,
|
|
// spaceAllocationsToExclude,
|
|
// );
|
|
|
|
if (
|
|
await this.isAllocationExist(allocationData, subspace, queryRunner)
|
|
) {
|
|
continue;
|
|
}
|
|
|
|
const allocation = this.createNewSubspaceAllocation(
|
|
subspace,
|
|
allocationData,
|
|
queryRunner,
|
|
);
|
|
allocations.push(allocation);
|
|
}
|
|
if (allocations.length > 0) {
|
|
await this.saveAllocations(allocations, queryRunner);
|
|
}
|
|
} catch (error) {
|
|
throw this.handleError(
|
|
error,
|
|
'Failed to create subspace product allocations',
|
|
);
|
|
}
|
|
}
|
|
|
|
async updateSubspaceProductAllocationsV2(
|
|
subSpaces: UpdateSubspaceDto[],
|
|
projectUuid: string,
|
|
queryRunner: QueryRunner,
|
|
) {
|
|
await Promise.all(
|
|
subSpaces.map(async (subspace) => {
|
|
await queryRunner.manager.delete(SubspaceProductAllocationEntity, {
|
|
subspace: subspace.uuid ? { uuid: subspace.uuid } : undefined,
|
|
tag: subspace.productAllocations
|
|
? {
|
|
uuid: Not(
|
|
In(
|
|
subspace.productAllocations
|
|
.filter((allocation) => allocation.tagUuid)
|
|
.map((allocation) => allocation.tagUuid),
|
|
),
|
|
),
|
|
}
|
|
: undefined,
|
|
product: subspace.productAllocations
|
|
? {
|
|
uuid: Not(
|
|
In(
|
|
subspace.productAllocations
|
|
.filter((allocation) => allocation.productUuid)
|
|
.map((allocation) => allocation.productUuid),
|
|
),
|
|
),
|
|
}
|
|
: undefined,
|
|
});
|
|
|
|
const subspaceEntity = await queryRunner.manager.findOne(
|
|
SubspaceEntity,
|
|
{
|
|
where: { uuid: subspace.uuid },
|
|
},
|
|
);
|
|
const processedTags = await this.tagService.upsertTags(
|
|
subspace.productAllocations,
|
|
projectUuid,
|
|
queryRunner,
|
|
);
|
|
|
|
const createdTagsByUUID = new Map(
|
|
processedTags.map((t) => [t.uuid, t]),
|
|
);
|
|
const createdTagsByName = new Map(
|
|
processedTags.map((t) => [t.name, t]),
|
|
);
|
|
|
|
// Create the product-tag mapping based on the processed tags
|
|
const productTagMapping = subspace.productAllocations.map(
|
|
({ tagUuid, tagName, productUuid }) => {
|
|
const inputTag = tagUuid
|
|
? createdTagsByUUID.get(tagUuid)
|
|
: createdTagsByName.get(tagName);
|
|
return {
|
|
tag: inputTag?.uuid,
|
|
product: productUuid,
|
|
};
|
|
},
|
|
);
|
|
|
|
await this.createProductAllocations(
|
|
subspaceEntity,
|
|
productTagMapping,
|
|
queryRunner,
|
|
);
|
|
}),
|
|
);
|
|
}
|
|
|
|
async unlinkModels(
|
|
allocations: SubspaceProductAllocationEntity[],
|
|
queryRunner: QueryRunner,
|
|
) {
|
|
try {
|
|
if (allocations.length === 0) return;
|
|
|
|
const allocationUuids = allocations.map((allocation) => allocation.uuid);
|
|
|
|
await queryRunner.manager.update(
|
|
SubspaceProductAllocationEntity,
|
|
{ uuid: In(allocationUuids) },
|
|
{ inheritedFromModel: null },
|
|
);
|
|
} catch (error) {
|
|
throw new HttpException(
|
|
'Failed to unlink models',
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
|
|
private createNewSubspaceAllocation(
|
|
subspace: SubspaceEntity,
|
|
allocationData: { product: string; tag: string },
|
|
queryRunner?: QueryRunner,
|
|
): SubspaceProductAllocationEntity {
|
|
return queryRunner
|
|
? queryRunner.manager.create(SubspaceProductAllocationEntity, {
|
|
subspace,
|
|
product: { uuid: allocationData.product },
|
|
tag: { uuid: allocationData.tag },
|
|
})
|
|
: this.subspaceProductAllocationRepository.create({
|
|
subspace,
|
|
product: { uuid: allocationData.product },
|
|
tag: { uuid: allocationData.tag },
|
|
});
|
|
}
|
|
|
|
private async isAllocationExist(
|
|
allocationData: { product: string; tag: string },
|
|
subspace: SubspaceEntity,
|
|
queryRunner?: QueryRunner,
|
|
): Promise<boolean> {
|
|
const allocation = queryRunner
|
|
? await queryRunner.manager.findOne(SubspaceProductAllocationEntity, {
|
|
where: {
|
|
subspace: { uuid: subspace.uuid },
|
|
product: { uuid: allocationData.product },
|
|
tag: { uuid: allocationData.tag },
|
|
},
|
|
})
|
|
: await this.subspaceProductAllocationRepository.findOne({
|
|
where: {
|
|
subspace: { uuid: subspace.uuid },
|
|
product: { uuid: allocationData.product },
|
|
tag: { uuid: allocationData.tag },
|
|
},
|
|
});
|
|
return !!allocation;
|
|
}
|
|
private async saveAllocation(
|
|
allocation: SubspaceProductAllocationEntity,
|
|
queryRunner?: QueryRunner,
|
|
): Promise<void> {
|
|
if (queryRunner) {
|
|
await queryRunner.manager.save(
|
|
SubspaceProductAllocationEntity,
|
|
allocation,
|
|
);
|
|
} else {
|
|
await this.subspaceProductAllocationRepository.save(allocation);
|
|
}
|
|
}
|
|
|
|
private async saveAllocations(
|
|
allocations: SubspaceProductAllocationEntity[],
|
|
queryRunner?: QueryRunner,
|
|
): Promise<void> {
|
|
if (queryRunner) {
|
|
await queryRunner.manager.save(
|
|
SubspaceProductAllocationEntity,
|
|
allocations,
|
|
);
|
|
} else {
|
|
await this.subspaceProductAllocationRepository.save(allocations);
|
|
}
|
|
}
|
|
private handleError(error: any, message: string): HttpException {
|
|
return new HttpException(
|
|
error instanceof HttpException ? error.message : message,
|
|
error instanceof HttpException
|
|
? error.getStatus()
|
|
: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
async clearAllAllocations(subspaceUuids: string[], queryRunner: QueryRunner) {
|
|
try {
|
|
await queryRunner.manager.delete(SubspaceProductAllocationEntity, {
|
|
subspace: { uuid: In(subspaceUuids) },
|
|
});
|
|
} catch (error) {
|
|
throw new HttpException(
|
|
error instanceof HttpException
|
|
? error.message
|
|
: 'An unexpected error occurred while clearing allocations',
|
|
error instanceof HttpException
|
|
? error.getStatus()
|
|
: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
);
|
|
}
|
|
}
|
|
}
|