dt-common-device 7.9.2 → 7.10.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.service.d.ts +1 -0
- package/dist/alerts/Alert.service.js +15 -0
- package/dist/alerts/alert.types.d.ts +2 -1
- package/dist/alerts/alert.types.js +1 -0
- package/dist/entities/admin/Admin.repository.js +24 -0
- package/dist/entities/device/local/repository/Device.repository.js +1 -1
- package/dist/events/InternalEventSubscription.js +23 -4
- package/dist/issues/issue.types.d.ts +2 -0
- package/dist/issues/issue.types.js +5 -2
- package/dist/utils/http.utils.js +4 -4
- package/dist/utils/redis.utils.d.ts +22 -0
- package/dist/utils/redis.utils.js +22 -0
- package/package.json +1 -1
|
@@ -37,6 +37,7 @@ export declare class AlertService {
|
|
|
37
37
|
raiseLockAccessMasterCodeAlert(device: IDevice, zone: any, source: Source): Promise<IAlertDocument | null>;
|
|
38
38
|
raiseSpecificDoorAccessAlert(userName: string, device: IDevice, zone: any, source: Source): Promise<IAlertDocument | null>;
|
|
39
39
|
raiseGuestLockFirstAccessAlert(userName: string, device: IDevice, zone: any, source: Source): Promise<IAlertDocument | null>;
|
|
40
|
+
raiseZoneNotMappedToAccessGroupAlert(zone: any, source: Source): Promise<IAlertDocument | null>;
|
|
40
41
|
/**
|
|
41
42
|
* Create a new alert with business logic validation
|
|
42
43
|
* Accepts either a CreateAlertData object or an AlertBuilder instance
|
|
@@ -78,6 +78,7 @@ const Alert_model_1 = require("./Alert.model");
|
|
|
78
78
|
const alert_types_1 = require("./alert.types");
|
|
79
79
|
const AlertBuilder_1 = require("./AlertBuilder");
|
|
80
80
|
const constants_1 = require("../constants");
|
|
81
|
+
const issues_1 = require("../issues");
|
|
81
82
|
const audit_1 = require("../audit");
|
|
82
83
|
let AlertService = (() => {
|
|
83
84
|
let _classDecorators = [(0, typedi_1.Service)()];
|
|
@@ -328,6 +329,20 @@ let AlertService = (() => {
|
|
|
328
329
|
type: alert_types_1.AlertType.GUEST_LOCK_FIRST_ACCESS,
|
|
329
330
|
});
|
|
330
331
|
}
|
|
332
|
+
async raiseZoneNotMappedToAccessGroupAlert(zone, source) {
|
|
333
|
+
return await this.createAlert({
|
|
334
|
+
zoneId: zone.zoneId,
|
|
335
|
+
propertyId: zone.propertyId,
|
|
336
|
+
entityType: alert_types_1.EntityType.ZONE,
|
|
337
|
+
entitySubType: issues_1.EntitySubType.ZONE,
|
|
338
|
+
title: `Zone Not Mapped to Access Group`,
|
|
339
|
+
description: `${zone?.name} is not mapped to any access group. Only Emergency Codes Generated. Add to an Access group to generate Guest and Staff Modes`,
|
|
340
|
+
createdBy: source,
|
|
341
|
+
category: alert_types_1.AlertCategory.OPERATIONS,
|
|
342
|
+
severity: alert_types_1.AlertSeverity.INFO,
|
|
343
|
+
type: alert_types_1.AlertType.ZONE_NOT_MAPPED_TO_ACCESS_GROUP,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
331
346
|
/**
|
|
332
347
|
* Create a new alert with business logic validation
|
|
333
348
|
* Accepts either a CreateAlertData object or an AlertBuilder instance
|
|
@@ -23,7 +23,8 @@ export declare enum AlertType {
|
|
|
23
23
|
LOCK_ACCESS_MASTER_RFID = "LOCK_ACCESS_MASTER_RFID",
|
|
24
24
|
SPECIFIC_DOOR_ACCESS = "SPECIFIC_DOOR_ACCESS",
|
|
25
25
|
GUEST_LOCK_FIRST_ACCESS = "GUEST_LOCK_FIRST_ACCESS",
|
|
26
|
-
DEVICE_ONLINE = "DEVICE_ONLINE"
|
|
26
|
+
DEVICE_ONLINE = "DEVICE_ONLINE",
|
|
27
|
+
ZONE_NOT_MAPPED_TO_ACCESS_GROUP = "ZONE_NOT_MAPPED_TO_ACCESS_GROUP"
|
|
27
28
|
}
|
|
28
29
|
export interface AlertDocument {
|
|
29
30
|
_id: string;
|
|
@@ -29,6 +29,7 @@ var AlertType;
|
|
|
29
29
|
AlertType["SPECIFIC_DOOR_ACCESS"] = "SPECIFIC_DOOR_ACCESS";
|
|
30
30
|
AlertType["GUEST_LOCK_FIRST_ACCESS"] = "GUEST_LOCK_FIRST_ACCESS";
|
|
31
31
|
AlertType["DEVICE_ONLINE"] = "DEVICE_ONLINE";
|
|
32
|
+
AlertType["ZONE_NOT_MAPPED_TO_ACCESS_GROUP"] = "ZONE_NOT_MAPPED_TO_ACCESS_GROUP";
|
|
32
33
|
})(AlertType || (exports.AlertType = AlertType = {}));
|
|
33
34
|
// Re-export EntityType from issue.types.ts to avoid duplication
|
|
34
35
|
var issue_types_1 = require("../issues/issue.types");
|
|
@@ -88,6 +88,24 @@ let AdminRepository = (() => {
|
|
|
88
88
|
this.postgres = (0, db_1.getPostgresClient)();
|
|
89
89
|
}
|
|
90
90
|
async getZonesByAccessGroupIds(accessGroupIds) {
|
|
91
|
+
// // Get propertyId from any of the accessGroupIds
|
|
92
|
+
// const accessGroupIdsResult = await this.postgres.query(
|
|
93
|
+
// `SELECT "propertyId" FROM dt_collections WHERE "id" = ANY($1) LIMIT 1`,
|
|
94
|
+
// [accessGroupIds]
|
|
95
|
+
// );
|
|
96
|
+
// const propertyId = accessGroupIdsResult.rows[0].propertyId;
|
|
97
|
+
// const sortedAccessGroupIds = [...accessGroupIds].sort((a, b) =>
|
|
98
|
+
// a.localeCompare(b)
|
|
99
|
+
// );
|
|
100
|
+
// // Check if the result is already cached
|
|
101
|
+
// const redisKey = `${propertyId}:zonesAndDevicesByAccessGroupIds:${sortedAccessGroupIds.join(
|
|
102
|
+
// ","
|
|
103
|
+
// )}`;
|
|
104
|
+
// const cachedResult = await this.redisUtils.get(redisKey);
|
|
105
|
+
// if (cachedResult) {
|
|
106
|
+
// return JSON.parse(cachedResult);
|
|
107
|
+
// }
|
|
108
|
+
// If not cached, get the result from the database
|
|
91
109
|
const result = await this.postgres.query(`SELECT "zc".*, "z"."id", "z"."name"
|
|
92
110
|
FROM "dt_zones_collection_map" "zc"
|
|
93
111
|
INNER JOIN "dt_zones" "z" ON "zc"."zoneId" = "z"."id"
|
|
@@ -163,6 +181,12 @@ let AdminRepository = (() => {
|
|
|
163
181
|
return e;
|
|
164
182
|
});
|
|
165
183
|
const collectionZoneDevices = Array.from(new Set(_collectionZone));
|
|
184
|
+
// Cache the result
|
|
185
|
+
// await this.redisUtils.set(
|
|
186
|
+
// redisKey,
|
|
187
|
+
// JSON.stringify(collectionZoneDevices),
|
|
188
|
+
// 60 * 60 * 24
|
|
189
|
+
// );
|
|
166
190
|
return collectionZoneDevices;
|
|
167
191
|
}
|
|
168
192
|
async getZonesByAccessGroups(accessGroupIds) {
|
|
@@ -60,7 +60,7 @@ let DeviceRepository = (() => {
|
|
|
60
60
|
}
|
|
61
61
|
catch (error) {
|
|
62
62
|
(0, config_1.getConfig)().LOGGER.error("Failed to create device:", error);
|
|
63
|
-
throw
|
|
63
|
+
throw error;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
async getDevice(deviceId, withHubDetails = false) {
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.InternalEventSubscription = exports.InternalEventType = void 0;
|
|
4
4
|
const dt_pub_sub_1 = require("dt-pub-sub");
|
|
5
5
|
const config_1 = require("../config/config");
|
|
6
|
+
const dt_audit_library_1 = require("dt-audit-library");
|
|
6
7
|
// Event types enum for better type safety
|
|
7
8
|
var InternalEventType;
|
|
8
9
|
(function (InternalEventType) {
|
|
@@ -54,8 +55,17 @@ class InternalEventSubscription {
|
|
|
54
55
|
message,
|
|
55
56
|
eventType: message["detail-type"],
|
|
56
57
|
});
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
(0, dt_audit_library_1.publishAudit)({
|
|
59
|
+
eventType: "internal_event_subscription_error",
|
|
60
|
+
properties: {
|
|
61
|
+
error: error instanceof Error
|
|
62
|
+
? error.message
|
|
63
|
+
: "Error Processing Internal Event",
|
|
64
|
+
errorStack: error instanceof Error
|
|
65
|
+
? error.stack
|
|
66
|
+
: "Error Processing Internal Event",
|
|
67
|
+
},
|
|
68
|
+
});
|
|
59
69
|
}
|
|
60
70
|
}
|
|
61
71
|
/**
|
|
@@ -67,8 +77,17 @@ class InternalEventSubscription {
|
|
|
67
77
|
}
|
|
68
78
|
catch (error) {
|
|
69
79
|
this.logger.error("Handler method execution failed", { error });
|
|
70
|
-
|
|
71
|
-
|
|
80
|
+
(0, dt_audit_library_1.publishAudit)({
|
|
81
|
+
eventType: "internal_event_subscription_error",
|
|
82
|
+
properties: {
|
|
83
|
+
error: error instanceof Error
|
|
84
|
+
? error.message
|
|
85
|
+
: "Error Processing Internal Event",
|
|
86
|
+
errorStack: error instanceof Error
|
|
87
|
+
? error.stack
|
|
88
|
+
: "Error Processing Internal Event",
|
|
89
|
+
},
|
|
90
|
+
});
|
|
72
91
|
}
|
|
73
92
|
}
|
|
74
93
|
/**
|
|
@@ -5,6 +5,7 @@ export declare enum IssuesCategory {
|
|
|
5
5
|
OTHER = "OTHER"
|
|
6
6
|
}
|
|
7
7
|
export declare enum EntityType {
|
|
8
|
+
ZONE = "ZONE",
|
|
8
9
|
DEVICE = "DEVICE",
|
|
9
10
|
COLLECTION = "COLLECTION",
|
|
10
11
|
USER = "USER",
|
|
@@ -18,6 +19,7 @@ export declare enum EntityType {
|
|
|
18
19
|
CLOUD_PMS_ACCOUNT = "CLOUD_PMS_ACCOUNT"
|
|
19
20
|
}
|
|
20
21
|
export declare enum EntitySubType {
|
|
22
|
+
ZONE = "ZONE",
|
|
21
23
|
LOCK = "LOCK",
|
|
22
24
|
HUB = "HUB",
|
|
23
25
|
TV = "TV",
|
|
@@ -10,6 +10,7 @@ var IssuesCategory;
|
|
|
10
10
|
})(IssuesCategory || (exports.IssuesCategory = IssuesCategory = {}));
|
|
11
11
|
var EntityType;
|
|
12
12
|
(function (EntityType) {
|
|
13
|
+
EntityType["ZONE"] = "ZONE";
|
|
13
14
|
EntityType["DEVICE"] = "DEVICE";
|
|
14
15
|
EntityType["COLLECTION"] = "COLLECTION";
|
|
15
16
|
EntityType["USER"] = "USER";
|
|
@@ -24,18 +25,20 @@ var EntityType;
|
|
|
24
25
|
})(EntityType || (exports.EntityType = EntityType = {}));
|
|
25
26
|
var EntitySubType;
|
|
26
27
|
(function (EntitySubType) {
|
|
28
|
+
EntitySubType["ZONE"] = "ZONE";
|
|
29
|
+
// DEVICE
|
|
27
30
|
EntitySubType["LOCK"] = "LOCK";
|
|
28
31
|
EntitySubType["HUB"] = "HUB";
|
|
29
32
|
EntitySubType["TV"] = "TV";
|
|
30
33
|
EntitySubType["THERMOSTAT"] = "THERMOSTAT";
|
|
31
34
|
EntitySubType["ON_PREM_SERVER"] = "ON_PREM_SERVER";
|
|
32
|
-
// PMS
|
|
35
|
+
// PMS PROVIDERS
|
|
33
36
|
EntitySubType["CLOUDBEDS"] = "CLOUDBEDS";
|
|
34
37
|
EntitySubType["STAYNTOUCH"] = "STAYNTOUCH";
|
|
35
38
|
EntitySubType["HOTELKEY"] = "HOTELKEY";
|
|
36
39
|
EntitySubType["YANOLJA"] = "YANOLJA";
|
|
37
40
|
EntitySubType["SKYTOUCH"] = "SKYTOUCH";
|
|
38
|
-
// DEVICE
|
|
41
|
+
// DEVICE PROVIDERS
|
|
39
42
|
EntitySubType["SMARTTHINGS"] = "SMARTTHINGS";
|
|
40
43
|
EntitySubType["TTLock"] = "TTLock";
|
|
41
44
|
EntitySubType["TUYA"] = "TUYA";
|
package/dist/utils/http.utils.js
CHANGED
|
@@ -31,10 +31,10 @@ function createAxiosInstance(baseURL) {
|
|
|
31
31
|
baseURL,
|
|
32
32
|
timeout: 60000, // 60 seconds timeout
|
|
33
33
|
maxRedirects: 5,
|
|
34
|
-
validateStatus: (status) => status <
|
|
34
|
+
validateStatus: (status) => status < 400, // Only treat 2xx and 3xx as successful
|
|
35
35
|
headers: {
|
|
36
36
|
"Content-Type": "application/json",
|
|
37
|
-
"User-Agent": `dt-common-device/${require(
|
|
37
|
+
"User-Agent": `dt-common-device/${require("../../package.json").version}`,
|
|
38
38
|
"x-api-key": (0, config_1.getDTApiKey)(),
|
|
39
39
|
},
|
|
40
40
|
});
|
|
@@ -48,7 +48,7 @@ function createAxiosInstance(baseURL) {
|
|
|
48
48
|
return config;
|
|
49
49
|
}, (error) => {
|
|
50
50
|
(0, config_1.getConfig)().LOGGER.error("Request interceptor error:", error);
|
|
51
|
-
return Promise.reject(error);
|
|
51
|
+
return Promise.reject(error instanceof Error ? error : new Error(String(error)));
|
|
52
52
|
});
|
|
53
53
|
// Add response interceptor for error handling
|
|
54
54
|
instance.interceptors.response.use((response) => {
|
|
@@ -73,7 +73,7 @@ function createAxiosInstance(baseURL) {
|
|
|
73
73
|
errorMessage: error.message,
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
|
-
return Promise.reject(error);
|
|
76
|
+
return Promise.reject(error instanceof Error ? error : new Error(String(error)));
|
|
77
77
|
});
|
|
78
78
|
return instance;
|
|
79
79
|
}
|
|
@@ -70,9 +70,31 @@ export declare class RedisUtils {
|
|
|
70
70
|
* @returns The fields and values
|
|
71
71
|
*/
|
|
72
72
|
hgetAll(key: string): Promise<any>;
|
|
73
|
+
/**
|
|
74
|
+
* Add a member to a set
|
|
75
|
+
* @param key - The key to add the member to
|
|
76
|
+
* @param member - The member to add
|
|
77
|
+
* @returns The number of members added
|
|
78
|
+
*/
|
|
73
79
|
sadd(key: string, member: string): Promise<number>;
|
|
80
|
+
/**
|
|
81
|
+
* Get all members of a set
|
|
82
|
+
* @param key - The key to get the members of
|
|
83
|
+
* @returns The members
|
|
84
|
+
*/
|
|
74
85
|
smembers(key: string): Promise<string[]>;
|
|
86
|
+
/**
|
|
87
|
+
* Remove a member from a set
|
|
88
|
+
* @param key - The key to remove the member from
|
|
89
|
+
* @param members - The members to remove
|
|
90
|
+
* @returns The number of members removed
|
|
91
|
+
*/
|
|
75
92
|
srem(key: string, ...members: string[]): Promise<number>;
|
|
93
|
+
/**
|
|
94
|
+
* Get all keys matching a pattern
|
|
95
|
+
* @param pattern - The Redis key pattern (e.g., "zones:batch:*")
|
|
96
|
+
* @returns The keys
|
|
97
|
+
*/
|
|
76
98
|
keys(pattern: string): Promise<string[]>;
|
|
77
99
|
/**
|
|
78
100
|
* Delete all keys matching a pattern
|
|
@@ -182,12 +182,29 @@ let RedisUtils = (() => {
|
|
|
182
182
|
throw error;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Add a member to a set
|
|
187
|
+
* @param key - The key to add the member to
|
|
188
|
+
* @param member - The member to add
|
|
189
|
+
* @returns The number of members added
|
|
190
|
+
*/
|
|
185
191
|
async sadd(key, member) {
|
|
186
192
|
return await this.client.sadd(key, member);
|
|
187
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Get all members of a set
|
|
196
|
+
* @param key - The key to get the members of
|
|
197
|
+
* @returns The members
|
|
198
|
+
*/
|
|
188
199
|
async smembers(key) {
|
|
189
200
|
return await this.client.smembers(key);
|
|
190
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Remove a member from a set
|
|
204
|
+
* @param key - The key to remove the member from
|
|
205
|
+
* @param members - The members to remove
|
|
206
|
+
* @returns The number of members removed
|
|
207
|
+
*/
|
|
191
208
|
async srem(key, ...members) {
|
|
192
209
|
try {
|
|
193
210
|
return await this.client.srem(key, ...members);
|
|
@@ -197,6 +214,11 @@ let RedisUtils = (() => {
|
|
|
197
214
|
throw error;
|
|
198
215
|
}
|
|
199
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Get all keys matching a pattern
|
|
219
|
+
* @param pattern - The Redis key pattern (e.g., "zones:batch:*")
|
|
220
|
+
* @returns The keys
|
|
221
|
+
*/
|
|
200
222
|
async keys(pattern) {
|
|
201
223
|
return this.client.keys(pattern);
|
|
202
224
|
}
|