mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-07-15 18:27:05 +00:00
Merge pull request #200 from SyncrowIOT/bugfix/update-space-model
fixed bugs
This commit is contained in:
@ -1,11 +1,4 @@
|
|||||||
import {
|
import { Entity, Column, OneToMany, ManyToOne, JoinColumn } from 'typeorm';
|
||||||
Entity,
|
|
||||||
Column,
|
|
||||||
OneToMany,
|
|
||||||
ManyToOne,
|
|
||||||
JoinColumn,
|
|
||||||
Unique,
|
|
||||||
} from 'typeorm';
|
|
||||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
import { SpaceModelDto } from '../dtos';
|
import { SpaceModelDto } from '../dtos';
|
||||||
import { SubspaceModelEntity } from './subspace-model';
|
import { SubspaceModelEntity } from './subspace-model';
|
||||||
@ -14,7 +7,6 @@ import { SpaceEntity } from '../../space/entities';
|
|||||||
import { TagModel } from './tag-model.entity';
|
import { TagModel } from './tag-model.entity';
|
||||||
|
|
||||||
@Entity({ name: 'space-model' })
|
@Entity({ name: 'space-model' })
|
||||||
@Unique(['modelName', 'project'])
|
|
||||||
export class SpaceModelEntity extends AbstractEntity<SpaceModelDto> {
|
export class SpaceModelEntity extends AbstractEntity<SpaceModelDto> {
|
||||||
@Column({
|
@Column({
|
||||||
type: 'uuid',
|
type: 'uuid',
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import { ICommand } from '@nestjs/cqrs';
|
import { ICommand } from '@nestjs/cqrs';
|
||||||
import { SpaceModelEntity } from '@app/common/modules/space-model';
|
import { SpaceModelEntity } from '@app/common/modules/space-model';
|
||||||
import { ModifyspaceModelPayload } from '../interfaces';
|
import { ModifyspaceModelPayload } from '../interfaces';
|
||||||
|
import { QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
export class PropogateUpdateSpaceModelCommand implements ICommand {
|
export class PropogateUpdateSpaceModelCommand implements ICommand {
|
||||||
constructor(
|
constructor(
|
||||||
public readonly param: {
|
public readonly param: {
|
||||||
spaceModel: SpaceModelEntity;
|
spaceModel: SpaceModelEntity;
|
||||||
modifiedSpaceModels: ModifyspaceModelPayload;
|
modifiedSpaceModels: ModifyspaceModelPayload;
|
||||||
|
queryRunner: QueryRunner;
|
||||||
},
|
},
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
@ -29,36 +29,37 @@ export class PropogateUpdateSpaceModelHandler
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async execute(command: PropogateUpdateSpaceModelCommand): Promise<void> {
|
async execute(command: PropogateUpdateSpaceModelCommand): Promise<void> {
|
||||||
const { spaceModel, modifiedSpaceModels } = command.param;
|
const { spaceModel, modifiedSpaceModels, queryRunner } = command.param;
|
||||||
const queryRunner = this.dataSource.createQueryRunner();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await queryRunner.connect();
|
const spaces = await queryRunner.manager.find(SpaceEntity, {
|
||||||
await queryRunner.startTransaction();
|
|
||||||
const spaces = await this.spaceRepository.find({
|
|
||||||
where: { spaceModel },
|
where: { spaceModel },
|
||||||
});
|
});
|
||||||
if (
|
|
||||||
modifiedSpaceModels.modifiedSubspaceModels.addedSubspaceModels.length >
|
const { modifiedSubspaceModels = {}, modifiedTags = {} } =
|
||||||
0
|
modifiedSpaceModels;
|
||||||
) {
|
|
||||||
|
const {
|
||||||
|
addedSubspaceModels = [],
|
||||||
|
updatedSubspaceModels = [],
|
||||||
|
deletedSubspaceModels = [],
|
||||||
|
} = modifiedSubspaceModels;
|
||||||
|
|
||||||
|
const { added = [], updated = [], deleted = [] } = modifiedTags;
|
||||||
|
|
||||||
|
if (addedSubspaceModels.length > 0) {
|
||||||
await this.addSubspaceModels(
|
await this.addSubspaceModels(
|
||||||
modifiedSpaceModels.modifiedSubspaceModels.addedSubspaceModels,
|
modifiedSpaceModels.modifiedSubspaceModels.addedSubspaceModels,
|
||||||
spaces,
|
spaces,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
);
|
);
|
||||||
} else if (
|
} else if (updatedSubspaceModels.length > 0) {
|
||||||
modifiedSpaceModels.modifiedSubspaceModels.updatedSubspaceModels
|
|
||||||
.length > 0
|
|
||||||
) {
|
|
||||||
await this.updateSubspaceModels(
|
await this.updateSubspaceModels(
|
||||||
modifiedSpaceModels.modifiedSubspaceModels.updatedSubspaceModels,
|
modifiedSpaceModels.modifiedSubspaceModels.updatedSubspaceModels,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (
|
if (deletedSubspaceModels.length > 0) {
|
||||||
modifiedSpaceModels.modifiedSubspaceModels.deletedSubspaceModels?.length
|
|
||||||
) {
|
|
||||||
const dtos: ModifySubspaceDto[] =
|
const dtos: ModifySubspaceDto[] =
|
||||||
modifiedSpaceModels.modifiedSubspaceModels.deletedSubspaceModels.map(
|
modifiedSpaceModels.modifiedSubspaceModels.deletedSubspaceModels.map(
|
||||||
(model) => ({
|
(model) => ({
|
||||||
@ -69,7 +70,7 @@ export class PropogateUpdateSpaceModelHandler
|
|||||||
await this.subSpaceService.modifySubSpace(dtos, queryRunner);
|
await this.subSpaceService.modifySubSpace(dtos, queryRunner);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modifiedSpaceModels.modifiedTags.added.length > 0) {
|
if (added.length > 0) {
|
||||||
await this.createTags(
|
await this.createTags(
|
||||||
modifiedSpaceModels.modifiedTags.added,
|
modifiedSpaceModels.modifiedTags.added,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
@ -78,26 +79,21 @@ export class PropogateUpdateSpaceModelHandler
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modifiedSpaceModels.modifiedTags.updated.length > 0) {
|
if (updated.length > 0) {
|
||||||
await this.updateTags(
|
await this.updateTags(
|
||||||
modifiedSpaceModels.modifiedTags.updated,
|
modifiedSpaceModels.modifiedTags.updated,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modifiedSpaceModels.modifiedTags.deleted.length > 0) {
|
if (deleted.length > 0) {
|
||||||
await this.deleteTags(
|
await this.deleteTags(
|
||||||
modifiedSpaceModels.modifiedTags.deleted,
|
modifiedSpaceModels.modifiedTags.deleted,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await queryRunner.commitTransaction();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await queryRunner.rollbackTransaction();
|
console.error(error);
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
await queryRunner.release();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import { CreateSpaceModelDto, UpdateSpaceModelDto } from '../dtos';
|
|||||||
import { ProjectParam } from 'src/community/dtos';
|
import { ProjectParam } from 'src/community/dtos';
|
||||||
import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
|
import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
|
||||||
import { SubSpaceModelService } from './subspace/subspace-model.service';
|
import { SubSpaceModelService } from './subspace/subspace-model.service';
|
||||||
import { DataSource } from 'typeorm';
|
import { DataSource, QueryRunner } from 'typeorm';
|
||||||
import {
|
import {
|
||||||
TypeORMCustomModel,
|
TypeORMCustomModel,
|
||||||
TypeORMCustomModelFindAllQuery,
|
TypeORMCustomModelFindAllQuery,
|
||||||
@ -49,7 +49,11 @@ export class SpaceModelService {
|
|||||||
try {
|
try {
|
||||||
const project = await this.validateProject(params.projectUuid);
|
const project = await this.validateProject(params.projectUuid);
|
||||||
|
|
||||||
await this.validateName(modelName, params.projectUuid);
|
await this.validateNameUsingQueryRunner(
|
||||||
|
modelName,
|
||||||
|
params.projectUuid,
|
||||||
|
queryRunner,
|
||||||
|
);
|
||||||
|
|
||||||
const spaceModel = this.spaceModelRepository.create({
|
const spaceModel = this.spaceModelRepository.create({
|
||||||
modelName,
|
modelName,
|
||||||
@ -140,20 +144,29 @@ export class SpaceModelService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update(dto: UpdateSpaceModelDto, param: SpaceModelParam) {
|
async update(dto: UpdateSpaceModelDto, param: SpaceModelParam) {
|
||||||
|
const queryRunner = this.dataSource.createQueryRunner();
|
||||||
|
|
||||||
await this.validateProject(param.projectUuid);
|
await this.validateProject(param.projectUuid);
|
||||||
const spaceModel = await this.validateSpaceModel(param.spaceModelUuid);
|
const spaceModel = await this.validateSpaceModel(param.spaceModelUuid);
|
||||||
const queryRunner = this.dataSource.createQueryRunner();
|
|
||||||
await queryRunner.connect();
|
await queryRunner.connect();
|
||||||
await queryRunner.startTransaction();
|
|
||||||
|
|
||||||
let modifiedSubspaceModels: ModifySubspaceModelPayload = {};
|
let modifiedSubspaceModels: ModifySubspaceModelPayload = {};
|
||||||
let modifiedTagsModelPayload: ModifiedTagsModelPayload = {};
|
let modifiedTagsModelPayload: ModifiedTagsModelPayload = {};
|
||||||
try {
|
try {
|
||||||
|
await queryRunner.startTransaction();
|
||||||
|
|
||||||
const { modelName } = dto;
|
const { modelName } = dto;
|
||||||
if (modelName) {
|
if (modelName) {
|
||||||
await this.validateName(modelName, param.projectUuid);
|
await this.validateNameUsingQueryRunner(
|
||||||
|
modelName,
|
||||||
|
param.projectUuid,
|
||||||
|
queryRunner,
|
||||||
|
);
|
||||||
spaceModel.modelName = modelName;
|
spaceModel.modelName = modelName;
|
||||||
await queryRunner.manager.save(spaceModel);
|
await queryRunner.manager.save(
|
||||||
|
this.spaceModelRepository.target,
|
||||||
|
spaceModel,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dto.subspaceModels) {
|
if (dto.subspaceModels) {
|
||||||
@ -182,6 +195,7 @@ export class SpaceModelService {
|
|||||||
modifiedSubspaceModels,
|
modifiedSubspaceModels,
|
||||||
modifiedTags: modifiedTagsModelPayload,
|
modifiedTags: modifiedTagsModelPayload,
|
||||||
},
|
},
|
||||||
|
queryRunner,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -191,6 +205,11 @@ export class SpaceModelService {
|
|||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await queryRunner.rollbackTransaction();
|
await queryRunner.rollbackTransaction();
|
||||||
|
|
||||||
|
if (error instanceof HttpException) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
error.message || 'Failed to update SpaceModel',
|
error.message || 'Failed to update SpaceModel',
|
||||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
@ -271,6 +290,23 @@ export class SpaceModelService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async validateNameUsingQueryRunner(
|
||||||
|
modelName: string,
|
||||||
|
projectUuid: string,
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
): Promise<void> {
|
||||||
|
const isModelExist = await queryRunner.manager.findOne(SpaceModelEntity, {
|
||||||
|
where: { modelName, project: { uuid: projectUuid }, disabled: false },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isModelExist) {
|
||||||
|
throw new HttpException(
|
||||||
|
`Model name ${modelName} already exists in the project with UUID ${projectUuid}.`,
|
||||||
|
HttpStatus.CONFLICT,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async validateSpaceModel(uuid: string): Promise<SpaceModelEntity> {
|
async validateSpaceModel(uuid: string): Promise<SpaceModelEntity> {
|
||||||
const spaceModel = await this.spaceModelRepository.findOne({
|
const spaceModel = await this.spaceModelRepository.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
@ -31,38 +31,50 @@ export class SubSpaceModelService {
|
|||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
otherTags?: CreateTagModelDto[],
|
otherTags?: CreateTagModelDto[],
|
||||||
): Promise<SubspaceModelEntity[]> {
|
): Promise<SubspaceModelEntity[]> {
|
||||||
this.validateInputDtos(subSpaceModelDtos, spaceModel);
|
try {
|
||||||
|
await this.validateInputDtos(subSpaceModelDtos, spaceModel);
|
||||||
|
|
||||||
const subspaces = subSpaceModelDtos.map((subspaceDto) =>
|
const subspaces = subSpaceModelDtos.map((subspaceDto) =>
|
||||||
queryRunner.manager.create(this.subspaceModelRepository.target, {
|
queryRunner.manager.create(this.subspaceModelRepository.target, {
|
||||||
subspaceName: subspaceDto.subspaceName,
|
subspaceName: subspaceDto.subspaceName,
|
||||||
spaceModel,
|
spaceModel,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const savedSubspaces = await queryRunner.manager.save(subspaces);
|
const savedSubspaces = await queryRunner.manager.save(subspaces);
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
subSpaceModelDtos.map(async (dto, index) => {
|
subSpaceModelDtos.map(async (dto, index) => {
|
||||||
const subspace = savedSubspaces[index];
|
const subspace = savedSubspaces[index];
|
||||||
|
|
||||||
const otherDtoTags = subSpaceModelDtos
|
const otherDtoTags = subSpaceModelDtos
|
||||||
.filter((_, i) => i !== index)
|
.filter((_, i) => i !== index)
|
||||||
.flatMap((otherDto) => otherDto.tags || []);
|
.flatMap((otherDto) => otherDto.tags || []);
|
||||||
|
|
||||||
if (dto.tags?.length) {
|
if (dto.tags?.length) {
|
||||||
subspace.tags = await this.tagModelService.createTags(
|
subspace.tags = await this.tagModelService.createTags(
|
||||||
dto.tags,
|
dto.tags,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
null,
|
null,
|
||||||
subspace,
|
subspace,
|
||||||
[...(otherTags || []), ...otherDtoTags],
|
[...(otherTags || []), ...otherDtoTags],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
return savedSubspaces;
|
return savedSubspaces;
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof HttpException) {
|
||||||
|
throw error; // Rethrow known HttpExceptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle unexpected errors
|
||||||
|
throw new HttpException(
|
||||||
|
`An error occurred while creating subspace models: ${error.message}`,
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteSubspaceModels(
|
async deleteSubspaceModels(
|
||||||
@ -104,38 +116,53 @@ export class SubSpaceModelService {
|
|||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
): Promise<ModifySubspaceModelPayload> {
|
): Promise<ModifySubspaceModelPayload> {
|
||||||
const modifiedSubspaceModels: ModifySubspaceModelPayload = {};
|
const modifiedSubspaceModels: ModifySubspaceModelPayload = {
|
||||||
for (const subspace of subspaceDtos) {
|
addedSubspaceModels: [],
|
||||||
switch (subspace.action) {
|
updatedSubspaceModels: [],
|
||||||
case ModifyAction.ADD:
|
deletedSubspaceModels: [],
|
||||||
const subspaceModel = await this.handleAddAction(
|
};
|
||||||
subspace,
|
try {
|
||||||
spaceModel,
|
for (const subspace of subspaceDtos) {
|
||||||
queryRunner,
|
switch (subspace.action) {
|
||||||
);
|
case ModifyAction.ADD:
|
||||||
modifiedSubspaceModels.addedSubspaceModels.push(subspaceModel);
|
const subspaceModel = await this.handleAddAction(
|
||||||
break;
|
subspace,
|
||||||
case ModifyAction.UPDATE:
|
spaceModel,
|
||||||
const updatedSubspaceModel = await this.handleUpdateAction(
|
queryRunner,
|
||||||
subspace,
|
);
|
||||||
queryRunner,
|
modifiedSubspaceModels.addedSubspaceModels.push(subspaceModel);
|
||||||
);
|
break;
|
||||||
modifiedSubspaceModels.updatedSubspaceModels.push(
|
case ModifyAction.UPDATE:
|
||||||
updatedSubspaceModel,
|
const updatedSubspaceModel = await this.handleUpdateAction(
|
||||||
);
|
subspace,
|
||||||
break;
|
queryRunner,
|
||||||
case ModifyAction.DELETE:
|
);
|
||||||
await this.handleDeleteAction(subspace, queryRunner);
|
modifiedSubspaceModels.updatedSubspaceModels.push(
|
||||||
modifiedSubspaceModels.deletedSubspaceModels.push(subspace.uuid);
|
updatedSubspaceModel,
|
||||||
break;
|
);
|
||||||
default:
|
break;
|
||||||
throw new HttpException(
|
case ModifyAction.DELETE:
|
||||||
`Invalid action "${subspace.action}".`,
|
await this.handleDeleteAction(subspace, queryRunner);
|
||||||
HttpStatus.BAD_REQUEST,
|
modifiedSubspaceModels.deletedSubspaceModels.push(subspace.uuid);
|
||||||
);
|
break;
|
||||||
|
default:
|
||||||
|
throw new HttpException(
|
||||||
|
`Invalid action "${subspace.action}".`,
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return modifiedSubspaceModels;
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof HttpException) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new HttpException(
|
||||||
|
`An error occurred while modifying subspace models: ${error.message}`,
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return modifiedSubspaceModels;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleAddAction(
|
private async handleAddAction(
|
||||||
@ -143,24 +170,35 @@ export class SubSpaceModelService {
|
|||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
): Promise<SubspaceModelEntity> {
|
): Promise<SubspaceModelEntity> {
|
||||||
const createTagDtos: CreateTagModelDto[] =
|
try {
|
||||||
subspace.tags?.map((tag) => ({
|
const createTagDtos: CreateTagModelDto[] =
|
||||||
tag: tag.tag,
|
subspace.tags?.map((tag) => ({
|
||||||
productUuid: tag.productUuid,
|
tag: tag.tag,
|
||||||
})) || [];
|
productUuid: tag.productUuid,
|
||||||
|
})) || [];
|
||||||
|
|
||||||
const [createdSubspaceModel] = await this.createSubSpaceModels(
|
const [createdSubspaceModel] = await this.createSubSpaceModels(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
subspaceName: subspace.subspaceName,
|
subspaceName: subspace.subspaceName,
|
||||||
tags: createTagDtos,
|
tags: createTagDtos,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
spaceModel,
|
spaceModel,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
);
|
);
|
||||||
|
|
||||||
return createdSubspaceModel;
|
return createdSubspaceModel;
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof HttpException) {
|
||||||
|
throw error; // Rethrow known HttpExceptions
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new HttpException(
|
||||||
|
`An error occurred while adding subspace: ${error.message}`,
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleUpdateAction(
|
private async handleUpdateAction(
|
||||||
@ -221,7 +259,7 @@ export class SubSpaceModelService {
|
|||||||
private async findOne(subspaceUuid: string): Promise<SubspaceModelEntity> {
|
private async findOne(subspaceUuid: string): Promise<SubspaceModelEntity> {
|
||||||
const subspace = await this.subspaceModelRepository.findOne({
|
const subspace = await this.subspaceModelRepository.findOne({
|
||||||
where: { uuid: subspaceUuid },
|
where: { uuid: subspaceUuid },
|
||||||
relations: ['tags'],
|
relations: ['tags', 'spaceModel'],
|
||||||
});
|
});
|
||||||
if (!subspace) {
|
if (!subspace) {
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
@ -232,59 +270,86 @@ export class SubSpaceModelService {
|
|||||||
return subspace;
|
return subspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
private validateInputDtos(
|
private async validateInputDtos(
|
||||||
subSpaceModelDtos: CreateSubspaceModelDto[],
|
subSpaceModelDtos: CreateSubspaceModelDto[],
|
||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
): void {
|
): Promise<void> {
|
||||||
if (subSpaceModelDtos.length === 0) {
|
try {
|
||||||
|
if (subSpaceModelDtos.length === 0) {
|
||||||
|
throw new HttpException(
|
||||||
|
'Subspace models cannot be empty.',
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.validateName(
|
||||||
|
subSpaceModelDtos.map((dto) => dto.subspaceName),
|
||||||
|
spaceModel,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof HttpException) {
|
||||||
|
throw error; // Rethrow known HttpExceptions to preserve their message and status
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap unexpected errors
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
'Subspace models cannot be empty.',
|
`An error occurred while validating subspace models: ${error.message}`,
|
||||||
HttpStatus.BAD_REQUEST,
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.validateName(
|
|
||||||
subSpaceModelDtos.map((dto) => dto.subspaceName),
|
|
||||||
spaceModel,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async validateName(
|
private async validateName(
|
||||||
names: string[],
|
names: string[],
|
||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const seenNames = new Set<string>();
|
try {
|
||||||
const duplicateNames = new Set<string>();
|
const seenNames = new Set<string>();
|
||||||
|
const duplicateNames = new Set<string>();
|
||||||
|
|
||||||
for (const name of names) {
|
// Check for duplicate names within the input array
|
||||||
if (!seenNames.add(name)) {
|
for (const name of names) {
|
||||||
duplicateNames.add(name);
|
if (!seenNames.add(name)) {
|
||||||
|
duplicateNames.add(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (duplicateNames.size > 0) {
|
if (duplicateNames.size > 0) {
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
`Duplicate subspace model names found: ${[...duplicateNames].join(', ')}`,
|
`Duplicate subspace model names found: ${[...duplicateNames].join(', ')}`,
|
||||||
HttpStatus.CONFLICT,
|
HttpStatus.CONFLICT,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingNames = await this.subspaceModelRepository.find({
|
// Check for existing names in the database
|
||||||
select: ['subspaceName'],
|
const existingNames = await this.subspaceModelRepository.find({
|
||||||
where: {
|
select: ['subspaceName'],
|
||||||
subspaceName: In([...seenNames]),
|
where: {
|
||||||
spaceModel: {
|
subspaceName: In([...seenNames]),
|
||||||
uuid: spaceModel.uuid,
|
spaceModel: {
|
||||||
|
uuid: spaceModel.uuid,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if (existingNames.length > 0) {
|
if (existingNames.length > 0) {
|
||||||
const existingNamesList = existingNames
|
const existingNamesList = existingNames
|
||||||
.map((e) => e.subspaceName)
|
.map((e) => e.subspaceName)
|
||||||
.join(', ');
|
.join(', ');
|
||||||
|
throw new HttpException(
|
||||||
|
`Subspace model names already exist in the space: ${existingNamesList}`,
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof HttpException) {
|
||||||
|
throw error; // Rethrow known HttpExceptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle unexpected errors
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
`Subspace model names already exist in the space: ${existingNamesList}`,
|
`An error occurred while validating subspace model names: ${error.message}`,
|
||||||
HttpStatus.BAD_REQUEST,
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,11 @@ export class TagModelService {
|
|||||||
spaceModel?: SpaceModelEntity,
|
spaceModel?: SpaceModelEntity,
|
||||||
subspaceModel?: SubspaceModelEntity,
|
subspaceModel?: SubspaceModelEntity,
|
||||||
): Promise<ModifiedTagsModelPayload> {
|
): Promise<ModifiedTagsModelPayload> {
|
||||||
const modifiedTagModels: ModifiedTagsModelPayload = {};
|
const modifiedTagModels: ModifiedTagsModelPayload = {
|
||||||
|
added: [],
|
||||||
|
updated: [],
|
||||||
|
deleted: [],
|
||||||
|
};
|
||||||
try {
|
try {
|
||||||
for (const tag of tags) {
|
for (const tag of tags) {
|
||||||
if (tag.action === ModifyAction.ADD) {
|
if (tag.action === ModifyAction.ADD) {
|
||||||
@ -190,25 +194,35 @@ export class TagModelService {
|
|||||||
productUuid: string,
|
productUuid: string,
|
||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const tagExists = await this.tagModelRepository.exists({
|
try {
|
||||||
where: [
|
const tagExists = await this.tagModelRepository.exists({
|
||||||
{
|
where: [
|
||||||
tag,
|
{
|
||||||
spaceModel: { uuid: spaceModel.uuid },
|
tag,
|
||||||
product: { uuid: productUuid },
|
spaceModel: { uuid: spaceModel.uuid },
|
||||||
disabled: false,
|
product: { uuid: productUuid },
|
||||||
},
|
disabled: false,
|
||||||
{
|
},
|
||||||
tag,
|
{
|
||||||
subspaceModel: { spaceModel: { uuid: spaceModel.uuid } },
|
tag,
|
||||||
product: { uuid: productUuid },
|
subspaceModel: { spaceModel: { uuid: spaceModel.uuid } },
|
||||||
disabled: false,
|
product: { uuid: productUuid },
|
||||||
},
|
disabled: false,
|
||||||
],
|
},
|
||||||
});
|
],
|
||||||
|
});
|
||||||
|
|
||||||
if (tagExists) {
|
if (tagExists) {
|
||||||
throw new HttpException(`Tag can't be reused`, HttpStatus.CONFLICT);
|
throw new HttpException(`Tag can't be reused`, HttpStatus.CONFLICT);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof HttpException) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
throw new HttpException(
|
||||||
|
`An error occurred while checking tag reuse: ${error.message}`,
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,31 +232,46 @@ export class TagModelService {
|
|||||||
spaceModel?: SpaceModelEntity,
|
spaceModel?: SpaceModelEntity,
|
||||||
subspaceModel?: SubspaceModelEntity,
|
subspaceModel?: SubspaceModelEntity,
|
||||||
): Promise<TagModel> {
|
): Promise<TagModel> {
|
||||||
const product = await this.productService.findOne(tagDto.productUuid);
|
try {
|
||||||
|
const product = await this.productService.findOne(tagDto.productUuid);
|
||||||
|
|
||||||
if (!product) {
|
if (!product) {
|
||||||
|
throw new HttpException(
|
||||||
|
`Product with UUID ${tagDto.productUuid} not found.`,
|
||||||
|
HttpStatus.NOT_FOUND,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spaceModel) {
|
||||||
|
await this.checkTagReuse(tagDto.tag, tagDto.productUuid, spaceModel);
|
||||||
|
} else if (subspaceModel && subspaceModel.spaceModel) {
|
||||||
|
await this.checkTagReuse(
|
||||||
|
tagDto.tag,
|
||||||
|
tagDto.productUuid,
|
||||||
|
subspaceModel.spaceModel,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new HttpException(
|
||||||
|
`Invalid subspaceModel or spaceModel provided.`,
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryRunner.manager.create(TagModel, {
|
||||||
|
tag: tagDto.tag,
|
||||||
|
product: product.data,
|
||||||
|
spaceModel,
|
||||||
|
subspaceModel,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof HttpException) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
`Product with UUID ${tagDto.productUuid} not found.`,
|
`An error occurred while preparing the tag entity: ${error.message}`,
|
||||||
HttpStatus.NOT_FOUND,
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spaceModel) {
|
|
||||||
await this.checkTagReuse(tagDto.tag, tagDto.productUuid, spaceModel);
|
|
||||||
} else {
|
|
||||||
await this.checkTagReuse(
|
|
||||||
tagDto.tag,
|
|
||||||
tagDto.productUuid,
|
|
||||||
subspaceModel.spaceModel,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryRunner.manager.create(TagModel, {
|
|
||||||
tag: tagDto.tag,
|
|
||||||
product: product.data,
|
|
||||||
spaceModel,
|
|
||||||
subspaceModel,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTagByUuid(uuid: string): Promise<TagModel> {
|
async getTagByUuid(uuid: string): Promise<TagModel> {
|
||||||
|
Reference in New Issue
Block a user