dt-common-device 13.0.22 → 13.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/admin/Admin.repository.d.ts +7 -0
  2. package/dist/admin/Admin.service.d.ts +5 -0
  3. package/dist/admin/index.d.ts +1 -0
  4. package/dist/alerts/AlertBuilder.example.d.ts +11 -0
  5. package/dist/alerts/AlertService.example.d.ts +55 -0
  6. package/dist/audit/AuditProperties.d.ts +16 -0
  7. package/dist/chronicle/Cronicle.service.d.ts +9 -0
  8. package/dist/chronicle/IChronicle.interface.d.ts +14 -0
  9. package/dist/chronicle/ICronicle.interface.d.ts +15 -0
  10. package/dist/chronicle/chronicle.service.d.ts +4 -0
  11. package/dist/chronicle/index.d.ts +2 -0
  12. package/dist/connection/Connection.repository.d.ts +8 -0
  13. package/dist/connection/Connection.service.d.ts +8 -0
  14. package/dist/connection/IConnection.d.ts +28 -0
  15. package/dist/connection/index.d.ts +2 -0
  16. package/dist/constants/ConnectionProviders.d.ts +1 -0
  17. package/dist/constants/ConnectionProviders.js +1 -0
  18. package/dist/copilotQueue/examples/CopilotQueue.example.d.ts +37 -0
  19. package/dist/copilotQueue/examples/index.d.ts +1 -0
  20. package/dist/device/cloud/entities/CloudConnection.d.ts +6 -0
  21. package/dist/device/cloud/entities/CloudDevice.d.ts +16 -0
  22. package/dist/device/cloud/entities/CloudDeviceService.d.ts +5 -0
  23. package/dist/device/cloud/entities/DeviceFactory.d.ts +7 -0
  24. package/dist/device/cloud/entities/index.d.ts +3 -0
  25. package/dist/device/cloud/interface.d.ts +101 -0
  26. package/dist/device/cloud/interfaces/ICloudConnection.d.ts +5 -0
  27. package/dist/device/cloud/interfaces/ICloudDevice.d.ts +9 -0
  28. package/dist/device/cloud/interfaces/ICloudDeviceService.d.ts +4 -0
  29. package/dist/device/cloud/interfaces/IConnectionService.d.ts +7 -0
  30. package/dist/device/cloud/interfaces/IDeviceConnectionService.d.ts +7 -0
  31. package/dist/device/cloud/interfaces/IDeviceFactory.d.ts +4 -0
  32. package/dist/device/cloud/interfaces/IDeviceService.d.ts +8 -0
  33. package/dist/device/cloud/interfaces/IDevicesService.d.ts +9 -0
  34. package/dist/device/cloud/interfaces/IHubService.d.ts +5 -0
  35. package/dist/device/cloud/interfaces/IRawDataTransformer.d.ts +4 -0
  36. package/dist/device/cloud/interfaces/IRawDevice.d.ts +17 -0
  37. package/dist/device/cloud/interfaces/index.d.ts +5 -0
  38. package/dist/device/cloud/services/CloudDevice.service.d.ts +5 -0
  39. package/dist/device/cloud/services/Connection.service.d.ts +8 -0
  40. package/dist/device/cloud/services/Device.service.d.ts +39 -0
  41. package/dist/device/cloud/services/DeviceCloudService.d.ts +42 -0
  42. package/dist/device/cloud/services/DeviceHub.service.d.ts +3 -0
  43. package/dist/device/cloud/services/Hub.service.d.ts +25 -0
  44. package/dist/device/cloud/services/SmartThingsDeviceService.d.ts +38 -0
  45. package/dist/device/cloud/services/SmartThingsDeviceService.js +52 -0
  46. package/dist/device/cloud/services/index.d.ts +2 -0
  47. package/dist/device/cloud/types.d.ts +52 -0
  48. package/dist/device/cloud/types.js +15 -0
  49. package/dist/device/index.d.ts +4 -0
  50. package/dist/device/local/entities/AlertBuilder.d.ts +87 -0
  51. package/dist/device/local/entities/AlertBuilder.example.d.ts +11 -0
  52. package/dist/device/local/entities/IssueBuilder.d.ts +109 -0
  53. package/dist/device/local/entities/IssueBuilder.example.d.ts +16 -0
  54. package/dist/device/local/entities/IssueBuilder.example.js +196 -0
  55. package/dist/device/local/entities/IssueBuilder.js +237 -0
  56. package/dist/device/local/entities/index.d.ts +2 -0
  57. package/dist/device/local/events/EventHandler.d.ts +11 -0
  58. package/dist/device/local/events/Events.d.ts +54 -0
  59. package/dist/device/local/events/index.d.ts +2 -0
  60. package/dist/device/local/handler/EventHandler.d.ts +7 -0
  61. package/dist/device/local/interface.d.ts +0 -0
  62. package/dist/device/local/interfaces/IConnection.d.ts +26 -0
  63. package/dist/device/local/interfaces/IDevice.d.ts +68 -0
  64. package/dist/device/local/interfaces/IDtDevice.d.ts +16 -0
  65. package/dist/device/local/interfaces/IHub.d.ts +46 -0
  66. package/dist/device/local/interfaces/IProperty.d.ts +29 -0
  67. package/dist/device/local/interfaces/ISchedule.d.ts +25 -0
  68. package/dist/device/local/interfaces/index.d.ts +3 -0
  69. package/dist/device/local/models/Alert.model.d.ts +28 -0
  70. package/dist/device/local/models/Issue.model.d.ts +28 -0
  71. package/dist/device/local/repository/Alert.repository.d.ts +106 -0
  72. package/dist/device/local/repository/Connection.repository.d.ts +8 -0
  73. package/dist/device/local/repository/Device.repository.d.ts +30 -0
  74. package/dist/device/local/repository/Hub.repository.d.ts +13 -0
  75. package/dist/device/local/repository/Issue.repository.d.ts +113 -0
  76. package/dist/device/local/repository/Property.repository.d.ts +8 -0
  77. package/dist/device/local/repository/Property.repository.js +95 -0
  78. package/dist/device/local/repository/Schedule.repository.d.ts +9 -0
  79. package/dist/device/local/repository/Schedule.repository.js +109 -0
  80. package/dist/device/local/services/Alert.service.d.ts +137 -0
  81. package/dist/device/local/services/AlertService.example.d.ts +55 -0
  82. package/dist/device/local/services/Connection.service.d.ts +8 -0
  83. package/dist/device/local/services/Device.service.d.ts +40 -0
  84. package/dist/device/local/services/DeviceHub.service.d.ts +11 -0
  85. package/dist/device/local/services/Hub.service.d.ts +12 -0
  86. package/dist/device/local/services/Issue.service.d.ts +168 -0
  87. package/dist/device/local/services/Issue.service.js +642 -0
  88. package/dist/device/local/services/IssueService.example.d.ts +68 -0
  89. package/dist/device/local/services/IssueService.example.js +177 -0
  90. package/dist/device/local/services/Property.service.d.ts +8 -0
  91. package/dist/device/local/services/Property.service.js +36 -0
  92. package/dist/device/local/services/Schedule.service.d.ts +9 -0
  93. package/dist/device/local/services/Schedule.service.js +26 -0
  94. package/dist/device/local/services/index.d.ts +3 -0
  95. package/dist/entities/accessGroup/AccessGroup.repository.d.ts +5 -0
  96. package/dist/entities/accessGroup/AccessGroup.service.d.ts +5 -0
  97. package/dist/entities/accessGroup/IAccessGroup.d.ts +14 -0
  98. package/dist/entities/accessGroup/index.d.ts +2 -0
  99. package/dist/entities/device/local/repository/DeviceProfile.repository.d.ts +5 -0
  100. package/dist/entities/guest/Guest.repository.d.ts +6 -0
  101. package/dist/entities/guest/Guest.service.d.ts +6 -0
  102. package/dist/entities/guest/IGuest.d.ts +12 -0
  103. package/dist/entities/guest/index.d.ts +2 -0
  104. package/dist/entities/schedules/ISchedule.d.ts +14 -0
  105. package/dist/entities/schedules/Schedule.repository.d.ts +6 -0
  106. package/dist/entities/schedules/Schedule.repository.js +74 -0
  107. package/dist/entities/schedules/Schedule.service.d.ts +6 -0
  108. package/dist/entities/schedules/Schedule.service.js +104 -0
  109. package/dist/entities/schedules/index.d.ts +2 -0
  110. package/dist/entities/user/IUser.d.ts +15 -0
  111. package/dist/entities/user/IUser.js +2 -0
  112. package/dist/entities/user/User.repository.d.ts +5 -0
  113. package/dist/entities/user/User.repository.js +68 -0
  114. package/dist/entities/user/User.service.d.ts +6 -0
  115. package/dist/entities/user/User.service.js +103 -0
  116. package/dist/entities/zone/IZone.d.ts +10 -0
  117. package/dist/entities/zone/IZone.js +2 -0
  118. package/dist/entities/zone/Zone.repository.d.ts +6 -0
  119. package/dist/entities/zone/Zone.repository.js +77 -0
  120. package/dist/entities/zone/Zone.service.d.ts +6 -0
  121. package/dist/entities/zone/Zone.service.js +104 -0
  122. package/dist/entities/zone/index.d.ts +2 -0
  123. package/dist/issues/IssueBuilder.example.d.ts +16 -0
  124. package/dist/issues/IssueBuilder.example.js +196 -0
  125. package/dist/issues/IssueService.example.d.ts +68 -0
  126. package/dist/issues/IssueService.example.js +292 -0
  127. package/dist/pms/IPms.d.ts +6 -0
  128. package/dist/pms/index.d.ts +1 -0
  129. package/dist/pms/webhookQueue/examples/index.d.ts +2 -0
  130. package/dist/pms/webhookQueue/examples/pms-integration.d.ts +65 -0
  131. package/dist/pms/webhookQueue/examples/pms-integration.js +254 -0
  132. package/dist/pms/webhookQueue/examples/usage.d.ts +7 -0
  133. package/dist/pms/webhookQueue/examples/usage.js +175 -0
  134. package/dist/pms/webhookQueue/index.d.ts +3 -0
  135. package/dist/pms/webhookQueue/interfaces/IWebhookQueue.d.ts +33 -0
  136. package/dist/pms/webhookQueue/interfaces/IWebhookQueue.js +2 -0
  137. package/dist/pms/webhookQueue/interfaces/IWebhookWorker.d.ts +38 -0
  138. package/dist/pms/webhookQueue/interfaces/IWebhookWorker.js +2 -0
  139. package/dist/pms/webhookQueue/interfaces/index.d.ts +1 -0
  140. package/dist/pms/webhookQueue/services/WebhookQueueFactory.d.ts +38 -0
  141. package/dist/pms/webhookQueue/services/WebhookQueueFactory.js +131 -0
  142. package/dist/pms/webhookQueue/services/WebhookQueueIntegration.d.ts +70 -0
  143. package/dist/pms/webhookQueue/services/WebhookQueueIntegration.js +207 -0
  144. package/dist/pms/webhookQueue/services/WebhookQueueService.d.ts +45 -0
  145. package/dist/pms/webhookQueue/services/WebhookQueueService.js +270 -0
  146. package/dist/pms/webhookQueue/services/WebhookWorker.d.ts +37 -0
  147. package/dist/pms/webhookQueue/services/WebhookWorker.js +201 -0
  148. package/dist/pms/webhookQueue/services/index.d.ts +1 -0
  149. package/dist/pms/webhookQueue/types/index.d.ts +1 -0
  150. package/dist/pms/webhookQueue/types/webhook.types.d.ts +39 -0
  151. package/dist/pms/webhookQueue/types/webhook.types.js +2 -0
  152. package/dist/property/IProperty.d.ts +29 -0
  153. package/dist/property/Property.repository.d.ts +8 -0
  154. package/dist/property/Property.repository.js +109 -0
  155. package/dist/property/Property.service.d.ts +8 -0
  156. package/dist/property/Property.service.js +124 -0
  157. package/dist/property/index.d.ts +2 -0
  158. package/dist/queue/interfaces/IHttpRequestJob.d.ts +9 -0
  159. package/dist/queue/utils/rateLimit.utils.js +7 -1
  160. package/dist/types/alert.types.d.ts +57 -0
  161. package/dist/types/config.types.d.ts +19 -0
  162. package/dist/types/index.d.ts +3 -0
  163. package/dist/types/issue.types.d.ts +90 -0
  164. package/dist/types/issue.types.js +40 -0
  165. package/dist/utils/http-utils.d.ts +13 -0
  166. package/package.json +1 -1
