From 7ec4171e1a67ee1d81a56ee79eb76089c3a26459 Mon Sep 17 00:00:00 2001 From: faris Aljohari <83524184+farisaljohari@users.noreply.github.com> Date: Mon, 12 May 2025 02:15:57 +0300 Subject: [PATCH] feat: add occupancy module with controller, service, and related DTOs for heat map data retrieval --- libs/common/src/constants/controller-route.ts | 11 +++ .../src/constants/presence.sensor.enum.ts | 4 ++ .../devices-status/devices-status.module.ts | 2 + .../services/devices-status.service.ts | 20 ++++++ .../src/helper/services/occupancy.service.ts | 49 +++++++++++++ .../proceduce_select_fact_space_occupancy.sql | 13 ++-- .../procedure_update_fact_space_occupancy.sql | 4 +- src/app.module.ts | 6 +- .../commission-device.module.ts | 2 + src/community/community.module.ts | 2 + src/door-lock/door.lock.module.ts | 2 + src/group/group.module.ts | 2 + src/invite-user/invite-user.module.ts | 2 + src/occupancy/controllers/index.ts | 1 + .../controllers/occupancy.controller.ts | 46 +++++++++++++ src/occupancy/dto/get-occupancy.dto.ts | 15 ++++ src/occupancy/dto/occupancy-params.dto.ts | 7 ++ src/occupancy/occupancy.module.ts | 11 +++ src/occupancy/services/index.ts | 1 + src/occupancy/services/occupancy.service.ts | 69 +++++++++++++++++++ src/power-clamp/power-clamp.module.ts | 2 + src/project/project.module.ts | 2 + src/space-model/space-model.module.ts | 2 + src/space/space.module.ts | 2 + .../visitor-password.module.ts | 2 + 25 files changed, 270 insertions(+), 9 deletions(-) create mode 100644 libs/common/src/constants/presence.sensor.enum.ts create mode 100644 libs/common/src/helper/services/occupancy.service.ts create mode 100644 src/occupancy/controllers/index.ts create mode 100644 src/occupancy/controllers/occupancy.controller.ts create mode 100644 src/occupancy/dto/get-occupancy.dto.ts create mode 100644 src/occupancy/dto/occupancy-params.dto.ts create mode 100644 src/occupancy/occupancy.module.ts create mode 100644 src/occupancy/services/index.ts create mode 100644 src/occupancy/services/occupancy.service.ts diff --git a/libs/common/src/constants/controller-route.ts b/libs/common/src/constants/controller-route.ts index 852c4a8..8fdffbe 100644 --- a/libs/common/src/constants/controller-route.ts +++ b/libs/common/src/constants/controller-route.ts @@ -504,6 +504,17 @@ export class ControllerRoute { 'This endpoint retrieves the historical data of power clamp devices based on the provided community or space UUID.'; }; }; + + static Occupancy = class { + public static readonly ROUTE = 'occupancy'; + + static ACTIONS = class { + public static readonly GET_OCCUPANCY_HEAT_MAP_SUMMARY = + 'Get occupancy heat map data'; + public static readonly GET_OCCUPANCY_HEAT_MAP_DESCRIPTION = + 'This endpoint retrieves the occupancy heat map data based on the provided parameters.'; + }; + }; static DEVICE = class { public static readonly ROUTE = 'devices'; diff --git a/libs/common/src/constants/presence.sensor.enum.ts b/libs/common/src/constants/presence.sensor.enum.ts new file mode 100644 index 0000000..d2f9e50 --- /dev/null +++ b/libs/common/src/constants/presence.sensor.enum.ts @@ -0,0 +1,4 @@ +export enum PresenceSensorEnum { + PRESENCE_STATE = 'presence_state', + SENSITIVITY = 'sensitivity', +} diff --git a/libs/common/src/firebase/devices-status/devices-status.module.ts b/libs/common/src/firebase/devices-status/devices-status.module.ts index 217a4d8..784b801 100644 --- a/libs/common/src/firebase/devices-status/devices-status.module.ts +++ b/libs/common/src/firebase/devices-status/devices-status.module.ts @@ -10,6 +10,7 @@ import { PowerClampMonthlyRepository, } from '@app/common/modules/power-clamp/repositories'; import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; @Module({ providers: [ @@ -21,6 +22,7 @@ import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service PowerClampDailyRepository, PowerClampMonthlyRepository, SqlLoaderService, + OccupancyService, ], controllers: [DeviceStatusFirebaseController], exports: [DeviceStatusFirebaseService, DeviceStatusLogRepository], diff --git a/libs/common/src/firebase/devices-status/services/devices-status.service.ts b/libs/common/src/firebase/devices-status/services/devices-status.service.ts index 739d846..f01b0be 100644 --- a/libs/common/src/firebase/devices-status/services/devices-status.service.ts +++ b/libs/common/src/firebase/devices-status/services/devices-status.service.ts @@ -21,6 +21,8 @@ import { DeviceStatusLogRepository } from '@app/common/modules/device-status-log import { ProductType } from '@app/common/constants/product-type.enum'; import { PowerClampService } from '@app/common/helper/services/power.clamp.service'; import { PowerClampEnergyEnum } from '@app/common/constants/power.clamp.enargy.enum'; +import { PresenceSensorEnum } from '@app/common/constants/presence.sensor.enum'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; @Injectable() export class DeviceStatusFirebaseService { private tuya: TuyaContext; @@ -29,6 +31,7 @@ export class DeviceStatusFirebaseService { private readonly configService: ConfigService, private readonly deviceRepository: DeviceRepository, private readonly powerClampService: PowerClampService, + private readonly occupancyService: OccupancyService, private deviceStatusLogRepository: DeviceStatusLogRepository, ) { const accessKey = this.configService.get('auth-config.ACCESS_KEY'); @@ -240,6 +243,23 @@ export class DeviceStatusFirebaseService { } } + if ( + addDeviceStatusDto.productType === ProductType.CPS || + addDeviceStatusDto.productType === ProductType.WPS + ) { + const occupancyCodes = new Set([PresenceSensorEnum.PRESENCE_STATE]); + + const occupancyStatus = addDeviceStatusDto?.log?.properties?.find( + (status) => occupancyCodes.has(status.code), + ); + + if (occupancyStatus) { + await this.occupancyService.updateOccupancySensorHistoricalData( + addDeviceStatusDto.deviceUuid, + ); + } + } + // Return the updated data const snapshot: DataSnapshot = await get(dataRef); return snapshot.val(); diff --git a/libs/common/src/helper/services/occupancy.service.ts b/libs/common/src/helper/services/occupancy.service.ts new file mode 100644 index 0000000..3e8fc7c --- /dev/null +++ b/libs/common/src/helper/services/occupancy.service.ts @@ -0,0 +1,49 @@ +import { DeviceRepository } from '@app/common/modules/device/repositories'; +import { Injectable } from '@nestjs/common'; +import { SqlLoaderService } from './sql-loader.service'; +import { DataSource } from 'typeorm'; +import { SQL_PROCEDURES_PATH } from '@app/common/constants/sql-query-path'; + +@Injectable() +export class OccupancyService { + constructor( + private readonly sqlLoader: SqlLoaderService, + private readonly dataSource: DataSource, + private readonly deviceRepository: DeviceRepository, + ) {} + + async updateOccupancySensorHistoricalData(deviceUuid: string): Promise { + try { + const now = new Date(); + const dateStr = now.toLocaleDateString('en-CA'); // YYYY-MM-DD + const device = await this.deviceRepository.findOne({ + where: { uuid: deviceUuid }, + relations: ['spaceDevice'], + }); + + await this.executeProcedure('procedure_update_fact_space_occupancy', [ + dateStr, + device.spaceDevice?.uuid, + ]); + } catch (err) { + console.error('Failed to insert or update occupancy data:', err); + throw err; + } + } + + private async executeProcedure( + procedureFileName: string, + params: (string | number | null)[], + ): Promise { + const query = this.loadQuery( + 'fact_space_occupancy_count', + procedureFileName, + ); + await this.dataSource.query(query, params); + console.log(`Procedure ${procedureFileName} executed successfully.`); + } + + private loadQuery(folderName: string, fileName: string): string { + return this.sqlLoader.loadQuery(folderName, fileName, SQL_PROCEDURES_PATH); + } +} diff --git a/libs/common/src/sql/procedures/fact_space_occupancy_count/proceduce_select_fact_space_occupancy.sql b/libs/common/src/sql/procedures/fact_space_occupancy_count/proceduce_select_fact_space_occupancy.sql index ac6756d..113eb07 100644 --- a/libs/common/src/sql/procedures/fact_space_occupancy_count/proceduce_select_fact_space_occupancy.sql +++ b/libs/common/src/sql/procedures/fact_space_occupancy_count/proceduce_select_fact_space_occupancy.sql @@ -1,12 +1,15 @@ WITH params AS ( SELECT $1::uuid AS space_id, - TO_DATE(NULLIF($2, ''), 'YYYY-MM') AS event_month + TO_DATE(NULLIF($2, ''), 'YYYY') AS event_year ) -select psdsd.* -from public."presence-sensor-daily-space-detection" psdsd +SELECT psdsd.* +FROM public."presence-sensor-daily-space-detection" psdsd JOIN params P ON true -where psdsd.space_uuid = P.space_id -AND (P.event_month IS NULL OR TO_CHAR(psdsd.event_date, 'YYYY-MM') = TO_CHAR(P.event_month, 'YYYY-MM')) +WHERE psdsd.space_uuid = P.space_id +AND ( + P.event_year IS NULL + OR TO_CHAR(psdsd.event_date, 'YYYY') = TO_CHAR(P.event_year, 'YYYY') +) ORDER BY space_uuid, event_date \ No newline at end of file diff --git a/libs/common/src/sql/procedures/fact_space_occupancy_count/procedure_update_fact_space_occupancy.sql b/libs/common/src/sql/procedures/fact_space_occupancy_count/procedure_update_fact_space_occupancy.sql index b166cb5..cc727c0 100644 --- a/libs/common/src/sql/procedures/fact_space_occupancy_count/procedure_update_fact_space_occupancy.sql +++ b/libs/common/src/sql/procedures/fact_space_occupancy_count/procedure_update_fact_space_occupancy.sql @@ -1,7 +1,7 @@ WITH params AS ( SELECT - TO_DATE(NULLIF($2, ''), 'YYYY-MM-DD') AS event_date, - $4::uuid AS space_id + TO_DATE(NULLIF($1, ''), 'YYYY-MM-DD') AS event_date, + $2::uuid AS space_id ), device_logs AS ( diff --git a/src/app.module.ts b/src/app.module.ts index 704d6b3..e674880 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -37,12 +37,13 @@ import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler'; import { HealthModule } from './health/health.module'; import { winstonLoggerOptions } from '../libs/common/src/logger/services/winston.logger'; +import { OccupancyModule } from './occupancy/occupancy.module'; @Module({ imports: [ ConfigModule.forRoot({ load: config, }), - /* ThrottlerModule.forRoot({ + /* ThrottlerModule.forRoot({ throttlers: [{ ttl: 100000, limit: 30 }], }), */ WinstonModule.forRoot(winstonLoggerOptions), @@ -77,13 +78,14 @@ import { winstonLoggerOptions } from '../libs/common/src/logger/services/winston DeviceCommissionModule, PowerClampModule, HealthModule, + OccupancyModule, ], providers: [ { provide: APP_INTERCEPTOR, useClass: LoggingInterceptor, }, - /* { + /* { provide: APP_GUARD, useClass: ThrottlerGuard, }, */ diff --git a/src/commission-device/commission-device.module.ts b/src/commission-device/commission-device.module.ts index 71c93bd..8821410 100644 --- a/src/commission-device/commission-device.module.ts +++ b/src/commission-device/commission-device.module.ts @@ -28,6 +28,7 @@ import { } from '@app/common/modules/power-clamp/repositories'; import { PowerClampService } from '@app/common/helper/services/power.clamp.service'; import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; @Module({ imports: [ConfigModule, SpaceRepositoryModule], @@ -55,6 +56,7 @@ import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service PowerClampDailyRepository, PowerClampMonthlyRepository, SqlLoaderService, + OccupancyService, ], exports: [], }) diff --git a/src/community/community.module.ts b/src/community/community.module.ts index 289ece4..a6f64df 100644 --- a/src/community/community.module.ts +++ b/src/community/community.module.ts @@ -63,6 +63,7 @@ import { PowerClampMonthlyRepository, } from '@app/common/modules/power-clamp/repositories'; import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; @Module({ imports: [ConfigModule, SpaceRepositoryModule, UserRepositoryModule], @@ -114,6 +115,7 @@ import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service PowerClampDailyRepository, PowerClampMonthlyRepository, SqlLoaderService, + OccupancyService, ], exports: [CommunityService, SpacePermissionService], }) diff --git a/src/door-lock/door.lock.module.ts b/src/door-lock/door.lock.module.ts index adbfceb..459a4fb 100644 --- a/src/door-lock/door.lock.module.ts +++ b/src/door-lock/door.lock.module.ts @@ -27,6 +27,7 @@ import { PowerClampMonthlyRepository, } from '@app/common/modules/power-clamp/repositories'; import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; @Module({ imports: [ConfigModule, DeviceRepositoryModule], controllers: [DoorLockController], @@ -52,6 +53,7 @@ import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service PowerClampDailyRepository, PowerClampMonthlyRepository, SqlLoaderService, + OccupancyService, ], exports: [DoorLockService], }) diff --git a/src/group/group.module.ts b/src/group/group.module.ts index a903373..8380793 100644 --- a/src/group/group.module.ts +++ b/src/group/group.module.ts @@ -25,6 +25,7 @@ import { PowerClampMonthlyRepository, } from '@app/common/modules/power-clamp/repositories'; import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; @Module({ imports: [ConfigModule, DeviceRepositoryModule], controllers: [GroupController], @@ -49,6 +50,7 @@ import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service PowerClampDailyRepository, PowerClampMonthlyRepository, SqlLoaderService, + OccupancyService, ], exports: [GroupService], }) diff --git a/src/invite-user/invite-user.module.ts b/src/invite-user/invite-user.module.ts index fdf5251..fb1ba8d 100644 --- a/src/invite-user/invite-user.module.ts +++ b/src/invite-user/invite-user.module.ts @@ -83,6 +83,7 @@ import { } from '@app/common/modules/power-clamp/repositories'; import { PowerClampService } from '@app/common/helper/services/power.clamp.service'; import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; @Module({ imports: [ConfigModule, InviteUserRepositoryModule, CommunityModule], @@ -152,6 +153,7 @@ import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service PowerClampDailyRepository, PowerClampMonthlyRepository, SqlLoaderService, + OccupancyService, ], exports: [InviteUserService], }) diff --git a/src/occupancy/controllers/index.ts b/src/occupancy/controllers/index.ts new file mode 100644 index 0000000..c1973ca --- /dev/null +++ b/src/occupancy/controllers/index.ts @@ -0,0 +1 @@ +export * from './occupancy.controller'; diff --git a/src/occupancy/controllers/occupancy.controller.ts b/src/occupancy/controllers/occupancy.controller.ts new file mode 100644 index 0000000..d6aa9b1 --- /dev/null +++ b/src/occupancy/controllers/occupancy.controller.ts @@ -0,0 +1,46 @@ +import { Controller, Get, Param, Query, UseGuards } from '@nestjs/common'; +import { + ApiTags, + ApiBearerAuth, + ApiOperation, + ApiParam, +} from '@nestjs/swagger'; +import { EnableDisableStatusEnum } from '@app/common/constants/days.enum'; +import { ControllerRoute } from '@app/common/constants/controller-route'; +import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard'; +import { OccupancyService } from '../services/occupancy.service'; +import { GetOccupancyHeatMapBySpaceDto } from '../dto/get-occupancy.dto'; +import { BaseResponseDto } from '@app/common/dto/base.response.dto'; +import { SpaceParamsDto } from '../dto/occupancy-params.dto'; + +@ApiTags('Occupancy Module') +@Controller({ + version: EnableDisableStatusEnum.ENABLED, + path: ControllerRoute.Occupancy.ROUTE, +}) +export class OccupancyController { + constructor(private readonly occupancyService: OccupancyService) {} + + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + @Get('heat-map/space/:spaceUuid') + @ApiOperation({ + summary: ControllerRoute.Occupancy.ACTIONS.GET_OCCUPANCY_HEAT_MAP_SUMMARY, + description: + ControllerRoute.Occupancy.ACTIONS.GET_OCCUPANCY_HEAT_MAP_DESCRIPTION, + }) + @ApiParam({ + name: 'spaceUuid', + description: 'UUID of the Space', + required: true, + }) + async getOccupancyHeatMapDataBySpace( + @Param() params: SpaceParamsDto, + @Query() query: GetOccupancyHeatMapBySpaceDto, + ): Promise { + return await this.occupancyService.getOccupancyHeatMapDataBySpace( + params, + query, + ); + } +} diff --git a/src/occupancy/dto/get-occupancy.dto.ts b/src/occupancy/dto/get-occupancy.dto.ts new file mode 100644 index 0000000..26ea0a5 --- /dev/null +++ b/src/occupancy/dto/get-occupancy.dto.ts @@ -0,0 +1,15 @@ +import { ApiPropertyOptional } from '@nestjs/swagger'; +import { Matches, IsNotEmpty } from 'class-validator'; + +export class GetOccupancyHeatMapBySpaceDto { + @ApiPropertyOptional({ + description: 'Input year in YYYY format to filter the data', + example: '2025', + required: false, + }) + @IsNotEmpty() + @Matches(/^\d{4}$/, { + message: 'Year must be in YYYY format', + }) + year: string; +} diff --git a/src/occupancy/dto/occupancy-params.dto.ts b/src/occupancy/dto/occupancy-params.dto.ts new file mode 100644 index 0000000..6e26d4f --- /dev/null +++ b/src/occupancy/dto/occupancy-params.dto.ts @@ -0,0 +1,7 @@ +import { IsNotEmpty, IsUUID } from 'class-validator'; + +export class SpaceParamsDto { + @IsUUID('4', { message: 'Invalid UUID format' }) + @IsNotEmpty() + spaceUuid: string; +} diff --git a/src/occupancy/occupancy.module.ts b/src/occupancy/occupancy.module.ts new file mode 100644 index 0000000..6293858 --- /dev/null +++ b/src/occupancy/occupancy.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; +import { OccupancyController } from './controllers'; +import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { OccupancyService } from './services'; +@Module({ + imports: [ConfigModule], + controllers: [OccupancyController], + providers: [OccupancyService, SqlLoaderService], +}) +export class OccupancyModule {} diff --git a/src/occupancy/services/index.ts b/src/occupancy/services/index.ts new file mode 100644 index 0000000..d8dc93e --- /dev/null +++ b/src/occupancy/services/index.ts @@ -0,0 +1 @@ +export * from './occupancy.service'; diff --git a/src/occupancy/services/occupancy.service.ts b/src/occupancy/services/occupancy.service.ts new file mode 100644 index 0000000..59afe18 --- /dev/null +++ b/src/occupancy/services/occupancy.service.ts @@ -0,0 +1,69 @@ +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { GetOccupancyHeatMapBySpaceDto } from '../dto/get-occupancy.dto'; +import { SuccessResponseDto } from '@app/common/dto/success.response.dto'; +import { SpaceParamsDto } from '../dto/occupancy-params.dto'; +import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { DataSource } from 'typeorm'; +import { SQL_PROCEDURES_PATH } from '@app/common/constants/sql-query-path'; +import { BaseResponseDto } from '@app/common/dto/base.response.dto'; + +@Injectable() +export class OccupancyService { + constructor( + private readonly sqlLoader: SqlLoaderService, + private readonly dataSource: DataSource, + ) {} + + async getOccupancyHeatMapDataBySpace( + params: SpaceParamsDto, + query: GetOccupancyHeatMapBySpaceDto, + ): Promise { + const { year } = query; + const { spaceUuid } = params; + + try { + const data = await this.executeProcedure( + 'proceduce_select_fact_space_occupancy', + [spaceUuid, year], + ); + const formattedData = data.map((item) => ({ + ...item, + event_date: new Date(item.event_date).toLocaleDateString('en-CA'), // YYYY-MM-DD + })); + return this.buildResponse( + `Occupancy heat map data fetched successfully for ${spaceUuid ? 'space' : 'community'}`, + formattedData, + ); + } catch (error) { + console.error('Failed to fetch occupancy heat map data', { + error, + spaceUuid, + }); + throw new HttpException( + error.response?.message || 'Failed to fetch occupancy heat map data', + error.status || HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } + + private buildResponse(message: string, data: any[]) { + return new SuccessResponseDto({ + message, + data, + statusCode: HttpStatus.OK, + }); + } + private async executeProcedure( + procedureFileName: string, + params: (string | number | null)[], + ): Promise { + const query = this.loadQuery( + 'fact_space_occupancy_count', + procedureFileName, + ); + return await this.dataSource.query(query, params); + } + private loadQuery(folderName: string, fileName: string): string { + return this.sqlLoader.loadQuery(folderName, fileName, SQL_PROCEDURES_PATH); + } +} diff --git a/src/power-clamp/power-clamp.module.ts b/src/power-clamp/power-clamp.module.ts index 3f0595c..e85ea1b 100644 --- a/src/power-clamp/power-clamp.module.ts +++ b/src/power-clamp/power-clamp.module.ts @@ -60,6 +60,7 @@ import { SubspaceProductAllocationService } from 'src/space/services/subspace/su import { NewTagRepository } from '@app/common/modules/tag/repositories/tag-repository'; import { SpaceModelProductAllocationService } from 'src/space-model/services/space-model-product-allocation.service'; import { SubspaceModelProductAllocationService } from 'src/space-model/services/subspace/subspace-model-product-allocation.service'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; @Module({ imports: [ConfigModule], controllers: [PowerClampController], @@ -109,6 +110,7 @@ import { SubspaceModelProductAllocationService } from 'src/space-model/services/ SubspaceModelProductAllocationService, SpaceModelProductAllocationRepoitory, SubspaceModelProductAllocationRepoitory, + OccupancyService, ], exports: [PowerClamp], }) diff --git a/src/project/project.module.ts b/src/project/project.module.ts index e52294d..fd9acb3 100644 --- a/src/project/project.module.ts +++ b/src/project/project.module.ts @@ -67,6 +67,7 @@ import { PowerClampMonthlyRepository, } from '@app/common/modules/power-clamp/repositories'; import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; const CommandHandlers = [CreateOrphanSpaceHandler]; @@ -124,6 +125,7 @@ const CommandHandlers = [CreateOrphanSpaceHandler]; PowerClampDailyRepository, PowerClampMonthlyRepository, SqlLoaderService, + OccupancyService, ], exports: [ProjectService, CqrsModule], }) diff --git a/src/space-model/space-model.module.ts b/src/space-model/space-model.module.ts index e5b4426..be57bb3 100644 --- a/src/space-model/space-model.module.ts +++ b/src/space-model/space-model.module.ts @@ -65,6 +65,7 @@ import { PowerClampMonthlyRepository, } from '@app/common/modules/power-clamp/repositories'; import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; const CommandHandlers = [ PropogateUpdateSpaceModelHandler, @@ -124,6 +125,7 @@ const CommandHandlers = [ PowerClampDailyRepository, PowerClampMonthlyRepository, SqlLoaderService, + OccupancyService, ], exports: [CqrsModule, SpaceModelService], }) diff --git a/src/space/space.module.ts b/src/space/space.module.ts index 13b4ecc..f74d993 100644 --- a/src/space/space.module.ts +++ b/src/space/space.module.ts @@ -90,6 +90,7 @@ import { PowerClampMonthlyRepository, } from '@app/common/modules/power-clamp/repositories'; import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; export const CommandHandlers = [DisableSpaceHandler]; @@ -166,6 +167,7 @@ export const CommandHandlers = [DisableSpaceHandler]; PowerClampMonthlyRepository, PowerClampService, SqlLoaderService, + OccupancyService, ], exports: [SpaceService], }) diff --git a/src/vistor-password/visitor-password.module.ts b/src/vistor-password/visitor-password.module.ts index 061f79d..91f9c2e 100644 --- a/src/vistor-password/visitor-password.module.ts +++ b/src/vistor-password/visitor-password.module.ts @@ -29,6 +29,7 @@ import { PowerClampMonthlyRepository, } from '@app/common/modules/power-clamp/repositories'; import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; +import { OccupancyService } from '@app/common/helper/services/occupancy.service'; @Module({ imports: [ConfigModule, DeviceRepositoryModule, DoorLockModule], controllers: [VisitorPasswordController], @@ -55,6 +56,7 @@ import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service PowerClampDailyRepository, PowerClampMonthlyRepository, SqlLoaderService, + OccupancyService, ], exports: [VisitorPasswordService], })