mirror of
https://github.com/SyncrowIOT/backend.git
synced 2026-10-26 00:57:53 +00:00
Merge pull request #177 from SyncrowIOT/feat/list-space-model
Feat/list-space-model
This commit is contained in:
@@ -273,6 +273,10 @@ export class ControllerRoute {
|
|||||||
'Create a New Space Model';
|
'Create a New Space Model';
|
||||||
public static readonly CREATE_SPACE_MODEL_DESCRIPTION =
|
public static readonly CREATE_SPACE_MODEL_DESCRIPTION =
|
||||||
'This endpoint allows you to create a new space model within a specified project. A space model defines the structure of spaces, including subspaces, products, and product items, and is uniquely identifiable within the project.';
|
'This endpoint allows you to create a new space model within a specified project. A space model defines the structure of spaces, including subspaces, products, and product items, and is uniquely identifiable within the project.';
|
||||||
|
|
||||||
|
public static readonly LIST_SPACE_MODEL_SUMMARY = 'List Space Models';
|
||||||
|
public static readonly LIST_SPACE_MODEL_DESCRIPTION =
|
||||||
|
'This endpoint allows you to retrieve a list of space models within a specified project. Each space model includes its structure, associated subspaces, products, and product items.';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export const PermissionMapping = {
|
|||||||
'UPDATE',
|
'UPDATE',
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'MODULE_ADD',
|
'MODULE_ADD',
|
||||||
|
'MODEL_VIEW',
|
||||||
'ASSIGN_USER_TO_SPACE',
|
'ASSIGN_USER_TO_SPACE',
|
||||||
'DELETE_USER_FROM_SPACE',
|
'DELETE_USER_FROM_SPACE',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export const RolePermissions = {
|
|||||||
'SPACE_UPDATE',
|
'SPACE_UPDATE',
|
||||||
'SPACE_DELETE',
|
'SPACE_DELETE',
|
||||||
'SPACE_MODULE_ADD',
|
'SPACE_MODULE_ADD',
|
||||||
|
'SPACE_MODEL_VIEW',
|
||||||
'ASSIGN_USER_TO_SPACE',
|
'ASSIGN_USER_TO_SPACE',
|
||||||
'DELETE_USER_FROM_SPACE',
|
'DELETE_USER_FROM_SPACE',
|
||||||
'SUBSPACE_VIEW',
|
'SUBSPACE_VIEW',
|
||||||
@@ -60,6 +61,7 @@ export const RolePermissions = {
|
|||||||
'SPACE_UPDATE',
|
'SPACE_UPDATE',
|
||||||
'SPACE_DELETE',
|
'SPACE_DELETE',
|
||||||
'SPACE_MODULE_ADD',
|
'SPACE_MODULE_ADD',
|
||||||
|
'SPACE_MODEL_VIEW',
|
||||||
'ASSIGN_USER_TO_SPACE',
|
'ASSIGN_USER_TO_SPACE',
|
||||||
'DELETE_USER_FROM_SPACE',
|
'DELETE_USER_FROM_SPACE',
|
||||||
'SUBSPACE_VIEW',
|
'SUBSPACE_VIEW',
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ interface FindAllQueryWithDefaults extends CustomFindAllQuery {
|
|||||||
function getDefaultQueryOptions(
|
function getDefaultQueryOptions(
|
||||||
query: Partial<TypeORMCustomModelFindAllQuery>,
|
query: Partial<TypeORMCustomModelFindAllQuery>,
|
||||||
): FindManyOptions & FindAllQueryWithDefaults {
|
): FindManyOptions & FindAllQueryWithDefaults {
|
||||||
const { page, size, includeDisable, modelName, ...rest } = query;
|
const { page, size, includeDisable, include, modelName, ...rest } = query;
|
||||||
|
|
||||||
// Set default if undefined or null
|
// Set default if undefined or null
|
||||||
const returnPage = page ? Number(page) : 1;
|
const returnPage = page ? Number(page) : 1;
|
||||||
@@ -48,7 +48,9 @@ function getDefaultQueryOptions(
|
|||||||
},
|
},
|
||||||
page: returnPage,
|
page: returnPage,
|
||||||
size: returnSize,
|
size: returnSize,
|
||||||
|
include: include || undefined,
|
||||||
includeDisable: returnIncludeDisable,
|
includeDisable: returnIncludeDisable,
|
||||||
|
|
||||||
modelName: modelName || query.modelName, // Ensure modelName is passed through
|
modelName: modelName || query.modelName, // Ensure modelName is passed through
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -97,7 +99,6 @@ export function TypeORMCustomModel(repository: Repository<any>) {
|
|||||||
|
|
||||||
// Use the where clause directly, without wrapping it under 'where'
|
// Use the where clause directly, without wrapping it under 'where'
|
||||||
const whereClause = buildTypeORMWhereClause({ where });
|
const whereClause = buildTypeORMWhereClause({ where });
|
||||||
console.log('Final where clause:', whereClause);
|
|
||||||
|
|
||||||
// Ensure the whereClause is passed directly to findAndCount
|
// Ensure the whereClause is passed directly to findAndCount
|
||||||
const [data, count] = await repository.findAndCount({
|
const [data, count] = await repository.findAndCount({
|
||||||
|
|||||||
@@ -19,6 +19,19 @@ const mappingInclude: { [key: string]: any } = {
|
|||||||
project: {
|
project: {
|
||||||
project: true,
|
project: true,
|
||||||
},
|
},
|
||||||
|
'space-model': {
|
||||||
|
subspaceModels: 'subspace-model',
|
||||||
|
spaceProductModels: 'space-product-model',
|
||||||
|
},
|
||||||
|
'subspace-model': {
|
||||||
|
productModels: 'subspace-product-model',
|
||||||
|
},
|
||||||
|
'subspace-product-model': {
|
||||||
|
itemModels: true,
|
||||||
|
},
|
||||||
|
'space-product-model': {
|
||||||
|
items: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function buildTypeORMIncludeQuery(
|
export function buildTypeORMIncludeQuery(
|
||||||
@@ -30,17 +43,33 @@ export function buildTypeORMIncludeQuery(
|
|||||||
const fieldsToInclude: string[] = includeParam.split(',');
|
const fieldsToInclude: string[] = includeParam.split(',');
|
||||||
|
|
||||||
fieldsToInclude.forEach((field: string) => {
|
fieldsToInclude.forEach((field: string) => {
|
||||||
if (mappingInclude[field]) {
|
const nestedFields = field.split('.');
|
||||||
relations.push(field); // Push mapped field
|
let currentModelName = modelName;
|
||||||
} else {
|
let isValid = true;
|
||||||
console.warn(
|
|
||||||
`Field ${field} not found in mappingInclude for ${modelName}`,
|
nestedFields.forEach((nestedField, index) => {
|
||||||
);
|
const currentMapping = mappingInclude[currentModelName];
|
||||||
|
if (currentMapping?.[nestedField]) {
|
||||||
|
currentModelName =
|
||||||
|
typeof currentMapping[nestedField] === 'string'
|
||||||
|
? currentMapping[nestedField]
|
||||||
|
: currentModelName;
|
||||||
|
} else {
|
||||||
|
console.warn(
|
||||||
|
`Field "${nestedFields.slice(0, index + 1).join('.')}" not found in mappingInclude for model "${currentModelName}"`,
|
||||||
|
);
|
||||||
|
isValid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isValid) {
|
||||||
|
relations.push(field);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return relations;
|
return relations.length ? relations : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined; // If no includes, return undefined
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
import { ControllerRoute } from '@app/common/constants/controller-route';
|
import { ControllerRoute } from '@app/common/constants/controller-route';
|
||||||
import { Body, Controller, Param, Post, UseGuards } from '@nestjs/common';
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Get,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
|
Query,
|
||||||
|
UseGuards,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
import { SpaceModelService } from '../services';
|
import { SpaceModelService } from '../services';
|
||||||
import { CreateSpaceModelDto } from '../dtos';
|
import { CreateSpaceModelDto } from '../dtos';
|
||||||
@@ -7,6 +15,7 @@ import { ProjectParam } from 'src/community/dtos';
|
|||||||
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
||||||
import { PermissionsGuard } from 'src/guards/permissions.guard';
|
import { PermissionsGuard } from 'src/guards/permissions.guard';
|
||||||
import { Permissions } from 'src/decorators/permissions.decorator';
|
import { Permissions } from 'src/decorators/permissions.decorator';
|
||||||
|
import { PaginationRequestGetListDto } from '@app/common/dto/pagination.request.dto';
|
||||||
|
|
||||||
@ApiTags('Space Model Module')
|
@ApiTags('Space Model Module')
|
||||||
@Controller({
|
@Controller({
|
||||||
@@ -34,4 +43,20 @@ export class SpaceModelController {
|
|||||||
projectParam,
|
projectParam,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@UseGuards(PermissionsGuard)
|
||||||
|
@Permissions('SPACE_MODEL_VIEW')
|
||||||
|
@ApiOperation({
|
||||||
|
summary: ControllerRoute.SPACE_MODEL.ACTIONS.LIST_SPACE_MODEL_SUMMARY,
|
||||||
|
description:
|
||||||
|
ControllerRoute.SPACE_MODEL.ACTIONS.LIST_SPACE_MODEL_DESCRIPTION,
|
||||||
|
})
|
||||||
|
@Get()
|
||||||
|
async listSpaceModel(
|
||||||
|
@Param() projectParam: ProjectParam,
|
||||||
|
@Query() query: PaginationRequestGetListDto,
|
||||||
|
): Promise<BaseResponseDto> {
|
||||||
|
return await this.spaceModelService.list(projectParam, query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,12 @@ import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
|
|||||||
import { SubSpaceModelService } from './subspace/subspace-model.service';
|
import { SubSpaceModelService } from './subspace/subspace-model.service';
|
||||||
import { SpaceProductModelService } from './space-product-model.service';
|
import { SpaceProductModelService } from './space-product-model.service';
|
||||||
import { DataSource } from 'typeorm';
|
import { DataSource } from 'typeorm';
|
||||||
|
import {
|
||||||
|
TypeORMCustomModel,
|
||||||
|
TypeORMCustomModelFindAllQuery,
|
||||||
|
} from '@app/common/models/typeOrmCustom.model';
|
||||||
|
import { PageResponse } from '@app/common/dto/pagination.response.dto';
|
||||||
|
import { SpaceModelDto } from '@app/common/modules/space-model/dtos';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SpaceModelService {
|
export class SpaceModelService {
|
||||||
@@ -87,6 +93,38 @@ export class SpaceModelService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async list(
|
||||||
|
param: ProjectParam,
|
||||||
|
pageable: Partial<TypeORMCustomModelFindAllQuery>,
|
||||||
|
) {
|
||||||
|
await this.validateProject(param.projectUuid);
|
||||||
|
|
||||||
|
try {
|
||||||
|
pageable.modelName = 'space-model';
|
||||||
|
pageable.where = {
|
||||||
|
project: { uuid: param.projectUuid },
|
||||||
|
};
|
||||||
|
pageable.include =
|
||||||
|
'subspaceModels,spaceProductModels,subspaceModels.productModels,subspaceModels.productModels.itemModels,spaceProductModels.items';
|
||||||
|
|
||||||
|
const customModel = TypeORMCustomModel(this.spaceModelRepository);
|
||||||
|
|
||||||
|
const { baseResponseDto, paginationResponseDto } =
|
||||||
|
await customModel.findAll(pageable);
|
||||||
|
|
||||||
|
return new PageResponse<SpaceModelDto>(
|
||||||
|
baseResponseDto,
|
||||||
|
paginationResponseDto,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
error.message ||
|
||||||
|
'An error occurred while fetching space models in project.',
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async validateProject(projectUuid: string) {
|
async validateProject(projectUuid: string) {
|
||||||
const project = await this.projectRepository.findOne({
|
const project = await this.projectRepository.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
|||||||
Reference in New Issue
Block a user