@@ -0,0 +1,642 @@
1
+ "use strict";
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
35
+ };
36
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
37
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
38
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.IssueService = void 0;
42
+ const typedi_1 = require("typedi");
43
+ const Issue_model_1 = require("../models/Issue.model");
44
+ const issue_types_1 = require("../../../types/issue.types");
45
+ const IssueBuilder_1 = require("../entities/IssueBuilder");
46
+ let IssueService = (() => {
47
+ let _classDecorators = [(0, typedi_1.Service)()];
48
+ let _classDescriptor;
49
+ let _classExtraInitializers = [];
50
+ let _classThis;
51
+ var IssueService = _classThis = class {
52
+ constructor(issueRepository) {
53
+ this.issueRepository = issueRepository;
54
+ }
55
+ /**
56
+ * Create a readiness issue using IssueBuilder
57
+ */
58
+ async createReadinessIssue(propertyId, title, description, createdBy, entityId, entityType, assignedTo, dueDate) {
59
+ const issueBuilder = IssueBuilder_1.IssueBuilder.createReadinessIssue()
60
+ .setPropertyId(propertyId)
61
+ .setTitle(title)
62
+ .setDescription(description)
63
+ .setCreatedBy(createdBy);
64
+ if (entityId)
65
+ issueBuilder.setEntityId(entityId);
66
+ if (entityType)
67
+ issueBuilder.setEntityType(entityType);
68
+ if (assignedTo)
69
+ issueBuilder.setAssignedTo(assignedTo);
70
+ if (dueDate)
71
+ issueBuilder.setDueDate(dueDate);
72
+ return await this.createIssue(issueBuilder);
73
+ }
74
+ /**
75
+ * Create an operations issue using IssueBuilder
76
+ */
77
+ async createOperationsIssue(propertyId, title, description, createdBy, entityId, entityType, assignedTo, dueDate) {
78
+ const issueBuilder = IssueBuilder_1.IssueBuilder.createOperationsIssue()
79
+ .setPropertyId(propertyId)
80
+ .setTitle(title)
81
+ .setDescription(description)
82
+ .setCreatedBy(createdBy);
83
+ if (entityId)
84
+ issueBuilder.setEntityId(entityId);
85
+ if (entityType)
86
+ issueBuilder.setEntityType(entityType);
87
+ if (assignedTo)
88
+ issueBuilder.setAssignedTo(assignedTo);
89
+ if (dueDate)
90
+ issueBuilder.setDueDate(dueDate);
91
+ return await this.createIssue(issueBuilder);
92
+ }
93
+ /**
94
+ * Create a security issue using IssueBuilder
95
+ */
96
+ async createSecurityIssue(propertyId, title, description, createdBy, entityId, entityType, assignedTo, dueDate) {
97
+ const issueBuilder = IssueBuilder_1.IssueBuilder.createSecurityIssue()
98
+ .setPropertyId(propertyId)
99
+ .setTitle(title)
100
+ .setDescription(description)
101
+ .setCreatedBy(createdBy);
102
+ if (entityId)
103
+ issueBuilder.setEntityId(entityId);
104
+ if (entityType)
105
+ issueBuilder.setEntityType(entityType);
106
+ if (assignedTo)
107
+ issueBuilder.setAssignedTo(assignedTo);
108
+ if (dueDate)
109
+ issueBuilder.setDueDate(dueDate);
110
+ return await this.createIssue(issueBuilder);
111
+ }
112
+ /**
113
+ * Create an energy issue using IssueBuilder
114
+ */
115
+ async createEnergyIssue(propertyId, title, description, createdBy, entityId, entityType, assignedTo, dueDate) {
116
+ const issueBuilder = IssueBuilder_1.IssueBuilder.createEnergyIssue()
117
+ .setPropertyId(propertyId)
118
+ .setTitle(title)
119
+ .setDescription(description)
120
+ .setCreatedBy(createdBy);
121
+ if (entityId)
122
+ issueBuilder.setEntityId(entityId);
123
+ if (entityType)
124
+ issueBuilder.setEntityType(entityType);
125
+ if (assignedTo)
126
+ issueBuilder.setAssignedTo(assignedTo);
127
+ if (dueDate)
128
+ issueBuilder.setDueDate(dueDate);
129
+ return await this.createIssue(issueBuilder);
130
+ }
131
+ /**
132
+ * Create a device-specific issue using IssueBuilder
133
+ */
134
+ async createDeviceIssue(deviceId, propertyId, title, description, createdBy, category, priority, assignedTo, dueDate) {
135
+ const issueBuilder = IssueBuilder_1.IssueBuilder.createDeviceIssue(deviceId, propertyId)
136
+ .setTitle(title)
137
+ .setDescription(description)
138
+ .setCreatedBy(createdBy);
139
+ if (category)
140
+ issueBuilder.setCategory(category);
141
+ if (priority)
142
+ issueBuilder.setPriority(priority);
143
+ if (assignedTo)
144
+ issueBuilder.setAssignedTo(assignedTo);
145
+ if (dueDate)
146
+ issueBuilder.setDueDate(dueDate);
147
+ return await this.createIssue(issueBuilder);
148
+ }
149
+ /**
150
+ * Create a hub-specific issue using IssueBuilder
151
+ */
152
+ async createHubIssue(hubId, propertyId, title, description, createdBy, category, priority, assignedTo, dueDate) {
153
+ const issueBuilder = IssueBuilder_1.IssueBuilder.createHubIssue(hubId, propertyId)
154
+ .setTitle(title)
155
+ .setDescription(description)
156
+ .setCreatedBy(createdBy);
157
+ if (category)
158
+ issueBuilder.setCategory(category);
159
+ if (priority)
160
+ issueBuilder.setPriority(priority);
161
+ if (assignedTo)
162
+ issueBuilder.setAssignedTo(assignedTo);
163
+ if (dueDate)
164
+ issueBuilder.setDueDate(dueDate);
165
+ return await this.createIssue(issueBuilder);
166
+ }
167
+ /**
168
+ * Create a user-specific issue using IssueBuilder
169
+ */
170
+ async createUserIssue(userId, propertyId, title, description, createdBy, category, priority, assignedTo, dueDate) {
171
+ const issueBuilder = IssueBuilder_1.IssueBuilder.createUserIssue(userId, propertyId)
172
+ .setTitle(title)
173
+ .setDescription(description)
174
+ .setCreatedBy(createdBy);
175
+ if (category)
176
+ issueBuilder.setCategory(category);
177
+ if (priority)
178
+ issueBuilder.setPriority(priority);
179
+ if (assignedTo)
180
+ issueBuilder.setAssignedTo(assignedTo);
181
+ if (dueDate)
182
+ issueBuilder.setDueDate(dueDate);
183
+ return await this.createIssue(issueBuilder);
184
+ }
185
+ /**
186
+ * Create a maintenance issue using IssueBuilder
187
+ */
188
+ async createMaintenanceIssue(propertyId, title, description, createdBy, entityId, entityType, assignedTo, dueDate) {
189
+ const issueBuilder = IssueBuilder_1.IssueBuilder.createMaintenanceIssue(propertyId, entityId, entityType)
190
+ .setTitle(title)
191
+ .setDescription(description)
192
+ .setCreatedBy(createdBy);
193
+ if (assignedTo)
194
+ issueBuilder.setAssignedTo(assignedTo);
195
+ if (dueDate)
196
+ issueBuilder.setDueDate(dueDate);
197
+ return await this.createIssue(issueBuilder);
198
+ }
199
+ /**
200
+ * Create an urgent issue using IssueBuilder
201
+ */
202
+ async createUrgentIssue(propertyId, title, description, createdBy, entityId, entityType, assignedTo, dueDate) {
203
+ const issueBuilder = IssueBuilder_1.IssueBuilder.createUrgentIssue(propertyId, entityId, entityType)
204
+ .setTitle(title)
205
+ .setDescription(description)
206
+ .setCreatedBy(createdBy);
207
+ if (assignedTo)
208
+ issueBuilder.setAssignedTo(assignedTo);
209
+ if (dueDate)
210
+ issueBuilder.setDueDate(dueDate);
211
+ return await this.createIssue(issueBuilder);
212
+ }
213
+ /**
214
+ * Create a new issue with business logic validation
215
+ * Accepts either a CreateIssueData object or an IssueBuilder instance
216
+ */
217
+ async createIssue(issueData) {
218
+ let processedIssueData;
219
+ // Handle IssueBuilder instance
220
+ if (issueData instanceof IssueBuilder_1.IssueBuilder) {
221
+ processedIssueData = issueData.build();
222
+ }
223
+ else {
224
+ processedIssueData = issueData;
225
+ }
226
+ // Business logic: Validate issue data
227
+ this.validateIssueData(processedIssueData);
228
+ // Business logic: Set default priority if not provided
229
+ if (!processedIssueData.priority) {
230
+ processedIssueData.priority = this.determineDefaultPriority(processedIssueData.category);
231
+ }
232
+ // Business logic: Validate due date is in the future
233
+ if (processedIssueData.dueDate && processedIssueData.dueDate <= new Date()) {
234
+ throw new Error("Due date must be in the future");
235
+ }
236
+ return await this.issueRepository.create(processedIssueData);
237
+ }
238
+ /**
239
+ * Get issue by ID with business logic
240
+ */
241
+ async getIssueById(id, includeDeleted = false) {
242
+ if (!id) {
243
+ throw new Error("Issue ID is required");
244
+ }
245
+ const issue = await this.issueRepository.findById(id, includeDeleted);
246
+ // Business logic: Check if issue is overdue
247
+ if (issue?.dueDate &&
248
+ issue.dueDate < new Date() &&
249
+ issue.status !== issue_types_1.IssueStatus.RESOLVED) {
250
+ // You could add a flag or handle overdue logic here
251
+ console.warn(`Issue ${id} is overdue`);
252
+ }
253
+ return issue;
254
+ }
255
+ /**
256
+ * Get all issues with business logic filtering
257
+ */
258
+ async getIssues(filters = {}) {
259
+ // Business logic: Validate filters
260
+ this.validateFilters(filters);
261
+ // Business logic: Apply business rules to filters
262
+ const enhancedFilters = this.applyBusinessRules(filters);
263
+ return await this.issueRepository.findAll(enhancedFilters);
264
+ }
265
+ /**
266
+ * Update an issue with business logic validation
267
+ */
268
+ async updateIssue(id, updateData) {
269
+ if (!id) {
270
+ throw new Error("Issue ID is required");
271
+ }
272
+ // Business logic: Validate update data
273
+ this.validateUpdateData(updateData);
274
+ // Business logic: Check if issue exists and is not deleted
275
+ const existingIssue = await this.issueRepository.findById(id);
276
+ if (!existingIssue) {
277
+ throw new Error("Issue not found");
278
+ }
279
+ // Business logic: Handle status transitions
280
+ if (updateData.status) {
281
+ this.validateStatusTransition(existingIssue.status, updateData.status);
282
+ }
283
+ // Business logic: Handle priority changes
284
+ if (updateData.priority) {
285
+ this.validatePriorityChange(existingIssue.priority, updateData.priority);
286
+ }
287
+ return await this.issueRepository.update(id, updateData);
288
+ }
289
+ /**
290
+ * Soft delete an issue with business logic
291
+ */
292
+ async deleteIssue(id, deletedBy) {
293
+ if (!id || !deletedBy) {
294
+ throw new Error("Issue ID and deleted by user are required");
295
+ }
296
+ // Business logic: Check if issue can be deleted
297
+ const issue = await this.issueRepository.findById(id);
298
+ if (!issue) {
299
+ throw new Error("Issue not found");
300
+ }
301
+ // Business logic: Prevent deletion of resolved issues (optional rule)
302
+ if (issue.status === issue_types_1.IssueStatus.RESOLVED) {
303
+ throw new Error("Cannot delete resolved issues");
304
+ }
305
+ return await this.issueRepository.softDelete(id, deletedBy);
306
+ }
307
+ /**
308
+ * Permanently delete an issue
309
+ */
310
+ async permanentlyDeleteIssue(id) {
311
+ return await this.issueRepository.hardDelete(id);
312
+ }
313
+ /**
314
+ * Add a comment with business logic
315
+ */
316
+ async addComment(issueId, commentData) {
317
+ if (!issueId || !commentData.userId || !commentData.content) {
318
+ throw new Error("Issue ID, user ID, and comment content are required");
319
+ }
320
+ // Business logic: Check if issue exists and is active
321
+ const issue = await this.issueRepository.findById(issueId);
322
+ if (!issue) {
323
+ throw new Error("Issue not found");
324
+ }
325
+ if (issue.isDeleted) {
326
+ throw new Error("Cannot add comment to deleted issue");
327
+ }
328
+ // Business logic: Update issue status based on comment (optional)
329
+ const shouldUpdateStatus = this.shouldUpdateStatusOnComment(commentData.content);
330
+ if (shouldUpdateStatus && issue.status === issue_types_1.IssueStatus.PENDING) {
331
+ await this.issueRepository.update(issueId, {
332
+ status: issue_types_1.IssueStatus.IN_PROGRESS,
333
+ updatedBy: commentData.userId,
334
+ });
335
+ }
336
+ // Add comment using the model instance methods
337
+ const issueModel = await Issue_model_1.IssueModel.findById(issueId);
338
+ if (issueModel) {
339
+ issueModel.addComment(commentData);
340
+ return await issueModel.save();
341
+ }
342
+ return null;
343
+ }
344
+ /**
345
+ * Update a comment on an issue
346
+ */
347
+ async updateComment(issueId, commentId, content, userId) {
348
+ const issueModel = await Issue_model_1.IssueModel.findById(issueId);
349
+ if (!issueModel)
350
+ return false;
351
+ const success = issueModel.updateComment(commentId, content, userId);
352
+ if (success) {
353
+ await issueModel.save();
354
+ }
355
+ return success;
356
+ }
357
+ /**
358
+ * Remove a comment from an issue
359
+ */
360
+ async removeComment(issueId, commentId) {
361
+ const issueModel = await Issue_model_1.IssueModel.findById(issueId);
362
+ if (!issueModel)
363
+ return false;
364
+ const success = issueModel.removeComment(commentId);
365
+ if (success) {
366
+ await issueModel.save();
367
+ }
368
+ return success;
369
+ }
370
+ /**
371
+ * Resolve an issue with business logic
372
+ */
373
+ async resolveIssue(id, resolvedBy) {
374
+ if (!id || !resolvedBy) {
375
+ throw new Error("Issue ID and resolved by user are required");
376
+ }
377
+ // Business logic: Check if issue can be resolved
378
+ const issue = await this.issueRepository.findById(id);
379
+ if (!issue) {
380
+ throw new Error("Issue not found");
381
+ }
382
+ if (issue.status === issue_types_1.IssueStatus.RESOLVED) {
383
+ throw new Error("Issue is already resolved");
384
+ }
385
+ if (issue.status === issue_types_1.IssueStatus.CANCELLED) {
386
+ throw new Error("Cannot resolve cancelled issue");
387
+ }
388
+ // Business logic: Auto-assign if not assigned
389
+ if (!issue.assignedTo) {
390
+ await this.issueRepository.update(id, {
391
+ assignedTo: resolvedBy,
392
+ updatedBy: resolvedBy,
393
+ });
394
+ }
395
+ // Resolve the issue using model instance methods
396
+ const issueModel = await Issue_model_1.IssueModel.findById(id);
397
+ if (issueModel) {
398
+ issueModel.resolve(resolvedBy);
399
+ return await issueModel.save();
400
+ }
401
+ return null;
402
+ }
403
+ /**
404
+ * Reopen a resolved issue
405
+ */
406
+ async reopenIssue(id, reopenedBy) {
407
+ const issueModel = await Issue_model_1.IssueModel.findById(id);
408
+ if (!issueModel)
409
+ return null;
410
+ issueModel.reopen(reopenedBy);
411
+ return await issueModel.save();
412
+ }
413
+ /**
414
+ * Assign an issue with business logic
415
+ */
416
+ async assignIssue(id, userId, assignedBy) {
417
+ if (!id || !userId || !assignedBy) {
418
+ throw new Error("Issue ID, assignee user ID, and assigned by user are required");
419
+ }
420
+ // Business logic: Check if issue can be assigned
421
+ const issue = await this.issueRepository.findById(id);
422
+ if (!issue) {
423
+ throw new Error("Issue not found");
424
+ }
425
+ if (issue.status === issue_types_1.IssueStatus.RESOLVED ||
426
+ issue.status === issue_types_1.IssueStatus.CLOSED) {
427
+ throw new Error("Cannot assign resolved or closed issue");
428
+ }
429
+ // Business logic: Update status to IN_PROGRESS when assigned
430
+ const updateData = {
431
+ assignedTo: userId,
432
+ updatedBy: assignedBy,
433
+ };
434
+ if (issue.status === issue_types_1.IssueStatus.PENDING) {
435
+ updateData.status = issue_types_1.IssueStatus.IN_PROGRESS;
436
+ }
437
+ return await this.issueRepository.update(id, updateData);
438
+ }
439
+ /**
440
+ * Unassign an issue
441
+ */
442
+ async unassignIssue(id, unassignedBy) {
443
+ const issueModel = await Issue_model_1.IssueModel.findById(id);
444
+ if (!issueModel)
445
+ return null;
446
+ issueModel.unassign(unassignedBy);
447
+ return await issueModel.save();
448
+ }
449
+ /**
450
+ * Get issues by property with business logic
451
+ */
452
+ async getIssuesByProperty(propertyId, includeDeleted = false) {
453
+ if (!propertyId) {
454
+ throw new Error("Property ID is required");
455
+ }
456
+ return await this.issueRepository.findByProperty(propertyId, includeDeleted);
457
+ }
458
+ /**
459
+ * Get issues assigned to a user with business logic
460
+ */
461
+ async getIssuesByAssignee(assignedTo, includeDeleted = false) {
462
+ if (!assignedTo) {
463
+ throw new Error("Assignee user ID is required");
464
+ }
465
+ return await this.issueRepository.findByAssignee(assignedTo, includeDeleted);
466
+ }
467
+ /**
468
+ * Get issues by entity
469
+ */
470
+ async getIssuesByEntity(entityId, entityType, includeDeleted = false) {
471
+ return await this.issueRepository.findByEntity(entityId, entityType, includeDeleted);
472
+ }
473
+ /**
474
+ * Get issues by status
475
+ */
476
+ async getIssuesByStatus(status, includeDeleted = false) {
477
+ return await this.issueRepository.findByStatus(status, includeDeleted);
478
+ }
479
+ /**
480
+ * Get issues by priority
481
+ */
482
+ async getIssuesByPriority(priority, includeDeleted = false) {
483
+ return await this.issueRepository.findByPriority(priority, includeDeleted);
484
+ }
485
+ /**
486
+ * Get overdue issues with business logic
487
+ */
488
+ async getOverdueIssues(includeDeleted = false) {
489
+ const overdueIssues = await this.issueRepository.findOverdue(includeDeleted);
490
+ // Business logic: Log overdue issues for monitoring
491
+ if (overdueIssues.length > 0) {
492
+ console.warn(`Found ${overdueIssues.length} overdue issues`);
493
+ }
494
+ return overdueIssues;
495
+ }
496
+ /**
497
+ * Get upcoming issues (due within specified days)
498
+ */
499
+ async getUpcomingIssues(days = 7, includeDeleted = false) {
500
+ return await this.issueRepository.findUpcoming(days, includeDeleted);
501
+ }
502
+ /**
503
+ * Get issue statistics with business logic
504
+ */
505
+ async getIssueStatistics(propertyId) {
506
+ const stats = await this.issueRepository.getStatistics(propertyId);
507
+ // Business logic: Calculate additional metrics
508
+ const responseTime = this.calculateAverageResponseTime(stats);
509
+ const resolutionRate = this.calculateResolutionRate(stats);
510
+ // Log resolution rate for monitoring
511
+ console.log(`Resolution rate: ${resolutionRate.toFixed(2)}%`);
512
+ console.log(`Response time: ${responseTime.toFixed(2)} days`);
513
+ // Business logic: Add alerts for critical metrics
514
+ if (stats.overdue > 0) {
515
+ console.warn(`Alert: ${stats.overdue} overdue issues detected`);
516
+ }
517
+ if (stats.byPriority[issue_types_1.IssuePriority.CRITICAL] > 0) {
518
+ console.error(`Alert: ${stats.byPriority[issue_types_1.IssuePriority.CRITICAL]} critical issues require immediate attention`);
519
+ }
520
+ return stats;
521
+ }
522
+ /**
523
+ * Search issues with business logic
524
+ */
525
+ async searchIssues(searchTerm, filters = {}) {
526
+ if (!searchTerm || searchTerm.trim().length < 2) {
527
+ throw new Error("Search term must be at least 2 characters long");
528
+ }
529
+ return await this.issueRepository.search(searchTerm, filters);
530
+ }
531
+ // Private business logic methods
532
+ validateIssueData(data) {
533
+ if (!data.title || data.title.trim().length < 5) {
534
+ throw new Error("Issue title must be at least 5 characters long");
535
+ }
536
+ if (!data.description || data.description.trim().length < 10) {
537
+ throw new Error("Issue description must be at least 10 characters long");
538
+ }
539
+ if (!data.propertyId) {
540
+ throw new Error("Property ID is required");
541
+ }
542
+ if (!data.createdBy) {
543
+ throw new Error("Created by user ID is required");
544
+ }
545
+ }
546
+ validateFilters(filters) {
547
+ if (filters.limit && (filters.limit < 1 || filters.limit > 100)) {
548
+ throw new Error("Limit must be between 1 and 100");
549
+ }
550
+ if (filters.skip && filters.skip < 0) {
551
+ throw new Error("Skip must be non-negative");
552
+ }
553
+ }
554
+ validateUpdateData(data) {
555
+ if (data.title && data.title.trim().length < 5) {
556
+ throw new Error("Issue title must be at least 5 characters long");
557
+ }
558
+ if (data.description && data.description.trim().length < 10) {
559
+ throw new Error("Issue description must be at least 10 characters long");
560
+ }
561
+ }
562
+ validateStatusTransition(currentStatus, newStatus) {
563
+ const validTransitions = {
564
+ [issue_types_1.IssueStatus.PENDING]: [
565
+ issue_types_1.IssueStatus.IN_PROGRESS,
566
+ issue_types_1.IssueStatus.CANCELLED,
567
+ issue_types_1.IssueStatus.ON_HOLD,
568
+ ],
569
+ [issue_types_1.IssueStatus.IN_PROGRESS]: [
570
+ issue_types_1.IssueStatus.RESOLVED,
571
+ issue_types_1.IssueStatus.CANCELLED,
572
+ issue_types_1.IssueStatus.ON_HOLD,
573
+ ],
574
+ [issue_types_1.IssueStatus.RESOLVED]: [issue_types_1.IssueStatus.CLOSED, issue_types_1.IssueStatus.PENDING], // Reopen
575
+ [issue_types_1.IssueStatus.CLOSED]: [issue_types_1.IssueStatus.PENDING], // Reopen
576
+ [issue_types_1.IssueStatus.CANCELLED]: [issue_types_1.IssueStatus.PENDING], // Reopen
577
+ [issue_types_1.IssueStatus.ON_HOLD]: [issue_types_1.IssueStatus.PENDING, issue_types_1.IssueStatus.IN_PROGRESS],
578
+ };
579
+ if (!validTransitions[currentStatus]?.includes(newStatus)) {
580
+ throw new Error(`Invalid status transition from ${currentStatus} to ${newStatus}`);
581
+ }
582
+ }
583
+ validatePriorityChange(currentPriority, newPriority) {
584
+ // Business rule: Only allow priority escalation, not de-escalation for critical issues
585
+ if (currentPriority === issue_types_1.IssuePriority.CRITICAL &&
586
+ newPriority !== issue_types_1.IssuePriority.CRITICAL) {
587
+ throw new Error("Cannot de-escalate priority of critical issues");
588
+ }
589
+ }
590
+ determineDefaultPriority(category) {
591
+ // Business logic: Determine default priority based on category
592
+ const categoryPriorities = {
593
+ [issue_types_1.IssuesCategory.READINESS]: issue_types_1.IssuePriority.MEDIUM,
594
+ [issue_types_1.IssuesCategory.OPERATIONS]: issue_types_1.IssuePriority.HIGH,
595
+ [issue_types_1.IssuesCategory.SECURITY]: issue_types_1.IssuePriority.CRITICAL,
596
+ [issue_types_1.IssuesCategory.ENERGY]: issue_types_1.IssuePriority.LOW,
597
+ [issue_types_1.IssuesCategory.OTHER]: issue_types_1.IssuePriority.MEDIUM,
598
+ };
599
+ return categoryPriorities[category] || issue_types_1.IssuePriority.MEDIUM;
600
+ }
601
+ applyBusinessRules(filters) {
602
+ // Business logic: Apply additional filters based on business rules
603
+ const enhancedFilters = { ...filters };
604
+ // Example: Always exclude cancelled issues unless explicitly requested
605
+ if (!enhancedFilters.status ||
606
+ enhancedFilters.status !== issue_types_1.IssueStatus.CANCELLED) {
607
+ enhancedFilters.status = { $ne: issue_types_1.IssueStatus.CANCELLED };
608
+ }
609
+ return enhancedFilters;
610
+ }
611
+ shouldUpdateStatusOnComment(content) {
612
+ // Business logic: Determine if comment should trigger status change
613
+ const statusKeywords = [
614
+ "working on",
615
+ "investigating",
616
+ "fixing",
617
+ "resolving",
618
+ ];
619
+ return statusKeywords.some((keyword) => content.toLowerCase().includes(keyword));
620
+ }
621
+ calculateAverageResponseTime(stats) {
622
+ // Business logic: Calculate average response time (placeholder)
623
+ return 0;
624
+ }
625
+ calculateResolutionRate(stats) {
626
+ // Business logic: Calculate resolution rate
627
+ if (stats.total === 0)
628
+ return 0;
629
+ return ((stats.resolved + stats.closed) / stats.total) * 100;
630
+ }
631
+ };
632
+ __setFunctionName(_classThis, "IssueService");
633
+ (() => {
634
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
635
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
636
+ IssueService = _classThis = _classDescriptor.value;
637
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
638
+ __runInitializers(_classThis, _classExtraInitializers);
639
+ })();
640
+ return IssueService = _classThis;
641
+ })();
642
+ exports.IssueService = IssueService;