diff --git a/libs/common/src/constants/controller-route.ts b/libs/common/src/constants/controller-route.ts index 515773e..26bc418 100644 --- a/libs/common/src/constants/controller-route.ts +++ b/libs/common/src/constants/controller-route.ts @@ -624,7 +624,7 @@ export class ControllerRoute { }; static AUTOMATION = class { - public static readonly ROUTE = 'automation'; + public static readonly ROUTE = '/projects/:projectUuid/automation'; static ACTIONS = class { public static readonly ADD_AUTOMATION_SUMMARY = 'Add automation'; diff --git a/src/automation/controllers/automation.controller.ts b/src/automation/controllers/automation.controller.ts index 864d551..a0db1ed 100644 --- a/src/automation/controllers/automation.controller.ts +++ b/src/automation/controllers/automation.controller.ts @@ -21,6 +21,7 @@ import { AutomationParamDto, SpaceParamDto } from '../dtos'; import { ControllerRoute } from '@app/common/constants/controller-route'; import { PermissionsGuard } from 'src/guards/permissions.guard'; import { Permissions } from 'src/decorators/permissions.decorator'; +import { ProjectParam } from '@app/common/dto/project-param.dto'; @ApiTags('Automation Module') @Controller({ @@ -38,9 +39,14 @@ export class AutomationController { summary: ControllerRoute.AUTOMATION.ACTIONS.ADD_AUTOMATION_SUMMARY, description: ControllerRoute.AUTOMATION.ACTIONS.ADD_AUTOMATION_DESCRIPTION, }) - async addAutomation(@Body() addAutomationDto: AddAutomationDto) { - const automation = - await this.automationService.addAutomation(addAutomationDto); + async addAutomation( + @Param() param: ProjectParam, + @Body() addAutomationDto: AddAutomationDto, + ) { + const automation = await this.automationService.addAutomation( + param, + addAutomationDto, + ); return { statusCode: HttpStatus.CREATED, success: true, @@ -59,9 +65,7 @@ export class AutomationController { ControllerRoute.AUTOMATION.ACTIONS.GET_AUTOMATION_BY_SPACE_DESCRIPTION, }) async getAutomationBySpace(@Param() param: SpaceParamDto) { - const automation = await this.automationService.getAutomationBySpace( - param.spaceUuid, - ); + const automation = await this.automationService.getAutomationBySpace(param); return automation; } @@ -75,9 +79,7 @@ export class AutomationController { ControllerRoute.AUTOMATION.ACTIONS.GET_AUTOMATION_DETAILS_DESCRIPTION, }) async getAutomationDetails(@Param() param: AutomationParamDto) { - const automation = await this.automationService.getAutomationDetails( - param.automationUuid, - ); + const automation = await this.automationService.getAutomationDetails(param); return automation; } @@ -113,7 +115,7 @@ export class AutomationController { ) { const automation = await this.automationService.updateAutomation( updateAutomationDto, - param.automationUuid, + param, ); return { statusCode: HttpStatus.CREATED, @@ -139,7 +141,7 @@ export class AutomationController { ) { await this.automationService.updateAutomationStatus( updateAutomationStatusDto, - param.automationUuid, + param, ); return { statusCode: HttpStatus.CREATED, diff --git a/src/automation/dtos/automation.param.dto.ts b/src/automation/dtos/automation.param.dto.ts index e0b3990..156caff 100644 --- a/src/automation/dtos/automation.param.dto.ts +++ b/src/automation/dtos/automation.param.dto.ts @@ -1,7 +1,8 @@ +import { ProjectParam } from '@app/common/dto/project-param.dto'; import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString } from 'class-validator'; -export class AutomationParamDto { +export class AutomationParamDto extends ProjectParam { @ApiProperty({ description: 'TuyaId of the automation', example: 'SfFi2Tbn09btes84', diff --git a/src/automation/dtos/space.param.dto.ts b/src/automation/dtos/space.param.dto.ts index 0631ea1..58a378f 100644 --- a/src/automation/dtos/space.param.dto.ts +++ b/src/automation/dtos/space.param.dto.ts @@ -1,7 +1,8 @@ +import { ProjectParam } from '@app/common/dto/project-param.dto'; import { ApiProperty } from '@nestjs/swagger'; import { IsUUID } from 'class-validator'; -export class SpaceParamDto { +export class SpaceParamDto extends ProjectParam { @ApiProperty({ description: 'UUID of the space', example: 'd290f1ee-6c54-4b01-90e6-d701748f0851', diff --git a/src/automation/services/automation.service.ts b/src/automation/services/automation.service.ts index 8999533..c15ca24 100644 --- a/src/automation/services/automation.service.ts +++ b/src/automation/services/automation.service.ts @@ -8,6 +8,7 @@ import { SpaceRepository } from '@app/common/modules/space/repositories'; import { AddAutomationDto, AutomationParamDto, + SpaceParamDto, UpdateAutomationDto, UpdateAutomationStatusDto, } from '../dtos'; @@ -39,6 +40,8 @@ import { BaseResponseDto } from '@app/common/dto/base.response.dto'; import { SuccessResponseDto } from '@app/common/dto/success.response.dto'; import { AutomationEntity } from '@app/common/modules/automation/entities'; import { DeleteTapToRunSceneInterface } from 'src/scene/interface/scene.interface'; +import { ProjectParam } from '@app/common/dto/project-param.dto'; +import { ProjectRepository } from '@app/common/modules/project/repositiories'; @Injectable() export class AutomationService { @@ -51,6 +54,7 @@ export class AutomationService { private readonly sceneDeviceRepository: SceneDeviceRepository, private readonly sceneRepository: SceneRepository, private readonly automationRepository: AutomationRepository, + private readonly projectRepository: ProjectRepository, ) { const accessKey = this.configService.get('auth-config.ACCESS_KEY'); const secretKey = this.configService.get('auth-config.SECRET_KEY'); @@ -63,8 +67,11 @@ export class AutomationService { } async addAutomation( + param: ProjectParam, addAutomationDto: AddAutomationDto, ): Promise { + await this.validateProject(param.projectUuid); + try { const { automationName, @@ -196,12 +203,14 @@ export class AutomationService { } } - async getAutomationBySpace(spaceUuid: string) { + async getAutomationBySpace(param: SpaceParamDto) { try { + await this.validateProject(param.projectUuid); + // Fetch automation data from the repository const automationData = await this.automationRepository.find({ where: { - space: { uuid: spaceUuid }, + space: { uuid: param.spaceUuid }, disabled: false, }, relations: ['space'], @@ -321,16 +330,18 @@ export class AutomationService { } } } - async getAutomationDetails(automationUuid: string) { + async getAutomationDetails(param: AutomationParamDto) { + await this.validateProject(param.projectUuid); + try { - const automation = await this.findAutomation(automationUuid); + const automation = await this.findAutomation(param.automationUuid); const automationDetails = await this.getAutomation(automation); return automationDetails; } catch (error) { console.error( - `Error fetching automation details for automationUuid ${automationUuid}:`, + `Error fetching automation details for automationUuid ${param.automationUuid}:`, error, ); @@ -466,6 +477,7 @@ export class AutomationService { async deleteAutomation(param: AutomationParamDto) { const { automationUuid } = param; + await this.validateProject(param.projectUuid); try { const automationData = await this.findAutomation(automationUuid); @@ -564,10 +576,12 @@ export class AutomationService { } async updateAutomation( updateAutomationDto: UpdateAutomationDto, - automationUuid: string, + param: AutomationParamDto, ) { + await this.validateProject(param.projectUuid); + try { - const automation = await this.findAutomation(automationUuid); + const automation = await this.findAutomation(param.automationUuid); const space = await this.getSpaceByUuid(automation.space.uuid); const updateTuyaAutomationResponse = @@ -584,14 +598,14 @@ export class AutomationService { ); } const updatedScene = await this.automationRepository.update( - { uuid: automationUuid }, + { uuid: param.automationUuid }, { space: { uuid: automation.space.uuid }, }, ); return new SuccessResponseDto({ data: updatedScene, - message: `Automation with ID ${automationUuid} updated successfully`, + message: `Automation with ID ${param.automationUuid} updated successfully`, }); } catch (err) { if (err instanceof BadRequestException) { @@ -606,11 +620,13 @@ export class AutomationService { } async updateAutomationStatus( updateAutomationStatusDto: UpdateAutomationStatusDto, - automationUuid: string, + param: AutomationParamDto, ) { const { isEnable, spaceUuid } = updateAutomationStatusDto; + await this.validateProject(param.projectUuid); + try { - const automation = await this.findAutomation(automationUuid); + const automation = await this.findAutomation(param.automationUuid); const space = await this.getSpaceByUuid(spaceUuid); if (!space.spaceTuyaUuid) { throw new HttpException( @@ -698,4 +714,17 @@ export class AutomationService { ); return convertedData; } + + private async validateProject(uuid: string) { + const project = await this.projectRepository.findOne({ + where: { uuid }, + }); + if (!project) { + throw new HttpException( + `A project with the uuid '${uuid}' doesn't exists.`, + HttpStatus.BAD_REQUEST, + ); + } + return project; + } }