dt-common-device 2.0.6 → 3.0.0

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 (187) hide show
  1. package/README.md +321 -99
  2. package/dist/alerts/Alert.model.d.ts +28 -0
  3. package/dist/alerts/Alert.model.js +222 -0
  4. package/dist/alerts/Alert.repository.d.ts +106 -0
  5. package/dist/alerts/Alert.repository.js +374 -0
  6. package/dist/alerts/Alert.service.d.ts +137 -0
  7. package/dist/alerts/Alert.service.js +476 -0
  8. package/dist/alerts/AlertBuilder.d.ts +87 -0
  9. package/dist/alerts/AlertBuilder.example.d.ts +11 -0
  10. package/dist/alerts/AlertBuilder.example.js +117 -0
  11. package/dist/alerts/AlertBuilder.js +185 -0
  12. package/dist/alerts/AlertService.example.d.ts +55 -0
  13. package/dist/alerts/AlertService.example.js +148 -0
  14. package/dist/alerts/alert.types.d.ts +57 -0
  15. package/dist/alerts/alert.types.js +22 -0
  16. package/dist/alerts/index.d.ts +3 -0
  17. package/dist/alerts/index.js +19 -0
  18. package/dist/config/config.d.ts +4 -4
  19. package/dist/config/config.js +3 -3
  20. package/dist/config/config.types.d.ts +19 -0
  21. package/dist/config/config.types.js +2 -0
  22. package/dist/connection/Connection.repository.d.ts +8 -0
  23. package/dist/connection/Connection.repository.js +92 -0
  24. package/dist/connection/Connection.service.d.ts +8 -0
  25. package/dist/connection/Connection.service.js +32 -0
  26. package/dist/connection/IConnection.d.ts +26 -0
  27. package/dist/connection/IConnection.js +14 -0
  28. package/dist/connection/index.d.ts +2 -0
  29. package/dist/connection/index.js +18 -0
  30. package/dist/device/cloud/entities/CloudDevice.d.ts +2 -2
  31. package/dist/device/cloud/entities/CloudDeviceService.d.ts +1 -1
  32. package/dist/device/cloud/entities/DeviceFactory.d.ts +1 -1
  33. package/dist/device/cloud/entities/DeviceFactory.js +1 -1
  34. package/dist/device/cloud/interfaces/ICloudDeviceService.d.ts +1 -1
  35. package/dist/device/cloud/interfaces/IRawDevice.d.ts +1 -1
  36. package/dist/device/local/interfaces/index.d.ts +2 -3
  37. package/dist/device/local/interfaces/index.js +2 -3
  38. package/dist/device/local/repository/Device.repository.d.ts +2 -0
  39. package/dist/device/local/repository/Device.repository.js +22 -3
  40. package/dist/device/local/repository/Hub.repository.js +4 -4
  41. package/dist/device/local/repository/Schedule.repository.js +2 -2
  42. package/dist/device/local/services/Device.service.d.ts +2 -2
  43. package/dist/device/local/services/Device.service.js +3 -1
  44. package/dist/device/local/services/index.d.ts +0 -4
  45. package/dist/device/local/services/index.js +0 -4
  46. package/dist/events/BaseEventHandler.d.ts +2 -2
  47. package/dist/events/BaseEventHandler.js +2 -2
  48. package/dist/events/BaseEventTransformer.d.ts +1 -1
  49. package/dist/events/BaseEventTransformer.js +1 -1
  50. package/dist/events/DeviceEventHandler.d.ts +1 -1
  51. package/dist/events/DeviceEventHandler.js +2 -2
  52. package/dist/events/EventHandler.js +1 -1
  53. package/dist/events/EventHandlerOrchestrator.js +1 -1
  54. package/dist/events/EventProcessingService.js +1 -1
  55. package/dist/events/InternalEventSubscription.js +1 -1
  56. package/dist/index.d.ts +7 -5
  57. package/dist/index.js +16 -13
  58. package/dist/issues/Issue.model.d.ts +28 -0
  59. package/dist/issues/Issue.model.js +260 -0
  60. package/dist/issues/Issue.repository.d.ts +113 -0
  61. package/dist/issues/Issue.repository.js +401 -0
  62. package/dist/issues/Issue.service.d.ts +168 -0
  63. package/dist/issues/Issue.service.js +642 -0
  64. package/dist/issues/IssueBuilder.d.ts +109 -0
  65. package/dist/issues/IssueBuilder.example.d.ts +16 -0
  66. package/dist/issues/IssueBuilder.example.js +196 -0
  67. package/dist/issues/IssueBuilder.js +237 -0
  68. package/dist/issues/IssueService.example.d.ts +68 -0
  69. package/dist/issues/IssueService.example.js +177 -0
  70. package/dist/issues/index.d.ts +2 -0
  71. package/dist/issues/index.js +18 -0
  72. package/dist/issues/issue.types.d.ts +90 -0
  73. package/dist/issues/issue.types.js +40 -0
  74. package/dist/property/IProperty.d.ts +29 -0
  75. package/dist/property/IProperty.js +2 -0
  76. package/dist/property/Property.repository.d.ts +8 -0
  77. package/dist/property/Property.repository.js +95 -0
  78. package/dist/property/Property.service.d.ts +8 -0
  79. package/dist/property/Property.service.js +36 -0
  80. package/dist/property/index.d.ts +2 -0
  81. package/dist/property/index.js +18 -0
  82. package/dist/queue/entities/HybridHttpQueue.d.ts +23 -0
  83. package/dist/queue/entities/HybridHttpQueue.js +189 -0
  84. package/dist/queue/entities/index.d.ts +1 -0
  85. package/dist/queue/entities/index.js +17 -0
  86. package/dist/queue/index.d.ts +5 -0
  87. package/dist/queue/index.js +22 -0
  88. package/dist/queue/interfaces/IHttpRequestJob.d.ts +9 -0
  89. package/dist/queue/interfaces/IHttpRequestJob.js +2 -0
  90. package/dist/queue/interfaces/IHybridHttpQueue.d.ts +16 -0
  91. package/dist/queue/interfaces/IHybridHttpQueue.js +2 -0
  92. package/dist/queue/interfaces/IJobResult.d.ts +6 -0
  93. package/dist/queue/interfaces/IJobResult.js +2 -0
  94. package/dist/queue/interfaces/IRateLimitConfig.d.ts +5 -0
  95. package/dist/queue/interfaces/IRateLimitConfig.js +2 -0
  96. package/dist/queue/interfaces/index.d.ts +4 -0
  97. package/dist/queue/interfaces/index.js +20 -0
  98. package/dist/queue/services/QueueService.d.ts +19 -0
  99. package/dist/queue/services/QueueService.js +73 -0
  100. package/dist/queue/services/index.d.ts +1 -0
  101. package/dist/queue/services/index.js +17 -0
  102. package/dist/queue/types/http.types.d.ts +21 -0
  103. package/dist/queue/types/http.types.js +2 -0
  104. package/dist/queue/types/index.d.ts +2 -0
  105. package/dist/queue/types/index.js +18 -0
  106. package/dist/queue/types/queue.types.d.ts +35 -0
  107. package/dist/queue/types/queue.types.js +2 -0
  108. package/dist/queue/utils/index.d.ts +3 -0
  109. package/dist/queue/utils/index.js +19 -0
  110. package/dist/queue/utils/jobUtils.d.ts +10 -0
  111. package/dist/queue/utils/jobUtils.js +64 -0
  112. package/dist/queue/utils/queueUtils.d.ts +5 -0
  113. package/dist/queue/utils/queueUtils.js +59 -0
  114. package/dist/queue/utils/rateLimit.utils.d.ts +6 -0
  115. package/dist/queue/utils/rateLimit.utils.js +44 -0
  116. package/package.json +2 -1
  117. package/src/{device/local/models → alerts}/Alert.model.ts +1 -1
  118. package/src/{device/local/repository → alerts}/Alert.repository.ts +2 -2
  119. package/src/{device/local/services → alerts}/Alert.service.ts +14 -7
  120. package/src/{device/local/entities → alerts}/AlertBuilder.example.ts +2 -2
  121. package/src/{device/local/entities → alerts}/AlertBuilder.ts +14 -8
  122. package/src/{device/local/services → alerts}/AlertService.example.ts +6 -5
  123. package/src/{types → alerts}/alert.types.ts +2 -2
  124. package/src/alerts/index.ts +3 -0
  125. package/src/config/config.ts +7 -7
  126. package/src/{types → config}/config.types.ts +1 -1
  127. package/src/{device/local/repository → connection}/Connection.repository.ts +2 -2
  128. package/src/{device/local/services → connection}/Connection.service.ts +2 -2
  129. package/src/connection/index.ts +3 -0
  130. package/src/device/cloud/entities/CloudDevice.ts +2 -2
  131. package/src/device/cloud/entities/CloudDeviceService.ts +1 -1
  132. package/src/device/cloud/entities/DeviceFactory.ts +2 -2
  133. package/src/device/cloud/interfaces/ICloudDeviceService.ts +1 -1
  134. package/src/device/cloud/interfaces/IRawDevice.ts +1 -1
  135. package/src/device/local/interfaces/index.ts +2 -3
  136. package/src/device/local/repository/Device.repository.ts +29 -3
  137. package/src/device/local/repository/Hub.repository.ts +4 -4
  138. package/src/device/local/repository/Schedule.repository.ts +2 -2
  139. package/src/device/local/services/Device.service.ts +5 -1
  140. package/src/device/local/services/index.ts +0 -4
  141. package/{TROUBLESHOOTING.md → src/docs/TROUBLESHOOTING.md} +2 -2
  142. package/src/events/BaseEventHandler.ts +3 -3
  143. package/src/events/BaseEventTransformer.ts +2 -2
  144. package/src/events/DeviceEventHandler.ts +3 -3
  145. package/src/events/EventHandler.ts +1 -1
  146. package/src/events/EventHandlerOrchestrator.ts +2 -2
  147. package/src/events/EventProcessingService.ts +2 -2
  148. package/src/events/InternalEventSubscription.ts +2 -2
  149. package/src/index.ts +19 -13
  150. package/src/{device/local/models → issues}/Issue.model.ts +1 -1
  151. package/src/{device/local/repository → issues}/Issue.repository.ts +2 -2
  152. package/src/{device/local/services → issues}/Issue.service.ts +4 -4
  153. package/src/{device/local/entities → issues}/IssueBuilder.example.ts +1 -1
  154. package/src/{device/local/entities → issues}/IssueBuilder.ts +1 -1
  155. package/src/{device/local/services → issues}/IssueService.example.ts +6 -5
  156. package/src/issues/index.ts +2 -0
  157. package/src/{device/local/repository → property}/Property.repository.ts +2 -2
  158. package/src/{device/local/services → property}/Property.service.ts +1 -1
  159. package/src/property/index.ts +2 -0
  160. package/src/queue/entities/HybridHttpQueue.ts +196 -0
  161. package/src/queue/entities/index.ts +1 -0
  162. package/src/queue/index.ts +6 -0
  163. package/src/queue/interfaces/IHttpRequestJob.ts +10 -0
  164. package/src/queue/interfaces/IHybridHttpQueue.ts +23 -0
  165. package/src/queue/interfaces/IJobResult.ts +6 -0
  166. package/src/queue/interfaces/IRateLimitConfig.ts +5 -0
  167. package/src/queue/interfaces/index.ts +4 -0
  168. package/src/queue/services/QueueService.ts +39 -0
  169. package/src/queue/services/index.ts +1 -0
  170. package/src/queue/types/http.types.ts +22 -0
  171. package/src/queue/types/index.ts +2 -0
  172. package/src/queue/types/queue.types.ts +22 -0
  173. package/src/queue/utils/index.ts +3 -0
  174. package/src/queue/utils/jobUtils.ts +80 -0
  175. package/src/queue/utils/queueUtils.ts +90 -0
  176. package/src/queue/utils/rateLimit.utils.ts +58 -0
  177. package/tsconfig.json +4 -0
  178. package/src/device/local/entities/README.md +0 -173
  179. package/src/device/local/entities/index.ts +0 -2
  180. package/src/types/index.ts +0 -3
  181. /package/src/{device/local/interfaces → connection}/IConnection.ts +0 -0
  182. /package/src/{device/local/models → docs}/Alert.model.md +0 -0
  183. /package/src/{device/local/models/README.md → docs/Alerts&IssuesModel.md} +0 -0
  184. /package/src/{device/local/models → docs}/Issue.model.md +0 -0
  185. /package/{SECURITY.md → src/docs/SECURITY.md} +0 -0
  186. /package/src/{types → issues}/issue.types.ts +0 -0
  187. /package/src/{device/local/interfaces → property}/IProperty.ts +0 -0
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QueueUtils = void 0;
4
+ const config_1 = require("../../config/config");
5
+ class QueueUtils {
6
+ static getQueueKey(microservice, connectionId, provider) {
7
+ return `${microservice}_${provider}_${connectionId}`;
8
+ }
9
+ static getOrCreateQueue(queueKey, queues) {
10
+ return (queues.get(queueKey) ??
11
+ queues
12
+ .set(queueKey, new (require("bullmq").Queue)(queueKey, {
13
+ connection: require("../../db/redis").getRedisClient(),
14
+ }))
15
+ .get(queueKey));
16
+ }
17
+ static getOrCreateWorker(queueKey, workers, processFunction, jobResults) {
18
+ if (workers.has(queueKey))
19
+ return;
20
+ const { Worker } = require("bullmq");
21
+ const worker = new Worker(queueKey, processFunction, {
22
+ connection: require("../../db/redis").getRedisClient(),
23
+ concurrency: 1,
24
+ removeOnComplete: { age: 300, count: 1 },
25
+ removeOnFail: { age: 300, count: 1 },
26
+ lockDuration: 300000,
27
+ stalledInterval: 60000,
28
+ });
29
+ // Simplified event handlers
30
+ worker.on("completed", (job) => {
31
+ (0, config_1.getConfig)().LOGGER.info(`HTTP request completed: ${job.id} [${queueKey}]`);
32
+ job.returnvalue
33
+ .then((result) => jobResults.set(job.id, {
34
+ result,
35
+ resolved: true,
36
+ timestamp: Date.now(),
37
+ }))
38
+ .catch((error) => jobResults.set(job.id, {
39
+ error: error.message,
40
+ resolved: true,
41
+ timestamp: Date.now(),
42
+ }));
43
+ });
44
+ worker.on("failed", (job, err) => {
45
+ (0, config_1.getConfig)().LOGGER.error(`HTTP request failed: ${job?.id} [${queueKey}], Error: ${err.message}`);
46
+ jobResults.set(job.id, {
47
+ error: err.message,
48
+ resolved: true,
49
+ timestamp: Date.now(),
50
+ });
51
+ });
52
+ worker.on("error", (err) => (0, config_1.getConfig)().LOGGER.error(`Worker error for ${queueKey}: ${err.message}`));
53
+ worker.on("stalled", (jobId) => (0, config_1.getConfig)().LOGGER.warn(`Job ${jobId} stalled in worker ${queueKey}`));
54
+ worker.on("active", (job) => (0, config_1.getConfig)().LOGGER.info(`HTTP request started: ${job.id} [${queueKey}]`));
55
+ workers.set(queueKey, worker);
56
+ (0, config_1.getConfig)().LOGGER.info(`Worker initialized for queue: ${queueKey}`);
57
+ }
58
+ }
59
+ exports.QueueUtils = QueueUtils;
@@ -0,0 +1,6 @@
1
+ import { IRateLimitConfig } from "../interfaces";
2
+ export declare class RateLimitUtils {
3
+ private static redisClient;
4
+ static checkRateLimit(connectionId: string, provider: string, rateLimitConfigs: Map<string, IRateLimitConfig>): Promise<boolean>;
5
+ static initializeRateLimitConfigs(): Map<string, IRateLimitConfig>;
6
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RateLimitUtils = void 0;
4
+ const redis_1 = require("../../db/redis");
5
+ const config_1 = require("../../config/config");
6
+ class RateLimitUtils {
7
+ static async checkRateLimit(connectionId, provider, rateLimitConfigs) {
8
+ const config = rateLimitConfigs.get(provider);
9
+ if (!config) {
10
+ (0, config_1.getConfig)().LOGGER.warn(`No rate limit config found for provider: ${provider}`);
11
+ return true;
12
+ }
13
+ const key = `rate_limit:${provider}:${connectionId}`;
14
+ const now = Date.now();
15
+ const windowStart = now - config.windowMs;
16
+ try {
17
+ const data = await this.redisClient.get(key);
18
+ const requests = data
19
+ ? JSON.parse(data).filter((t) => t > windowStart)
20
+ : [];
21
+ if (requests.length >= config.maxRequests)
22
+ return false;
23
+ requests.push(now);
24
+ await this.redisClient.setex(key, Math.ceil(config.windowMs / 1000), JSON.stringify(requests));
25
+ return true;
26
+ }
27
+ catch (error) {
28
+ (0, config_1.getConfig)().LOGGER.error(`Rate limit check error: ${error}`);
29
+ return true;
30
+ }
31
+ }
32
+ static initializeRateLimitConfigs() {
33
+ const configs = new Map();
34
+ // Configure rate limits for different providers
35
+ configs.set("Sensibo", {
36
+ maxRequests: 40,
37
+ windowMs: 60000,
38
+ provider: "Sensibo",
39
+ });
40
+ return configs;
41
+ }
42
+ }
43
+ exports.RateLimitUtils = RateLimitUtils;
44
+ RateLimitUtils.redisClient = (0, redis_1.getRedisClient)();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dt-common-device",
3
- "version": "2.0.6",
3
+ "version": "3.0.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -39,6 +39,7 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "axios": "1.10.0",
42
+ "bullmq": "5.56.4",
42
43
  "dt-audit-library": "^1.0.3",
43
44
  "dt-pub-sub": "^1.0.0",
44
45
  "ioredis": "5.6.1",
@@ -6,7 +6,7 @@ import {
6
6
  AlertDocument as IAlertDocument,
7
7
  CreateAlertData,
8
8
  UpdateAlertData,
9
- } from "../../../types/alert.types";
9
+ } from "./alert.types";
10
10
 
