mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-27 15:04:53 +00:00
updated create space model
This commit is contained in:
@ -3,3 +3,4 @@ export * from './project-param.dto';
|
|||||||
export * from './update-space-model.dto';
|
export * from './update-space-model.dto';
|
||||||
export * from './space-model-param';
|
export * from './space-model-param';
|
||||||
export * from './subspaces-model-dtos';
|
export * from './subspaces-model-dtos';
|
||||||
|
export * from './tag-model-dtos';
|
||||||
|
|||||||
@ -0,0 +1,2 @@
|
|||||||
|
export * from './create-tag-model.dto';
|
||||||
|
export * from './update-tag-model.dto';
|
||||||
|
|||||||
21
src/space-model/dtos/tag-model-dtos/update-tag-model.dto.ts
Normal file
21
src/space-model/dtos/tag-model-dtos/update-tag-model.dto.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator';
|
||||||
|
|
||||||
|
export class UpdateTagModelDto {
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'UUID of the tag to be updated',
|
||||||
|
example: '123e4567-e89b-12d3-a456-426614174000',
|
||||||
|
})
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsUUID()
|
||||||
|
uuid: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Updated name of the tag',
|
||||||
|
example: 'Updated Tag Name',
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
tag?: string;
|
||||||
|
}
|
||||||
@ -1,2 +1,3 @@
|
|||||||
export * from './space-model.service';
|
export * from './space-model.service';
|
||||||
export * from './subspace';
|
export * from './subspace';
|
||||||
|
export * from './tag-model.service';
|
||||||
|
|||||||
@ -17,6 +17,8 @@ import { SpaceModelDto } from '@app/common/modules/space-model/dtos';
|
|||||||
import { SpaceModelParam } from '../dtos/space-model-param';
|
import { SpaceModelParam } from '../dtos/space-model-param';
|
||||||
import { ProjectService } from 'src/project/services';
|
import { ProjectService } from 'src/project/services';
|
||||||
import { ProjectEntity } from '@app/common/modules/project/entities';
|
import { ProjectEntity } from '@app/common/modules/project/entities';
|
||||||
|
import { TagModelService } from './tag-model.service';
|
||||||
|
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SpaceModelService {
|
export class SpaceModelService {
|
||||||
@ -25,21 +27,21 @@ export class SpaceModelService {
|
|||||||
private readonly spaceModelRepository: SpaceModelRepository,
|
private readonly spaceModelRepository: SpaceModelRepository,
|
||||||
private readonly projectService: ProjectService,
|
private readonly projectService: ProjectService,
|
||||||
private readonly subSpaceModelService: SubSpaceModelService,
|
private readonly subSpaceModelService: SubSpaceModelService,
|
||||||
|
private readonly tagModelService: TagModelService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async createSpaceModel(
|
async createSpaceModel(
|
||||||
createSpaceModelDto: CreateSpaceModelDto,
|
createSpaceModelDto: CreateSpaceModelDto,
|
||||||
params: ProjectParam,
|
params: ProjectParam,
|
||||||
) {
|
): Promise<BaseResponseDto> {
|
||||||
const { modelName, subspaceModels } = createSpaceModelDto;
|
const { modelName, subspaceModels, tags } = createSpaceModelDto;
|
||||||
const project = await this.validateProject(params.projectUuid);
|
|
||||||
|
|
||||||
const queryRunner = this.dataSource.createQueryRunner();
|
const queryRunner = this.dataSource.createQueryRunner();
|
||||||
|
|
||||||
await queryRunner.connect();
|
await queryRunner.connect();
|
||||||
await queryRunner.startTransaction();
|
await queryRunner.startTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const project = await this.validateProject(params.projectUuid);
|
||||||
|
|
||||||
const isModelExist = await this.validateName(
|
const isModelExist = await this.validateName(
|
||||||
modelName,
|
modelName,
|
||||||
params.projectUuid,
|
params.projectUuid,
|
||||||
@ -55,13 +57,25 @@ export class SpaceModelService {
|
|||||||
modelName,
|
modelName,
|
||||||
project,
|
project,
|
||||||
});
|
});
|
||||||
|
|
||||||
const savedSpaceModel = await queryRunner.manager.save(spaceModel);
|
const savedSpaceModel = await queryRunner.manager.save(spaceModel);
|
||||||
|
|
||||||
if (subspaceModels) {
|
if (subspaceModels?.length) {
|
||||||
await this.subSpaceModelService.createSubSpaceModels(
|
savedSpaceModel.subspaceModels =
|
||||||
subspaceModels,
|
await this.subSpaceModelService.createSubSpaceModels(
|
||||||
savedSpaceModel,
|
subspaceModels,
|
||||||
|
savedSpaceModel,
|
||||||
|
queryRunner,
|
||||||
|
tags,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tags?.length) {
|
||||||
|
savedSpaceModel.tags = await this.tagModelService.createTags(
|
||||||
|
tags,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
|
savedSpaceModel,
|
||||||
|
null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,14 +89,16 @@ export class SpaceModelService {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
await queryRunner.rollbackTransaction();
|
await queryRunner.rollbackTransaction();
|
||||||
|
|
||||||
if (error instanceof HttpException) {
|
const errorMessage =
|
||||||
throw error;
|
error instanceof HttpException
|
||||||
}
|
? error.message
|
||||||
|
: 'An unexpected error occurred';
|
||||||
|
const statusCode =
|
||||||
|
error instanceof HttpException
|
||||||
|
? error.getStatus()
|
||||||
|
: HttpStatus.INTERNAL_SERVER_ERROR;
|
||||||
|
|
||||||
throw new HttpException(
|
throw new HttpException(errorMessage, statusCode);
|
||||||
error.message || `An unexpected error occurred`,
|
|
||||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
||||||
);
|
|
||||||
} finally {
|
} finally {
|
||||||
await queryRunner.release();
|
await queryRunner.release();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
SpaceModelEntity,
|
SpaceModelEntity,
|
||||||
|
SubspaceModelEntity,
|
||||||
SubspaceModelRepository,
|
SubspaceModelRepository,
|
||||||
} from '@app/common/modules/space-model';
|
} from '@app/common/modules/space-model';
|
||||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||||
@ -7,6 +8,7 @@ import {
|
|||||||
CreateSubspaceModelDto,
|
CreateSubspaceModelDto,
|
||||||
UpdateSubspaceModelDto,
|
UpdateSubspaceModelDto,
|
||||||
ModifySubspacesModelDto,
|
ModifySubspacesModelDto,
|
||||||
|
CreateTagModelDto,
|
||||||
} from '../../dtos';
|
} from '../../dtos';
|
||||||
import { QueryRunner } from 'typeorm';
|
import { QueryRunner } from 'typeorm';
|
||||||
import {
|
import {
|
||||||
@ -15,47 +17,53 @@ import {
|
|||||||
IUpdateSubspaceModelInterface,
|
IUpdateSubspaceModelInterface,
|
||||||
} from 'src/space-model/interfaces';
|
} from 'src/space-model/interfaces';
|
||||||
import { DeleteSubspaceModelDto } from 'src/space-model/dtos/subspaces-model-dtos';
|
import { DeleteSubspaceModelDto } from 'src/space-model/dtos/subspaces-model-dtos';
|
||||||
|
import { TagModelService } from '../tag-model.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SubSpaceModelService {
|
export class SubSpaceModelService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly subspaceModelRepository: SubspaceModelRepository,
|
private readonly subspaceModelRepository: SubspaceModelRepository,
|
||||||
|
private readonly tagModelService: TagModelService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async createSubSpaceModels(
|
async createSubSpaceModels(
|
||||||
subSpaceModelDtos: CreateSubspaceModelDto[],
|
subSpaceModelDtos: CreateSubspaceModelDto[],
|
||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
) {
|
otherTags: CreateTagModelDto[],
|
||||||
|
): Promise<SubspaceModelEntity[]> {
|
||||||
this.validateInputDtos(subSpaceModelDtos);
|
this.validateInputDtos(subSpaceModelDtos);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
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,
|
spaceModel,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const newSubspaces = await queryRunner.manager.save(subspaces);
|
const savedSubspaces = await queryRunner.manager.save(subspaces);
|
||||||
|
|
||||||
const addedSubspaces = await Promise.all(
|
await Promise.all(
|
||||||
subSpaceModelDtos.map(async (dto, index) => {
|
subSpaceModelDtos.map(async (dto, index) => {
|
||||||
const subspaceModel = newSubspaces[index];
|
const subspace = savedSubspaces[index];
|
||||||
|
|
||||||
return {
|
if (dto.tags && dto.tags.length > 0) {
|
||||||
subspaceModel,
|
const tagModels = await this.tagModelService.createTags(
|
||||||
};
|
dto.tags,
|
||||||
|
queryRunner,
|
||||||
|
null,
|
||||||
|
subspace,
|
||||||
|
otherTags,
|
||||||
|
);
|
||||||
|
subspace.tags = tagModels;
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
return addedSubspaces;
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof HttpException) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return savedSubspaces;
|
||||||
|
} catch (error) {
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
error.message || `An unexpected error occurred`,
|
error.message || 'Failed to create subspaces.',
|
||||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -230,13 +238,6 @@ export class SubSpaceModelService {
|
|||||||
const actions = [];
|
const actions = [];
|
||||||
|
|
||||||
if (dto.add) {
|
if (dto.add) {
|
||||||
actions.push(
|
|
||||||
this.createSubSpaceModels(dto.add, spaceModel, queryRunner).then(
|
|
||||||
(addedSubspaces) => {
|
|
||||||
subspaces.new = addedSubspaces;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dto.update) {
|
if (dto.update) {
|
||||||
|
|||||||
128
src/space-model/services/tag-model.service.ts
Normal file
128
src/space-model/services/tag-model.service.ts
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
|
||||||
|
import { QueryRunner } from 'typeorm';
|
||||||
|
import {
|
||||||
|
SpaceModelEntity,
|
||||||
|
TagModel,
|
||||||
|
} from '@app/common/modules/space-model/entities';
|
||||||
|
import { SubspaceModelEntity } from '@app/common/modules/space-model/entities';
|
||||||
|
import { TagModelRepository } from '@app/common/modules/space-model';
|
||||||
|
import { CreateTagModelDto, UpdateTagModelDto } from '../dtos';
|
||||||
|
import { ProductService } from 'src/product/services';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TagModelService {
|
||||||
|
constructor(
|
||||||
|
private readonly tagModelRepository: TagModelRepository,
|
||||||
|
private readonly productService: ProductService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async createTags(
|
||||||
|
tags: CreateTagModelDto[],
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
spaceModel?: SpaceModelEntity,
|
||||||
|
subspaceModel?: SubspaceModelEntity,
|
||||||
|
otherTags?: CreateTagModelDto[],
|
||||||
|
): Promise<TagModel[]> {
|
||||||
|
let alltags: CreateTagModelDto[] = [];
|
||||||
|
if (!tags.length) {
|
||||||
|
throw new HttpException('Tags cannot be empty.', HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
if (otherTags) {
|
||||||
|
alltags = [...tags, ...otherTags];
|
||||||
|
}
|
||||||
|
const duplicates = this.checkForDuplicates(alltags);
|
||||||
|
if (duplicates.length > 0) {
|
||||||
|
throw new HttpException(
|
||||||
|
`Duplicate tags found for the same product: ${duplicates.join(', ')}`,
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const tagEntities = await Promise.all(
|
||||||
|
tags.map(async (tagDto) => {
|
||||||
|
const product = await this.productService.findOne(tagDto.productUuid);
|
||||||
|
if (!product) {
|
||||||
|
throw new HttpException(
|
||||||
|
`Product with UUID ${tagDto.productUuid} not found.`,
|
||||||
|
HttpStatus.NOT_FOUND,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryRunner.manager.create(TagModel, {
|
||||||
|
tag: tagDto.tag,
|
||||||
|
product: product.data,
|
||||||
|
spaceModel,
|
||||||
|
subspaceModel,
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await queryRunner.manager.save(tagEntities);
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
'Failed to save tag models due to an unexpected error.',
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateTags(tags: UpdateTagModelDto[], queryRunner: QueryRunner) {
|
||||||
|
try {
|
||||||
|
const updatePromises = tags.map(async (tagDto) => {
|
||||||
|
const existingTag = await this.tagModelRepository.findOne({
|
||||||
|
where: { uuid: tagDto.uuid },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!existingTag) {
|
||||||
|
throw new HttpException(
|
||||||
|
`Tag with ID ${tagDto.uuid} not found`,
|
||||||
|
HttpStatus.NOT_FOUND,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
existingTag.tag = tagDto.tag || existingTag.tag;
|
||||||
|
|
||||||
|
return queryRunner.manager.save(existingTag);
|
||||||
|
});
|
||||||
|
|
||||||
|
return await Promise.all(updatePromises);
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
error.message || 'Failed to update tags',
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteTags(tagUuids: string[], queryRunner: QueryRunner) {
|
||||||
|
try {
|
||||||
|
const deletePromises = tagUuids.map((id) =>
|
||||||
|
queryRunner.manager.softDelete(this.tagModelRepository.target, id),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(deletePromises);
|
||||||
|
return { message: 'Tags deleted successfully', tagUuids };
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
error.message || 'Failed to delete tags',
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkForDuplicates(tags: CreateTagModelDto[]): string[] {
|
||||||
|
const seen = new Map<string, boolean>();
|
||||||
|
const duplicates: string[] = [];
|
||||||
|
|
||||||
|
tags.forEach((tagDto) => {
|
||||||
|
const key = `${tagDto.productUuid}-${tagDto.tag}`;
|
||||||
|
if (seen.has(key)) {
|
||||||
|
duplicates.push(`${tagDto.tag} for Product: ${tagDto.productUuid}`);
|
||||||
|
} else {
|
||||||
|
seen.set(key, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return duplicates;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,10 +2,15 @@ import { SpaceRepositoryModule } from '@app/common/modules/space/space.repositor
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ConfigModule } from '@nestjs/config';
|
import { ConfigModule } from '@nestjs/config';
|
||||||
import { SpaceModelController } from './controllers';
|
import { SpaceModelController } from './controllers';
|
||||||
import { SpaceModelService, SubSpaceModelService } from './services';
|
import {
|
||||||
|
SpaceModelService,
|
||||||
|
SubSpaceModelService,
|
||||||
|
TagModelService,
|
||||||
|
} from './services';
|
||||||
import {
|
import {
|
||||||
SpaceModelRepository,
|
SpaceModelRepository,
|
||||||
SubspaceModelRepository,
|
SubspaceModelRepository,
|
||||||
|
TagModelRepository,
|
||||||
} from '@app/common/modules/space-model';
|
} from '@app/common/modules/space-model';
|
||||||
import { ProjectRepository } from '@app/common/modules/project/repositiories';
|
import { ProjectRepository } from '@app/common/modules/project/repositiories';
|
||||||
import { ProductRepository } from '@app/common/modules/product/repositories';
|
import { ProductRepository } from '@app/common/modules/product/repositories';
|
||||||
@ -35,6 +40,8 @@ const CommandHandlers = [PropogateSubspaceHandler];
|
|||||||
SubspaceRepository,
|
SubspaceRepository,
|
||||||
SubspaceProductRepository,
|
SubspaceProductRepository,
|
||||||
SubspaceProductItemRepository,
|
SubspaceProductItemRepository,
|
||||||
|
TagModelService,
|
||||||
|
TagModelRepository,
|
||||||
],
|
],
|
||||||
exports: [CqrsModule],
|
exports: [CqrsModule],
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user