dt-common-device 6.2.1 → 7.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.
- package/dist/alerts/Alert.model.js +6 -0
- package/dist/alerts/Alert.repository.d.ts +35 -1
- package/dist/alerts/Alert.repository.js +146 -1
- package/dist/alerts/Alert.service.d.ts +41 -7
- package/dist/alerts/Alert.service.js +98 -14
- package/dist/alerts/AlertBuilder.d.ts +6 -2
- package/dist/alerts/AlertBuilder.js +17 -4
- package/dist/alerts/alert.types.d.ts +3 -0
- package/dist/entities/admin/Admin.repository.d.ts +0 -1
- package/dist/entities/admin/Admin.repository.js +1 -2
- package/dist/issues/Issue.model.js +6 -0
- package/dist/issues/Issue.repository.d.ts +14 -1
- package/dist/issues/Issue.repository.js +58 -1
- package/dist/issues/Issue.service.d.ts +14 -1
- package/dist/issues/Issue.service.js +48 -7
- package/dist/issues/IssueBuilder.d.ts +10 -6
- package/dist/issues/IssueBuilder.js +27 -10
- package/dist/issues/issue.types.d.ts +3 -0
- package/dist/utils/http.utils.js +1 -1
- package/package.json +1 -1
|
@@ -48,6 +48,11 @@ const AlertSchema = new mongoose_1.Schema({
|
|
|
48
48
|
required: true,
|
|
49
49
|
index: true,
|
|
50
50
|
},
|
|
51
|
+
zoneId: {
|
|
52
|
+
type: String,
|
|
53
|
+
required: true,
|
|
54
|
+
index: true,
|
|
55
|
+
},
|
|
51
56
|
title: {
|
|
52
57
|
type: String,
|
|
53
58
|
required: true,
|
|
@@ -116,6 +121,7 @@ const AlertSchema = new mongoose_1.Schema({
|
|
|
116
121
|
exports.AlertSchema = AlertSchema;
|
|
117
122
|
// Compound indexes to match Prisma schema
|
|
118
123
|
AlertSchema.index({ propertyId: 1, isActive: 1, isRead: 1 });
|
|
124
|
+
AlertSchema.index({ zoneId: 1, category: 1 });
|
|
119
125
|
AlertSchema.index({ entityId: 1, entityType: 1 });
|
|
120
126
|
AlertSchema.index({ createdAt: 1 });
|
|
121
127
|
// Pre-save middleware to update the updatedAt field
|
|
@@ -45,7 +45,7 @@ export declare class AlertRepository {
|
|
|
45
45
|
/**
|
|
46
46
|
* Get alert statistics
|
|
47
47
|
*/
|
|
48
|
-
getStatistics(propertyId?: string): Promise<{
|
|
48
|
+
getStatistics(propertyId?: string, zoneId?: string): Promise<{
|
|
49
49
|
total: number;
|
|
50
50
|
active: number;
|
|
51
51
|
unread: number;
|
|
@@ -61,4 +61,38 @@ export declare class AlertRepository {
|
|
|
61
61
|
* Bulk soft delete alerts
|
|
62
62
|
*/
|
|
63
63
|
bulkSoftDelete(ids: string[], deletedBy: string): Promise<number>;
|
|
64
|
+
/**
|
|
65
|
+
* Find alerts by zone ID
|
|
66
|
+
*/
|
|
67
|
+
findByZoneId(zoneId: string, includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Find alerts by zone ID and category
|
|
70
|
+
*/
|
|
71
|
+
findByZoneIdAndCategory(zoneId: string, category: AlertCategory, includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
72
|
+
/**
|
|
73
|
+
* Find alerts by zone ID and severity
|
|
74
|
+
*/
|
|
75
|
+
findByZoneIdAndSeverity(zoneId: string, severity: AlertSeverity, includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Find alerts by zone ID and active status
|
|
78
|
+
*/
|
|
79
|
+
findByZoneIdAndActiveStatus(zoneId: string, isActive: boolean, includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Find alerts by zone ID and read status
|
|
82
|
+
*/
|
|
83
|
+
findByZoneIdAndReadStatus(zoneId: string, isRead: boolean, includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Find alerts by multiple zone IDs
|
|
86
|
+
*/
|
|
87
|
+
findByZoneIds(zoneIds: string[], includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
88
|
+
/**
|
|
89
|
+
* Get alert statistics by zone ID and severity
|
|
90
|
+
*/
|
|
91
|
+
getStatisticsByZoneAndSeverity(zoneId: string, severity?: AlertSeverity): Promise<{
|
|
92
|
+
total: number;
|
|
93
|
+
active: number;
|
|
94
|
+
unread: number;
|
|
95
|
+
snoozed: number;
|
|
96
|
+
byCategory: Record<AlertCategory, number>;
|
|
97
|
+
}>;
|
|
64
98
|
}
|
|
@@ -52,6 +52,8 @@ let AlertRepository = (() => {
|
|
|
52
52
|
const query = {};
|
|
53
53
|
if (filters.propertyId)
|
|
54
54
|
query.propertyId = filters.propertyId;
|
|
55
|
+
if (filters.zoneId)
|
|
56
|
+
query.zoneId = filters.zoneId;
|
|
55
57
|
if (filters.category)
|
|
56
58
|
query.category = filters.category;
|
|
57
59
|
if (filters.severity)
|
|
@@ -215,11 +217,13 @@ let AlertRepository = (() => {
|
|
|
215
217
|
/**
|
|
216
218
|
* Get alert statistics
|
|
217
219
|
*/
|
|
218
|
-
async getStatistics(propertyId) {
|
|
220
|
+
async getStatistics(propertyId, zoneId) {
|
|
219
221
|
try {
|
|
220
222
|
const query = { isDeleted: false };
|
|
221
223
|
if (propertyId)
|
|
222
224
|
query.propertyId = propertyId;
|
|
225
|
+
if (zoneId)
|
|
226
|
+
query.zoneId = zoneId;
|
|
223
227
|
const [total, active, unread, snoozed, severityStats, categoryStats] = await Promise.all([
|
|
224
228
|
Alert_model_1.AlertModel.countDocuments(query),
|
|
225
229
|
Alert_model_1.AlertModel.countDocuments({ ...query, isActive: true }),
|
|
@@ -297,6 +301,147 @@ let AlertRepository = (() => {
|
|
|
297
301
|
throw new Error(`Failed to bulk soft delete alerts: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
298
302
|
}
|
|
299
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Find alerts by zone ID
|
|
306
|
+
*/
|
|
307
|
+
async findByZoneId(zoneId, includeDeleted = false) {
|
|
308
|
+
try {
|
|
309
|
+
const query = { zoneId };
|
|
310
|
+
if (!includeDeleted) {
|
|
311
|
+
query.isDeleted = false;
|
|
312
|
+
}
|
|
313
|
+
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
|
|
314
|
+
return results.map((result) => result.toObject());
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
throw new Error(`Failed to find alerts by zone ID: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Find alerts by zone ID and category
|
|
322
|
+
*/
|
|
323
|
+
async findByZoneIdAndCategory(zoneId, category, includeDeleted = false) {
|
|
324
|
+
try {
|
|
325
|
+
const query = { zoneId, category };
|
|
326
|
+
if (!includeDeleted) {
|
|
327
|
+
query.isDeleted = false;
|
|
328
|
+
}
|
|
329
|
+
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
|
|
330
|
+
return results.map((result) => result.toObject());
|
|
331
|
+
}
|
|
332
|
+
catch (error) {
|
|
333
|
+
throw new Error(`Failed to find alerts by zone ID and category: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Find alerts by zone ID and severity
|
|
338
|
+
*/
|
|
339
|
+
async findByZoneIdAndSeverity(zoneId, severity, includeDeleted = false) {
|
|
340
|
+
try {
|
|
341
|
+
const query = { zoneId, severity };
|
|
342
|
+
if (!includeDeleted) {
|
|
343
|
+
query.isDeleted = false;
|
|
344
|
+
}
|
|
345
|
+
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
|
|
346
|
+
return results.map((result) => result.toObject());
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
throw new Error(`Failed to find alerts by zone ID and severity: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Find alerts by zone ID and active status
|
|
354
|
+
*/
|
|
355
|
+
async findByZoneIdAndActiveStatus(zoneId, isActive, includeDeleted = false) {
|
|
356
|
+
try {
|
|
357
|
+
const query = { zoneId, isActive };
|
|
358
|
+
if (!includeDeleted) {
|
|
359
|
+
query.isDeleted = false;
|
|
360
|
+
}
|
|
361
|
+
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
|
|
362
|
+
return results.map((result) => result.toObject());
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
throw new Error(`Failed to find alerts by zone ID and active status: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Find alerts by zone ID and read status
|
|
370
|
+
*/
|
|
371
|
+
async findByZoneIdAndReadStatus(zoneId, isRead, includeDeleted = false) {
|
|
372
|
+
try {
|
|
373
|
+
const query = { zoneId, isRead };
|
|
374
|
+
if (!includeDeleted) {
|
|
375
|
+
query.isDeleted = false;
|
|
376
|
+
}
|
|
377
|
+
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
|
|
378
|
+
return results.map((result) => result.toObject());
|
|
379
|
+
}
|
|
380
|
+
catch (error) {
|
|
381
|
+
throw new Error(`Failed to find alerts by zone ID and read status: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Find alerts by multiple zone IDs
|
|
386
|
+
*/
|
|
387
|
+
async findByZoneIds(zoneIds, includeDeleted = false) {
|
|
388
|
+
try {
|
|
389
|
+
if (!zoneIds || zoneIds.length === 0) {
|
|
390
|
+
throw new Error("Zone IDs array is required and cannot be empty");
|
|
391
|
+
}
|
|
392
|
+
const query = { zoneId: { $in: zoneIds } };
|
|
393
|
+
if (!includeDeleted) {
|
|
394
|
+
query.isDeleted = false;
|
|
395
|
+
}
|
|
396
|
+
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
|
|
397
|
+
return results.map((result) => result.toObject());
|
|
398
|
+
}
|
|
399
|
+
catch (error) {
|
|
400
|
+
throw new Error(`Failed to find alerts by zone IDs: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Get alert statistics by zone ID and severity
|
|
405
|
+
*/
|
|
406
|
+
async getStatisticsByZoneAndSeverity(zoneId, severity) {
|
|
407
|
+
try {
|
|
408
|
+
const query = { isDeleted: false, zoneId };
|
|
409
|
+
if (severity)
|
|
410
|
+
query.severity = severity;
|
|
411
|
+
const [total, active, unread, snoozed, categoryStats] = await Promise.all([
|
|
412
|
+
Alert_model_1.AlertModel.countDocuments(query),
|
|
413
|
+
Alert_model_1.AlertModel.countDocuments({ ...query, isActive: true }),
|
|
414
|
+
Alert_model_1.AlertModel.countDocuments({ ...query, isRead: false }),
|
|
415
|
+
Alert_model_1.AlertModel.countDocuments({
|
|
416
|
+
...query,
|
|
417
|
+
snoozeUntil: { $exists: true, $ne: null },
|
|
418
|
+
}),
|
|
419
|
+
Alert_model_1.AlertModel.aggregate([
|
|
420
|
+
{ $match: query },
|
|
421
|
+
{ $group: { _id: "$category", count: { $sum: 1 } } },
|
|
422
|
+
]),
|
|
423
|
+
]);
|
|
424
|
+
const byCategory = Object.values(alert_types_1.AlertCategory).reduce((acc, category) => {
|
|
425
|
+
acc[category] = 0;
|
|
426
|
+
return acc;
|
|
427
|
+
}, {});
|
|
428
|
+
categoryStats.forEach((stat) => {
|
|
429
|
+
if (stat._id in byCategory) {
|
|
430
|
+
byCategory[stat._id] = stat.count;
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
return {
|
|
434
|
+
total,
|
|
435
|
+
active,
|
|
436
|
+
unread,
|
|
437
|
+
snoozed,
|
|
438
|
+
byCategory,
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
catch (error) {
|
|
442
|
+
throw new Error(`Failed to get alert statistics by zone and severity: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
300
445
|
};
|
|
301
446
|
__setFunctionName(_classThis, "AlertRepository");
|
|
302
447
|
(() => {
|
|
@@ -9,27 +9,27 @@ export declare class AlertService {
|
|
|
9
9
|
/**
|
|
10
10
|
* Create a readiness alert using AlertBuilder
|
|
11
11
|
*/
|
|
12
|
-
raiseReadinessAlert(propertyId: string, title: string, description: string, entityId?: string, entityType?: EntityType, createdBy?: string): Promise<IAlertDocument>;
|
|
12
|
+
raiseReadinessAlert(propertyId: string, zoneId: string, title: string, description: string, entityId?: string, entityType?: EntityType, createdBy?: string): Promise<IAlertDocument>;
|
|
13
13
|
/**
|
|
14
14
|
* Create an operations alert using AlertBuilder
|
|
15
15
|
*/
|
|
16
|
-
raiseOperationsAlert(propertyId: string, title: string, description: string, entityId?: string, entityType?: EntityType, createdBy?: string): Promise<IAlertDocument>;
|
|
16
|
+
raiseOperationsAlert(propertyId: string, zoneId: string, title: string, description: string, entityId?: string, entityType?: EntityType, createdBy?: string): Promise<IAlertDocument>;
|
|
17
17
|
/**
|
|
18
18
|
* Create a security alert using AlertBuilder
|
|
19
19
|
*/
|
|
20
|
-
raiseSecurityAlert(propertyId: string, title: string, description: string, entityId?: string, entityType?: EntityType, createdBy?: string): Promise<IAlertDocument>;
|
|
20
|
+
raiseSecurityAlert(propertyId: string, zoneId: string, title: string, description: string, entityId?: string, entityType?: EntityType, createdBy?: string): Promise<IAlertDocument>;
|
|
21
21
|
/**
|
|
22
22
|
* Create an energy alert using AlertBuilder
|
|
23
23
|
*/
|
|
24
|
-
raiseEnergyAlert(propertyId: string, title: string, description: string, entityId?: string, entityType?: EntityType, createdBy?: string): Promise<IAlertDocument>;
|
|
24
|
+
raiseEnergyAlert(propertyId: string, zoneId: string, title: string, description: string, entityId?: string, entityType?: EntityType, createdBy?: string): Promise<IAlertDocument>;
|
|
25
25
|
/**
|
|
26
26
|
* Create a device-specific alert using AlertBuilder
|
|
27
27
|
*/
|
|
28
|
-
raiseDeviceAlert(deviceId: string, propertyId: string, title: string, description: string, category?: AlertCategory, severity?: AlertSeverity, source?: Source): Promise<IAlertDocument>;
|
|
28
|
+
raiseDeviceAlert(deviceId: string, propertyId: string, zoneId: string, title: string, description: string, category?: AlertCategory, severity?: AlertSeverity, source?: Source): Promise<IAlertDocument>;
|
|
29
29
|
/**
|
|
30
30
|
* Create a hub-specific alert using AlertBuilder
|
|
31
31
|
*/
|
|
32
|
-
raiseHubAlert(hubId: string, propertyId: string, title: string, description: string, category?: AlertCategory, severity?: AlertSeverity, createdBy?: string): Promise<IAlertDocument>;
|
|
32
|
+
raiseHubAlert(hubId: string, propertyId: string, zoneId: string, title: string, description: string, category?: AlertCategory, severity?: AlertSeverity, createdBy?: string): Promise<IAlertDocument>;
|
|
33
33
|
/**
|
|
34
34
|
* Raise alert for device going offline (OPERATIONAL only)
|
|
35
35
|
*/
|
|
@@ -106,7 +106,7 @@ export declare class AlertService {
|
|
|
106
106
|
/**
|
|
107
107
|
* Get alert statistics with business logic
|
|
108
108
|
*/
|
|
109
|
-
getAlertStatistics(propertyId?: string): Promise<{
|
|
109
|
+
getAlertStatistics(propertyId?: string, zoneId?: string): Promise<{
|
|
110
110
|
total: number;
|
|
111
111
|
active: number;
|
|
112
112
|
unread: number;
|
|
@@ -114,6 +114,40 @@ export declare class AlertService {
|
|
|
114
114
|
bySeverity: Record<AlertSeverity, number>;
|
|
115
115
|
byCategory: Record<AlertCategory, number>;
|
|
116
116
|
}>;
|
|
117
|
+
/**
|
|
118
|
+
* Get alerts by zone ID
|
|
119
|
+
*/
|
|
120
|
+
getAlertsByZoneId(zoneId: string, includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
121
|
+
/**
|
|
122
|
+
* Get alerts by zone ID and category
|
|
123
|
+
*/
|
|
124
|
+
getAlertsByZoneIdAndCategory(zoneId: string, category: AlertCategory, includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
125
|
+
/**
|
|
126
|
+
* Get alerts by zone ID and severity
|
|
127
|
+
*/
|
|
128
|
+
getAlertsByZoneIdAndSeverity(zoneId: string, severity: AlertSeverity, includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
129
|
+
/**
|
|
130
|
+
* Get alerts by multiple zone IDs
|
|
131
|
+
*/
|
|
132
|
+
getAlertsByZoneIds(zoneIds: string[], includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
133
|
+
/**
|
|
134
|
+
* Get alert statistics by zone ID and severity
|
|
135
|
+
*/
|
|
136
|
+
getAlertStatisticsByZoneAndSeverity(zoneId: string, severity?: AlertSeverity): Promise<{
|
|
137
|
+
total: number;
|
|
138
|
+
active: number;
|
|
139
|
+
unread: number;
|
|
140
|
+
snoozed: number;
|
|
141
|
+
byCategory: Record<AlertCategory, number>;
|
|
142
|
+
}>;
|
|
143
|
+
/**
|
|
144
|
+
* Get alerts by zone ID and active status
|
|
145
|
+
*/
|
|
146
|
+
getAlertsByZoneIdAndActiveStatus(zoneId: string, isActive: boolean, includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
147
|
+
/**
|
|
148
|
+
* Get alerts by zone ID and read status
|
|
149
|
+
*/
|
|
150
|
+
getAlertsByZoneIdAndReadStatus(zoneId: string, isRead: boolean, includeDeleted?: boolean): Promise<IAlertDocument[]>;
|
|
117
151
|
private validateAlertData;
|
|
118
152
|
private validateFilters;
|
|
119
153
|
private validateUpdateData;
|
|
@@ -89,9 +89,10 @@ let AlertService = (() => {
|
|
|
89
89
|
/**
|
|
90
90
|
* Create a readiness alert using AlertBuilder
|
|
91
91
|
*/
|
|
92
|
-
async raiseReadinessAlert(propertyId, title, description, entityId, entityType, createdBy) {
|
|
92
|
+
async raiseReadinessAlert(propertyId, zoneId, title, description, entityId, entityType, createdBy) {
|
|
93
93
|
const alertBuilder = AlertBuilder_1.AlertBuilder.createReadinessAlert()
|
|
94
94
|
.setPropertyId(propertyId)
|
|
95
|
+
.setZoneId(zoneId)
|
|
95
96
|
.setTitle(title)
|
|
96
97
|
.setDescription(description);
|
|
97
98
|
if (entityId)
|
|
@@ -105,9 +106,10 @@ let AlertService = (() => {
|
|
|
105
106
|
/**
|
|
106
107
|
* Create an operations alert using AlertBuilder
|
|
107
108
|
*/
|
|
108
|
-
async raiseOperationsAlert(propertyId, title, description, entityId, entityType, createdBy) {
|
|
109
|
+
async raiseOperationsAlert(propertyId, zoneId, title, description, entityId, entityType, createdBy) {
|
|
109
110
|
const alertBuilder = AlertBuilder_1.AlertBuilder.createOperationsAlert()
|
|
110
111
|
.setPropertyId(propertyId)
|
|
112
|
+
.setZoneId(zoneId)
|
|
111
113
|
.setTitle(title)
|
|
112
114
|
.setDescription(description);
|
|
113
115
|
if (entityId)
|
|
@@ -121,9 +123,10 @@ let AlertService = (() => {
|
|
|
121
123
|
/**
|
|
122
124
|
* Create a security alert using AlertBuilder
|
|
123
125
|
*/
|
|
124
|
-
async raiseSecurityAlert(propertyId, title, description, entityId, entityType, createdBy) {
|
|
126
|
+
async raiseSecurityAlert(propertyId, zoneId, title, description, entityId, entityType, createdBy) {
|
|
125
127
|
const alertBuilder = AlertBuilder_1.AlertBuilder.createSecurityAlert()
|
|
126
128
|
.setPropertyId(propertyId)
|
|
129
|
+
.setZoneId(zoneId)
|
|
127
130
|
.setTitle(title)
|
|
128
131
|
.setDescription(description);
|
|
129
132
|
if (entityId)
|
|
@@ -137,9 +140,10 @@ let AlertService = (() => {
|
|
|
137
140
|
/**
|
|
138
141
|
* Create an energy alert using AlertBuilder
|
|
139
142
|
*/
|
|
140
|
-
async raiseEnergyAlert(propertyId, title, description, entityId, entityType, createdBy) {
|
|
143
|
+
async raiseEnergyAlert(propertyId, zoneId, title, description, entityId, entityType, createdBy) {
|
|
141
144
|
const alertBuilder = AlertBuilder_1.AlertBuilder.createEnergyAlert()
|
|
142
145
|
.setPropertyId(propertyId)
|
|
146
|
+
.setZoneId(zoneId)
|
|
143
147
|
.setTitle(title)
|
|
144
148
|
.setDescription(description);
|
|
145
149
|
if (entityId)
|
|
@@ -153,8 +157,8 @@ let AlertService = (() => {
|
|
|
153
157
|
/**
|
|
154
158
|
* Create a device-specific alert using AlertBuilder
|
|
155
159
|
*/
|
|
156
|
-
async raiseDeviceAlert(deviceId, propertyId, title, description, category, severity, source) {
|
|
157
|
-
const alertBuilder = AlertBuilder_1.AlertBuilder.createDeviceAlert(deviceId, propertyId)
|
|
160
|
+
async raiseDeviceAlert(deviceId, propertyId, zoneId, title, description, category, severity, source) {
|
|
161
|
+
const alertBuilder = AlertBuilder_1.AlertBuilder.createDeviceAlert(deviceId, propertyId, zoneId)
|
|
158
162
|
.setTitle(title)
|
|
159
163
|
.setDescription(description);
|
|
160
164
|
if (category)
|
|
@@ -168,8 +172,8 @@ let AlertService = (() => {
|
|
|
168
172
|
/**
|
|
169
173
|
* Create a hub-specific alert using AlertBuilder
|
|
170
174
|
*/
|
|
171
|
-
async raiseHubAlert(hubId, propertyId, title, description, category, severity, createdBy) {
|
|
172
|
-
const alertBuilder = AlertBuilder_1.AlertBuilder.createHubAlert(hubId, propertyId)
|
|
175
|
+
async raiseHubAlert(hubId, propertyId, zoneId, title, description, category, severity, createdBy) {
|
|
176
|
+
const alertBuilder = AlertBuilder_1.AlertBuilder.createHubAlert(hubId, propertyId, zoneId)
|
|
173
177
|
.setTitle(title)
|
|
174
178
|
.setDescription(description);
|
|
175
179
|
if (category)
|
|
@@ -184,25 +188,25 @@ let AlertService = (() => {
|
|
|
184
188
|
* Raise alert for device going offline (OPERATIONAL only)
|
|
185
189
|
*/
|
|
186
190
|
async raiseDeviceOfflineAlert(device, source, reason) {
|
|
187
|
-
return await this.raiseDeviceAlert(device.deviceId, device.propertyId, "Device Offline", `Device ${device.name} (${device.deviceId}) has gone offline. ${reason ? `Reason: ${reason}` : ""}`, alert_types_1.AlertCategory.OPERATIONS, alert_types_1.AlertSeverity.HIGH, source);
|
|
191
|
+
return await this.raiseDeviceAlert(device.deviceId, device.propertyId, device.zoneId, "Device Offline", `Device ${device.name} (${device.deviceId}) has gone offline. ${reason ? `Reason: ${reason}` : ""}`, alert_types_1.AlertCategory.OPERATIONS, alert_types_1.AlertSeverity.HIGH, source);
|
|
188
192
|
}
|
|
189
193
|
/**
|
|
190
194
|
* Raise alert for device coming online (OPERATIONAL only)
|
|
191
195
|
*/
|
|
192
196
|
async raiseDeviceOnlineAlert(device, source, reason) {
|
|
193
|
-
return await this.raiseDeviceAlert(device.deviceId, device.propertyId, "Device Online", `Device ${device.name} (${device.deviceId}) is now online. ${reason ? `Reason: ${reason}` : ""}`, alert_types_1.AlertCategory.OPERATIONS, alert_types_1.AlertSeverity.INFO, source);
|
|
197
|
+
return await this.raiseDeviceAlert(device.deviceId, device.propertyId, device.zoneId, "Device Online", `Device ${device.name} (${device.deviceId}) is now online. ${reason ? `Reason: ${reason}` : ""}`, alert_types_1.AlertCategory.OPERATIONS, alert_types_1.AlertSeverity.INFO, source);
|
|
194
198
|
}
|
|
195
199
|
/**
|
|
196
200
|
* Raise alert for device battery level below threshold (READINESS + OPERATIONAL + ENERGY)
|
|
197
201
|
*/
|
|
198
202
|
async raiseDeviceBatteryAlert(device, batteryLevel, threshold, source) {
|
|
199
|
-
return await this.raiseDeviceAlert(device.deviceId, device.propertyId, "Device Battery Low", `Device ${device.name} (${device.deviceId}) battery level is ${batteryLevel}%, which is below the property threshold of ${threshold}%.`, alert_types_1.AlertCategory.ENERGY, alert_types_1.AlertSeverity.MEDIUM, source);
|
|
203
|
+
return await this.raiseDeviceAlert(device.deviceId, device.propertyId, device.zoneId, "Device Battery Low", `Device ${device.name} (${device.deviceId}) battery level is ${batteryLevel}%, which is below the property threshold of ${threshold}%.`, alert_types_1.AlertCategory.ENERGY, alert_types_1.AlertSeverity.MEDIUM, source);
|
|
200
204
|
}
|
|
201
205
|
/**
|
|
202
206
|
* Raise alert for device issue (jammed or malfunctioned) (READINESS + OPERATIONAL)
|
|
203
207
|
*/
|
|
204
208
|
async raiseDeviceIssueAlert(device, issueType, source, reason) {
|
|
205
|
-
return await this.raiseDeviceAlert(device.deviceId, device.propertyId, `Device Issue - ${issueType}`, `Device ${device.name} (${device.deviceId}) has an issue: ${issueType}. ${reason ? `Reason: ${reason}` : ""}`, alert_types_1.AlertCategory.READINESS, alert_types_1.AlertSeverity.HIGH, source);
|
|
209
|
+
return await this.raiseDeviceAlert(device.deviceId, device.propertyId, device.zoneId, `Device Issue - ${issueType}`, `Device ${device.name} (${device.deviceId}) has an issue: ${issueType}. ${reason ? `Reason: ${reason}` : ""}`, alert_types_1.AlertCategory.READINESS, alert_types_1.AlertSeverity.HIGH, source);
|
|
206
210
|
}
|
|
207
211
|
/**
|
|
208
212
|
* Create a new alert with business logic validation
|
|
@@ -401,8 +405,8 @@ let AlertService = (() => {
|
|
|
401
405
|
/**
|
|
402
406
|
* Get alert statistics with business logic
|
|
403
407
|
*/
|
|
404
|
-
async getAlertStatistics(propertyId) {
|
|
405
|
-
const stats = await this.alertRepository.getStatistics(propertyId);
|
|
408
|
+
async getAlertStatistics(propertyId, zoneId) {
|
|
409
|
+
const stats = await this.alertRepository.getStatistics(propertyId, zoneId);
|
|
406
410
|
// Business logic: Add alerts for critical metrics
|
|
407
411
|
if (stats.unread > 0) {
|
|
408
412
|
console.warn(`Alert: ${stats.unread} unread alerts require attention`);
|
|
@@ -415,6 +419,83 @@ let AlertService = (() => {
|
|
|
415
419
|
}
|
|
416
420
|
return stats;
|
|
417
421
|
}
|
|
422
|
+
/**
|
|
423
|
+
* Get alerts by zone ID
|
|
424
|
+
*/
|
|
425
|
+
async getAlertsByZoneId(zoneId, includeDeleted = false) {
|
|
426
|
+
if (!zoneId) {
|
|
427
|
+
throw new Error("Zone ID is required");
|
|
428
|
+
}
|
|
429
|
+
return await this.alertRepository.findByZoneId(zoneId, includeDeleted);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Get alerts by zone ID and category
|
|
433
|
+
*/
|
|
434
|
+
async getAlertsByZoneIdAndCategory(zoneId, category, includeDeleted = false) {
|
|
435
|
+
if (!zoneId) {
|
|
436
|
+
throw new Error("Zone ID is required");
|
|
437
|
+
}
|
|
438
|
+
if (!category) {
|
|
439
|
+
throw new Error("Alert category is required");
|
|
440
|
+
}
|
|
441
|
+
return await this.alertRepository.findByZoneIdAndCategory(zoneId, category, includeDeleted);
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Get alerts by zone ID and severity
|
|
445
|
+
*/
|
|
446
|
+
async getAlertsByZoneIdAndSeverity(zoneId, severity, includeDeleted = false) {
|
|
447
|
+
if (!zoneId) {
|
|
448
|
+
throw new Error("Zone ID is required");
|
|
449
|
+
}
|
|
450
|
+
if (!severity) {
|
|
451
|
+
throw new Error("Alert severity is required");
|
|
452
|
+
}
|
|
453
|
+
return await this.alertRepository.findByZoneIdAndSeverity(zoneId, severity, includeDeleted);
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Get alerts by multiple zone IDs
|
|
457
|
+
*/
|
|
458
|
+
async getAlertsByZoneIds(zoneIds, includeDeleted = false) {
|
|
459
|
+
if (!zoneIds || zoneIds.length === 0) {
|
|
460
|
+
throw new Error("Zone IDs array is required and cannot be empty");
|
|
461
|
+
}
|
|
462
|
+
return await this.alertRepository.findByZoneIds(zoneIds, includeDeleted);
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Get alert statistics by zone ID and severity
|
|
466
|
+
*/
|
|
467
|
+
async getAlertStatisticsByZoneAndSeverity(zoneId, severity) {
|
|
468
|
+
if (!zoneId) {
|
|
469
|
+
throw new Error("Zone ID is required");
|
|
470
|
+
}
|
|
471
|
+
const stats = await this.alertRepository.getStatisticsByZoneAndSeverity(zoneId, severity);
|
|
472
|
+
// Business logic: Add alerts for critical metrics
|
|
473
|
+
if (stats.unread > 0) {
|
|
474
|
+
console.warn(`Alert: ${stats.unread} unread alerts in zone ${zoneId} require attention`);
|
|
475
|
+
}
|
|
476
|
+
if (severity === alert_types_1.AlertSeverity.CRITICAL && stats.total > 0) {
|
|
477
|
+
console.error(`Alert: ${stats.total} critical alerts in zone ${zoneId} require immediate attention`);
|
|
478
|
+
}
|
|
479
|
+
return stats;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Get alerts by zone ID and active status
|
|
483
|
+
*/
|
|
484
|
+
async getAlertsByZoneIdAndActiveStatus(zoneId, isActive, includeDeleted = false) {
|
|
485
|
+
if (!zoneId) {
|
|
486
|
+
throw new Error("Zone ID is required");
|
|
487
|
+
}
|
|
488
|
+
return await this.alertRepository.findByZoneIdAndActiveStatus(zoneId, isActive, includeDeleted);
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Get alerts by zone ID and read status
|
|
492
|
+
*/
|
|
493
|
+
async getAlertsByZoneIdAndReadStatus(zoneId, isRead, includeDeleted = false) {
|
|
494
|
+
if (!zoneId) {
|
|
495
|
+
throw new Error("Zone ID is required");
|
|
496
|
+
}
|
|
497
|
+
return await this.alertRepository.findByZoneIdAndReadStatus(zoneId, isRead, includeDeleted);
|
|
498
|
+
}
|
|
418
499
|
// Private business logic methods
|
|
419
500
|
validateAlertData(data) {
|
|
420
501
|
if (!data.title || data.title.trim().length < 3) {
|
|
@@ -426,6 +507,9 @@ let AlertService = (() => {
|
|
|
426
507
|
if (!data.propertyId) {
|
|
427
508
|
throw new Error("Property ID is required");
|
|
428
509
|
}
|
|
510
|
+
if (!data.zoneId) {
|
|
511
|
+
throw new Error("Zone ID is required");
|
|
512
|
+
}
|
|
429
513
|
if (!data.entityType) {
|
|
430
514
|
throw new Error("Entity type is required");
|
|
431
515
|
}
|
|
@@ -28,6 +28,10 @@ export declare class AlertBuilder {
|
|
|
28
28
|
* Sets the property ID
|
|
29
29
|
*/
|
|
30
30
|
setPropertyId(propertyId: string): this;
|
|
31
|
+
/**
|
|
32
|
+
* Sets the zone ID
|
|
33
|
+
*/
|
|
34
|
+
setZoneId(zoneId: string): this;
|
|
31
35
|
/**
|
|
32
36
|
* Sets the alert title
|
|
33
37
|
*/
|
|
@@ -79,9 +83,9 @@ export declare class AlertBuilder {
|
|
|
79
83
|
/**
|
|
80
84
|
* Creates a device-specific alert builder
|
|
81
85
|
*/
|
|
82
|
-
static createDeviceAlert(deviceId: string, propertyId: string): AlertBuilder;
|
|
86
|
+
static createDeviceAlert(deviceId: string, propertyId: string, zoneId: string): AlertBuilder;
|
|
83
87
|
/**
|
|
84
88
|
* Creates a hub-specific alert builder
|
|
85
89
|
*/
|
|
86
|
-
static createHubAlert(hubId: string, propertyId: string): AlertBuilder;
|
|
90
|
+
static createHubAlert(hubId: string, propertyId: string, zoneId: string): AlertBuilder;
|
|
87
91
|
}
|
|
@@ -42,6 +42,16 @@ class AlertBuilder {
|
|
|
42
42
|
this.data.propertyId = propertyId;
|
|
43
43
|
return this;
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Sets the zone ID
|
|
47
|
+
*/
|
|
48
|
+
setZoneId(zoneId) {
|
|
49
|
+
if (!zoneId || zoneId.trim() === "") {
|
|
50
|
+
throw new Error("Zone ID is required and cannot be empty");
|
|
51
|
+
}
|
|
52
|
+
this.data.zoneId = zoneId;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
45
55
|
/**
|
|
46
56
|
* Sets the alert title
|
|
47
57
|
*/
|
|
@@ -112,6 +122,7 @@ class AlertBuilder {
|
|
|
112
122
|
const requiredFields = [
|
|
113
123
|
"category",
|
|
114
124
|
"propertyId",
|
|
125
|
+
"zoneId",
|
|
115
126
|
"title",
|
|
116
127
|
"description",
|
|
117
128
|
"entityType",
|
|
@@ -167,20 +178,22 @@ class AlertBuilder {
|
|
|
167
178
|
/**
|
|
168
179
|
* Creates a device-specific alert builder
|
|
169
180
|
*/
|
|
170
|
-
static createDeviceAlert(deviceId, propertyId) {
|
|
181
|
+
static createDeviceAlert(deviceId, propertyId, zoneId) {
|
|
171
182
|
return new AlertBuilder()
|
|
172
183
|
.setEntityType(alert_types_1.EntityType.DEVICE)
|
|
173
184
|
.setEntityId(deviceId)
|
|
174
|
-
.setPropertyId(propertyId)
|
|
185
|
+
.setPropertyId(propertyId)
|
|
186
|
+
.setZoneId(zoneId);
|
|
175
187
|
}
|
|
176
188
|
/**
|
|
177
189
|
* Creates a hub-specific alert builder
|
|
178
190
|
*/
|
|
179
|
-
static createHubAlert(hubId, propertyId) {
|
|
191
|
+
static createHubAlert(hubId, propertyId, zoneId) {
|
|
180
192
|
return new AlertBuilder()
|
|
181
193
|
.setEntityType(alert_types_1.EntityType.HUB)
|
|
182
194
|
.setEntityId(hubId)
|
|
183
|
-
.setPropertyId(propertyId)
|
|
195
|
+
.setPropertyId(propertyId)
|
|
196
|
+
.setZoneId(zoneId);
|
|
184
197
|
}
|
|
185
198
|
}
|
|
186
199
|
exports.AlertBuilder = AlertBuilder;
|
|
@@ -17,6 +17,7 @@ export interface AlertDocument {
|
|
|
17
17
|
_id: string;
|
|
18
18
|
category: AlertCategory;
|
|
19
19
|
propertyId: string;
|
|
20
|
+
zoneId: string;
|
|
20
21
|
title: string;
|
|
21
22
|
description: string;
|
|
22
23
|
entityId?: string;
|
|
@@ -34,6 +35,7 @@ export interface AlertDocument {
|
|
|
34
35
|
export interface CreateAlertData {
|
|
35
36
|
category: AlertCategory;
|
|
36
37
|
propertyId: string;
|
|
38
|
+
zoneId: string;
|
|
37
39
|
title: string;
|
|
38
40
|
description: string;
|
|
39
41
|
entityId?: string;
|
|
@@ -56,6 +58,7 @@ export interface UpdateAlertData {
|
|
|
56
58
|
}
|
|
57
59
|
export interface IAlertQuery {
|
|
58
60
|
propertyId?: string;
|
|
61
|
+
zoneId?: string;
|
|
59
62
|
category?: AlertCategory;
|
|
60
63
|
severity?: AlertSeverity;
|
|
61
64
|
entityType?: EntityType;
|
|
@@ -84,7 +84,6 @@ let AdminRepository = (() => {
|
|
|
84
84
|
let _classThis;
|
|
85
85
|
var AdminRepository = _classThis = class {
|
|
86
86
|
constructor() {
|
|
87
|
-
this.axiosInstance = (0, utils_1.getAdminServiceAxiosInstance)();
|
|
88
87
|
this.deviceRepository = typedi_1.default.get(Device_repository_1.DeviceRepository);
|
|
89
88
|
this.postgres = (0, db_1.getPostgresClient)();
|
|
90
89
|
}
|
|
@@ -112,7 +111,7 @@ let AdminRepository = (() => {
|
|
|
112
111
|
const collectionZone = [];
|
|
113
112
|
for (let zone of response) {
|
|
114
113
|
let zoneIds = [];
|
|
115
|
-
const zones = (await
|
|
114
|
+
const zones = (await (0, utils_1.getAdminServiceAxiosInstance)().get(`/zones/child?zoneId=${zone.zoneId}`))?.data?.data;
|
|
116
115
|
zoneIds.push(zone.zoneId);
|
|
117
116
|
if (zones.childZones?.length > 0) {
|
|
118
117
|
const nestedZoneIds = new Set(_zones(zones.childZones));
|
|
@@ -56,6 +56,11 @@ const IssueSchema = new mongoose_1.Schema({
|
|
|
56
56
|
required: true,
|
|
57
57
|
index: true,
|
|
58
58
|
},
|
|
59
|
+
zoneId: {
|
|
60
|
+
type: String,
|
|
61
|
+
required: true,
|
|
62
|
+
index: true,
|
|
63
|
+
},
|
|
59
64
|
title: {
|
|
60
65
|
type: String,
|
|
61
66
|
required: true,
|
|
@@ -129,6 +134,7 @@ const IssueSchema = new mongoose_1.Schema({
|
|
|
129
134
|
});
|
|
130
135
|
exports.IssueSchema = IssueSchema;
|
|
131
136
|
IssueSchema.index({ propertyId: 1, status: 1 });
|
|
137
|
+
IssueSchema.index({ zoneId: 1, status: 1 });
|
|
132
138
|
IssueSchema.index({ assignedTo: 1, status: 1 });
|
|
133
139
|
IssueSchema.index({ entityId: 1, entityType: 1 });
|
|
134
140
|
// Pre-save middleware to update the updatedAt field
|
|
@@ -47,6 +47,7 @@ export declare class IssueRepository {
|
|
|
47
47
|
*/
|
|
48
48
|
search(searchTerm: string, filters?: {
|
|
49
49
|
propertyId?: string;
|
|
50
|
+
zoneId?: string;
|
|
50
51
|
includeDeleted?: boolean;
|
|
51
52
|
limit?: number;
|
|
52
53
|
skip?: number;
|
|
@@ -54,7 +55,7 @@ export declare class IssueRepository {
|
|
|
54
55
|
/**
|
|
55
56
|
* Get issue statistics
|
|
56
57
|
*/
|
|
57
|
-
getStatistics(propertyId?: string): Promise<{
|
|
58
|
+
getStatistics(propertyId?: string, zoneId?: string): Promise<{
|
|
58
59
|
total: number;
|
|
59
60
|
pending: number;
|
|
60
61
|
inProgress: number;
|
|
@@ -72,4 +73,16 @@ export declare class IssueRepository {
|
|
|
72
73
|
* Bulk soft delete issues
|
|
73
74
|
*/
|
|
74
75
|
bulkSoftDelete(ids: string[], deletedBy: string): Promise<number>;
|
|
76
|
+
/**
|
|
77
|
+
* Find issues by zone ID
|
|
78
|
+
*/
|
|
79
|
+
findByZoneId(zoneId: string, includeDeleted?: boolean): Promise<IIssueDocument[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Find issues by zone ID and status
|
|
82
|
+
*/
|
|
83
|
+
findByZoneIdAndStatus(zoneId: string, status: string, includeDeleted?: boolean): Promise<IIssueDocument[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Find issues by multiple zone IDs
|
|
86
|
+
*/
|
|
87
|
+
findByZoneIds(zoneIds: string[], includeDeleted?: boolean): Promise<IIssueDocument[]>;
|
|
75
88
|
}
|
|
@@ -52,6 +52,8 @@ let IssueRepository = (() => {
|
|
|
52
52
|
const query = {};
|
|
53
53
|
if (filters.propertyId)
|
|
54
54
|
query.propertyId = filters.propertyId;
|
|
55
|
+
if (filters.zoneId)
|
|
56
|
+
query.zoneId = filters.zoneId;
|
|
55
57
|
if (filters.assignedTo)
|
|
56
58
|
query.assignedTo = filters.assignedTo;
|
|
57
59
|
if (filters.status)
|
|
@@ -229,6 +231,8 @@ let IssueRepository = (() => {
|
|
|
229
231
|
};
|
|
230
232
|
if (filters.propertyId)
|
|
231
233
|
query.propertyId = filters.propertyId;
|
|
234
|
+
if (filters.zoneId)
|
|
235
|
+
query.zoneId = filters.zoneId;
|
|
232
236
|
if (!filters.includeDeleted)
|
|
233
237
|
query.isDeleted = false;
|
|
234
238
|
const queryBuilder = Issue_model_1.IssueModel.find(query).sort({ createdAt: -1 });
|
|
@@ -246,11 +250,13 @@ let IssueRepository = (() => {
|
|
|
246
250
|
/**
|
|
247
251
|
* Get issue statistics
|
|
248
252
|
*/
|
|
249
|
-
async getStatistics(propertyId) {
|
|
253
|
+
async getStatistics(propertyId, zoneId) {
|
|
250
254
|
try {
|
|
251
255
|
const query = { isDeleted: false };
|
|
252
256
|
if (propertyId)
|
|
253
257
|
query.propertyId = propertyId;
|
|
258
|
+
if (zoneId)
|
|
259
|
+
query.zoneId = zoneId;
|
|
254
260
|
const [total, pending, inProgress, resolved, closed, overdue, priorityStats, categoryStats,] = await Promise.all([
|
|
255
261
|
Issue_model_1.IssueModel.countDocuments(query),
|
|
256
262
|
Issue_model_1.IssueModel.countDocuments({ ...query, status: issue_types_1.IssueStatus.PENDING }),
|
|
@@ -341,6 +347,57 @@ let IssueRepository = (() => {
|
|
|
341
347
|
throw new Error(`Failed to bulk soft delete issues: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
342
348
|
}
|
|
343
349
|
}
|
|
350
|
+
/**
|
|
351
|
+
* Find issues by zone ID
|
|
352
|
+
*/
|
|
353
|
+
async findByZoneId(zoneId, includeDeleted = false) {
|
|
354
|
+
try {
|
|
355
|
+
const query = { zoneId };
|
|
356
|
+
if (!includeDeleted) {
|
|
357
|
+
query.isDeleted = false;
|
|
358
|
+
}
|
|
359
|
+
const results = await Issue_model_1.IssueModel.find(query).sort({ createdAt: -1 });
|
|
360
|
+
return results.map((result) => result.toObject());
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
throw new Error(`Failed to find issues by zone ID: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Find issues by zone ID and status
|
|
368
|
+
*/
|
|
369
|
+
async findByZoneIdAndStatus(zoneId, status, includeDeleted = false) {
|
|
370
|
+
try {
|
|
371
|
+
const query = { zoneId, status };
|
|
372
|
+
if (!includeDeleted) {
|
|
373
|
+
query.isDeleted = false;
|
|
374
|
+
}
|
|
375
|
+
const results = await Issue_model_1.IssueModel.find(query).sort({ createdAt: -1 });
|
|
376
|
+
return results.map((result) => result.toObject());
|
|
377
|
+
}
|
|
378
|
+
catch (error) {
|
|
379
|
+
throw new Error(`Failed to find issues by zone ID and status: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Find issues by multiple zone IDs
|
|
384
|
+
*/
|
|
385
|
+
async findByZoneIds(zoneIds, includeDeleted = false) {
|
|
386
|
+
try {
|
|
387
|
+
if (!zoneIds || zoneIds.length === 0) {
|
|
388
|
+
throw new Error("Zone IDs array is required and cannot be empty");
|
|
389
|
+
}
|
|
390
|
+
const query = { zoneId: { $in: zoneIds } };
|
|
391
|
+
if (!includeDeleted) {
|
|
392
|
+
query.isDeleted = false;
|
|
393
|
+
}
|
|
394
|
+
const results = await Issue_model_1.IssueModel.find(query).sort({ createdAt: -1 });
|
|
395
|
+
return results.map((result) => result.toObject());
|
|
396
|
+
}
|
|
397
|
+
catch (error) {
|
|
398
|
+
throw new Error(`Failed to find issues by zone IDs: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
344
401
|
};
|
|
345
402
|
__setFunctionName(_classThis, "IssueRepository");
|
|
346
403
|
(() => {
|
|
@@ -123,7 +123,7 @@ export declare class IssueService {
|
|
|
123
123
|
/**
|
|
124
124
|
* Get issue statistics with business logic
|
|
125
125
|
*/
|
|
126
|
-
getIssueStatistics(propertyId?: string): Promise<{
|
|
126
|
+
getIssueStatistics(propertyId?: string, zoneId?: string): Promise<{
|
|
127
127
|
total: number;
|
|
128
128
|
pending: number;
|
|
129
129
|
inProgress: number;
|
|
@@ -138,10 +138,23 @@ export declare class IssueService {
|
|
|
138
138
|
*/
|
|
139
139
|
searchIssues(searchTerm: string, filters?: {
|
|
140
140
|
propertyId?: string;
|
|
141
|
+
zoneId?: string;
|
|
141
142
|
includeDeleted?: boolean;
|
|
142
143
|
limit?: number;
|
|
143
144
|
skip?: number;
|
|
144
145
|
}): Promise<IIssueDocument[]>;
|
|
146
|
+
/**
|
|
147
|
+
* Get issues by zone ID
|
|
148
|
+
*/
|
|
149
|
+
getIssuesByZoneId(zoneId: string, includeDeleted?: boolean): Promise<IIssueDocument[]>;
|
|
150
|
+
/**
|
|
151
|
+
* Get issues by zone ID and status
|
|
152
|
+
*/
|
|
153
|
+
getIssuesByZoneIdAndStatus(zoneId: string, status: string, includeDeleted?: boolean): Promise<IIssueDocument[]>;
|
|
154
|
+
/**
|
|
155
|
+
* Get issues by multiple zone IDs
|
|
156
|
+
*/
|
|
157
|
+
getIssuesByZoneIds(zoneIds: string[], includeDeleted?: boolean): Promise<IIssueDocument[]>;
|
|
145
158
|
private validateIssueData;
|
|
146
159
|
private validateFilters;
|
|
147
160
|
private validateUpdateData;
|
|
@@ -93,6 +93,7 @@ let IssueService = (() => {
|
|
|
93
93
|
async createReadinessIssue(data) {
|
|
94
94
|
const issueBuilder = IssueBuilder_1.IssueBuilder.createReadinessIssue()
|
|
95
95
|
.setPropertyId(data.propertyId)
|
|
96
|
+
.setZoneId(data.zoneId)
|
|
96
97
|
.setTitle(data.title)
|
|
97
98
|
.setDescription(data.description)
|
|
98
99
|
.setCreatedBy(data.createdBy);
|
|
@@ -112,6 +113,7 @@ let IssueService = (() => {
|
|
|
112
113
|
async createOperationsIssue(data) {
|
|
113
114
|
const issueBuilder = IssueBuilder_1.IssueBuilder.createOperationsIssue()
|
|
114
115
|
.setPropertyId(data.propertyId)
|
|
116
|
+
.setZoneId(data.zoneId)
|
|
115
117
|
.setTitle(data.title)
|
|
116
118
|
.setDescription(data.description)
|
|
117
119
|
.setCreatedBy(data.createdBy);
|
|
@@ -131,6 +133,7 @@ let IssueService = (() => {
|
|
|
131
133
|
async createSecurityIssue(data) {
|
|
132
134
|
const issueBuilder = IssueBuilder_1.IssueBuilder.createSecurityIssue()
|
|
133
135
|
.setPropertyId(data.propertyId)
|
|
136
|
+
.setZoneId(data.zoneId)
|
|
134
137
|
.setTitle(data.title)
|
|
135
138
|
.setDescription(data.description)
|
|
136
139
|
.setCreatedBy(data.createdBy);
|
|
@@ -150,6 +153,7 @@ let IssueService = (() => {
|
|
|
150
153
|
async createEnergyIssue(data) {
|
|
151
154
|
const issueBuilder = IssueBuilder_1.IssueBuilder.createEnergyIssue()
|
|
152
155
|
.setPropertyId(data.propertyId)
|
|
156
|
+
.setZoneId(data.zoneId)
|
|
153
157
|
.setTitle(data.title)
|
|
154
158
|
.setDescription(data.description)
|
|
155
159
|
.setCreatedBy(data.createdBy);
|
|
@@ -167,7 +171,7 @@ let IssueService = (() => {
|
|
|
167
171
|
* Create a device-specific issue using IssueBuilder
|
|
168
172
|
*/
|
|
169
173
|
async createDeviceIssue(data) {
|
|
170
|
-
const issueBuilder = IssueBuilder_1.IssueBuilder.createDeviceIssue(data.entityId, data.propertyId)
|
|
174
|
+
const issueBuilder = IssueBuilder_1.IssueBuilder.createDeviceIssue(data.entityId, data.propertyId, data.zoneId)
|
|
171
175
|
.setTitle(data.title)
|
|
172
176
|
.setDescription(data.description)
|
|
173
177
|
.setCreatedBy(data.createdBy);
|
|
@@ -185,7 +189,7 @@ let IssueService = (() => {
|
|
|
185
189
|
* Create a hub-specific issue using IssueBuilder
|
|
186
190
|
*/
|
|
187
191
|
async createHubIssue(data) {
|
|
188
|
-
const issueBuilder = IssueBuilder_1.IssueBuilder.createHubIssue(data.entityId, data.propertyId)
|
|
192
|
+
const issueBuilder = IssueBuilder_1.IssueBuilder.createHubIssue(data.entityId, data.propertyId, data.zoneId)
|
|
189
193
|
.setTitle(data.title)
|
|
190
194
|
.setDescription(data.description)
|
|
191
195
|
.setCreatedBy(data.createdBy);
|
|
@@ -203,7 +207,7 @@ let IssueService = (() => {
|
|
|
203
207
|
* Create a user-specific issue using IssueBuilder
|
|
204
208
|
*/
|
|
205
209
|
async createUserIssue(data) {
|
|
206
|
-
const issueBuilder = IssueBuilder_1.IssueBuilder.createUserIssue(data.entityId, data.propertyId)
|
|
210
|
+
const issueBuilder = IssueBuilder_1.IssueBuilder.createUserIssue(data.entityId, data.propertyId, data.zoneId)
|
|
207
211
|
.setTitle(data.title)
|
|
208
212
|
.setDescription(data.description)
|
|
209
213
|
.setCreatedBy(data.createdBy);
|
|
@@ -225,6 +229,7 @@ let IssueService = (() => {
|
|
|
225
229
|
entityId: device.deviceId,
|
|
226
230
|
entityType: issue_types_1.EntityType.DEVICE,
|
|
227
231
|
propertyId: device.propertyId,
|
|
232
|
+
zoneId: device.zoneId,
|
|
228
233
|
title: "Device Offline - Requires Attention",
|
|
229
234
|
description: `Device ${device.name} (${device.deviceId}) has been offline for longer than the baseline time. ${reason ? `Reason: ${reason}` : ""} This requires immediate attention to restore device functionality.`,
|
|
230
235
|
createdBy: source,
|
|
@@ -238,6 +243,7 @@ let IssueService = (() => {
|
|
|
238
243
|
entityId: device.deviceId,
|
|
239
244
|
entityType: issue_types_1.EntityType.DEVICE,
|
|
240
245
|
propertyId: device.propertyId,
|
|
246
|
+
zoneId: device.zoneId,
|
|
241
247
|
title: "Door Left Open - Requires Attention",
|
|
242
248
|
description: `Zone ${zone?.name} has a door left open, for more than 10 minutes. ${reason ? `Reason: ${reason}` : ""}. Please check the zone and close the door.`,
|
|
243
249
|
createdBy: source,
|
|
@@ -253,6 +259,7 @@ let IssueService = (() => {
|
|
|
253
259
|
entityId: device.deviceId,
|
|
254
260
|
entityType: issue_types_1.EntityType.DEVICE,
|
|
255
261
|
propertyId: device.propertyId,
|
|
262
|
+
zoneId: device.zoneId,
|
|
256
263
|
title: "Device Battery Low - Requires Attention",
|
|
257
264
|
description: `Device ${device.name} (${device.deviceId}) battery level is ${batteryLevel}%, which is below the property threshold of ${threshold}%. Please replace or charge the device battery.`,
|
|
258
265
|
createdBy: source,
|
|
@@ -268,6 +275,7 @@ let IssueService = (() => {
|
|
|
268
275
|
entityId: device.deviceId,
|
|
269
276
|
entityType: issue_types_1.EntityType.DEVICE,
|
|
270
277
|
propertyId: device.propertyId,
|
|
278
|
+
zoneId: device.zoneId,
|
|
271
279
|
title: `Device Malfunction - ${issueType} - Requires Attention`,
|
|
272
280
|
description: `Device ${device.name} (${device.deviceId}) has a malfunction: ${issueType}. ${reason ? `Reason: ${reason}` : ""} This requires immediate attention to resolve the device malfunction.`,
|
|
273
281
|
createdBy: source,
|
|
@@ -279,7 +287,7 @@ let IssueService = (() => {
|
|
|
279
287
|
* Create a maintenance issue using IssueBuilder
|
|
280
288
|
*/
|
|
281
289
|
async createMaintenanceIssue(data) {
|
|
282
|
-
const issueBuilder = IssueBuilder_1.IssueBuilder.createMaintenanceIssue(data.propertyId, data.entityId, data.entityType)
|
|
290
|
+
const issueBuilder = IssueBuilder_1.IssueBuilder.createMaintenanceIssue(data.propertyId, data.zoneId, data.entityId, data.entityType)
|
|
283
291
|
.setTitle(data.title)
|
|
284
292
|
.setDescription(data.description)
|
|
285
293
|
.setCreatedBy(data.createdBy);
|
|
@@ -293,7 +301,7 @@ let IssueService = (() => {
|
|
|
293
301
|
* Create an urgent issue using IssueBuilder
|
|
294
302
|
*/
|
|
295
303
|
async createUrgentIssue(data) {
|
|
296
|
-
const issueBuilder = IssueBuilder_1.IssueBuilder.createUrgentIssue(data.propertyId, data.entityId, data.entityType)
|
|
304
|
+
const issueBuilder = IssueBuilder_1.IssueBuilder.createUrgentIssue(data.propertyId, data.zoneId, data.entityId, data.entityType)
|
|
297
305
|
.setTitle(data.title)
|
|
298
306
|
.setDescription(data.description)
|
|
299
307
|
.setCreatedBy(data.createdBy);
|
|
@@ -569,8 +577,8 @@ let IssueService = (() => {
|
|
|
569
577
|
/**
|
|
570
578
|
* Get issue statistics with business logic
|
|
571
579
|
*/
|
|
572
|
-
async getIssueStatistics(propertyId) {
|
|
573
|
-
const stats = await this.issueRepository.getStatistics(propertyId);
|
|
580
|
+
async getIssueStatistics(propertyId, zoneId) {
|
|
581
|
+
const stats = await this.issueRepository.getStatistics(propertyId, zoneId);
|
|
574
582
|
// Business logic: Calculate additional metrics
|
|
575
583
|
const responseTime = this.calculateAverageResponseTime(stats);
|
|
576
584
|
const resolutionRate = this.calculateResolutionRate(stats);
|
|
@@ -595,6 +603,36 @@ let IssueService = (() => {
|
|
|
595
603
|
}
|
|
596
604
|
return await this.issueRepository.search(searchTerm, filters);
|
|
597
605
|
}
|
|
606
|
+
/**
|
|
607
|
+
* Get issues by zone ID
|
|
608
|
+
*/
|
|
609
|
+
async getIssuesByZoneId(zoneId, includeDeleted = false) {
|
|
610
|
+
if (!zoneId) {
|
|
611
|
+
throw new Error("Zone ID is required");
|
|
612
|
+
}
|
|
613
|
+
return await this.issueRepository.findByZoneId(zoneId, includeDeleted);
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Get issues by zone ID and status
|
|
617
|
+
*/
|
|
618
|
+
async getIssuesByZoneIdAndStatus(zoneId, status, includeDeleted = false) {
|
|
619
|
+
if (!zoneId) {
|
|
620
|
+
throw new Error("Zone ID is required");
|
|
621
|
+
}
|
|
622
|
+
if (!status) {
|
|
623
|
+
throw new Error("Status is required");
|
|
624
|
+
}
|
|
625
|
+
return await this.issueRepository.findByZoneIdAndStatus(zoneId, status, includeDeleted);
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Get issues by multiple zone IDs
|
|
629
|
+
*/
|
|
630
|
+
async getIssuesByZoneIds(zoneIds, includeDeleted = false) {
|
|
631
|
+
if (!zoneIds || zoneIds.length === 0) {
|
|
632
|
+
throw new Error("Zone IDs array is required and cannot be empty");
|
|
633
|
+
}
|
|
634
|
+
return await this.issueRepository.findByZoneIds(zoneIds, includeDeleted);
|
|
635
|
+
}
|
|
598
636
|
// Private business logic methods
|
|
599
637
|
validateIssueData(data) {
|
|
600
638
|
if (!data.title || data.title.trim().length < 5) {
|
|
@@ -606,6 +644,9 @@ let IssueService = (() => {
|
|
|
606
644
|
if (!data.propertyId) {
|
|
607
645
|
throw new Error("Property ID is required");
|
|
608
646
|
}
|
|
647
|
+
if (!data.zoneId) {
|
|
648
|
+
throw new Error("Zone ID is required");
|
|
649
|
+
}
|
|
609
650
|
if (!data.createdBy) {
|
|
610
651
|
throw new Error("Created by user ID is required");
|
|
611
652
|
}
|
|
@@ -30,6 +30,10 @@ export declare class IssueBuilder {
|
|
|
30
30
|
* Sets the property ID
|
|
31
31
|
*/
|
|
32
32
|
setPropertyId(propertyId: string): this;
|
|
33
|
+
/**
|
|
34
|
+
* Sets the zone ID
|
|
35
|
+
*/
|
|
36
|
+
setZoneId(zoneId: string): this;
|
|
33
37
|
/**
|
|
34
38
|
* Sets the issue title
|
|
35
39
|
*/
|
|
@@ -85,25 +89,25 @@ export declare class IssueBuilder {
|
|
|
85
89
|
/**
|
|
86
90
|
* Creates a device-specific issue builder
|
|
87
91
|
*/
|
|
88
|
-
static createDeviceIssue(deviceId: string, propertyId: string): IssueBuilder;
|
|
92
|
+
static createDeviceIssue(deviceId: string, propertyId: string, zoneId: string): IssueBuilder;
|
|
89
93
|
/**
|
|
90
94
|
* Creates a hub-specific issue builder
|
|
91
95
|
*/
|
|
92
|
-
static createHubIssue(hubId: string, propertyId: string): IssueBuilder;
|
|
96
|
+
static createHubIssue(hubId: string, propertyId: string, zoneId: string): IssueBuilder;
|
|
93
97
|
/**
|
|
94
98
|
* Creates a user-specific issue builder
|
|
95
99
|
*/
|
|
96
|
-
static createUserIssue(userId: string, propertyId: string): IssueBuilder;
|
|
100
|
+
static createUserIssue(userId: string, propertyId: string, zoneId: string): IssueBuilder;
|
|
97
101
|
/**
|
|
98
102
|
* Creates a property-specific issue builder
|
|
99
103
|
*/
|
|
100
|
-
static createPropertyIssue(propertyId: string): IssueBuilder;
|
|
104
|
+
static createPropertyIssue(propertyId: string, zoneId: string): IssueBuilder;
|
|
101
105
|
/**
|
|
102
106
|
* Creates a maintenance issue builder
|
|
103
107
|
*/
|
|
104
|
-
static createMaintenanceIssue(propertyId: string, entityId?: string, entityType?: EntityType): IssueBuilder;
|
|
108
|
+
static createMaintenanceIssue(propertyId: string, zoneId: string, entityId?: string, entityType?: EntityType): IssueBuilder;
|
|
105
109
|
/**
|
|
106
110
|
* Creates an urgent issue builder
|
|
107
111
|
*/
|
|
108
|
-
static createUrgentIssue(propertyId: string, entityId?: string, entityType?: EntityType): IssueBuilder;
|
|
112
|
+
static createUrgentIssue(propertyId: string, zoneId: string, entityId?: string, entityType?: EntityType): IssueBuilder;
|
|
109
113
|
}
|
|
@@ -44,6 +44,16 @@ class IssueBuilder {
|
|
|
44
44
|
this.data.propertyId = propertyId;
|
|
45
45
|
return this;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Sets the zone ID
|
|
49
|
+
*/
|
|
50
|
+
setZoneId(zoneId) {
|
|
51
|
+
if (!zoneId || zoneId.trim() === "") {
|
|
52
|
+
throw new Error("Zone ID is required and cannot be empty");
|
|
53
|
+
}
|
|
54
|
+
this.data.zoneId = zoneId;
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
47
57
|
/**
|
|
48
58
|
* Sets the issue title
|
|
49
59
|
*/
|
|
@@ -124,6 +134,7 @@ class IssueBuilder {
|
|
|
124
134
|
const requiredFields = [
|
|
125
135
|
"category",
|
|
126
136
|
"propertyId",
|
|
137
|
+
"zoneId",
|
|
127
138
|
"title",
|
|
128
139
|
"description",
|
|
129
140
|
"entityId",
|
|
@@ -180,46 +191,51 @@ class IssueBuilder {
|
|
|
180
191
|
/**
|
|
181
192
|
* Creates a device-specific issue builder
|
|
182
193
|
*/
|
|
183
|
-
static createDeviceIssue(deviceId, propertyId) {
|
|
194
|
+
static createDeviceIssue(deviceId, propertyId, zoneId) {
|
|
184
195
|
return new IssueBuilder()
|
|
185
196
|
.setEntityType(issue_types_1.EntityType.DEVICE)
|
|
186
197
|
.setEntityId(deviceId)
|
|
187
|
-
.setPropertyId(propertyId)
|
|
198
|
+
.setPropertyId(propertyId)
|
|
199
|
+
.setZoneId(zoneId);
|
|
188
200
|
}
|
|
189
201
|
/**
|
|
190
202
|
* Creates a hub-specific issue builder
|
|
191
203
|
*/
|
|
192
|
-
static createHubIssue(hubId, propertyId) {
|
|
204
|
+
static createHubIssue(hubId, propertyId, zoneId) {
|
|
193
205
|
return new IssueBuilder()
|
|
194
206
|
.setEntityType(issue_types_1.EntityType.HUB)
|
|
195
207
|
.setEntityId(hubId)
|
|
196
|
-
.setPropertyId(propertyId)
|
|
208
|
+
.setPropertyId(propertyId)
|
|
209
|
+
.setZoneId(zoneId);
|
|
197
210
|
}
|
|
198
211
|
/**
|
|
199
212
|
* Creates a user-specific issue builder
|
|
200
213
|
*/
|
|
201
|
-
static createUserIssue(userId, propertyId) {
|
|
214
|
+
static createUserIssue(userId, propertyId, zoneId) {
|
|
202
215
|
return new IssueBuilder()
|
|
203
216
|
.setEntityType(issue_types_1.EntityType.USER)
|
|
204
217
|
.setEntityId(userId)
|
|
205
|
-
.setPropertyId(propertyId)
|
|
218
|
+
.setPropertyId(propertyId)
|
|
219
|
+
.setZoneId(zoneId);
|
|
206
220
|
}
|
|
207
221
|
/**
|
|
208
222
|
* Creates a property-specific issue builder
|
|
209
223
|
*/
|
|
210
|
-
static createPropertyIssue(propertyId) {
|
|
224
|
+
static createPropertyIssue(propertyId, zoneId) {
|
|
211
225
|
return new IssueBuilder()
|
|
212
226
|
.setEntityType(issue_types_1.EntityType.PROPERTY)
|
|
213
227
|
.setEntityId(propertyId)
|
|
214
|
-
.setPropertyId(propertyId)
|
|
228
|
+
.setPropertyId(propertyId)
|
|
229
|
+
.setZoneId(zoneId);
|
|
215
230
|
}
|
|
216
231
|
/**
|
|
217
232
|
* Creates a maintenance issue builder
|
|
218
233
|
*/
|
|
219
|
-
static createMaintenanceIssue(propertyId, entityId, entityType) {
|
|
234
|
+
static createMaintenanceIssue(propertyId, zoneId, entityId, entityType) {
|
|
220
235
|
const builder = new IssueBuilder()
|
|
221
236
|
.setCategory(issue_types_1.IssuesCategory.READINESS)
|
|
222
237
|
.setPropertyId(propertyId)
|
|
238
|
+
.setZoneId(zoneId)
|
|
223
239
|
.setPriority(issue_types_1.IssuePriority.MEDIUM);
|
|
224
240
|
if (entityId)
|
|
225
241
|
builder.setEntityId(entityId);
|
|
@@ -230,10 +246,11 @@ class IssueBuilder {
|
|
|
230
246
|
/**
|
|
231
247
|
* Creates an urgent issue builder
|
|
232
248
|
*/
|
|
233
|
-
static createUrgentIssue(propertyId, entityId, entityType) {
|
|
249
|
+
static createUrgentIssue(propertyId, zoneId, entityId, entityType) {
|
|
234
250
|
const builder = new IssueBuilder()
|
|
235
251
|
.setCategory(issue_types_1.IssuesCategory.OPERATIONS)
|
|
236
252
|
.setPropertyId(propertyId)
|
|
253
|
+
.setZoneId(zoneId)
|
|
237
254
|
.setPriority(issue_types_1.IssuePriority.URGENT);
|
|
238
255
|
if (entityId)
|
|
239
256
|
builder.setEntityId(entityId);
|
|
@@ -42,6 +42,7 @@ export interface IssueDocument {
|
|
|
42
42
|
_id: string;
|
|
43
43
|
category: IssuesCategory;
|
|
44
44
|
propertyId: string;
|
|
45
|
+
zoneId: string;
|
|
45
46
|
title: string;
|
|
46
47
|
description: string;
|
|
47
48
|
entityId?: string;
|
|
@@ -61,6 +62,7 @@ export interface IssueDocument {
|
|
|
61
62
|
export interface CreateIssueData {
|
|
62
63
|
category: IssuesCategory;
|
|
63
64
|
propertyId: string;
|
|
65
|
+
zoneId: string;
|
|
64
66
|
title: string;
|
|
65
67
|
description: string;
|
|
66
68
|
entityId: string;
|
|
@@ -90,6 +92,7 @@ export interface AddCommentData {
|
|
|
90
92
|
}
|
|
91
93
|
export interface IIssueQuery {
|
|
92
94
|
propertyId?: string;
|
|
95
|
+
zoneId?: string;
|
|
93
96
|
assignedTo?: string;
|
|
94
97
|
status?: IssueStatus;
|
|
95
98
|
priority?: IssuePriority;
|
package/dist/utils/http.utils.js
CHANGED
|
@@ -34,7 +34,7 @@ function createAxiosInstance(baseURL) {
|
|
|
34
34
|
validateStatus: (status) => status < 500, // Don't throw on 4xx errors
|
|
35
35
|
headers: {
|
|
36
36
|
"Content-Type": "application/json",
|
|
37
|
-
"User-Agent":
|
|
37
|
+
"User-Agent": `dt-common-device/${require('../../package.json').version}`,
|
|
38
38
|
"x-api-key": (0, config_1.getDTApiKey)(),
|
|
39
39
|
},
|
|
40
40
|
});
|