dt-common-device 13.7.0 → 13.8.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/config/config.js +2 -35
- package/dist/constants/ConnectionProviders.d.ts +1 -0
- package/dist/constants/ConnectionProviders.js +1 -0
- package/dist/constants/Event.d.ts +12 -0
- package/dist/constants/Event.js +12 -0
- package/dist/copilotQueue/utils/queueManager.js +2 -35
- package/dist/entities/admin/Admin.repository.d.ts +11 -2
- package/dist/entities/admin/Admin.repository.js +73 -2
- package/dist/entities/admin/Admin.service.d.ts +2 -1
- package/dist/entities/admin/Admin.service.js +9 -0
- package/dist/entities/admin/IAdmin.d.ts +40 -0
- package/dist/entities/device/local/interfaces/IDevice.d.ts +6 -0
- package/dist/entities/device/local/repository/Device.repository.d.ts +7 -0
- package/dist/entities/device/local/repository/Device.repository.js +11 -0
- package/dist/entities/device/local/services/Device.service.d.ts +8 -0
- package/dist/entities/device/local/services/Device.service.js +21 -0
- package/dist/utils/http.utils.d.ts +2 -1
- package/dist/webhookQueue/services/WebhookQueueService.js +3 -36
- package/package.json +1 -1
package/dist/config/config.js
CHANGED
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
@@ -63,6 +30,7 @@ const db_1 = require("../db/db");
|
|
|
63
30
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
64
31
|
const events_1 = require("../events");
|
|
65
32
|
const constants_1 = require("./constants");
|
|
33
|
+
const notificationQueue_1 = require("../notificationQueue");
|
|
66
34
|
dotenv_1.default.config();
|
|
67
35
|
let config = null;
|
|
68
36
|
let auditInitialized = false;
|
|
@@ -361,8 +329,7 @@ async function shutdown() {
|
|
|
361
329
|
}
|
|
362
330
|
// Close notification queue connections
|
|
363
331
|
try {
|
|
364
|
-
|
|
365
|
-
await closeNotificationQueue();
|
|
332
|
+
await (0, notificationQueue_1.closeNotificationQueue)();
|
|
366
333
|
}
|
|
367
334
|
catch (error) {
|
|
368
335
|
getConfig().LOGGER.error("Failed to close notification queue", { error });
|
|
@@ -73,6 +73,10 @@ export declare const DT_EVENT_TYPES: {
|
|
|
73
73
|
UNPROCESSED: string;
|
|
74
74
|
UNHANDLED: string;
|
|
75
75
|
};
|
|
76
|
+
MAINTENANCE_MODE: {
|
|
77
|
+
ENABLED: string;
|
|
78
|
+
DISABLED: string;
|
|
79
|
+
};
|
|
76
80
|
};
|
|
77
81
|
CONNECTION: {
|
|
78
82
|
CREATE: {
|
|
@@ -140,6 +144,10 @@ export declare const DT_EVENT_TYPES: {
|
|
|
140
144
|
SUCCESS: string;
|
|
141
145
|
FAILED: string;
|
|
142
146
|
};
|
|
147
|
+
MAINTENANCE_MODE: {
|
|
148
|
+
ENABLED: string;
|
|
149
|
+
DISABLED: string;
|
|
150
|
+
};
|
|
143
151
|
};
|
|
144
152
|
ZONE: {
|
|
145
153
|
CREATE: {
|
|
@@ -157,6 +165,10 @@ export declare const DT_EVENT_TYPES: {
|
|
|
157
165
|
SUCCESS: string;
|
|
158
166
|
FAILED: string;
|
|
159
167
|
};
|
|
168
|
+
MAINTENANCE_MODE: {
|
|
169
|
+
ENABLED: string;
|
|
170
|
+
DISABLED: string;
|
|
171
|
+
};
|
|
160
172
|
};
|
|
161
173
|
ISSUE: {
|
|
162
174
|
CREATE: {
|
package/dist/constants/Event.js
CHANGED
|
@@ -76,6 +76,10 @@ exports.DT_EVENT_TYPES = {
|
|
|
76
76
|
UNPROCESSED: "device.webhook.unprocessed",
|
|
77
77
|
UNHANDLED: "device.webhook.unhandled",
|
|
78
78
|
},
|
|
79
|
+
MAINTENANCE_MODE: {
|
|
80
|
+
ENABLED: "device.maintenance_mode.enabled",
|
|
81
|
+
DISABLED: "device.maintenance_mode.disabled",
|
|
82
|
+
},
|
|
79
83
|
},
|
|
80
84
|
CONNECTION: {
|
|
81
85
|
CREATE: {
|
|
@@ -143,6 +147,10 @@ exports.DT_EVENT_TYPES = {
|
|
|
143
147
|
SUCCESS: "accessgroup.delete.success",
|
|
144
148
|
FAILED: "accessgroup.delete.failed",
|
|
145
149
|
},
|
|
150
|
+
MAINTENANCE_MODE: {
|
|
151
|
+
ENABLED: "access_group.maintenance_mode.enabled",
|
|
152
|
+
DISABLED: "access_group.maintenance_mode.disabled",
|
|
153
|
+
},
|
|
146
154
|
},
|
|
147
155
|
ZONE: {
|
|
148
156
|
CREATE: {
|
|
@@ -160,6 +168,10 @@ exports.DT_EVENT_TYPES = {
|
|
|
160
168
|
SUCCESS: "zone.delete.success",
|
|
161
169
|
FAILED: "zone.delete.failed",
|
|
162
170
|
},
|
|
171
|
+
MAINTENANCE_MODE: {
|
|
172
|
+
ENABLED: "zone.maintenance_mode.enabled",
|
|
173
|
+
DISABLED: "zone.maintenance_mode.disabled",
|
|
174
|
+
},
|
|
163
175
|
},
|
|
164
176
|
ISSUE: {
|
|
165
177
|
CREATE: {
|
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.QueueManager = void 0;
|
|
37
4
|
const redis_1 = require("../../db/redis");
|
|
@@ -44,7 +11,7 @@ class QueueManager {
|
|
|
44
11
|
if (queues.has(queueKey)) {
|
|
45
12
|
return queues.get(queueKey);
|
|
46
13
|
}
|
|
47
|
-
const { Queue } = await
|
|
14
|
+
const { Queue } = await import("bullmq");
|
|
48
15
|
const queue = new Queue(queueKey, {
|
|
49
16
|
connection: (0, redis_1.getRedisClient)(),
|
|
50
17
|
});
|
|
@@ -58,7 +25,7 @@ class QueueManager {
|
|
|
58
25
|
if (workers.has(queueKey)) {
|
|
59
26
|
return workers.get(queueKey);
|
|
60
27
|
}
|
|
61
|
-
const { Worker } = await
|
|
28
|
+
const { Worker } = await import("bullmq");
|
|
62
29
|
const worker = new Worker(queueKey, processor, {
|
|
63
30
|
connection: (0, redis_1.getRedisClient)(),
|
|
64
31
|
concurrency: 1, // Process one job at a time for FIFO ordering
|
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import { IAccessGroup, IUser, IZone, IZoneAccessGroup } from "./IAdmin";
|
|
1
|
+
import { IAccessGroup, IDeliverableLocksByAccessGroupResult, IUser, IZone, IZoneAccessGroup, ILocksAndZonesByAccessGroup } from "./IAdmin";
|
|
2
2
|
export declare class AdminRepository {
|
|
3
3
|
private readonly deviceRepository;
|
|
4
4
|
private readonly postgres;
|
|
5
5
|
private readonly localDeviceService;
|
|
6
6
|
private readonly redisUtils;
|
|
7
7
|
constructor();
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Raw zones + devices for access groups (all non-HUB devices). Used when callers need the full list (e.g. UI).
|
|
10
|
+
*/
|
|
11
|
+
private loadCollectionZonesDevicesByAccessGroupIds;
|
|
12
|
+
getZonesByAccessGroupIds(accessGroupIds: string[], propertyId: string): Promise<ILocksAndZonesByAccessGroup[]>;
|
|
13
|
+
/**
|
|
14
|
+
* ZN-2: same data as {@link getZonesByAccessGroupIds}, but `devices` are only LOCKs that are not
|
|
15
|
+
* under maintenance (zone or device). `maintenanceSkips` is structured data for audit emission.
|
|
16
|
+
*/
|
|
17
|
+
getDeliverableLockDevicesByAccessGroupIds(accessGroupIds: string[], propertyId: string): Promise<IDeliverableLocksByAccessGroupResult>;
|
|
9
18
|
getZonesByAccessGroups(accessGroupIds: string[], type?: string[]): Promise<any[]>;
|
|
10
19
|
getAccessGroup(accessGroupId: string, propertyId?: string): Promise<IAccessGroup | null>;
|
|
11
20
|
getZoneAccessGroupByZoneId(zoneId: string): Promise<IZoneAccessGroup[] | null>;
|
|
@@ -91,7 +91,13 @@ let AdminRepository = (() => {
|
|
|
91
91
|
this.localDeviceService = typedi_1.default.get(services_1.LocalDeviceService);
|
|
92
92
|
this.redisUtils = typedi_1.default.get(utils_1.RedisUtils);
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Raw zones + devices for access groups (all non-HUB devices). Used when callers need the full list (e.g. UI).
|
|
96
|
+
*/
|
|
97
|
+
async loadCollectionZonesDevicesByAccessGroupIds(accessGroupIds, propertyId) {
|
|
98
|
+
if (!accessGroupIds?.length) {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
95
101
|
// If not cached, get the result from the database
|
|
96
102
|
const result = await this.postgres.query(`SELECT
|
|
97
103
|
"zc"."id" AS "zoneCollectionMapId",
|
|
@@ -100,7 +106,8 @@ let AdminRepository = (() => {
|
|
|
100
106
|
"z"."id" AS "zoneId",
|
|
101
107
|
"z"."name" AS "zoneName",
|
|
102
108
|
"z"."zoneTypeId",
|
|
103
|
-
"zt"."name" AS "zoneTypeName"
|
|
109
|
+
"zt"."name" AS "zoneTypeName",
|
|
110
|
+
"z"."isUnderMaintenance"
|
|
104
111
|
FROM "dt_zones_collection_map" AS "zc"
|
|
105
112
|
INNER JOIN "dt_zones" AS "z" ON "zc"."zoneId" = "z"."id"
|
|
106
113
|
LEFT JOIN "dt_zoneTypes" AS "zt" ON "z"."zoneTypeId" = "zt"."id"
|
|
@@ -171,6 +178,14 @@ let AdminRepository = (() => {
|
|
|
171
178
|
zoneIds: _zoneIds,
|
|
172
179
|
excludeDeviceType: interfaces_1.DeviceType.HUB,
|
|
173
180
|
});
|
|
181
|
+
// Fetch isUnderMaintenance for ALL zone IDs (including child zones not in the collection map)
|
|
182
|
+
const allCollectionIds = collectionZone.map((e) => e.collectionId);
|
|
183
|
+
const [allZoneMaintenanceResult, collectionMaintenanceResult] = await Promise.all([
|
|
184
|
+
this.postgres.query(`SELECT "id", "isUnderMaintenance" FROM "dt_zones" WHERE "id" = ANY($1)`, [_zoneIds]),
|
|
185
|
+
this.postgres.query(`SELECT "id", "isUnderMaintenance" FROM "dt_collections" WHERE "id" = ANY($1)`, [allCollectionIds]),
|
|
186
|
+
]);
|
|
187
|
+
const zoneMaintenanceMap = new Map(allZoneMaintenanceResult.rows.map((r) => [r.id, r.isUnderMaintenance ?? false]));
|
|
188
|
+
const collectionMaintenanceMap = new Map(collectionMaintenanceResult.rows.map((r) => [r.id, r.isUnderMaintenance ?? false]));
|
|
174
189
|
const _collectionZone = collectionZone.map((e) => {
|
|
175
190
|
const zones = e.zoneIds;
|
|
176
191
|
let devices = [];
|
|
@@ -184,18 +199,21 @@ let AdminRepository = (() => {
|
|
|
184
199
|
const _devices = devices.concat(device);
|
|
185
200
|
devices = _devices;
|
|
186
201
|
// Create zone data for each zone
|
|
202
|
+
// Use zoneMaintenanceMap for isUnderMaintenance so child zones are also covered
|
|
187
203
|
const zoneInfo = response.find((r) => r.zoneId === element);
|
|
188
204
|
const zoneData = {
|
|
189
205
|
zoneId: element,
|
|
190
206
|
deviceIds: device?.map((d) => d.deviceId), // Get first device ID if available
|
|
191
207
|
zoneName: zoneInfo?.zoneName || "",
|
|
192
208
|
zoneType: zoneInfo?.zoneTypeName || null,
|
|
209
|
+
isUnderMaintenance: zoneMaintenanceMap.get(element) ?? false,
|
|
193
210
|
};
|
|
194
211
|
zonesData.push(zoneData);
|
|
195
212
|
});
|
|
196
213
|
e.devices = devices;
|
|
197
214
|
e.zones = zonesData;
|
|
198
215
|
e.parentZone = response;
|
|
216
|
+
e.isUnderMaintenance = collectionMaintenanceMap.get(e.collectionId) ?? false;
|
|
199
217
|
return e;
|
|
200
218
|
});
|
|
201
219
|
const collectionZoneDevices = Array.from(new Set(_collectionZone));
|
|
@@ -207,6 +225,59 @@ let AdminRepository = (() => {
|
|
|
207
225
|
// );
|
|
208
226
|
return collectionZoneDevices;
|
|
209
227
|
}
|
|
228
|
+
async getZonesByAccessGroupIds(accessGroupIds, propertyId) {
|
|
229
|
+
return await this.loadCollectionZonesDevicesByAccessGroupIds(accessGroupIds, propertyId);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* ZN-2: same data as {@link getZonesByAccessGroupIds}, but `devices` are only LOCKs that are not
|
|
233
|
+
* under maintenance (zone or device). `maintenanceSkips` is structured data for audit emission.
|
|
234
|
+
*/
|
|
235
|
+
async getDeliverableLockDevicesByAccessGroupIds(accessGroupIds, propertyId) {
|
|
236
|
+
if (!accessGroupIds?.length) {
|
|
237
|
+
return { collections: [], maintenanceSkips: [] };
|
|
238
|
+
}
|
|
239
|
+
const raw = await this.loadCollectionZonesDevicesByAccessGroupIds(accessGroupIds, propertyId);
|
|
240
|
+
const maintenanceSkips = [];
|
|
241
|
+
const collections = raw.map((cz) => {
|
|
242
|
+
const inactiveIds = new Set();
|
|
243
|
+
for (const zone of cz.zones || []) {
|
|
244
|
+
if (zone.isUnderMaintenance) {
|
|
245
|
+
(zone.deviceIds || []).forEach((id) => {
|
|
246
|
+
if (id != null && id !== "")
|
|
247
|
+
inactiveIds.add(String(id));
|
|
248
|
+
});
|
|
249
|
+
maintenanceSkips.push({
|
|
250
|
+
accessGroupId: cz.collectionId,
|
|
251
|
+
zoneId: zone.zoneId,
|
|
252
|
+
deviceIds: (zone.deviceIds || [])
|
|
253
|
+
.map((x) => String(x))
|
|
254
|
+
.filter((x) => x !== ""),
|
|
255
|
+
reason: "zone inactive",
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
for (const dev of cz.devices || []) {
|
|
260
|
+
if (dev.deviceType?.type !== "LOCK" || !dev.isUnderMaintenance) {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
const did = String(dev.deviceId);
|
|
264
|
+
if (inactiveIds.has(did)) {
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
inactiveIds.add(did);
|
|
268
|
+
maintenanceSkips.push({
|
|
269
|
+
accessGroupId: cz.collectionId,
|
|
270
|
+
zoneId: dev.zoneId,
|
|
271
|
+
deviceIds: [did],
|
|
272
|
+
reason: "device under maintenance",
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
const deliverableDevices = (cz.devices || []).filter((d) => d.deviceType?.type === "LOCK" &&
|
|
276
|
+
!inactiveIds.has(String(d.deviceId)));
|
|
277
|
+
return { ...cz, devices: deliverableDevices, skippedDevices: cz.devices.filter((device) => device.deviceType?.type === "LOCK" && inactiveIds.has(String(device.deviceId))) };
|
|
278
|
+
});
|
|
279
|
+
return { collections, maintenanceSkips };
|
|
280
|
+
}
|
|
210
281
|
async getZonesByAccessGroups(accessGroupIds, type) {
|
|
211
282
|
// Fetch zone IDs associated with these access groups
|
|
212
283
|
const zonesIdsQuery = `
|
|
@@ -3,7 +3,8 @@ export declare class AdminService {
|
|
|
3
3
|
private readonly adminRepository;
|
|
4
4
|
private readonly redisUtils;
|
|
5
5
|
constructor();
|
|
6
|
-
getZonesByAccessGroupIds(accessGroupIds: string[], propertyId: string): Promise<
|
|
6
|
+
getZonesByAccessGroupIds(accessGroupIds: string[], propertyId: string): Promise<import("./IAdmin").ILocksAndZonesByAccessGroup[]>;
|
|
7
|
+
getDeliverableLockDevicesByAccessGroupIds(accessGroupIds: string[], propertyId: string): Promise<import("./IAdmin").IDeliverableLocksByAccessGroupResult>;
|
|
7
8
|
getZonesByAccessGroups(accessGroupIds: string[], type?: string[]): Promise<any[]>;
|
|
8
9
|
getAccessGroup(accessGroupId: string, propertyId?: string): Promise<IAccessGroup | null>;
|
|
9
10
|
getAccessGroupByZoneId(zoneId: string): Promise<IAccessGroup[] | []>;
|
|
@@ -95,6 +95,15 @@ let AdminService = (() => {
|
|
|
95
95
|
return [];
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
+
async getDeliverableLockDevicesByAccessGroupIds(accessGroupIds, propertyId) {
|
|
99
|
+
try {
|
|
100
|
+
return await this.adminRepository.getDeliverableLockDevicesByAccessGroupIds(accessGroupIds, propertyId);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
console.log(error);
|
|
104
|
+
return { collections: [], maintenanceSkips: [] };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
98
107
|
async getZonesByAccessGroups(accessGroupIds, type) {
|
|
99
108
|
try {
|
|
100
109
|
return await this.adminRepository.getZonesByAccessGroups(accessGroupIds, type);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IDevice } from "../device/local/interfaces";
|
|
1
2
|
export interface IAccessGroup {
|
|
2
3
|
id: string;
|
|
3
4
|
propertyId: string;
|
|
@@ -48,3 +49,42 @@ export interface IUser {
|
|
|
48
49
|
deletedAt?: Date | null;
|
|
49
50
|
imageURL?: string | null;
|
|
50
51
|
}
|
|
52
|
+
/** ZN-2 skip metadata for callers that emit maintenance audits (e.g. smart-access-node). */
|
|
53
|
+
export type IZn2MaintenanceSkipReason = "zone inactive" | "device under maintenance";
|
|
54
|
+
export interface IZn2MaintenanceSkip {
|
|
55
|
+
accessGroupId: string;
|
|
56
|
+
zoneId: string;
|
|
57
|
+
deviceIds: string[];
|
|
58
|
+
reason: IZn2MaintenanceSkipReason;
|
|
59
|
+
}
|
|
60
|
+
/** LOCK devices eligible for guest programming after zone + device maintenance rules. */
|
|
61
|
+
export interface IDeliverableLocksByAccessGroupResult {
|
|
62
|
+
collections: {
|
|
63
|
+
collectionId: string;
|
|
64
|
+
devices: IDevice[];
|
|
65
|
+
skippedDevices: IDevice[];
|
|
66
|
+
zones: {
|
|
67
|
+
zoneId: string;
|
|
68
|
+
deviceIds: string[];
|
|
69
|
+
zoneName: string;
|
|
70
|
+
zoneTypeName: string;
|
|
71
|
+
isUnderMaintenance: boolean;
|
|
72
|
+
}[];
|
|
73
|
+
parentZone: any;
|
|
74
|
+
isUnderMaintenance: boolean;
|
|
75
|
+
}[];
|
|
76
|
+
maintenanceSkips: IZn2MaintenanceSkip[];
|
|
77
|
+
}
|
|
78
|
+
export interface ILocksAndZonesByAccessGroup {
|
|
79
|
+
collectionId: string;
|
|
80
|
+
devices: IDevice[];
|
|
81
|
+
zones: {
|
|
82
|
+
zoneId: string;
|
|
83
|
+
deviceIds: string[];
|
|
84
|
+
zoneName: string;
|
|
85
|
+
zoneTypeName: string;
|
|
86
|
+
isUnderMaintenance: boolean;
|
|
87
|
+
}[];
|
|
88
|
+
parentZone: any;
|
|
89
|
+
isUnderMaintenance: boolean;
|
|
90
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export interface IDevice {
|
|
2
2
|
deviceId: string;
|
|
3
3
|
propertyId: string;
|
|
4
|
+
collectionId?: string;
|
|
4
5
|
zoneId: string;
|
|
5
6
|
name: string;
|
|
6
7
|
hubId: string[];
|
|
@@ -48,6 +49,11 @@ export interface IDevice {
|
|
|
48
49
|
capabilities?: Record<string, any>;
|
|
49
50
|
isDeleted?: boolean;
|
|
50
51
|
deletedAt?: Date;
|
|
52
|
+
/** Persisted maintenance; ZONE-sourced rows mirror parent zone toggles (smart-cloud). */
|
|
53
|
+
isUnderMaintenance?: boolean;
|
|
54
|
+
underMaintenanceSince?: string | Date | null;
|
|
55
|
+
maintenanceReason?: string | null;
|
|
56
|
+
maintenanceSource?: "ZONE" | "DEVICE" | null;
|
|
51
57
|
}
|
|
52
58
|
export declare class IStatus {
|
|
53
59
|
online: boolean;
|
|
@@ -8,6 +8,13 @@ export declare class DeviceRepository {
|
|
|
8
8
|
getDevice(deviceId: string, withHubDetails?: boolean): Promise<IDevice>;
|
|
9
9
|
updateDevice(deviceId: string, body: any): Promise<IDevice>;
|
|
10
10
|
updateDevices(query: any, updateData: any): Promise<any>;
|
|
11
|
+
/** Sync Mongo `devices_v2` when smart-cloud toggles zone maintenance (operational device-service). */
|
|
12
|
+
syncDevicesZoneMaintenance(body: {
|
|
13
|
+
zoneId: string;
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
maintenanceReason?: string | null;
|
|
16
|
+
underMaintenanceSince?: string | null;
|
|
17
|
+
}): Promise<any>;
|
|
11
18
|
deleteDevice(deviceId: string): Promise<void>;
|
|
12
19
|
getDevices(deviceIds: string[], withHubDetails?: boolean): Promise<IDevice[]>;
|
|
13
20
|
getPropertyDevices(propertyId: string, selectDeviceId?: boolean, type?: string, withHubDetails?: boolean): Promise<IDevice[]>;
|
|
@@ -96,6 +96,17 @@ let DeviceRepository = (() => {
|
|
|
96
96
|
throw new Error(`Failed to update devices: ${error.message}`);
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
|
+
/** Sync Mongo `devices_v2` when smart-cloud toggles zone maintenance (operational device-service). */
|
|
100
|
+
async syncDevicesZoneMaintenance(body) {
|
|
101
|
+
try {
|
|
102
|
+
const response = await this.axiosInstance.put(`/devices/maintenance/zone`, body);
|
|
103
|
+
return response.data;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
(0, config_1.getConfig)().LOGGER.error("Failed to sync zone maintenance to devices:", error);
|
|
107
|
+
throw new Error(`Failed to sync zone maintenance: ${error.message || "Unknown error"}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
99
110
|
async deleteDevice(deviceId) {
|
|
100
111
|
try {
|
|
101
112
|
await this.axiosInstance.delete(`/devices/${deviceId}`);
|
|
@@ -13,6 +13,14 @@ export declare class LocalDeviceService {
|
|
|
13
13
|
getDevices(deviceIds: string[], withHubDetails?: boolean): Promise<IDevice[]>;
|
|
14
14
|
getPropertyDevices(propertyId: string, selectDeviceId?: boolean, type?: string, withHubDetails?: boolean): Promise<IDevice[]>;
|
|
15
15
|
updateDevice(deviceId: string, body: Partial<IDevice>, auditBody: IAuditProperties): Promise<any>;
|
|
16
|
+
/**
|
|
17
|
+
* When a zone’s maintenance flag changes in smart-cloud, mirror the same rules as `dt_devices`
|
|
18
|
+
* onto operational Mongo (`devices_v2`) via device-service.
|
|
19
|
+
*/
|
|
20
|
+
syncDevicesZoneMaintenance(zoneId: string, enabled: boolean, options?: {
|
|
21
|
+
maintenanceReason?: string | null;
|
|
22
|
+
underMaintenanceSince?: string | Date | null;
|
|
23
|
+
}): Promise<any>;
|
|
16
24
|
updateDevices(query: any, updateData: any): Promise<any>;
|
|
17
25
|
deleteDevice(deviceId: string, auditBody: IAuditProperties): Promise<any>;
|
|
18
26
|
getState(deviceId: string): Promise<any>;
|
|
@@ -154,6 +154,27 @@ let LocalDeviceService = (() => {
|
|
|
154
154
|
await this.deviceRepository.updateDevice(deviceId, body);
|
|
155
155
|
return await this.eventHandler.onDeviceUpdate(deviceId, body, auditBody);
|
|
156
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* When a zone’s maintenance flag changes in smart-cloud, mirror the same rules as `dt_devices`
|
|
159
|
+
* onto operational Mongo (`devices_v2`) via device-service.
|
|
160
|
+
*/
|
|
161
|
+
async syncDevicesZoneMaintenance(zoneId, enabled, options) {
|
|
162
|
+
if (!zoneId) {
|
|
163
|
+
throw new Error("Zone ID is required");
|
|
164
|
+
}
|
|
165
|
+
const body = { zoneId, enabled };
|
|
166
|
+
if (enabled && options) {
|
|
167
|
+
if (options.maintenanceReason !== undefined) {
|
|
168
|
+
body.maintenanceReason = options.maintenanceReason;
|
|
169
|
+
}
|
|
170
|
+
const since = options.underMaintenanceSince;
|
|
171
|
+
if (since !== undefined && since !== null) {
|
|
172
|
+
body.underMaintenanceSince =
|
|
173
|
+
since instanceof Date ? since.toISOString() : since;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return await this.deviceRepository.syncDevicesZoneMaintenance(body);
|
|
177
|
+
}
|
|
157
178
|
async updateDevices(query, updateData) {
|
|
158
179
|
if (!query || !updateData) {
|
|
159
180
|
throw new Error("Query and update data are required");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import axios from "axios";
|
|
1
2
|
/**
|
|
2
3
|
* Validates if a URL is properly formatted and accessible
|
|
3
4
|
*/
|
|
@@ -5,7 +6,7 @@ export declare function validateServiceUrl(url: string): boolean;
|
|
|
5
6
|
/**
|
|
6
7
|
* Creates a properly configured axios instance with error handling
|
|
7
8
|
*/
|
|
8
|
-
export declare function createAxiosInstance(baseURL?: string):
|
|
9
|
+
export declare function createAxiosInstance(baseURL?: string): axios.AxiosInstance;
|
|
9
10
|
export declare function getDeviceServiceAxiosInstance(): any;
|
|
10
11
|
export declare function getAdminServiceAxiosInstance(): any;
|
|
11
12
|
export declare function getMonitoringServiceAxiosInstance(): any;
|
|
@@ -1,20 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
2
|
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
19
3
|
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
20
4
|
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
@@ -49,23 +33,6 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
49
33
|
}
|
|
50
34
|
return useValue ? value : void 0;
|
|
51
35
|
};
|
|
52
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
53
|
-
var ownKeys = function(o) {
|
|
54
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
55
|
-
var ar = [];
|
|
56
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
57
|
-
return ar;
|
|
58
|
-
};
|
|
59
|
-
return ownKeys(o);
|
|
60
|
-
};
|
|
61
|
-
return function (mod) {
|
|
62
|
-
if (mod && mod.__esModule) return mod;
|
|
63
|
-
var result = {};
|
|
64
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
65
|
-
__setModuleDefault(result, mod);
|
|
66
|
-
return result;
|
|
67
|
-
};
|
|
68
|
-
})();
|
|
69
36
|
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
70
37
|
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
71
38
|
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
@@ -144,7 +111,7 @@ let WebhookQueueService = (() => {
|
|
|
144
111
|
try {
|
|
145
112
|
// Create queue instance if not exists locally
|
|
146
113
|
if (!this.webhookQueues.has(queueName)) {
|
|
147
|
-
const { Queue } = await
|
|
114
|
+
const { Queue } = await import("bullmq");
|
|
148
115
|
const queue = new Queue(queueName, {
|
|
149
116
|
connection: (0, redis_1.getRedisClient)(),
|
|
150
117
|
});
|
|
@@ -219,7 +186,7 @@ let WebhookQueueService = (() => {
|
|
|
219
186
|
try {
|
|
220
187
|
// Create queue instance if not exists locally
|
|
221
188
|
if (!this.webhookQueues.has(queueName)) {
|
|
222
|
-
const { Queue } = await
|
|
189
|
+
const { Queue } = await import("bullmq");
|
|
223
190
|
const queue = new Queue(queueName, {
|
|
224
191
|
connection: (0, redis_1.getRedisClient)(),
|
|
225
192
|
});
|
|
@@ -245,7 +212,7 @@ let WebhookQueueService = (() => {
|
|
|
245
212
|
if (queues.has(queueKey)) {
|
|
246
213
|
return queues.get(queueKey);
|
|
247
214
|
}
|
|
248
|
-
const { Queue } = await
|
|
215
|
+
const { Queue } = await import("bullmq");
|
|
249
216
|
const queue = new Queue(queueKey, {
|
|
250
217
|
connection: (0, redis_1.getRedisClient)(),
|
|
251
218
|
});
|