dt-common-device 1.3.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/TROUBLESHOOTING.md +184 -0
  2. package/dist/config/config.d.ts +9 -2
  3. package/dist/config/config.js +97 -14
  4. package/dist/constants/Event.d.ts +75 -0
  5. package/dist/constants/Event.js +78 -0
  6. package/dist/db/db.d.ts +1 -0
  7. package/dist/db/db.js +18 -2
  8. package/dist/device/cloud/entities/CloudDevice.d.ts +1 -0
  9. package/dist/device/cloud/entities/CloudDevice.js +3 -0
  10. package/dist/device/local/entities/AlertBuilder.d.ts +87 -0
  11. package/dist/device/local/entities/AlertBuilder.example.d.ts +11 -0
  12. package/dist/device/local/entities/AlertBuilder.example.js +117 -0
  13. package/dist/device/local/entities/AlertBuilder.js +179 -0
  14. package/dist/device/local/entities/IssueBuilder.d.ts +109 -0
  15. package/dist/device/local/entities/IssueBuilder.example.d.ts +16 -0
  16. package/dist/device/local/entities/IssueBuilder.example.js +196 -0
  17. package/dist/device/local/entities/IssueBuilder.js +237 -0
  18. package/dist/device/local/entities/index.d.ts +2 -0
  19. package/dist/device/local/entities/index.js +7 -0
  20. package/dist/device/local/events/EventHandler.js +6 -6
  21. package/dist/device/local/events/Events.d.ts +33 -12
  22. package/dist/device/local/events/Events.js +33 -12
  23. package/dist/device/local/interfaces/IDevice.d.ts +10 -9
  24. package/dist/device/local/interfaces/IDevice.js +7 -0
  25. package/dist/device/local/models/Alert.model.d.ts +28 -0
  26. package/dist/device/local/models/Alert.model.js +222 -0
  27. package/dist/device/local/models/Issue.model.d.ts +28 -0
  28. package/dist/device/local/models/Issue.model.js +260 -0
  29. package/dist/device/local/repository/Alert.repository.d.ts +106 -0
  30. package/dist/device/local/repository/Alert.repository.js +374 -0
  31. package/dist/device/local/repository/Device.repository.d.ts +11 -2
  32. package/dist/device/local/repository/Device.repository.js +163 -30
  33. package/dist/device/local/repository/Hub.repository.d.ts +1 -1
  34. package/dist/device/local/repository/Hub.repository.js +60 -18
  35. package/dist/device/local/repository/Issue.repository.d.ts +113 -0
  36. package/dist/device/local/repository/Issue.repository.js +401 -0
  37. package/dist/device/local/repository/Schedule.repository.d.ts +1 -1
  38. package/dist/device/local/repository/Schedule.repository.js +14 -18
  39. package/dist/device/local/services/Alert.service.d.ts +135 -5
  40. package/dist/device/local/services/Alert.service.js +471 -7
  41. package/dist/device/local/services/AlertService.example.d.ts +55 -0
  42. package/dist/device/local/services/AlertService.example.js +148 -0
  43. package/dist/device/local/services/Device.service.d.ts +9 -6
  44. package/dist/device/local/services/Device.service.js +61 -41
  45. package/dist/device/local/services/Issue.service.d.ts +168 -0
  46. package/dist/device/local/services/Issue.service.js +642 -0
  47. package/dist/device/local/services/IssueService.example.d.ts +68 -0
  48. package/dist/device/local/services/IssueService.example.js +177 -0
  49. package/dist/device/local/services/index.d.ts +7 -5
  50. package/dist/device/local/services/index.js +21 -11
  51. package/dist/events/BaseEventHandler.d.ts +43 -0
  52. package/dist/events/BaseEventHandler.js +111 -0
  53. package/dist/events/BaseEventTransformer.d.ts +26 -0
  54. package/dist/events/BaseEventTransformer.js +72 -0
  55. package/dist/events/DeviceEventHandler.d.ts +15 -0
  56. package/dist/events/DeviceEventHandler.js +152 -0
  57. package/dist/events/DeviceEventTransformerFactory.d.ts +27 -0
  58. package/dist/events/DeviceEventTransformerFactory.js +116 -0
  59. package/dist/events/EventHandler.d.ts +11 -0
  60. package/dist/events/EventHandler.js +111 -0
  61. package/dist/events/EventHandlerOrchestrator.d.ts +35 -0
  62. package/dist/events/EventHandlerOrchestrator.js +141 -0
  63. package/dist/events/EventProcessingService.d.ts +43 -0
  64. package/dist/events/EventProcessingService.js +243 -0
  65. package/dist/events/InternalEventSubscription.d.ts +44 -0
  66. package/dist/events/InternalEventSubscription.js +152 -0
  67. package/dist/events/index.d.ts +9 -0
  68. package/dist/events/index.js +21 -0
  69. package/dist/events/interfaces/DeviceEvent.d.ts +48 -0
  70. package/dist/events/interfaces/IEventHandler.d.ts +23 -0
  71. package/dist/{device/cloud/interface.js → events/interfaces/IEventHandler.js} +0 -1
  72. package/dist/events/interfaces/IEventTransformer.d.ts +7 -0
  73. package/dist/{device/cloud/interfaces/IDeviceConnectionService.js → events/interfaces/IEventTransformer.js} +0 -1
  74. package/dist/events/interfaces/IInternalEvent.d.ts +42 -0
  75. package/dist/events/interfaces/IInternalEvent.js +2 -0
  76. package/dist/events/interfaces/index.d.ts +4 -0
  77. package/dist/{device → events/interfaces}/index.js +4 -4
  78. package/dist/index.d.ts +6 -2
  79. package/dist/index.js +9 -2
  80. package/dist/types/alert.types.d.ts +57 -0
  81. package/dist/types/alert.types.js +22 -0
  82. package/dist/types/config.types.d.ts +15 -4
  83. package/dist/types/index.d.ts +2 -0
  84. package/dist/types/index.js +2 -0
  85. package/dist/types/issue.types.d.ts +90 -0
  86. package/dist/types/issue.types.js +40 -0
  87. package/dist/utils/http-utils.d.ts +13 -0
  88. package/dist/utils/http-utils.js +117 -0
  89. package/package.json +2 -1
  90. package/src/config/config.ts +117 -14
  91. package/src/{device/local/events/Events.ts → constants/Event.ts} +34 -13
  92. package/src/db/db.ts +14 -5
  93. package/src/device/cloud/entities/CloudDevice.ts +4 -0
  94. package/src/device/local/entities/AlertBuilder.example.ts +126 -0
  95. package/src/device/local/entities/AlertBuilder.ts +202 -0
  96. package/src/device/local/entities/IssueBuilder.example.ts +210 -0
  97. package/src/device/local/entities/IssueBuilder.ts +263 -0
  98. package/src/device/local/entities/README.md +173 -0
  99. package/src/device/local/entities/index.ts +2 -0
  100. package/src/device/local/interfaces/IDevice.ts +11 -9
  101. package/src/device/local/models/Alert.model.md +319 -0
  102. package/src/device/local/models/Alert.model.ts +283 -0
  103. package/src/device/local/models/Issue.model.md +386 -0
  104. package/src/device/local/models/Issue.model.ts +350 -0
  105. package/src/device/local/models/README.md +312 -0
  106. package/src/device/local/repository/Alert.repository.ts +465 -0
  107. package/src/device/local/repository/Device.repository.ts +251 -30
  108. package/src/device/local/repository/Hub.repository.ts +74 -18
  109. package/src/device/local/repository/Issue.repository.ts +517 -0
  110. package/src/device/local/repository/Schedule.repository.ts +28 -22
  111. package/src/device/local/services/Alert.service.ts +617 -5
  112. package/src/device/local/services/AlertService.example.ts +229 -0
  113. package/src/device/local/services/Device.service.ts +74 -52
  114. package/src/device/local/services/Issue.service.ts +872 -0
  115. package/src/device/local/services/IssueService.example.ts +307 -0
  116. package/src/device/local/services/index.ts +7 -5
  117. package/src/events/BaseEventHandler.ts +145 -0
  118. package/src/events/BaseEventTransformer.ts +97 -0
  119. package/src/events/DeviceEventHandler.ts +211 -0
  120. package/src/events/DeviceEventTransformerFactory.ts +77 -0
  121. package/src/{device/local/events → events}/EventHandler.ts +24 -19
  122. package/src/events/EventHandlerOrchestrator.ts +119 -0
  123. package/src/events/EventProcessingService.ts +248 -0
  124. package/src/events/InternalEventSubscription.ts +219 -0
  125. package/src/events/index.ts +9 -0
  126. package/src/events/interfaces/DeviceEvent.ts +56 -0
  127. package/src/events/interfaces/IEventHandler.ts +28 -0
  128. package/src/events/interfaces/IEventTransformer.ts +8 -0
  129. package/src/events/interfaces/IInternalEvent.ts +47 -0
  130. package/src/events/interfaces/index.ts +4 -0
  131. package/src/index.ts +9 -2
  132. package/src/types/alert.types.ts +64 -0
  133. package/src/types/config.types.ts +17 -4
  134. package/src/types/index.ts +2 -0
  135. package/src/types/issue.types.ts +98 -0
  136. package/src/utils/http-utils.ts +143 -0
  137. package/dist/device/cloud/interface.d.ts +0 -101
  138. package/dist/device/cloud/interfaces/IDeviceConnectionService.d.ts +0 -7
  139. package/dist/device/cloud/interfaces/IDevicesService.d.ts +0 -9
  140. package/dist/device/cloud/services/Device.service.d.ts +0 -39
  141. package/dist/device/cloud/services/Device.service.js +0 -9
  142. package/dist/device/cloud/services/DeviceCloudService.d.ts +0 -42
  143. package/dist/device/cloud/services/DeviceCloudService.js +0 -59
  144. package/dist/device/cloud/services/DeviceHub.service.d.ts +0 -3
  145. package/dist/device/cloud/services/DeviceHub.service.js +0 -6
  146. package/dist/device/cloud/services/Hub.service.d.ts +0 -25
  147. package/dist/device/cloud/services/Hub.service.js +0 -9
  148. package/dist/device/cloud/services/SmartThingsDeviceService.d.ts +0 -38
  149. package/dist/device/cloud/services/SmartThingsDeviceService.js +0 -52
  150. package/dist/device/index.d.ts +0 -4
  151. package/dist/device/local/interface.d.ts +0 -0
  152. package/dist/device/local/interface.js +0 -1
  153. package/dist/device/local/services/DeviceHub.service.d.ts +0 -11
  154. package/dist/device/local/services/DeviceHub.service.js +0 -40
  155. package/src/device/local/events/index.ts +0 -2
  156. /package/dist/{device/cloud/interfaces/IDevicesService.js → events/interfaces/DeviceEvent.js} +0 -0
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AlertServiceExample = void 0;
4
+ const AlertBuilder_1 = require("../entities/AlertBuilder");
5
+ const alert_types_1 = require("../../../types/alert.types");
6
+ /**
7
+ * Example usage of the updated AlertService with AlertBuilder integration
8
+ * This file demonstrates various ways to use the AlertService with the new AlertBuilder
9
+ */
10
+ class AlertServiceExample {
11
+ constructor(alertService) {
12
+ this.alertService = alertService;
13
+ }
14
+ /**
15
+ * Example 1: Using the updated createAlert method with AlertBuilder
16
+ */
17
+ async createAlertWithBuilder() {
18
+ const alertBuilder = new AlertBuilder_1.AlertBuilder()
19
+ .setCategory(alert_types_1.AlertCategory.OPERATIONS)
20
+ .setPropertyId("prop123")
21
+ .setTitle("Device Offline")
22
+ .setDescription("Device has been offline for more than 5 minutes")
23
+ .setEntityId("device456")
24
+ .setEntityType(alert_types_1.EntityType.DEVICE)
25
+ .setSeverity(alert_types_1.AlertSeverity.HIGH)
26
+ .setCreatedBy("user789");
27
+ // Pass the AlertBuilder directly to createAlert
28
+ const alert = await this.alertService.createAlert(alertBuilder);
29
+ return alert;
30
+ }
31
+ /**
32
+ * Example 2: Using convenience methods for specific alert types
33
+ */
34
+ async createSpecificAlerts() {
35
+ // Create a readiness alert
36
+ const readinessAlert = await this.alertService.raiseReadinessAlert("prop123", "System Maintenance Required", "System maintenance is scheduled for tonight", "system456", alert_types_1.EntityType.PROPERTY, "admin");
37
+ // Create an operations alert
38
+ const operationsAlert = await this.alertService.raiseOperationsAlert("prop123", "Device Temperature High", "Device temperature exceeds normal operating range", "device789", alert_types_1.EntityType.DEVICE, "monitor");
39
+ // Create a security alert
40
+ const securityAlert = await this.alertService.raiseSecurityAlert("prop123", "Unauthorized Access Attempt", "Multiple failed login attempts detected", "user123", alert_types_1.EntityType.USER, "security-system");
41
+ // Create an energy alert
42
+ const energyAlert = await this.alertService.raiseEnergyAlert("prop123", "High Energy Consumption", "Energy usage is 20% above normal levels", "zone456", alert_types_1.EntityType.COLLECTION, "energy-monitor");
43
+ return { readinessAlert, operationsAlert, securityAlert, energyAlert };
44
+ }
45
+ /**
46
+ * Example 3: Using device-specific alert methods
47
+ */
48
+ async createDeviceAlerts() {
49
+ // Create a device alert with default category and severity
50
+ const deviceAlert1 = await this.alertService.raiseDeviceAlert("device123", "prop456", "Device Battery Low", "Device battery level is below 20%", undefined, // Use default category
51
+ undefined, // Use default severity
52
+ "system");
53
+ // Create a device alert with custom category and severity
54
+ const deviceAlert2 = await this.alertService.raiseDeviceAlert("device789", "prop456", "Device Firmware Update Available", "New firmware version is available for installation", alert_types_1.AlertCategory.READINESS, alert_types_1.AlertSeverity.MEDIUM, "firmware-manager");
55
+ return { deviceAlert1, deviceAlert2 };
56
+ }
57
+ /**
58
+ * Example 4: Using hub-specific alert methods
59
+ */
60
+ async createHubAlerts() {
61
+ // Create a hub alert with default settings
62
+ const hubAlert1 = await this.alertService.raiseHubAlert("hub123", "prop456", "Hub Connection Lost", "Hub has lost connection to the network", undefined, // Use default category
63
+ undefined, // Use default severity
64
+ "network-monitor");
65
+ // Create a hub alert with custom settings
66
+ const hubAlert2 = await this.alertService.raiseHubAlert("hub789", "prop456", "Hub Maintenance Required", "Hub requires scheduled maintenance", alert_types_1.AlertCategory.READINESS, alert_types_1.AlertSeverity.LOW, "maintenance-system");
67
+ return { hubAlert1, hubAlert2 };
68
+ }
69
+ /**
70
+ * Example 5: Using static factory methods with AlertBuilder
71
+ */
72
+ async createAlertsWithStaticMethods() {
73
+ // Create a device alert using static factory method
74
+ const deviceAlert = AlertBuilder_1.AlertBuilder.createDeviceAlert("device123", "prop456")
75
+ .setCategory(alert_types_1.AlertCategory.OPERATIONS)
76
+ .setTitle("Device Offline")
77
+ .setDescription("Device has been offline for more than 5 minutes")
78
+ .setSeverity(alert_types_1.AlertSeverity.HIGH)
79
+ .setCreatedBy("monitor");
80
+ const alert1 = await this.alertService.createAlert(deviceAlert);
81
+ // Create a hub alert using static factory method
82
+ const hubAlert = AlertBuilder_1.AlertBuilder.createHubAlert("hub789", "prop202")
83
+ .setCategory(alert_types_1.AlertCategory.SECURITY)
84
+ .setTitle("Hub Security Breach")
85
+ .setDescription("Unauthorized access attempt detected on hub")
86
+ .setSeverity(alert_types_1.AlertSeverity.CRITICAL)
87
+ .setCreatedBy("security-system");
88
+ const alert2 = await this.alertService.createAlert(hubAlert);
89
+ return { alert1, alert2 };
90
+ }
91
+ /**
92
+ * Example 6: Creating multiple alerts efficiently
93
+ */
94
+ async createMultipleAlerts() {
95
+ const alerts = [];
96
+ // Create multiple device alerts efficiently
97
+ const deviceIds = ["device1", "device2", "device3"];
98
+ const propertyId = "prop123";
99
+ for (const deviceId of deviceIds) {
100
+ const alertBuilder = AlertBuilder_1.AlertBuilder.createDeviceAlert(deviceId, propertyId)
101
+ .setCategory(alert_types_1.AlertCategory.OPERATIONS)
102
+ .setTitle(`Device ${deviceId} Status`)
103
+ .setDescription(`Status check for device ${deviceId}`)
104
+ .setSeverity(alert_types_1.AlertSeverity.MEDIUM)
105
+ .setCreatedBy("batch-processor");
106
+ const alert = await this.alertService.createAlert(alertBuilder);
107
+ alerts.push(alert);
108
+ }
109
+ return alerts;
110
+ }
111
+ /**
112
+ * Example 7: Creating alerts with snooze functionality
113
+ */
114
+ async createSnoozedAlert() {
115
+ const snoozeUntil = new Date();
116
+ snoozeUntil.setHours(snoozeUntil.getHours() + 2); // Snooze for 2 hours
117
+ const alertBuilder = new AlertBuilder_1.AlertBuilder()
118
+ .setCategory(alert_types_1.AlertCategory.OTHER)
119
+ .setPropertyId("prop303")
120
+ .setTitle("Scheduled Maintenance")
121
+ .setDescription("System maintenance scheduled for tonight")
122
+ .setEntityType(alert_types_1.EntityType.PROPERTY)
123
+ .setSeverity(alert_types_1.AlertSeverity.INFO)
124
+ .setCreatedBy("admin")
125
+ .setSnoozeUntil(snoozeUntil);
126
+ const alert = await this.alertService.createAlert(alertBuilder);
127
+ return alert;
128
+ }
129
+ /**
130
+ * Example 8: Backward compatibility - still works with CreateAlertData
131
+ */
132
+ async createAlertWithLegacyData() {
133
+ const alertData = {
134
+ category: alert_types_1.AlertCategory.OPERATIONS,
135
+ propertyId: "prop123",
136
+ title: "Legacy Alert",
137
+ description: "This alert was created using the old CreateAlertData format",
138
+ entityId: "device456",
139
+ entityType: alert_types_1.EntityType.DEVICE,
140
+ severity: alert_types_1.AlertSeverity.MEDIUM,
141
+ createdBy: "legacy-system"
142
+ };
143
+ // This still works with the updated createAlert method
144
+ const alert = await this.alertService.createAlert(alertData);
145
+ return alert;
146
+ }
147
+ }
148
+ exports.AlertServiceExample = AlertServiceExample;
@@ -1,10 +1,9 @@
1
- import { IDevice } from "../interfaces";
1
+ import { IDevice, INewStatus } from "../interfaces";
2
2
  export declare class LocalDeviceService {
3
3
  private readonly eventHandler;
4
- private readonly alertService;
5
4
  private readonly deviceRepository;
6
5
  constructor();
7
- createDevice(body: IDevice): Promise<void>;
6
+ createDevice(body: IDevice): Promise<IDevice>;
8
7
  getDevice(deviceId: string, withHubDetails?: boolean): Promise<IDevice>;
9
8
  getDevices(deviceIds: string[], withHubDetails?: boolean): Promise<IDevice[]>;
10
9
  getPropertyDevices(propertyId: string, selectDeviceId?: boolean, type?: string, withHubDetails?: boolean): Promise<IDevice[]>;
@@ -14,11 +13,15 @@ export declare class LocalDeviceService {
14
13
  getState(deviceId: string): Promise<any>;
15
14
  setState(deviceId: string, newState: any): Promise<void>;
16
15
  getStatus(deviceId: string): Promise<Record<string, any>>;
17
- setStatus(deviceId: string, newStatus: any): Promise<void>;
16
+ setStatus(deviceId: string, newStatus: INewStatus): Promise<void>;
18
17
  getBatteryLevel(deviceId: string): Promise<Record<string, any>>;
19
- setBatteryLevel(deviceId: string, newBatteryLevel: any): Promise<void>;
18
+ setBatteryLevel(deviceId: string, batteryLevel: number): Promise<void>;
20
19
  getMetaData(deviceId: string): Promise<any>;
21
- setMetaData(deviceId: string, metaData: Record<string, any>): Promise<void>;
20
+ setMetaData(deviceId: string, metaData: Record<string, any>): Promise<any>;
22
21
  getDevicesByZone(zoneId: string): Promise<import("../interfaces/IDtDevice").IDtDevice[]>;
23
22
  getDevicesByAccessGroup(accessGroupId: string): Promise<import("../interfaces/IDtDevice").IDtDevice[]>;
23
+ querySelect(query: any, fields: string[]): Promise<any>;
24
+ queryCount(query: any): Promise<number>;
25
+ deleteDevices(query: any): Promise<any>;
26
+ queryDevices(query: any): Promise<any>;
24
27
  }
@@ -4,22 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.LocalDeviceService = void 0;
7
- const config_1 = require("../../../config/config");
8
- const EventHandler_1 = require("../events/EventHandler");
7
+ const EventHandler_1 = require("../../../events/EventHandler");
9
8
  const lodash_1 = require("lodash");
10
- const Alert_service_1 = require("./Alert.service");
11
9
  const Device_repository_1 = require("../repository/Device.repository");
12
10
  const typedi_1 = __importDefault(require("typedi"));
13
11
  class LocalDeviceService {
14
12
  constructor() {
15
- (0, config_1.checkAwsEnv)();
16
- (0, config_1.ensureAuditInitialized)();
17
13
  this.eventHandler = new EventHandler_1.EventHandler();
18
- this.alertService = new Alert_service_1.AlertService();
19
14
  this.deviceRepository = typedi_1.default.get(Device_repository_1.DeviceRepository);
20
15
  }
21
16
  async createDevice(body) {
22
- return await this.eventHandler.onDeviceCreate(body);
17
+ const device = await this.deviceRepository.createDevice(body);
18
+ await this.eventHandler.onDeviceCreate(device);
19
+ return device;
23
20
  }
24
21
  async getDevice(deviceId, withHubDetails = false) {
25
22
  if (!deviceId) {
@@ -71,6 +68,7 @@ class LocalDeviceService {
71
68
  const oldState = (await this.getState(deviceId))?.data?.state ?? {};
72
69
  const changedKeys = Object.keys(newState).filter((key) => !(0, lodash_1.isEqual)(oldState[key], newState[key]));
73
70
  if (changedKeys.length > 0) {
71
+ await this.deviceRepository.setState(deviceId, newState);
74
72
  return await this.eventHandler.onStateChange(deviceId, newState);
75
73
  }
76
74
  }
@@ -80,27 +78,22 @@ class LocalDeviceService {
80
78
  }
81
79
  return await this.deviceRepository.getStatus(deviceId);
82
80
  }
83
- //TODO: Define type of newStatus
84
81
  async setStatus(deviceId, newStatus) {
85
82
  if (!deviceId || !newStatus) {
86
83
  throw new Error("Device ID and new status are required");
87
84
  }
88
- // If old status and new status are different
89
85
  const oldStatus = await this.getStatus(deviceId);
90
- const changedKeys = Object.keys(newStatus).filter((key) => !(0, lodash_1.isEqual)(oldStatus?.data?.[key], newStatus?.[key]));
91
- if (changedKeys.length > 0) {
92
- return await this.eventHandler.onStatusChange(deviceId, newStatus);
93
- }
94
- // If both old and new status are offline, check the time difference between the last offline status and current time
95
- if (oldStatus?.data?.online === false &&
96
- oldStatus?.data?.lastUpdated &&
97
- newStatus?.online === false) {
98
- const lastOfflineTime = new Date(oldStatus?.data?.lastUpdated).getTime();
99
- const currentTime = Date.now();
100
- const timeDifference = currentTime - lastOfflineTime;
101
- // Compare it with the baseline profile time of the device. If the difference is higher, then raise an operational alert
102
- if (timeDifference > 1000 * 60 * 60 * 24) {
103
- return await this.alertService.raiseOperationsAlert();
86
+ const isStatusChanged = !(0, lodash_1.isEqual)(oldStatus, newStatus);
87
+ if (isStatusChanged) {
88
+ await this.deviceRepository.setStatus(deviceId, newStatus);
89
+ await this.eventHandler.onStatusChange(deviceId, newStatus);
90
+ }
91
+ const isBothOffline = oldStatus?.online === false && newStatus?.online === false;
92
+ if (isBothOffline && oldStatus?.lastUpdated) {
93
+ const timeDifference = Date.now() - new Date(oldStatus.lastUpdated).getTime();
94
+ if (timeDifference > 86400000) {
95
+ //return await this.alertService.raiseOperationsAlert();
96
+ return;
104
97
  }
105
98
  }
106
99
  }
@@ -110,24 +103,24 @@ class LocalDeviceService {
110
103
  }
111
104
  return await this.deviceRepository.getBatteryLevel(deviceId);
112
105
  }
113
- //TODO: Define payload type of newBatteryLevel
114
- async setBatteryLevel(deviceId, newBatteryLevel) {
115
- if (!deviceId || !newBatteryLevel) {
116
- throw new Error("Device ID and new battery level are required");
117
- }
118
- // If old battery level and new battery level are different
106
+ async setBatteryLevel(deviceId, batteryLevel) {
107
+ // Fetch the old battery level state
119
108
  const oldBatteryLevel = await this.getBatteryLevel(deviceId);
120
- const changedKeys = Object.keys(newBatteryLevel).filter((key) => !(0, lodash_1.isEqual)(oldBatteryLevel?.data?.[key], newBatteryLevel?.[key]));
121
- if (changedKeys.length > 0) {
122
- return await this.eventHandler.onBatteryLevelChange(deviceId, newBatteryLevel);
123
- }
124
- // If current battery level is less than 20% and lsat updated time is more than 8 hours, raise an energy alert
125
- if (newBatteryLevel?.value < 20 &&
126
- oldBatteryLevel?.data?.value < 20 &&
127
- new Date(oldBatteryLevel?.data?.lastUpdated).getTime() <
128
- Date.now() - 1000 * 60 * 60 * 8) {
129
- //TODO: Raise an energy alert
130
- await this.alertService.raiseEnergyAlert();
109
+ const isDifferent = !(0, lodash_1.isEqual)(oldBatteryLevel?.value, batteryLevel);
110
+ if (isDifferent) {
111
+ await this.deviceRepository.setBatteryLevel(deviceId, batteryLevel);
112
+ await this.eventHandler.onBatteryLevelChange(deviceId, batteryLevel);
113
+ }
114
+ // Check if battery is low and not updated for 8 hours
115
+ if (batteryLevel < 20 &&
116
+ oldBatteryLevel?.value < 20 &&
117
+ oldBatteryLevel?.lastUpdated &&
118
+ new Date(oldBatteryLevel.lastUpdated).getTime() <
119
+ Date.now() - 1000 * 60 * 60 * 8 // 8 hours in ms
120
+ ) {
121
+ // TODO: Raise an energy alert
122
+ // await this.alertService.raiseEnergyAlert();
123
+ return;
131
124
  }
132
125
  }
133
126
  async getMetaData(deviceId) {
@@ -140,7 +133,8 @@ class LocalDeviceService {
140
133
  if (!deviceId || !metaData) {
141
134
  throw new Error("Device ID and meta data are required");
142
135
  }
143
- return await this.eventHandler.onDeviceMetaChange(deviceId, metaData);
136
+ await this.eventHandler.onDeviceMetaChange(deviceId, metaData);
137
+ return await this.deviceRepository.setMetaData(deviceId, metaData);
144
138
  }
145
139
  async getDevicesByZone(zoneId) {
146
140
  if (!zoneId) {
@@ -154,5 +148,31 @@ class LocalDeviceService {
154
148
  }
155
149
  return await this.deviceRepository.getDevicesByAccessGroup(accessGroupId);
156
150
  }
151
+ async querySelect(query, fields) {
152
+ if (!query || Object.keys(query).length === 0) {
153
+ throw new Error("Query is required");
154
+ }
155
+ return await this.deviceRepository.querySelect(query, fields);
156
+ }
157
+ async queryCount(query) {
158
+ if (!query || Object.keys(query).length === 0) {
159
+ throw new Error("Query is required");
160
+ }
161
+ const count = await this.deviceRepository.queryCount(query);
162
+ return count;
163
+ }
164
+ async deleteDevices(query) {
165
+ if (!query || Object.keys(query).length === 0) {
166
+ throw new Error("Query is required");
167
+ }
168
+ return await this.deviceRepository.deleteDevices(query);
169
+ }
170
+ async queryDevices(query) {
171
+ if (!query || Object.keys(query).length === 0) {
172
+ throw new Error("Query is required");
173
+ }
174
+ const count = await this.deviceRepository.queryDevices(query);
175
+ return count;
176
+ }
157
177
  }
158
178
  exports.LocalDeviceService = LocalDeviceService;
@@ -0,0 +1,168 @@
1
+ import { IssueRepository } from "../repository/Issue.repository";
2
+ import { IIssueDocument } from "../models/Issue.model";
3
+ import { CreateIssueData, UpdateIssueData, AddCommentData, IssueStatus, IssuePriority, IssuesCategory, EntityType } from "../../../types/issue.types";
4
+ import { IssueBuilder } from "../entities/IssueBuilder";
5
+ export declare class IssueService {
6
+ private readonly issueRepository;
7
+ constructor(issueRepository: IssueRepository);
8
+ /**
9
+ * Create a readiness issue using IssueBuilder
10
+ */
11
+ createReadinessIssue(propertyId: string, title: string, description: string, createdBy: string, entityId?: string, entityType?: EntityType, assignedTo?: string, dueDate?: Date): Promise<IIssueDocument>;
12
+ /**
13
+ * Create an operations issue using IssueBuilder
14
+ */
15
+ createOperationsIssue(propertyId: string, title: string, description: string, createdBy: string, entityId?: string, entityType?: EntityType, assignedTo?: string, dueDate?: Date): Promise<IIssueDocument>;
16
+ /**
17
+ * Create a security issue using IssueBuilder
18
+ */
19
+ createSecurityIssue(propertyId: string, title: string, description: string, createdBy: string, entityId?: string, entityType?: EntityType, assignedTo?: string, dueDate?: Date): Promise<IIssueDocument>;
20
+ /**
21
+ * Create an energy issue using IssueBuilder
22
+ */
23
+ createEnergyIssue(propertyId: string, title: string, description: string, createdBy: string, entityId?: string, entityType?: EntityType, assignedTo?: string, dueDate?: Date): Promise<IIssueDocument>;
24
+ /**
25
+ * Create a device-specific issue using IssueBuilder
26
+ */
27
+ createDeviceIssue(deviceId: string, propertyId: string, title: string, description: string, createdBy: string, category?: IssuesCategory, priority?: IssuePriority, assignedTo?: string, dueDate?: Date): Promise<IIssueDocument>;
28
+ /**
29
+ * Create a hub-specific issue using IssueBuilder
30
+ */
31
+ createHubIssue(hubId: string, propertyId: string, title: string, description: string, createdBy: string, category?: IssuesCategory, priority?: IssuePriority, assignedTo?: string, dueDate?: Date): Promise<IIssueDocument>;
32
+ /**
33
+ * Create a user-specific issue using IssueBuilder
34
+ */
35
+ createUserIssue(userId: string, propertyId: string, title: string, description: string, createdBy: string, category?: IssuesCategory, priority?: IssuePriority, assignedTo?: string, dueDate?: Date): Promise<IIssueDocument>;
36
+ /**
37
+ * Create a maintenance issue using IssueBuilder
38
+ */
39
+ createMaintenanceIssue(propertyId: string, title: string, description: string, createdBy: string, entityId?: string, entityType?: EntityType, assignedTo?: string, dueDate?: Date): Promise<IIssueDocument>;
40
+ /**
41
+ * Create an urgent issue using IssueBuilder
42
+ */
43
+ createUrgentIssue(propertyId: string, title: string, description: string, createdBy: string, entityId?: string, entityType?: EntityType, assignedTo?: string, dueDate?: Date): Promise<IIssueDocument>;
44
+ /**
45
+ * Create a new issue with business logic validation
46
+ * Accepts either a CreateIssueData object or an IssueBuilder instance
47
+ */
48
+ createIssue(issueData: CreateIssueData | IssueBuilder): Promise<IIssueDocument>;
49
+ /**
50
+ * Get issue by ID with business logic
51
+ */
52
+ getIssueById(id: string, includeDeleted?: boolean): Promise<IIssueDocument | null>;
53
+ /**
54
+ * Get all issues with business logic filtering
55
+ */
56
+ getIssues(filters?: {
57
+ propertyId?: string;
58
+ assignedTo?: string;
59
+ status?: IssueStatus;
60
+ priority?: IssuePriority;
61
+ category?: IssuesCategory;
62
+ entityType?: EntityType;
63
+ entityId?: string;
64
+ includeDeleted?: boolean;
65
+ limit?: number;
66
+ skip?: number;
67
+ }): Promise<IIssueDocument[]>;
68
+ /**
69
+ * Update an issue with business logic validation
70
+ */
71
+ updateIssue(id: string, updateData: UpdateIssueData): Promise<IIssueDocument | null>;
72
+ /**
73
+ * Soft delete an issue with business logic
74
+ */
75
+ deleteIssue(id: string, deletedBy: string): Promise<boolean>;
76
+ /**
77
+ * Permanently delete an issue
78
+ */
79
+ permanentlyDeleteIssue(id: string): Promise<boolean>;
80
+ /**
81
+ * Add a comment with business logic
82
+ */
83
+ addComment(issueId: string, commentData: AddCommentData): Promise<IIssueDocument | null>;
84
+ /**
85
+ * Update a comment on an issue
86
+ */
87
+ updateComment(issueId: string, commentId: string, content: string, userId: string): Promise<boolean>;
88
+ /**
89
+ * Remove a comment from an issue
90
+ */
91
+ removeComment(issueId: string, commentId: string): Promise<boolean>;
92
+ /**
93
+ * Resolve an issue with business logic
94
+ */
95
+ resolveIssue(id: string, resolvedBy: string): Promise<IIssueDocument | null>;
96
+ /**
97
+ * Reopen a resolved issue
98
+ */
99
+ reopenIssue(id: string, reopenedBy: string): Promise<IIssueDocument | null>;
100
+ /**
101
+ * Assign an issue with business logic
102
+ */
103
+ assignIssue(id: string, userId: string, assignedBy: string): Promise<IIssueDocument | null>;
104
+ /**
105
+ * Unassign an issue
106
+ */
107
+ unassignIssue(id: string, unassignedBy: string): Promise<IIssueDocument | null>;
108
+ /**
109
+ * Get issues by property with business logic
110
+ */
111
+ getIssuesByProperty(propertyId: string, includeDeleted?: boolean): Promise<IIssueDocument[]>;
112
+ /**
113
+ * Get issues assigned to a user with business logic
114
+ */
115
+ getIssuesByAssignee(assignedTo: string, includeDeleted?: boolean): Promise<IIssueDocument[]>;
116
+ /**
117
+ * Get issues by entity
118
+ */
119
+ getIssuesByEntity(entityId: string, entityType: EntityType, includeDeleted?: boolean): Promise<IIssueDocument[]>;
120
+ /**
121
+ * Get issues by status
122
+ */
123
+ getIssuesByStatus(status: IssueStatus, includeDeleted?: boolean): Promise<IIssueDocument[]>;
124
+ /**
125
+ * Get issues by priority
126
+ */
127
+ getIssuesByPriority(priority: IssuePriority, includeDeleted?: boolean): Promise<IIssueDocument[]>;
128
+ /**
129
+ * Get overdue issues with business logic
130
+ */
131
+ getOverdueIssues(includeDeleted?: boolean): Promise<IIssueDocument[]>;
132
+ /**
133
+ * Get upcoming issues (due within specified days)
134
+ */
135
+ getUpcomingIssues(days?: number, includeDeleted?: boolean): Promise<IIssueDocument[]>;
136
+ /**
137
+ * Get issue statistics with business logic
138
+ */
139
+ getIssueStatistics(propertyId?: string): Promise<{
140
+ total: number;
141
+ pending: number;
142
+ inProgress: number;
143
+ resolved: number;
144
+ closed: number;
145
+ overdue: number;
146
+ byPriority: Record<IssuePriority, number>;
147
+ byCategory: Record<IssuesCategory, number>;
148
+ }>;
149
+ /**
150
+ * Search issues with business logic
151
+ */
152
+ searchIssues(searchTerm: string, filters?: {
153
+ propertyId?: string;
154
+ includeDeleted?: boolean;
155
+ limit?: number;
156
+ skip?: number;
157
+ }): Promise<IIssueDocument[]>;
158
+ private validateIssueData;
159
+ private validateFilters;
160
+ private validateUpdateData;
161
+ private validateStatusTransition;
162
+ private validatePriorityChange;
163
+ private determineDefaultPriority;
164
+ private applyBusinessRules;
165
+ private shouldUpdateStatusOnComment;
166
+ private calculateAverageResponseTime;
167
+ private calculateResolutionRate;
168
+ }