dt-common-device
Version:
A secure and robust device management library for IoT applications
475 lines (474 loc) • 20.5 kB
JavaScript
;
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
var _, done = false;
for (var i = decorators.length - 1; i >= 0; i--) {
var context = {};
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
if (kind === "accessor") {
if (result === void 0) continue;
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
if (_ = accept(result.get)) descriptor.get = _;
if (_ = accept(result.set)) descriptor.set = _;
if (_ = accept(result.init)) initializers.unshift(_);
}
else if (_ = accept(result)) {
if (kind === "field") initializers.unshift(_);
else descriptor[key] = _;
}
}
if (target) Object.defineProperty(target, contextIn.name, descriptor);
done = true;
};
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
var useValue = arguments.length > 2;
for (var i = 0; i < initializers.length; i++) {
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
}
return useValue ? value : void 0;
};
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AlertRepository = void 0;
const typedi_1 = require("typedi");
const Alert_model_1 = require("./Alert.model");
const alert_types_1 = require("./alert.types");
let AlertRepository = (() => {
let _classDecorators = [(0, typedi_1.Service)()];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
var AlertRepository = _classThis = class {
buildQuery(filters = {}) {
const query = {};
if (filters.propertyId)
query.propertyId = filters.propertyId;
if (filters.zoneId)
query.zoneId = filters.zoneId;
if (filters.category)
query.category = filters.category;
if (filters.severity)
query.severity = filters.severity;
if (filters.entityType)
query.entityType = filters.entityType;
if (filters.entityId)
query.entityId = filters.entityId;
if (filters.isActive !== undefined)
query.isActive = filters.isActive;
if (filters.isRead !== undefined)
query.isRead = filters.isRead;
if (!filters.includeDeleted)
query.isDeleted = false;
if (!filters.includeSnoozed)
query.snoozeUntil = { $exists: false, $eq: null };
if (filters.type) {
if (Array.isArray(filters.type)) {
query.type = { $in: filters.type };
}
else {
query.type = filters.type;
}
}
// Date filtering
if (filters.startDate || filters.endDate) {
query.createdAt = {};
if (filters.startDate)
query.createdAt.$gte = new Date(filters.startDate);
if (filters.endDate)
query.createdAt.$lte = new Date(filters.endDate);
}
return query;
}
buildOptions(filters = {}) {
const options = {};
if (filters.sort)
options.sort = filters.sort;
if (filters.skip)
options.skip = filters.skip;
if (filters.limit)
options.limit = filters.limit;
return options;
}
/**
* Create a new alert
*/
async create(alertData) {
try {
const alert = new Alert_model_1.AlertModel({
...alertData,
severity: alertData.severity || alert_types_1.AlertSeverity.LOW,
isRead: false,
isActive: true,
isDeleted: false,
});
const savedAlert = await alert.save();
return savedAlert.toObject();
}
catch (error) {
throw new Error(`Failed to create alert: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Find alert by ID
*/
async findById(id, includeDeleted = false) {
try {
const query = { _id: id };
if (!includeDeleted) {
query.isDeleted = false;
}
const result = await Alert_model_1.AlertModel.findOne(query);
return result ? result.toObject() : null;
}
catch (error) {
throw new Error(`Failed to find alert by ID: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Find all alerts with filters
*/
async query(filters = {}) {
try {
const query = this.buildQuery(filters);
const options = this.buildOptions(filters);
const results = await Alert_model_1.AlertModel.find(query, null, options);
return results.map((result) => result.toObject());
}
catch (error) {
throw new Error(`Failed to find alerts: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Update an alert
*/
async update(id, updateData) {
try {
const result = await Alert_model_1.AlertModel.findByIdAndUpdate(id, { ...updateData, updatedAt: new Date() }, { new: true, runValidators: true });
return result ? result.toObject() : null;
}
catch (error) {
throw new Error(`Failed to update alert: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Soft delete an alert
*/
async softDelete(id, deletedBy) {
try {
const result = await Alert_model_1.AlertModel.findByIdAndUpdate(id, {
isDeleted: true,
updatedBy: deletedBy,
updatedAt: new Date(),
});
return !!result;
}
catch (error) {
throw new Error(`Failed to soft delete alert: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Permanently delete an alert
*/
async hardDelete(id) {
try {
const result = await Alert_model_1.AlertModel.findByIdAndDelete(id);
return !!result;
}
catch (error) {
throw new Error(`Failed to permanently delete alert: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Count alerts with filters
*/
async count(filters = {}) {
try {
const query = this.buildQuery(filters);
return await Alert_model_1.AlertModel.countDocuments(query);
}
catch (error) {
throw new Error(`Failed to count alerts: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Find alerts by category
*/
async findByCategory(category, includeDeleted = false) {
try {
return await Alert_model_1.AlertModel.findByCategory(category, includeDeleted);
}
catch (error) {
throw new Error(`Failed to find alerts by category: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Find snoozed alerts
*/
async findSnoozed(includeDeleted = false) {
try {
return await Alert_model_1.AlertModel.findSnoozed(includeDeleted);
}
catch (error) {
throw new Error(`Failed to find snoozed alerts: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Find expired snooze alerts
*/
async findExpiredSnooze(includeDeleted = false) {
try {
return await Alert_model_1.AlertModel.findExpiredSnooze(includeDeleted);
}
catch (error) {
throw new Error(`Failed to find expired snooze alerts: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Get alert statistics
*/
async getStatistics(propertyId, zoneId) {
try {
const query = { isDeleted: false };
if (propertyId)
query.propertyId = propertyId;
if (zoneId)
query.zoneId = zoneId;
const [total, active, unread, snoozed, severityStats, categoryStats] = await Promise.all([
Alert_model_1.AlertModel.countDocuments(query),
Alert_model_1.AlertModel.countDocuments({ ...query, isActive: true }),
Alert_model_1.AlertModel.countDocuments({ ...query, isRead: false }),
Alert_model_1.AlertModel.countDocuments({
...query,
snoozeUntil: { $exists: true, $ne: null },
}),
Alert_model_1.AlertModel.aggregate([
{ $match: query },
{ $group: { _id: "$severity", count: { $sum: 1 } } },
]),
Alert_model_1.AlertModel.aggregate([
{ $match: query },
{ $group: { _id: "$category", count: { $sum: 1 } } },
]),
]);
const bySeverity = Object.values(alert_types_1.AlertSeverity).reduce((acc, severity) => {
acc[severity] = 0;
return acc;
}, {});
const byCategory = Object.values(alert_types_1.AlertCategory).reduce((acc, category) => {
acc[category] = 0;
return acc;
}, {});
// Type-safe handling of aggregation results
severityStats.forEach((stat) => {
if (stat._id in bySeverity) {
bySeverity[stat._id] = stat.count;
}
});
categoryStats.forEach((stat) => {
if (stat._id in byCategory) {
byCategory[stat._id] = stat.count;
}
});
return {
total,
active,
unread,
snoozed,
bySeverity,
byCategory,
};
}
catch (error) {
throw new Error(`Failed to get alert statistics: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Bulk update alerts
*/
async bulkUpdate(ids, updateData) {
try {
const result = await Alert_model_1.AlertModel.updateMany({ _id: { $in: ids } }, { ...updateData, updatedAt: new Date() });
return result.modifiedCount;
}
catch (error) {
throw new Error(`Failed to bulk update alerts: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Bulk soft delete alerts
*/
async bulkSoftDelete(ids, deletedBy) {
try {
const result = await Alert_model_1.AlertModel.updateMany({ _id: { $in: ids } }, {
isDeleted: true,
updatedBy: deletedBy,
updatedAt: new Date(),
});
return result.modifiedCount;
}
catch (error) {
throw new Error(`Failed to bulk soft delete alerts: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Find alerts by zone ID
*/
async findByZoneId(zoneId, includeDeleted = false) {
try {
const query = { zoneId };
if (!includeDeleted) {
query.isDeleted = false;
}
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
return results.map((result) => result.toObject());
}
catch (error) {
throw new Error(`Failed to find alerts by zone ID: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Find alerts by zone ID and category
*/
async findByZoneIdAndCategory(zoneId, category, includeDeleted = false) {
try {
const query = { zoneId, category };
if (!includeDeleted) {
query.isDeleted = false;
}
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
return results.map((result) => result.toObject());
}
catch (error) {
throw new Error(`Failed to find alerts by zone ID and category: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Find alerts by zone ID and severity
*/
async findByZoneIdAndSeverity(zoneId, severity, includeDeleted = false) {
try {
const query = { zoneId, severity };
if (!includeDeleted) {
query.isDeleted = false;
}
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
return results.map((result) => result.toObject());
}
catch (error) {
throw new Error(`Failed to find alerts by zone ID and severity: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Find alerts by zone ID and active status
*/
async findByZoneIdAndActiveStatus(zoneId, isActive, includeDeleted = false) {
try {
const query = { zoneId, isActive };
if (!includeDeleted) {
query.isDeleted = false;
}
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
return results.map((result) => result.toObject());
}
catch (error) {
throw new Error(`Failed to find alerts by zone ID and active status: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Find alerts by zone ID and read status
*/
async findByZoneIdAndReadStatus(zoneId, isRead, includeDeleted = false) {
try {
const query = { zoneId, isRead };
if (!includeDeleted) {
query.isDeleted = false;
}
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
return results.map((result) => result.toObject());
}
catch (error) {
throw new Error(`Failed to find alerts by zone ID and read status: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Find alerts by multiple zone IDs
*/
async findByZoneIds(zoneIds, includeDeleted = false) {
try {
if (!zoneIds || zoneIds.length === 0) {
throw new Error("Zone IDs array is required and cannot be empty");
}
const query = { zoneId: { $in: zoneIds } };
if (!includeDeleted) {
query.isDeleted = false;
}
const results = await Alert_model_1.AlertModel.find(query).sort({ createdAt: -1 });
return results.map((result) => result.toObject());
}
catch (error) {
throw new Error(`Failed to find alerts by zone IDs: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
/**
* Get alert statistics by zone ID and severity
*/
async getStatisticsByZoneAndSeverity(zoneId, severity) {
try {
const query = { isDeleted: false, zoneId };
if (severity)
query.severity = severity;
const [total, active, unread, snoozed, categoryStats] = await Promise.all([
Alert_model_1.AlertModel.countDocuments(query),
Alert_model_1.AlertModel.countDocuments({ ...query, isActive: true }),
Alert_model_1.AlertModel.countDocuments({ ...query, isRead: false }),
Alert_model_1.AlertModel.countDocuments({
...query,
snoozeUntil: { $exists: true, $ne: null },
}),
Alert_model_1.AlertModel.aggregate([
{ $match: query },
{ $group: { _id: "$category", count: { $sum: 1 } } },
]),
]);
const byCategory = Object.values(alert_types_1.AlertCategory).reduce((acc, category) => {
acc[category] = 0;
return acc;
}, {});
categoryStats.forEach((stat) => {
if (stat._id in byCategory) {
byCategory[stat._id] = stat.count;
}
});
return {
total,
active,
unread,
snoozed,
byCategory,
};
}
catch (error) {
throw new Error(`Failed to get alert statistics by zone and severity: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
};
__setFunctionName(_classThis, "AlertRepository");
(() => {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
AlertRepository = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
})();
return AlertRepository = _classThis;
})();
exports.AlertRepository = AlertRepository;