diff --git a/libs/common/src/dto/community-space.param.ts b/libs/common/src/dto/community-space.param.ts new file mode 100644 index 0000000..b0e829e --- /dev/null +++ b/libs/common/src/dto/community-space.param.ts @@ -0,0 +1,12 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { ProjectParam } from './project-param.dto'; +import { IsUUID } from 'class-validator'; + +export class CommunityParam extends ProjectParam { + @ApiProperty({ + description: 'UUID of the community this space belongs to', + example: 'd290f1ee-6c54-4b01-90e6-d701748f0851', + }) + @IsUUID() + communityUuid: string; +} diff --git a/libs/common/src/dto/get.space.param.ts b/libs/common/src/dto/get.space.param.ts new file mode 100644 index 0000000..9167540 --- /dev/null +++ b/libs/common/src/dto/get.space.param.ts @@ -0,0 +1,12 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsUUID } from 'class-validator'; +import { CommunityParam } from './community-space.param'; + +export class GetSpaceParam extends CommunityParam { + @ApiProperty({ + description: 'UUID of the Space', + example: 'd290f1ee-6c54-4b01-90e6-d701748f0851', + }) + @IsUUID() + spaceUuid: string; +} diff --git a/src/automation/automation.module.ts b/src/automation/automation.module.ts index 1230238..c90d106 100644 --- a/src/automation/automation.module.ts +++ b/src/automation/automation.module.ts @@ -17,10 +17,11 @@ import { import { SceneDeviceRepository } from '@app/common/modules/scene-device/repositories'; import { AutomationRepository } from '@app/common/modules/automation/repositories'; import { ProjectRepository } from '@app/common/modules/project/repositiories/project.repository'; +import { AutomationSpaceController } from './controllers/automation-space.controller'; @Module({ imports: [ConfigModule, SpaceRepositoryModule, DeviceStatusFirebaseModule], - controllers: [AutomationController], + controllers: [AutomationController, AutomationSpaceController], providers: [ AutomationService, TuyaService, diff --git a/src/automation/services/automation.service.ts b/src/automation/services/automation.service.ts index c15ca24..254c8b7 100644 --- a/src/automation/services/automation.service.ts +++ b/src/automation/services/automation.service.ts @@ -8,7 +8,6 @@ import { SpaceRepository } from '@app/common/modules/space/repositories'; import { AddAutomationDto, AutomationParamDto, - SpaceParamDto, UpdateAutomationDto, UpdateAutomationStatusDto, } from '../dtos'; @@ -42,6 +41,7 @@ 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'; +import { GetSpaceParam } from '@app/common/dto/get.space.param'; @Injectable() export class AutomationService { @@ -81,16 +81,19 @@ export class AutomationService { conditions, spaceUuid, } = addAutomationDto; - const space = await this.getSpaceByUuid(spaceUuid); - const automation = await this.add({ - automationName, - effectiveTime, - decisionExpr, - actions, - conditions, - spaceTuyaId: space.spaceTuyaUuid, - spaceUuid, - }); + const space = await this.getSpaceByUuid(spaceUuid, param.projectUuid); + const automation = await this.add( + { + automationName, + effectiveTime, + decisionExpr, + actions, + conditions, + spaceTuyaId: space.spaceTuyaUuid, + spaceUuid, + }, + param.projectUuid, + ); return new SuccessResponseDto({ message: `Successfully created new automation with uuid ${automation.uuid}`, data: automation, @@ -109,9 +112,15 @@ export class AutomationService { ); } } - async createAutomationExternalService(params: AddAutomationParams) { + async createAutomationExternalService( + params: AddAutomationParams, + projectUuid: string, + ) { try { - const formattedActions = await this.prepareActions(params.actions); + const formattedActions = await this.prepareActions( + params.actions, + projectUuid, + ); const formattedCondition = await this.prepareConditions( params.conditions, ); @@ -149,9 +158,12 @@ export class AutomationService { } } } - async add(params: AddAutomationParams) { + async add(params: AddAutomationParams, projectUuid: string) { try { - const response = await this.createAutomationExternalService(params); + const response = await this.createAutomationExternalService( + params, + projectUuid, + ); const automation = await this.automationRepository.save({ automationTuyaUuid: response.result.id, @@ -176,11 +188,16 @@ export class AutomationService { } } - async getSpaceByUuid(spaceUuid: string) { + async getSpaceByUuid(spaceUuid: string, projectUuid: string) { try { const space = await this.spaceRepository.findOne({ where: { uuid: spaceUuid, + community: { + project: { + uuid: projectUuid, + }, + }, }, relations: ['community'], }); @@ -203,14 +220,21 @@ export class AutomationService { } } - async getAutomationBySpace(param: SpaceParamDto) { + async getAutomationBySpace(param: GetSpaceParam) { try { await this.validateProject(param.projectUuid); // Fetch automation data from the repository const automationData = await this.automationRepository.find({ where: { - space: { uuid: param.spaceUuid }, + space: { + uuid: param.spaceUuid, + community: { + project: { + uuid: param.projectUuid, + }, + }, + }, disabled: false, }, relations: ['space'], @@ -259,9 +283,10 @@ export class AutomationService { ); } } - async findAutomationBySpace(spaceUuid: string) { + + async findAutomationBySpace(spaceUuid: string, projectUuid: string) { try { - await this.getSpaceByUuid(spaceUuid); + await this.getSpaceByUuid(spaceUuid, projectUuid); const automationData = await this.automationRepository.find({ where: { @@ -334,7 +359,10 @@ export class AutomationService { await this.validateProject(param.projectUuid); try { - const automation = await this.findAutomation(param.automationUuid); + const automation = await this.findAutomation( + param.automationUuid, + param.projectUuid, + ); const automationDetails = await this.getAutomation(automation); @@ -460,9 +488,15 @@ export class AutomationService { } } } - async findAutomation(sceneUuid: string): Promise { + async findAutomation( + sceneUuid: string, + projectUuid: string, + ): Promise { const automation = await this.automationRepository.findOne({ - where: { uuid: sceneUuid }, + where: { + uuid: sceneUuid, + space: { community: { project: { uuid: projectUuid } } }, + }, relations: ['space'], }); @@ -480,8 +514,14 @@ export class AutomationService { await this.validateProject(param.projectUuid); try { - const automationData = await this.findAutomation(automationUuid); - const space = await this.getSpaceByUuid(automationData.space.uuid); + const automationData = await this.findAutomation( + automationUuid, + param.projectUuid, + ); + const space = await this.getSpaceByUuid( + automationData.space.uuid, + param.projectUuid, + ); await this.delete(automationData.automationTuyaUuid, space.spaceTuyaUuid); const existingSceneDevice = await this.sceneDeviceRepository.findOne({ where: { automationTuyaUuid: automationData.automationTuyaUuid }, @@ -534,11 +574,12 @@ export class AutomationService { spaceTuyaUuid: string, automationUuid: string, updateAutomationDto: UpdateAutomationDto, + projectUuid: string, ) { const { automationName, decisionExpr, actions, conditions, effectiveTime } = updateAutomationDto; try { - const formattedActions = await this.prepareActions(actions); + const formattedActions = await this.prepareActions(actions, projectUuid); const formattedCondition = await this.prepareConditions(conditions); const response = await this.tuyaService.updateAutomation( automationUuid, @@ -581,14 +622,21 @@ export class AutomationService { await this.validateProject(param.projectUuid); try { - const automation = await this.findAutomation(param.automationUuid); - const space = await this.getSpaceByUuid(automation.space.uuid); + const automation = await this.findAutomation( + param.automationUuid, + param.projectUuid, + ); + const space = await this.getSpaceByUuid( + automation.space.uuid, + param.projectUuid, + ); const updateTuyaAutomationResponse = await this.updateAutomationExternalService( space.spaceTuyaUuid, automation.automationTuyaUuid, updateAutomationDto, + param.projectUuid, ); if (!updateTuyaAutomationResponse.success) { @@ -626,8 +674,11 @@ export class AutomationService { await this.validateProject(param.projectUuid); try { - const automation = await this.findAutomation(param.automationUuid); - const space = await this.getSpaceByUuid(spaceUuid); + const automation = await this.findAutomation( + param.automationUuid, + param.projectUuid, + ); + const space = await this.getSpaceByUuid(spaceUuid, param.projectUuid); if (!space.spaceTuyaUuid) { throw new HttpException( `Invalid space UUID ${spaceUuid}`, @@ -654,7 +705,10 @@ export class AutomationService { } } - private async prepareActions(actions: Action[]): Promise { + private async prepareActions( + actions: Action[], + projectUuid: string, + ): Promise { const convertedData = convertKeysToSnakeCase(actions) as ConvertedAction[]; await Promise.all( @@ -687,7 +741,10 @@ export class AutomationService { action.action_executor === ActionExecutorEnum.RULE_ENABLE ) { if (action.action_type === ActionTypeEnum.AUTOMATION) { - const automation = await this.findAutomation(action.entity_id); + const automation = await this.findAutomation( + action.entity_id, + projectUuid, + ); action.entity_id = automation.automationTuyaUuid; } }