11
11
  // Interface for instance methods
12
12
  interface IAlertMethods {
@@ -1,12 +1,12 @@
1
1
  import { Service } from "typedi";
2
- import { AlertModel, IAlertDocument } from "../models/Alert.model";
2
+ import { AlertModel, IAlertDocument } from "./Alert.model";
3
3
  import {
4
4
  CreateAlertData,
5
5
  UpdateAlertData,
6
6
  AlertCategory,
7
7
  AlertSeverity,
8
8
  EntityType,
9
- } from "../../../types/alert.types";
9
+ } from "./alert.types";
10
10
 
11
11
  @Service()
12
12
  export class AlertRepository {
@@ -1,14 +1,14 @@
1
1
  import { Service } from "typedi";
2
- import { AlertRepository } from "../repository/Alert.repository";
3
- import { AlertModel, IAlertDocument } from "../models/Alert.model";
2
+ import { AlertRepository } from "./Alert.repository";
3
+ import { AlertModel, IAlertDocument } from "./Alert.model";
4
4
  import {
5
5
  CreateAlertData,
6
6
  UpdateAlertData,
7
7
  AlertCategory,
8
8
  AlertSeverity,
9
9
  EntityType,
10
- } from "../../../types/alert.types";
11
- import { AlertBuilder } from "../entities/AlertBuilder";
10
+ } from "./alert.types";
11
+ import { AlertBuilder } from "./AlertBuilder";
12
12
 
