diff --git a/libs/common/src/modules/space-model/entities/subspace-model.entity.ts b/libs/common/src/modules/space-model/entities/subspace-model.entity.ts index abb1c64..776f831 100644 --- a/libs/common/src/modules/space-model/entities/subspace-model.entity.ts +++ b/libs/common/src/modules/space-model/entities/subspace-model.entity.ts @@ -1,9 +1,10 @@ -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, ManyToOne, Unique } from 'typeorm'; import { AbstractEntity } from '../../abstract/entities/abstract.entity'; import { SpaceModelEntity } from './space-model.entity'; import { SubSpaceModelDto } from '../dtos'; @Entity({ name: 'subspace-model' }) +@Unique(['subspaceName', 'spaceModel']) export class SubspaceModelEntity extends AbstractEntity { @Column({ type: 'uuid', diff --git a/src/space-model/dtos/create-space-product-model.dto.ts b/src/space-model/dtos/create-space-product-model.dto.ts index 63fb9dd..8b98bc6 100644 --- a/src/space-model/dtos/create-space-product-model.dto.ts +++ b/src/space-model/dtos/create-space-product-model.dto.ts @@ -1,5 +1,11 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsNotEmpty, IsString, IsArray, ValidateNested } from 'class-validator'; +import { + IsNotEmpty, + IsString, + IsArray, + ValidateNested, + IsInt, +} from 'class-validator'; import { Type } from 'class-transformer'; import { CreateSpaceProductItemModelDto } from './create-space-product-item-model.dto'; @@ -17,6 +23,7 @@ export class CreateSpaceProductModelDto { example: 3, }) @IsNotEmpty() + @IsInt() productCount: number; @ApiProperty({ diff --git a/src/space-model/services/space-model.service.ts b/src/space-model/services/space-model.service.ts index f7b8f28..37b9ab1 100644 --- a/src/space-model/services/space-model.service.ts +++ b/src/space-model/services/space-model.service.ts @@ -36,7 +36,7 @@ export class SpaceModelService { ); } - const spaceModel = await this.spaceModelRepository.create({ + const spaceModel = this.spaceModelRepository.create({ modelName, project, }); diff --git a/src/space-model/services/space-product-item-model.service.ts b/src/space-model/services/space-product-item-model.service.ts index ebf7d2d..0a5b43d 100644 --- a/src/space-model/services/space-product-item-model.service.ts +++ b/src/space-model/services/space-product-item-model.service.ts @@ -24,6 +24,10 @@ export class SpaceProductItemModelService { await this.create(itemModelDto, spaceProductModel, spaceModel); } } catch (error) { + if (error instanceof HttpException) { + throw error; + } + throw new HttpException( error.message || `An unexpected error occurred`, HttpStatus.INTERNAL_SERVER_ERROR, diff --git a/src/space-model/services/space-product-model.service.ts b/src/space-model/services/space-product-model.service.ts index 10ee9f5..c478dca 100644 --- a/src/space-model/services/space-product-model.service.ts +++ b/src/space-model/services/space-product-model.service.ts @@ -24,6 +24,10 @@ export class SpaceProductModelService { await this.create(spaceProductModelDto, spaceModel); } } catch (error) { + if (error instanceof HttpException) { + throw error; + } + throw new HttpException( error.message || `An unexpected error occurred`, HttpStatus.INTERNAL_SERVER_ERROR, diff --git a/src/space-model/services/subspace-model.service.ts b/src/space-model/services/subspace-model.service.ts index 45d33ef..5d4d347 100644 --- a/src/space-model/services/subspace-model.service.ts +++ b/src/space-model/services/subspace-model.service.ts @@ -16,6 +16,7 @@ export class SubSpaceModelService { spaceModel: SpaceModelEntity, ) { try { + this.validateInputDtos(subSpaceModelDtos); for (const subspaceDto of subSpaceModelDtos) { const subspace = this.subspaceModelRepository.create({ subspaceName: subspaceDto.subspaceName, @@ -24,10 +25,46 @@ export class SubSpaceModelService { await this.subspaceModelRepository.save(subspace); } } catch (error) { + if (error instanceof HttpException) { + throw error; + } + throw new HttpException( error.message || `An unexpected error occurred`, HttpStatus.INTERNAL_SERVER_ERROR, ); } } + + private validateInputDtos(subSpaceModelDtos: CreateSubspaceModelDto[]) { + if (subSpaceModelDtos.length === 0) { + throw new HttpException( + 'Subspace models cannot be empty.', + HttpStatus.BAD_REQUEST, + ); + } + + const incomingNames = subSpaceModelDtos.map((dto) => dto.subspaceName); + this.validateName(incomingNames); + } + + private validateName(names: string[]) { + const seenNames = new Set(); + const duplicateNames = new Set(); + + for (const name of names) { + if (seenNames.has(name)) { + duplicateNames.add(name); + } else { + seenNames.add(name); + } + } + + if (duplicateNames.size > 0) { + throw new HttpException( + `Duplicate subspace names found in request: ${[...duplicateNames].join(', ')}`, + HttpStatus.CONFLICT, + ); + } + } }