13
13
  @Service()
14
14
  export class AlertService {
@@ -156,7 +156,9 @@ export class AlertService {
156
156
  * Create a new alert with business logic validation
157
157
  * Accepts either a CreateAlertData object or an AlertBuilder instance
158
158
  */
159
- async createAlert(alertData: CreateAlertData | AlertBuilder): Promise<IAlertDocument> {
159
+ async createAlert(
160
+ alertData: CreateAlertData | AlertBuilder
161
+ ): Promise<IAlertDocument> {
160
162
  let processedAlertData: CreateAlertData;
161
163
 
162
164
  // Handle AlertBuilder instance
@@ -171,11 +173,16 @@ export class AlertService {
171
173
 
172
174
  // Business logic: Set default severity if not provided
173
175
  if (!processedAlertData.severity) {
174
- processedAlertData.severity = this.determineDefaultSeverity(processedAlertData.category);
176
+ processedAlertData.severity = this.determineDefaultSeverity(
177
+ processedAlertData.category
178
+ );
175
179
  }
176
180
 
177
181
  // Business logic: Validate snooze date is in the future
178
- if (processedAlertData.snoozeUntil && processedAlertData.snoozeUntil <= new Date()) {
182
+ if (
183
+ processedAlertData.snoozeUntil &&
184
+ processedAlertData.snoozeUntil <= new Date()
185
+ ) {
179
186
  throw new Error("Snooze date must be in the future");
180
187
  }
181
188
 
@@ -1,5 +1,5 @@
1
1
  import { AlertBuilder } from "./AlertBuilder";
2
- import { AlertCategory, AlertSeverity, EntityType } from "../../../types/alert.types";
2
+ import { AlertCategory, AlertSeverity, EntityType } from "./alert.types";
3
3
 
4
4
  /**
5
5
  * Example usage of AlertBuilder
@@ -123,4 +123,4 @@ export function createMultipleAlerts() {
123
123
  .build();
124
124
 
125
125
  return [alert1, alert2];
126
- }
126
+ }
@@ -3,15 +3,15 @@ import {
3
3
  AlertCategory,
4
4
  AlertSeverity,
5
5
  EntityType,
6
- } from "../../../types/alert.types";
6
+ } from "./alert.types";
7
7
 
8
8
  /**
9
9
  * AlertBuilder - A builder pattern implementation for constructing CreateAlertData objects
10
- *
10
+ *
11
11
  * This builder provides a fluent interface for creating alert data with proper validation
12
12
  * and default values. It follows the Builder pattern which is a standard design pattern
13
13
  * in TypeScript for constructing complex objects.
14
- *
14
+ *
15
15
  * Usage example:
16
16
  * const alertData = new AlertBuilder()
17
17
  * .setCategory(AlertCategory.OPERATIONS)
@@ -120,8 +120,16 @@ export class AlertBuilder {
120
120
  * Validates that all required fields are present
121
121
  */
122
122
  private validate(): void {
123
- const requiredFields = ["category", "propertyId", "title", "description", "entityType"];
124
- const missingFields = requiredFields.filter(field => !this.data[field as keyof CreateAlertData]);
123
+ const requiredFields = [
124
+ "category",
125
+ "propertyId",
126
+ "title",
127
+ "description",
128
+ "entityType",
129
+ ];
130
+ const missingFields = requiredFields.filter(
131
+ (field) => !this.data[field as keyof CreateAlertData]
132
+ );
125
133
 
126
134
  if (missingFields.length > 0) {
127
135
  throw new Error(`Missing required fields: ${missingFields.join(", ")}`);
@@ -197,6 +205,4 @@ export class AlertBuilder {
197
205
  .setEntityId(hubId)
198
206
  .setPropertyId(propertyId);
199
207
  }
200
-
201
-
202
- }
208
+ }
@@ -1,6 +1,6 @@
1
1
  import { AlertService } from "./Alert.service";
2
- import { AlertBuilder } from "../entities/AlertBuilder";
3
- import { AlertCategory, AlertSeverity, EntityType } from "../../../types/alert.types";
2
+ import { AlertBuilder } from "./AlertBuilder";
3
+ import { AlertCategory, AlertSeverity, EntityType } from "./alert.types";
4
4
 
5
5
  /**
6
6
  * Example usage of the updated AlertService with AlertBuilder integration
@@ -215,15 +215,16 @@ export class AlertServiceExample {
215
215
  category: AlertCategory.OPERATIONS,
216
216
  propertyId: "prop123",
217
217
  title: "Legacy Alert",
218
- description: "This alert was created using the old CreateAlertData format",
218
+ description:
219
+ "This alert was created using the old CreateAlertData format",
219
220
  entityId: "device456",
220
221
  entityType: EntityType.DEVICE,
221
222
  severity: AlertSeverity.MEDIUM,
222
- createdBy: "legacy-system"
223
+ createdBy: "legacy-system",
223
224
  };
224
225
 
225
226
  // This still works with the updated createAlert method
226
227
  const alert = await this.alertService.createAlert(alertData);
227
228
  return alert;
228
229
  }
229
- }
230
+ }
@@ -1,4 +1,4 @@
1
- import { EntityType } from "./issue.types";
1
+ import { EntityType } from "../issues/issue.types";
2
2
 
3
3
  export enum AlertCategory {
4
4
  READINESS = "READINESS",
@@ -61,4 +61,4 @@ export interface UpdateAlertData {
61
61
  }
62
62
 
63
63
  // Re-export EntityType from issue.types.ts to avoid duplication
64
- export { EntityType } from "./issue.types";
64
+ export { EntityType } from "../issues/issue.types";
@@ -0,0 +1,3 @@
1
+ export * from "./Alert.service";
2
+ export * from "./AlertBuilder";
3
+ export * from "./alert.types";
@@ -1,17 +1,17 @@
1
- import { DeviceConfig } from "../types";
2
1
  import { initializeAudit } from "dt-audit-library";
3
- import { connectDatabase } from "../db/db";
2
+ import { connectDatabase } from "src/db/db";
4
3
  import dotenv from "dotenv";
5
- import { InternalEventSubscription } from "../events";
6
- import { validateServiceUrl } from "../utils/http.utils";
4
+ import { InternalEventSubscription } from "src/events";
5
+ import { validateServiceUrl } from "src/utils/http.utils";
6
+ import { IConfig } from "./config.types";
7
7
 
8
8
  dotenv.config();
9
9
 
10
- let config: DeviceConfig | null = null;
10
+ let config: IConfig | null = null;
11
11
  let auditInitialized = false;
12
12
  let eventSubscription: InternalEventSubscription | null = null;
13
13
 
14
- export async function initialize(cfg: DeviceConfig): Promise<void> {
14
+ export async function initialize(cfg: IConfig): Promise<void> {
15
15
  // Initialize config
16
16
  config = { ...cfg };
17
17
 
@@ -77,7 +77,7 @@ export async function initialize(cfg: DeviceConfig): Promise<void> {
77
77
  console.log("dt-common-device: Initialization completed successfully");
78
78
  }
79
79
 
80
- export function getConfig(): DeviceConfig {
80
+ export function getConfig(): IConfig {
81
81
  if (!config) {
82
82
  throw new Error(
83
83
  "dt-common-device: Library not initialized. Call initialize() first."
@@ -8,7 +8,7 @@ export interface ILogger {
8
8
 
9
9
  type AllowedSource = "ACCESS_SERVICE" | "ADMIN_SERVICE" | "ENERGY_SERVICE";
10
10
 
11
- export type DeviceConfig = {
11
+ export type IConfig = {
12
12
  SOURCE: AllowedSource;
13
13
  SQS_QUEUE_URL: string;
14
14
  DEVICE_SERVICE?: string;
@@ -1,5 +1,5 @@
1
- import { getPostgresClient } from "../../../db";
2
- import { IConnection } from "../interfaces/IConnection";
1
+ import { getPostgresClient } from "src/db";
2
+ import { IConnection } from "./IConnection";
3
3
  import { Service } from "typedi";
4
4
 
5
5
  @Service()
@@ -1,6 +1,6 @@
1
1
  import { Container } from "typedi";
2
- import { ConnectionRepository } from "../repository/Connection.repository";
3
- import { IConnection } from "../interfaces/IConnection";
2
+ import { ConnectionRepository } from "./Connection.repository";
3
+ import { IConnection } from "./IConnection";
4
4
 
5
5
  export class LocalConnectionService {
6
6
  private readonly connectionRepository: ConnectionRepository;
@@ -0,0 +1,3 @@
1
+ export * from "./IConnection";
2
+ export * from "./Connection.service";
3
+
@@ -1,7 +1,7 @@
1
- import { IDevice } from "../../local/interfaces";
1
+ import { IDevice } from "src/device/local/interfaces";
2
2
  import { ICloudDevice } from "../interfaces/ICloudDevice";
3
3
  import { ICloudDeviceService } from "../interfaces/ICloudDeviceService";
4
- import { IConnection } from "../../local/interfaces/IConnection";
4
+ import { IConnection } from "src/connection";
5
5
 
6
6
  export abstract class CloudDevice implements ICloudDevice {
7
7
  deviceId: string;
@@ -1,5 +1,5 @@
1
1
  import { ICloudDeviceService } from "../interfaces/ICloudDeviceService";
2
- import { IConnection } from "../../local/interfaces/IConnection";
2
+ import { IConnection } from "src/connection";
3
3
 
4
4
  export class CloudDeviceService implements ICloudDeviceService {
5
5
  async getConnection(deviceId: string): Promise<IConnection> {
@@ -1,5 +1,5 @@
1
- import { IDevice } from "../../local/interfaces";
2
- import { LocalDeviceService } from "../../local/services/Device.service";
1
+ import { IDevice } from "src/device/local/interfaces";
2
+ import { LocalDeviceService } from "src/device/local/services/Device.service";
3
3
  import { IDeviceFactory } from "../interfaces/IDeviceFactory";
4
4
 
5
5
  export class DeviceFactory implements IDeviceFactory {
@@ -1,5 +1,5 @@
1
1
  // Interface for CloudDeviceService
2
- import { IConnection } from "../../local/interfaces/IConnection";
2
+ import { IConnection } from "../../../connection";
3
3
 
4
4
  export interface ICloudDeviceService {
5
5
  getConnection(deviceId: string): Promise<IConnection>;
@@ -1,4 +1,4 @@
1
- import { IConnection } from "../../local/interfaces";
1
+ import { IConnection } from "../../../connection";
2
2
 
3
3
  export enum DeviceType {
4
4
  HUB = "HUB",
@@ -1,4 +1,3 @@
1
1
  export * from "./IDevice";
2
- export * from "./IProperty";
3
- export * from "./IConnection";
4
- export * from "./IProperty";
2
+ export * from "./IDtDevice";
3
+ export * from "./ISchedule";
@@ -1,9 +1,9 @@
1
1
  import { IDevice, IStatus } from "../interfaces/IDevice";
2
- import { getConfig } from "../../../config/config";
3
- import { getPostgresClient } from "../../../db";
2
+ import { getConfig } from "src/config/config";
3
+ import { getPostgresClient } from "src/db";
4
4
  import { Service } from "typedi";
5
5
  import { IDtDevice } from "../interfaces/IDtDevice";
6
- import { getDeviceServiceAxiosInstance } from "../../../utils/http.utils";
6
+ import { getDeviceServiceAxiosInstance } from "src/utils/http.utils";
7
7
 
8
8
  @Service()
9
9
  export class DeviceRepository {
@@ -44,6 +44,32 @@ export class DeviceRepository {
44
44
  }
45
45
  }
46
46
 
47
+ async updateDevice(deviceId: string, body: any): Promise<IDevice> {
48
+ try {
49
+ const response = await this.axiosInstance.put(
50
+ `/devices/${deviceId}`,
51
+ body
52
+ );
53
+ return response.data;
54
+ } catch (error: any) {
55
+ getConfig().LOGGER.error(`Failed to update device ${deviceId}:`, error);
56
+ throw new Error(
57
+ `Failed to update device: ${error.message || "Unknown error"}`
58
+ );
59
+ }
60
+ }
61
+
62
+ async deleteDevice(deviceId: string): Promise<void> {
63
+ try {
64
+ await this.axiosInstance.delete(`/devices/${deviceId}`);
65
+ } catch (error: any) {
66
+ getConfig().LOGGER.error(`Failed to delete device ${deviceId}:`, error);
67
+ throw new Error(
68
+ `Failed to delete device: ${error.message || "Unknown error"}`
69
+ );
70
+ }
71
+ }
72
+
47
73
  async getDevices(
48
74
  deviceIds: string[],
49
75
  withHubDetails: boolean = false
@@ -1,8 +1,8 @@
1
- import { getConfig } from "../../../config/config";
2
- import { getPostgresClient } from "../../../db";
1
+ import { getConfig } from "src/config/config";
2
+ import { getPostgresClient } from "src/db";
3
3
  import { Service } from "typedi";
4
4
  import { IDevice } from "../interfaces";
5
- import { getDeviceServiceAxiosInstance } from "../../../utils/http.utils";
5
+ import { getDeviceServiceAxiosInstance } from "src/utils/http.utils";
6
6
 
7
7
  @Service()
8
8
  export class HubRepository {
@@ -26,7 +26,7 @@ export class HubRepository {
26
26
 
27
27
  async getHubs(hubIds: string[]): Promise<IDevice[]> {
28
28
  try {
29
- const query = hubIds && hubIds.length ? `?ids=${hubIds.join(",")}` : "";
29
+ const query = hubIds?.length ? `?ids=${hubIds.join(",")}` : "";
30
30
  const response = await this.axiosInstance.get(`/devices/hubs${query}`);
31
31
  return response.data;
32
32
  } catch (error: any) {
@@ -1,7 +1,7 @@
1
1
  import { Service } from "typedi";
2
- import { getConfig } from "../../../config/config";
2
+ import { getConfig } from "src/config/config";
3
3
  import { ISchedule } from "../interfaces/ISchedule";
4
- import { getDeviceServiceAxiosInstance } from "../../../utils/http.utils";
4
+ import { getDeviceServiceAxiosInstance } from "src/utils/http.utils";
5
5
 
6
6
  @Service()
7
7
  export class ScheduleRepository {
@@ -1,5 +1,5 @@
1
1
  import { IDevice, IStatus } from "../interfaces";
2
- import { EventHandler } from "../../../events/EventHandler";
2
+ import { EventHandler } from "src/events/EventHandler";
3
3
  import { isEqual } from "lodash";
4
4
  import { DeviceRepository } from "../repository/Device.repository";
5
5
  import Container from "typedi";
@@ -74,6 +74,8 @@ export class LocalDeviceService {
74
74
  if (!deviceId) {
75
75
  throw new Error("Device ID is required");
76
76
  }
77
+
78
+ await this.deviceRepository.updateDevice(deviceId, body);
77
79
  return await this.eventHandler.onDeviceUpdate(deviceId, body);
78
80
  }
79
81
 
@@ -81,6 +83,8 @@ export class LocalDeviceService {
81
83
  if (!deviceId) {
82
84
  throw new Error("Device ID is required");
83
85
  }
86
+
87
+ await this.deviceRepository.deleteDevice(deviceId);
84
88
  return await this.eventHandler.onDeviceDelete(deviceId);
85
89
  }
86
90
 
@@ -1,7 +1,3 @@
1
- export * from "./Alert.service";
2
- export * from "./Connection.service";
3
1
  export * from "./Device.service";
4
2
  export * from "./Hub.service";
5
- export * from "./Issue.service";
6
- export * from "./Property.service";
7
3
  export * from "./Schedule.service";
@@ -20,7 +20,7 @@ This error typically occurs when HTTP requests fail due to network connectivity
20
20
 
21
21
  ```typescript
22
22
  // Ensure DEVICE_SERVICE URL is properly configured
23
- const config: DeviceConfig = {
23
+ const config: IConfig = {
24
24
  DEVICE_SERVICE: "http://localhost:3000", // or your actual service URL
25
25
  // ... other config
26
26
  };
@@ -41,7 +41,7 @@ This error typically occurs when HTTP requests fail due to network connectivity
41
41
 
42
42
  4. **Enable Debug Logging**
43
43
  ```typescript
44
- const config: DeviceConfig = {
44
+ const config: IConfig = {
45
45
  LOGGER: {
46
46
  info: (msg, ...args) => console.log(msg, ...args),
47
47
  warn: (msg, ...args) => console.warn(msg, ...args),
@@ -1,8 +1,8 @@
1
1
  import { DeviceEvent } from "./interfaces/DeviceEvent";
2
2
  import { IEventHandler } from "./interfaces/IEventHandler";
3
- import { getConfig } from "../config/config";
4
- import { ILogger } from "../types/config.types";
5
- import { LocalDeviceService } from "../device/local/services/Device.service";
3
+ import { getConfig } from "src/config/config";
4
+ import { ILogger } from "src/config/config.types";
5
+ import { LocalDeviceService } from "src/device/local/services/Device.service";
6
6
 
7
7
  export abstract class BaseEventHandler implements IEventHandler {
8
8
  protected readonly supportedEventTypes: string[];
@@ -1,5 +1,5 @@
1
- import { getConfig } from "../config/config";
2
- import { ILogger } from "../types/config.types";
1
+ import { getConfig } from "src/config/config";
2
+ import { ILogger } from "src/config/config.types";
3
3
  import { DeviceEvent } from "./interfaces/DeviceEvent";
4
4
  import { IEventTransformer } from "./interfaces/IEventTransformer";
5
5
 
@@ -1,6 +1,6 @@
1
- import { DT_EVENT_TYPES } from "../constants/Event";
2
- import { IDevice } from "../device/local/interfaces";
3
- import { LocalHubService } from "../device/local/services";
1
+ import { DT_EVENT_TYPES } from "src/constants/Event";
2
+ import { IDevice } from "src/device/local/interfaces";
3
+ import { LocalHubService } from "src/device/local/services";
4
4
  import { BaseEventHandler } from "./BaseEventHandler";
5
5
  import {
6
6
  DeviceEvent,
@@ -1,6 +1,6 @@
1
1
  import { eventDispatcher } from "dt-pub-sub";
2
2
  import { publishAudit } from "dt-audit-library";
3
- import { DT_EVENT_TYPES } from "../constants/Event";
3
+ import { DT_EVENT_TYPES } from "src/constants/Event";
4
4
 
5
5
  export class EventHandler {
6
6
  private readonly source: string;
@@ -1,8 +1,8 @@
1
1
  import { Service } from "typedi";
2
2
  import { IEventHandler } from "./interfaces/IEventHandler";
3
3
  import { DeviceEvent } from "./interfaces/DeviceEvent";
4
- import { ILogger } from "../types/config.types";
5
- import { getConfig } from "../config/config";
4
+ import { ILogger } from "src/config/config.types";
5
+ import { getConfig } from "src/config/config";
6
6
 
7
7
  @Service()
8
8
  export class EventHandlerOrchestrator {
@@ -1,7 +1,7 @@
1
1
  import { Service } from "typedi";
2
2
  import { DeviceEventHandler } from "./DeviceEventHandler";
3
- import { ILogger } from "../types/config.types";
4
- import { getConfig } from "../config/config";
3
+ import { ILogger } from "src/config/config.types";
4
+ import { getConfig } from "src/config/config";
5
5
  import { DeviceEvent } from "./interfaces/DeviceEvent";
6
6
  import { IEventTransformer } from "./interfaces/IEventTransformer";
7
7
  import { EventHandlerOrchestrator } from "./EventHandlerOrchestrator";
@@ -1,5 +1,5 @@
1
1
  import { eventDispatcher } from "dt-pub-sub";
2
- import { getConfig } from "../config/config";
2
+ import { getConfig } from "src/config/config";
3
3
  import {
4
4
  IInternalEvent,
5
5
  HeartbeatEventData,
@@ -7,7 +7,7 @@ import {
7
7
  ReservationEventData,
8
8
  ServiceEventData,
9
9
  } from "./interfaces/IInternalEvent";
10
- import { ILogger } from "../types/config.types";
10
+ import { ILogger } from "src/config/config.types";
11
11
 
12
12
  // Event types enum for better type safety
13
13
  export enum InternalEventType {