grm-shared-library 1.1.202 → 1.1.204

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 (244) hide show
  1. package/dist/cjs/index.js +1 -0
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/kafka/topics.js +26 -0
  4. package/dist/cjs/kafka/topics.js.map +1 -1
  5. package/dist/cjs/modules/common/constants/service.const.js +1 -0
  6. package/dist/cjs/modules/common/constants/service.const.js.map +1 -1
  7. package/dist/cjs/modules/permission/data/permissions.data.js +26 -0
  8. package/dist/cjs/modules/permission/data/permissions.data.js.map +1 -1
  9. package/dist/cjs/modules/permission/enums/permission-actions.enum.js +40 -0
  10. package/dist/cjs/modules/permission/enums/permission-actions.enum.js.map +1 -1
  11. package/dist/cjs/modules/permission/enums/permissions-module.enum.js +1 -0
  12. package/dist/cjs/modules/permission/enums/permissions-module.enum.js.map +1 -1
  13. package/dist/cjs/modules/role/data/roles.data.js +83 -0
  14. package/dist/cjs/modules/role/data/roles.data.js.map +1 -1
  15. package/dist/cjs/modules/socket/enums/redis-channel-name.enum.js +1 -0
  16. package/dist/cjs/modules/socket/enums/redis-channel-name.enum.js.map +1 -1
  17. package/dist/cjs/modules/socket/enums/room-type.enum.js +8 -0
  18. package/dist/cjs/modules/socket/enums/room-type.enum.js.map +1 -1
  19. package/dist/cjs/modules/socket/enums/socket-event-name.enum.js +5 -0
  20. package/dist/cjs/modules/socket/enums/socket-event-name.enum.js.map +1 -1
  21. package/dist/cjs/modules/support/constants/support-defaults.const.js +139 -0
  22. package/dist/cjs/modules/support/constants/support-defaults.const.js.map +1 -0
  23. package/dist/cjs/modules/support/constants/support-kafka.const.js +51 -0
  24. package/dist/cjs/modules/support/constants/support-kafka.const.js.map +1 -0
  25. package/dist/cjs/modules/support/dtos/create-support-ticket-message.dto.js +82 -0
  26. package/dist/cjs/modules/support/dtos/create-support-ticket-message.dto.js.map +1 -0
  27. package/dist/cjs/modules/support/dtos/create-support-ticket.dto.js +169 -0
  28. package/dist/cjs/modules/support/dtos/create-support-ticket.dto.js.map +1 -0
  29. package/dist/cjs/modules/support/dtos/customer-feedback.dto.js +401 -0
  30. package/dist/cjs/modules/support/dtos/customer-feedback.dto.js.map +1 -0
  31. package/dist/cjs/modules/support/dtos/support-configuration.dto.js +732 -0
  32. package/dist/cjs/modules/support/dtos/support-configuration.dto.js.map +1 -0
  33. package/dist/cjs/modules/support/dtos/support-related-entity.dto.js +38 -0
  34. package/dist/cjs/modules/support/dtos/support-related-entity.dto.js.map +1 -0
  35. package/dist/cjs/modules/support/dtos/support-report-query.dto.js +127 -0
  36. package/dist/cjs/modules/support/dtos/support-report-query.dto.js.map +1 -0
  37. package/dist/cjs/modules/support/dtos/support-sync.dto.js +175 -0
  38. package/dist/cjs/modules/support/dtos/support-sync.dto.js.map +1 -0
  39. package/dist/cjs/modules/support/dtos/support-ticket-actions.dto.js +225 -0
  40. package/dist/cjs/modules/support/dtos/support-ticket-actions.dto.js.map +1 -0
  41. package/dist/cjs/modules/support/dtos/support-ticket-query.dto.js +225 -0
  42. package/dist/cjs/modules/support/dtos/support-ticket-query.dto.js.map +1 -0
  43. package/dist/cjs/modules/support/enums/support-audit-action.enum.js +87 -0
  44. package/dist/cjs/modules/support/enums/support-audit-action.enum.js.map +1 -0
  45. package/dist/cjs/modules/support/enums/support-feedback.enum.js +110 -0
  46. package/dist/cjs/modules/support/enums/support-feedback.enum.js.map +1 -0
  47. package/dist/cjs/modules/support/enums/support-provider-code.enum.js +66 -0
  48. package/dist/cjs/modules/support/enums/support-provider-code.enum.js.map +1 -0
  49. package/dist/cjs/modules/support/enums/support-related-entity-type.enum.js +50 -0
  50. package/dist/cjs/modules/support/enums/support-related-entity-type.enum.js.map +1 -0
  51. package/dist/cjs/modules/support/enums/support-routing.enum.js +58 -0
  52. package/dist/cjs/modules/support/enums/support-routing.enum.js.map +1 -0
  53. package/dist/cjs/modules/support/enums/support-sla.enum.js +55 -0
  54. package/dist/cjs/modules/support/enums/support-sla.enum.js.map +1 -0
  55. package/dist/cjs/modules/support/enums/support-sync.enum.js +133 -0
  56. package/dist/cjs/modules/support/enums/support-sync.enum.js.map +1 -0
  57. package/dist/cjs/modules/support/enums/support-ticket-channel.enum.js +36 -0
  58. package/dist/cjs/modules/support/enums/support-ticket-channel.enum.js.map +1 -0
  59. package/dist/cjs/modules/support/enums/support-ticket-message.enum.js +54 -0
  60. package/dist/cjs/modules/support/enums/support-ticket-message.enum.js.map +1 -0
  61. package/dist/cjs/modules/support/enums/support-ticket-priority.enum.js +41 -0
  62. package/dist/cjs/modules/support/enums/support-ticket-priority.enum.js.map +1 -0
  63. package/dist/cjs/modules/support/enums/support-ticket-status.enum.js +138 -0
  64. package/dist/cjs/modules/support/enums/support-ticket-status.enum.js.map +1 -0
  65. package/dist/cjs/modules/support/index.js +60 -0
  66. package/dist/cjs/modules/support/index.js.map +1 -0
  67. package/dist/cjs/modules/support/interfaces/customer-feedback.js +3 -0
  68. package/dist/cjs/modules/support/interfaces/customer-feedback.js.map +1 -0
  69. package/dist/cjs/modules/support/interfaces/support-configuration.js +3 -0
  70. package/dist/cjs/modules/support/interfaces/support-configuration.js.map +1 -0
  71. package/dist/cjs/modules/support/interfaces/support-events.js +3 -0
  72. package/dist/cjs/modules/support/interfaces/support-events.js.map +1 -0
  73. package/dist/cjs/modules/support/interfaces/support-provider-descriptor.js +3 -0
  74. package/dist/cjs/modules/support/interfaces/support-provider-descriptor.js.map +1 -0
  75. package/dist/cjs/modules/support/interfaces/support-realtime.js +18 -0
  76. package/dist/cjs/modules/support/interfaces/support-realtime.js.map +1 -0
  77. package/dist/cjs/modules/support/interfaces/support-reports.js +3 -0
  78. package/dist/cjs/modules/support/interfaces/support-reports.js.map +1 -0
  79. package/dist/cjs/modules/support/interfaces/support-sync.js +3 -0
  80. package/dist/cjs/modules/support/interfaces/support-sync.js.map +1 -0
  81. package/dist/cjs/modules/support/interfaces/support-ticket-message.js +3 -0
  82. package/dist/cjs/modules/support/interfaces/support-ticket-message.js.map +1 -0
  83. package/dist/cjs/modules/support/interfaces/support-ticket.js +3 -0
  84. package/dist/cjs/modules/support/interfaces/support-ticket.js.map +1 -0
  85. package/dist/cjs/modules/support/utils/support-feedback.util.js +66 -0
  86. package/dist/cjs/modules/support/utils/support-feedback.util.js.map +1 -0
  87. package/dist/cjs/modules/support/utils/support-redaction.util.js +173 -0
  88. package/dist/cjs/modules/support/utils/support-redaction.util.js.map +1 -0
  89. package/dist/cjs/modules/support/utils/support-routing.util.js +87 -0
  90. package/dist/cjs/modules/support/utils/support-routing.util.js.map +1 -0
  91. package/dist/cjs/modules/support/utils/support-sla.util.js +239 -0
  92. package/dist/cjs/modules/support/utils/support-sla.util.js.map +1 -0
  93. package/dist/cjs/modules/support/utils/support-status.util.js +93 -0
  94. package/dist/cjs/modules/support/utils/support-status.util.js.map +1 -0
  95. package/dist/cjs/modules/support/utils/support-sync.util.js +151 -0
  96. package/dist/cjs/modules/support/utils/support-sync.util.js.map +1 -0
  97. package/dist/cjs/modules/support/utils/support-ticket-number.util.js +61 -0
  98. package/dist/cjs/modules/support/utils/support-ticket-number.util.js.map +1 -0
  99. package/dist/esm/index.js +1 -0
  100. package/dist/esm/index.js.map +1 -1
  101. package/dist/esm/kafka/topics.js +26 -0
  102. package/dist/esm/kafka/topics.js.map +1 -1
  103. package/dist/esm/modules/common/constants/service.const.js +1 -0
  104. package/dist/esm/modules/common/constants/service.const.js.map +1 -1
  105. package/dist/esm/modules/permission/data/permissions.data.js +26 -0
  106. package/dist/esm/modules/permission/data/permissions.data.js.map +1 -1
  107. package/dist/esm/modules/permission/enums/permission-actions.enum.js +40 -0
  108. package/dist/esm/modules/permission/enums/permission-actions.enum.js.map +1 -1
  109. package/dist/esm/modules/permission/enums/permissions-module.enum.js +1 -0
  110. package/dist/esm/modules/permission/enums/permissions-module.enum.js.map +1 -1
  111. package/dist/esm/modules/role/data/roles.data.js +83 -0
  112. package/dist/esm/modules/role/data/roles.data.js.map +1 -1
  113. package/dist/esm/modules/socket/enums/redis-channel-name.enum.js +1 -0
  114. package/dist/esm/modules/socket/enums/redis-channel-name.enum.js.map +1 -1
  115. package/dist/esm/modules/socket/enums/room-type.enum.js +8 -0
  116. package/dist/esm/modules/socket/enums/room-type.enum.js.map +1 -1
  117. package/dist/esm/modules/socket/enums/socket-event-name.enum.js +5 -0
  118. package/dist/esm/modules/socket/enums/socket-event-name.enum.js.map +1 -1
  119. package/dist/esm/modules/support/constants/support-defaults.const.js +136 -0
  120. package/dist/esm/modules/support/constants/support-defaults.const.js.map +1 -0
  121. package/dist/esm/modules/support/constants/support-kafka.const.js +48 -0
  122. package/dist/esm/modules/support/constants/support-kafka.const.js.map +1 -0
  123. package/dist/esm/modules/support/dtos/create-support-ticket-message.dto.js +77 -0
  124. package/dist/esm/modules/support/dtos/create-support-ticket-message.dto.js.map +1 -0
  125. package/dist/esm/modules/support/dtos/create-support-ticket.dto.js +165 -0
  126. package/dist/esm/modules/support/dtos/create-support-ticket.dto.js.map +1 -0
  127. package/dist/esm/modules/support/dtos/customer-feedback.dto.js +392 -0
  128. package/dist/esm/modules/support/dtos/customer-feedback.dto.js.map +1 -0
  129. package/dist/esm/modules/support/dtos/support-configuration.dto.js +716 -0
  130. package/dist/esm/modules/support/dtos/support-configuration.dto.js.map +1 -0
  131. package/dist/esm/modules/support/dtos/support-related-entity.dto.js +34 -0
  132. package/dist/esm/modules/support/dtos/support-related-entity.dto.js.map +1 -0
  133. package/dist/esm/modules/support/dtos/support-report-query.dto.js +123 -0
  134. package/dist/esm/modules/support/dtos/support-report-query.dto.js.map +1 -0
  135. package/dist/esm/modules/support/dtos/support-sync.dto.js +169 -0
  136. package/dist/esm/modules/support/dtos/support-sync.dto.js.map +1 -0
  137. package/dist/esm/modules/support/dtos/support-ticket-actions.dto.js +213 -0
  138. package/dist/esm/modules/support/dtos/support-ticket-actions.dto.js.map +1 -0
  139. package/dist/esm/modules/support/dtos/support-ticket-query.dto.js +221 -0
  140. package/dist/esm/modules/support/dtos/support-ticket-query.dto.js.map +1 -0
  141. package/dist/esm/modules/support/enums/support-audit-action.enum.js +84 -0
  142. package/dist/esm/modules/support/enums/support-audit-action.enum.js.map +1 -0
  143. package/dist/esm/modules/support/enums/support-feedback.enum.js +107 -0
  144. package/dist/esm/modules/support/enums/support-feedback.enum.js.map +1 -0
  145. package/dist/esm/modules/support/enums/support-provider-code.enum.js +63 -0
  146. package/dist/esm/modules/support/enums/support-provider-code.enum.js.map +1 -0
  147. package/dist/esm/modules/support/enums/support-related-entity-type.enum.js +47 -0
  148. package/dist/esm/modules/support/enums/support-related-entity-type.enum.js.map +1 -0
  149. package/dist/esm/modules/support/enums/support-routing.enum.js +55 -0
  150. package/dist/esm/modules/support/enums/support-routing.enum.js.map +1 -0
  151. package/dist/esm/modules/support/enums/support-sla.enum.js +52 -0
  152. package/dist/esm/modules/support/enums/support-sla.enum.js.map +1 -0
  153. package/dist/esm/modules/support/enums/support-sync.enum.js +130 -0
  154. package/dist/esm/modules/support/enums/support-sync.enum.js.map +1 -0
  155. package/dist/esm/modules/support/enums/support-ticket-channel.enum.js +33 -0
  156. package/dist/esm/modules/support/enums/support-ticket-channel.enum.js.map +1 -0
  157. package/dist/esm/modules/support/enums/support-ticket-message.enum.js +51 -0
  158. package/dist/esm/modules/support/enums/support-ticket-message.enum.js.map +1 -0
  159. package/dist/esm/modules/support/enums/support-ticket-priority.enum.js +38 -0
  160. package/dist/esm/modules/support/enums/support-ticket-priority.enum.js.map +1 -0
  161. package/dist/esm/modules/support/enums/support-ticket-status.enum.js +135 -0
  162. package/dist/esm/modules/support/enums/support-ticket-status.enum.js.map +1 -0
  163. package/dist/esm/modules/support/index.js +44 -0
  164. package/dist/esm/modules/support/index.js.map +1 -0
  165. package/dist/esm/modules/support/interfaces/customer-feedback.js +2 -0
  166. package/dist/esm/modules/support/interfaces/customer-feedback.js.map +1 -0
  167. package/dist/esm/modules/support/interfaces/support-configuration.js +2 -0
  168. package/dist/esm/modules/support/interfaces/support-configuration.js.map +1 -0
  169. package/dist/esm/modules/support/interfaces/support-events.js +2 -0
  170. package/dist/esm/modules/support/interfaces/support-events.js.map +1 -0
  171. package/dist/esm/modules/support/interfaces/support-provider-descriptor.js +2 -0
  172. package/dist/esm/modules/support/interfaces/support-provider-descriptor.js.map +1 -0
  173. package/dist/esm/modules/support/interfaces/support-realtime.js +15 -0
  174. package/dist/esm/modules/support/interfaces/support-realtime.js.map +1 -0
  175. package/dist/esm/modules/support/interfaces/support-reports.js +2 -0
  176. package/dist/esm/modules/support/interfaces/support-reports.js.map +1 -0
  177. package/dist/esm/modules/support/interfaces/support-sync.js +2 -0
  178. package/dist/esm/modules/support/interfaces/support-sync.js.map +1 -0
  179. package/dist/esm/modules/support/interfaces/support-ticket-message.js +2 -0
  180. package/dist/esm/modules/support/interfaces/support-ticket-message.js.map +1 -0
  181. package/dist/esm/modules/support/interfaces/support-ticket.js +2 -0
  182. package/dist/esm/modules/support/interfaces/support-ticket.js.map +1 -0
  183. package/dist/esm/modules/support/utils/support-feedback.util.js +60 -0
  184. package/dist/esm/modules/support/utils/support-feedback.util.js.map +1 -0
  185. package/dist/esm/modules/support/utils/support-redaction.util.js +164 -0
  186. package/dist/esm/modules/support/utils/support-redaction.util.js.map +1 -0
  187. package/dist/esm/modules/support/utils/support-routing.util.js +82 -0
  188. package/dist/esm/modules/support/utils/support-routing.util.js.map +1 -0
  189. package/dist/esm/modules/support/utils/support-sla.util.js +229 -0
  190. package/dist/esm/modules/support/utils/support-sla.util.js.map +1 -0
  191. package/dist/esm/modules/support/utils/support-status.util.js +81 -0
  192. package/dist/esm/modules/support/utils/support-status.util.js.map +1 -0
  193. package/dist/esm/modules/support/utils/support-sync.util.js +142 -0
  194. package/dist/esm/modules/support/utils/support-sync.util.js.map +1 -0
  195. package/dist/esm/modules/support/utils/support-ticket-number.util.js +56 -0
  196. package/dist/esm/modules/support/utils/support-ticket-number.util.js.map +1 -0
  197. package/dist/types/index.d.ts +1 -0
  198. package/dist/types/kafka/topics.d.ts +21 -0
  199. package/dist/types/modules/common/constants/service.const.d.ts +4 -0
  200. package/dist/types/modules/permission/enums/permission-actions.enum.d.ts +21 -0
  201. package/dist/types/modules/permission/enums/permissions-module.enum.d.ts +2 -1
  202. package/dist/types/modules/socket/enums/redis-channel-name.enum.d.ts +2 -1
  203. package/dist/types/modules/socket/enums/room-type.enum.d.ts +8 -0
  204. package/dist/types/modules/socket/enums/socket-event-name.enum.d.ts +2 -1
  205. package/dist/types/modules/support/constants/support-defaults.const.d.ts +129 -0
  206. package/dist/types/modules/support/constants/support-kafka.const.d.ts +47 -0
  207. package/dist/types/modules/support/dtos/create-support-ticket-message.dto.d.ts +30 -0
  208. package/dist/types/modules/support/dtos/create-support-ticket.dto.d.ts +35 -0
  209. package/dist/types/modules/support/dtos/customer-feedback.dto.d.ts +83 -0
  210. package/dist/types/modules/support/dtos/support-configuration.dto.d.ts +130 -0
  211. package/dist/types/modules/support/dtos/support-related-entity.dto.d.ts +13 -0
  212. package/dist/types/modules/support/dtos/support-report-query.dto.d.ts +29 -0
  213. package/dist/types/modules/support/dtos/support-sync.dto.d.ts +40 -0
  214. package/dist/types/modules/support/dtos/support-ticket-actions.dto.d.ts +74 -0
  215. package/dist/types/modules/support/dtos/support-ticket-query.dto.d.ts +41 -0
  216. package/dist/types/modules/support/enums/support-audit-action.enum.d.ts +80 -0
  217. package/dist/types/modules/support/enums/support-feedback.enum.d.ts +65 -0
  218. package/dist/types/modules/support/enums/support-provider-code.enum.d.ts +57 -0
  219. package/dist/types/modules/support/enums/support-related-entity-type.enum.d.ts +41 -0
  220. package/dist/types/modules/support/enums/support-routing.enum.d.ts +48 -0
  221. package/dist/types/modules/support/enums/support-sla.enum.d.ts +47 -0
  222. package/dist/types/modules/support/enums/support-sync.enum.d.ts +108 -0
  223. package/dist/types/modules/support/enums/support-ticket-channel.enum.d.ts +30 -0
  224. package/dist/types/modules/support/enums/support-ticket-message.enum.d.ts +42 -0
  225. package/dist/types/modules/support/enums/support-ticket-priority.enum.d.ts +24 -0
  226. package/dist/types/modules/support/enums/support-ticket-status.enum.d.ts +58 -0
  227. package/dist/types/modules/support/index.d.ts +38 -0
  228. package/dist/types/modules/support/interfaces/customer-feedback.d.ts +115 -0
  229. package/dist/types/modules/support/interfaces/support-configuration.d.ts +170 -0
  230. package/dist/types/modules/support/interfaces/support-events.d.ts +126 -0
  231. package/dist/types/modules/support/interfaces/support-provider-descriptor.d.ts +92 -0
  232. package/dist/types/modules/support/interfaces/support-realtime.d.ts +65 -0
  233. package/dist/types/modules/support/interfaces/support-reports.d.ts +162 -0
  234. package/dist/types/modules/support/interfaces/support-sync.d.ts +105 -0
  235. package/dist/types/modules/support/interfaces/support-ticket-message.d.ts +66 -0
  236. package/dist/types/modules/support/interfaces/support-ticket.d.ts +180 -0
  237. package/dist/types/modules/support/utils/support-feedback.util.d.ts +23 -0
  238. package/dist/types/modules/support/utils/support-redaction.util.d.ts +48 -0
  239. package/dist/types/modules/support/utils/support-routing.util.d.ts +50 -0
  240. package/dist/types/modules/support/utils/support-sla.util.d.ts +69 -0
  241. package/dist/types/modules/support/utils/support-status.util.d.ts +44 -0
  242. package/dist/types/modules/support/utils/support-sync.util.d.ts +76 -0
  243. package/dist/types/modules/support/utils/support-ticket-number.util.d.ts +39 -0
  244. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support-sync.js","sourceRoot":"","sources":["../../../../../src/modules/support/interfaces/support-sync.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=support-ticket-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support-ticket-message.js","sourceRoot":"","sources":["../../../../../src/modules/support/interfaces/support-ticket-message.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=support-ticket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support-ticket.js","sourceRoot":"","sources":["../../../../../src/modules/support/interfaces/support-ticket.ts"],"names":[],"mappings":""}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.feedbackTypeRequiresRating = feedbackTypeRequiresRating;
4
+ exports.deriveFeedbackSentiment = deriveFeedbackSentiment;
5
+ exports.isValidFeedbackRating = isValidFeedbackRating;
6
+ exports.feedbackWarrantsTicket = feedbackWarrantsTicket;
7
+ const support_defaults_const_1 = require("../constants/support-defaults.const");
8
+ const support_feedback_enum_1 = require("../enums/support-feedback.enum");
9
+ /** Whether this kind of feedback carries a star rating. */
10
+ function feedbackTypeRequiresRating(type) {
11
+ return support_feedback_enum_1.RATING_CUSTOMER_FEEDBACK_TYPES.includes(type);
12
+ }
13
+ /**
14
+ * Derive sentiment from the feedback TYPE and rating.
15
+ *
16
+ * Never from the message text. An automated reading of "the guard never came"
17
+ * that lands on POSITIVE is worse than no reading at all, and a support desk
18
+ * that starts distrusting one column stops trusting the dashboard. When a real
19
+ * classifier is added it writes this same field, and the rule below becomes its
20
+ * fallback rather than being replaced.
21
+ */
22
+ function deriveFeedbackSentiment(type, rating) {
23
+ if (rating != null && Number.isFinite(rating)) {
24
+ if (rating <= support_defaults_const_1.SUPPORT_FEEDBACK_RATING.NEGATIVE_AT_OR_BELOW) {
25
+ return support_feedback_enum_1.CustomerFeedbackSentiment.NEGATIVE;
26
+ }
27
+ if (rating >= support_defaults_const_1.SUPPORT_FEEDBACK_RATING.POSITIVE_AT_OR_ABOVE) {
28
+ return support_feedback_enum_1.CustomerFeedbackSentiment.POSITIVE;
29
+ }
30
+ return support_feedback_enum_1.CustomerFeedbackSentiment.NEUTRAL;
31
+ }
32
+ switch (type) {
33
+ case support_feedback_enum_1.CustomerFeedbackType.COMPLIMENT:
34
+ return support_feedback_enum_1.CustomerFeedbackSentiment.POSITIVE;
35
+ case support_feedback_enum_1.CustomerFeedbackType.COMPLAINT:
36
+ case support_feedback_enum_1.CustomerFeedbackType.BUG_REPORT:
37
+ return support_feedback_enum_1.CustomerFeedbackSentiment.NEGATIVE;
38
+ case support_feedback_enum_1.CustomerFeedbackType.FEATURE_REQUEST:
39
+ case support_feedback_enum_1.CustomerFeedbackType.GENERAL:
40
+ return support_feedback_enum_1.CustomerFeedbackSentiment.NEUTRAL;
41
+ default:
42
+ return support_feedback_enum_1.CustomerFeedbackSentiment.UNKNOWN;
43
+ }
44
+ }
45
+ /** Whether a rating is inside the allowed range. */
46
+ function isValidFeedbackRating(rating) {
47
+ if (typeof rating !== 'number' || !Number.isFinite(rating))
48
+ return false;
49
+ if (!Number.isInteger(rating))
50
+ return false;
51
+ return rating >= support_defaults_const_1.SUPPORT_FEEDBACK_RATING.MIN && rating <= support_defaults_const_1.SUPPORT_FEEDBACK_RATING.MAX;
52
+ }
53
+ /**
54
+ * Whether a piece of feedback is the kind an agent should probably act on.
55
+ *
56
+ * Advisory only - it drives a hint in the admin, never an automatic conversion.
57
+ * Promoting somebody's complaint into a ticket without a human deciding is how a
58
+ * queue fills with work nobody chose to take on.
59
+ */
60
+ function feedbackWarrantsTicket(type, rating) {
61
+ if (type === support_feedback_enum_1.CustomerFeedbackType.BUG_REPORT || type === support_feedback_enum_1.CustomerFeedbackType.COMPLAINT) {
62
+ return true;
63
+ }
64
+ return rating != null && rating <= support_defaults_const_1.SUPPORT_FEEDBACK_RATING.NEGATIVE_AT_OR_BELOW;
65
+ }
66
+ //# sourceMappingURL=support-feedback.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support-feedback.util.js","sourceRoot":"","sources":["../../../../../src/modules/support/utils/support-feedback.util.ts"],"names":[],"mappings":";;AAQA,gEAEC;AAWD,0DA0BC;AAGD,sDAIC;AASD,wDAQC;AAvED,gFAA8E;AAC9E,0EAIwC;AAExC,2DAA2D;AAC3D,SAAgB,0BAA0B,CAAC,IAA0B;IACjE,OAAO,sDAA8B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,uBAAuB,CACnC,IAA0B,EAC1B,MAAsB;IAEtB,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,IAAI,MAAM,IAAI,gDAAuB,CAAC,oBAAoB,EAAE,CAAC;YACzD,OAAO,iDAAyB,CAAC,QAAQ,CAAC;QAC9C,CAAC;QACD,IAAI,MAAM,IAAI,gDAAuB,CAAC,oBAAoB,EAAE,CAAC;YACzD,OAAO,iDAAyB,CAAC,QAAQ,CAAC;QAC9C,CAAC;QACD,OAAO,iDAAyB,CAAC,OAAO,CAAC;IAC7C,CAAC;IAED,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,4CAAoB,CAAC,UAAU;YAChC,OAAO,iDAAyB,CAAC,QAAQ,CAAC;QAC9C,KAAK,4CAAoB,CAAC,SAAS,CAAC;QACpC,KAAK,4CAAoB,CAAC,UAAU;YAChC,OAAO,iDAAyB,CAAC,QAAQ,CAAC;QAC9C,KAAK,4CAAoB,CAAC,eAAe,CAAC;QAC1C,KAAK,4CAAoB,CAAC,OAAO;YAC7B,OAAO,iDAAyB,CAAC,OAAO,CAAC;QAC7C;YACI,OAAO,iDAAyB,CAAC,OAAO,CAAC;IACjD,CAAC;AACL,CAAC;AAED,oDAAoD;AACpD,SAAgB,qBAAqB,CAAC,MAAe;IACjD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACzE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,OAAO,MAAM,IAAI,gDAAuB,CAAC,GAAG,IAAI,MAAM,IAAI,gDAAuB,CAAC,GAAG,CAAC;AAC1F,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,sBAAsB,CAClC,IAA0B,EAC1B,MAAsB;IAEtB,IAAI,IAAI,KAAK,4CAAoB,CAAC,UAAU,IAAI,IAAI,KAAK,4CAAoB,CAAC,SAAS,EAAE,CAAC;QACtF,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,gDAAuB,CAAC,oBAAoB,CAAC;AACpF,CAAC"}
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.maskSupportIdentifier = maskSupportIdentifier;
4
+ exports.maskSupportUrl = maskSupportUrl;
5
+ exports.scrubSupportText = scrubSupportText;
6
+ exports.sanitizeSupportPayload = sanitizeSupportPayload;
7
+ exports.truncateForSupport = truncateForSupport;
8
+ exports.previewSupportText = previewSupportText;
9
+ exports.snapshotSupportPayload = snapshotSupportPayload;
10
+ const support_defaults_const_1 = require("../constants/support-defaults.const");
11
+ /**
12
+ * Mask an identifier for logging: enough to correlate, never enough to reuse.
13
+ * `+254712345678` becomes `+254***5678`.
14
+ */
15
+ function maskSupportIdentifier(value) {
16
+ if (value == null)
17
+ return 'unknown';
18
+ const raw = String(value).trim();
19
+ if (raw === '')
20
+ return 'unknown';
21
+ if (raw.length <= 8)
22
+ return `${raw.slice(0, 2)}***`;
23
+ return `${raw.slice(0, 4)}***${raw.slice(-4)}`;
24
+ }
25
+ /**
26
+ * Reduce a URL to scheme and host.
27
+ *
28
+ * A helpdesk URL routinely carries an API token in its query string, and a URL
29
+ * is the single most-logged value in an HTTP client.
30
+ */
31
+ function maskSupportUrl(value) {
32
+ if (value == null)
33
+ return 'unknown';
34
+ const raw = String(value).trim();
35
+ if (raw === '')
36
+ return 'unknown';
37
+ try {
38
+ const url = new URL(raw);
39
+ return `${url.protocol}//${url.host}${url.pathname}`;
40
+ }
41
+ catch {
42
+ return raw.split('?')[0];
43
+ }
44
+ }
45
+ /**
46
+ * Replace anything credential- or PII-shaped in free text.
47
+ *
48
+ * Applied to every provider message before it is stored or logged. It is a
49
+ * belt-and-braces pass on top of key-based redaction: a helpdesk that puts a
50
+ * token in a prose error defeats key matching, and that message still ends up
51
+ * in a table an operator can read.
52
+ */
53
+ function scrubSupportText(input) {
54
+ return String(input !== null && input !== void 0 ? input : '')
55
+ .replace(/Bearer\s+[A-Za-z0-9._-]+/gi, 'Bearer [REDACTED]')
56
+ .replace(/Token\s+token=[A-Za-z0-9._-]+/gi, 'Token token=[REDACTED]')
57
+ .replace(/\b(sk|pk)_(test|prod|live)_[A-Za-z0-9_-]+/gi, '[REDACTED]')
58
+ .replace(/\beyJ[A-Za-z0-9._-]{10,}/g, '[REDACTED]')
59
+ .replace(/\+[1-9]\d{9,14}\b/g, (match) => maskSupportIdentifier(match));
60
+ }
61
+ /** Keys whose VALUE is redacted wherever it appears in a payload, at any depth. */
62
+ const SENSITIVE_SUPPORT_KEYS = [
63
+ 'password',
64
+ 'passwd',
65
+ 'secret',
66
+ 'token',
67
+ 'apikey',
68
+ 'api_key',
69
+ 'apitoken',
70
+ 'api_token',
71
+ 'authorization',
72
+ 'auth',
73
+ 'credential',
74
+ 'accesstoken',
75
+ 'access_token',
76
+ 'refreshtoken',
77
+ 'refresh_token',
78
+ 'otp',
79
+ 'pin',
80
+ 'signature',
81
+ 'privatekey',
82
+ 'private_key',
83
+ 'sessionid',
84
+ 'session_id',
85
+ 'cookie',
86
+ 'setcookie',
87
+ 'set_cookie',
88
+ ];
89
+ function isSensitiveSupportKey(key) {
90
+ const normalized = key.toLowerCase().replace(/[^a-z_]/g, '');
91
+ return SENSITIVE_SUPPORT_KEYS.some((candidate) => normalized.includes(candidate.replace(/_/g, '')));
92
+ }
93
+ /**
94
+ * Redact a payload by key before it is persisted on a synchronization row or an
95
+ * audit entry.
96
+ *
97
+ * Depth-bounded, because a provider can return an arbitrarily nested object and
98
+ * an audit writer must not be a place a stack overflow can happen. Anything
99
+ * past the bound is replaced with a marker rather than dropped silently.
100
+ */
101
+ function sanitizeSupportPayload(value, depth = 0) {
102
+ if (depth > 6)
103
+ return '[TRUNCATED]';
104
+ if (value == null)
105
+ return value;
106
+ if (Array.isArray(value)) {
107
+ return value.slice(0, 50).map((item) => sanitizeSupportPayload(item, depth + 1));
108
+ }
109
+ if (typeof value === 'object') {
110
+ const source = value;
111
+ const result = {};
112
+ for (const key of Object.keys(source)) {
113
+ result[key] = isSensitiveSupportKey(key)
114
+ ? '[REDACTED]'
115
+ : sanitizeSupportPayload(source[key], depth + 1);
116
+ }
117
+ return result;
118
+ }
119
+ if (typeof value === 'string')
120
+ return scrubSupportText(value);
121
+ return value;
122
+ }
123
+ /**
124
+ * Trim a value to a limit without ever throwing.
125
+ *
126
+ * A support message that runs long is truncated and still sent. Refusing to
127
+ * record what a customer said because it exceeded a column width would lose the
128
+ * thing the whole domain exists to capture.
129
+ */
130
+ function truncateForSupport(value, maxLength) {
131
+ if (value == null)
132
+ return undefined;
133
+ const trimmed = String(value).trim();
134
+ if (trimmed === '')
135
+ return undefined;
136
+ return trimmed.length <= maxLength ? trimmed : trimmed.slice(0, maxLength);
137
+ }
138
+ /**
139
+ * A one-line preview of a longer body, for list rows.
140
+ *
141
+ * Newlines collapse to spaces so a multi-line message cannot break a table row,
142
+ * and the result is ellipsised rather than hard-cut so a reader can tell there
143
+ * is more.
144
+ */
145
+ function previewSupportText(value, maxLength = 140) {
146
+ const collapsed = String(value !== null && value !== void 0 ? value : '')
147
+ .replace(/\s+/g, ' ')
148
+ .trim();
149
+ if (collapsed.length <= maxLength)
150
+ return collapsed;
151
+ return `${collapsed.slice(0, Math.max(0, maxLength - 1))}…`;
152
+ }
153
+ /** A provider response body reduced to something safe and small enough to keep. */
154
+ function snapshotSupportPayload(body) {
155
+ var _a;
156
+ if (body == null || typeof body !== 'object')
157
+ return null;
158
+ const redacted = sanitizeSupportPayload(body);
159
+ const serialized = (_a = JSON.stringify(redacted)) !== null && _a !== void 0 ? _a : '';
160
+ if (serialized.length > support_defaults_const_1.SUPPORT_FIELD_LIMITS.SYNC_SNAPSHOT_MAX_LENGTH) {
161
+ return {
162
+ truncated: true,
163
+ preview: serialized.slice(0, support_defaults_const_1.SUPPORT_FIELD_LIMITS.SYNC_SNAPSHOT_MAX_LENGTH),
164
+ };
165
+ }
166
+ try {
167
+ return JSON.parse(serialized);
168
+ }
169
+ catch {
170
+ return { unparsed: serialized };
171
+ }
172
+ }
173
+ //# sourceMappingURL=support-redaction.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support-redaction.util.js","sourceRoot":"","sources":["../../../../../src/modules/support/utils/support-redaction.util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.supportRoutingRuleMatches = supportRoutingRuleMatches;
4
+ exports.decideSupportQueue = decideSupportQueue;
5
+ exports.applyForcedPriority = applyForcedPriority;
6
+ const support_routing_enum_1 = require("../enums/support-routing.enum");
7
+ /** Whether one rule matches one ticket. */
8
+ function supportRoutingRuleMatches(rule, subject) {
9
+ if (!rule.active)
10
+ return false;
11
+ if (rule.organizationId !== subject.organizationId)
12
+ return false;
13
+ switch (rule.matchType) {
14
+ case support_routing_enum_1.SupportRoutingMatchType.ANY:
15
+ return true;
16
+ case support_routing_enum_1.SupportRoutingMatchType.CATEGORY:
17
+ return !!rule.matchCategoryId && rule.matchCategoryId === subject.categoryId;
18
+ case support_routing_enum_1.SupportRoutingMatchType.PRIORITY:
19
+ return !!rule.matchPriority && rule.matchPriority === subject.priority;
20
+ case support_routing_enum_1.SupportRoutingMatchType.CHANNEL:
21
+ return !!rule.matchChannel && rule.matchChannel === subject.channel;
22
+ case support_routing_enum_1.SupportRoutingMatchType.COUNTRY:
23
+ return !!rule.matchCountryCode && rule.matchCountryCode === subject.countryCode;
24
+ case support_routing_enum_1.SupportRoutingMatchType.CONTROL_CENTRE:
25
+ return (rule.matchControlCentreId != null &&
26
+ rule.matchControlCentreId === subject.controlCentreId);
27
+ case support_routing_enum_1.SupportRoutingMatchType.APP_ID:
28
+ return !!rule.matchAppId && rule.matchAppId === subject.appId;
29
+ case support_routing_enum_1.SupportRoutingMatchType.RELATED_ENTITY_TYPE:
30
+ return (!!rule.matchRelatedEntityType &&
31
+ subject.relatedEntityTypes.includes(rule.matchRelatedEntityType));
32
+ default:
33
+ // An unrecognised match type never matches. A rule the running code
34
+ // does not understand must not silently become a catch-all.
35
+ return false;
36
+ }
37
+ }
38
+ /**
39
+ * Pick a queue.
40
+ *
41
+ * Rules are sorted by ascending `priority` and the FIRST match wins. No
42
+ * scoring, no weighting, no learning: an operator has to be able to answer "why
43
+ * did this land here?" by reading the table, and a routing decision nobody can
44
+ * explain is one nobody can fix at 2am.
45
+ *
46
+ * Ties on `priority` are broken by rule id, so the same inputs always produce
47
+ * the same answer - a routing engine whose output depends on row order is a
48
+ * routing engine that cannot be tested.
49
+ */
50
+ function decideSupportQueue(rules, subject, fallbackQueueId) {
51
+ var _a;
52
+ const ordered = [...rules].sort((left, right) => {
53
+ if (left.priority !== right.priority)
54
+ return left.priority - right.priority;
55
+ return left.id.localeCompare(right.id);
56
+ });
57
+ for (const rule of ordered) {
58
+ if (supportRoutingRuleMatches(rule, subject)) {
59
+ return {
60
+ queueId: rule.targetQueueId,
61
+ ruleId: rule.id,
62
+ ruleName: rule.name,
63
+ forcedPriority: (_a = rule.forcePriority) !== null && _a !== void 0 ? _a : null,
64
+ };
65
+ }
66
+ }
67
+ return {
68
+ queueId: fallbackQueueId !== null && fallbackQueueId !== void 0 ? fallbackQueueId : null,
69
+ ruleId: null,
70
+ ruleName: null,
71
+ forcedPriority: null,
72
+ };
73
+ }
74
+ /**
75
+ * The priority a new ticket should start at.
76
+ *
77
+ * A rule may raise a priority and never lower one. A customer who says their
78
+ * panic button is broken has told us something a routing table cannot know
79
+ * better than they do, and quietly downgrading them is the failure mode this
80
+ * rule exists to prevent.
81
+ */
82
+ function applyForcedPriority(requested, forced, rank) {
83
+ if (!forced)
84
+ return requested;
85
+ return rank[forced] < rank[requested] ? forced : requested;
86
+ }
87
+ //# sourceMappingURL=support-routing.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support-routing.util.js","sourceRoot":"","sources":["../../../../../src/modules/support/utils/support-routing.util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.timezoneForCountry = timezoneForCountry;
4
+ exports.resolveBusinessCalendar = resolveBusinessCalendar;
5
+ exports.addBusinessMinutes = addBusinessMinutes;
6
+ exports.businessMinutesBetween = businessMinutesBetween;
7
+ exports.resolveSlaTargets = resolveSlaTargets;
8
+ exports.computeSlaDueAt = computeSlaDueAt;
9
+ exports.evaluateSlaState = evaluateSlaState;
10
+ exports.minutesUntil = minutesUntil;
11
+ const supported_countries_const_1 = require("../../country/constants/supported-countries.const");
12
+ const country_defaults_const_1 = require("../../country/constants/country-defaults.const");
13
+ const support_defaults_const_1 = require("../constants/support-defaults.const");
14
+ const support_sla_enum_1 = require("../enums/support-sla.enum");
15
+ /** Safety bound on the day-by-day walk, so a misconfigured calendar cannot hang a request. */
16
+ const MAX_CALENDAR_DAYS = 400;
17
+ /**
18
+ * The timezone a country's working hours are measured in.
19
+ *
20
+ * Read from the country configuration rather than from the server clock. Every
21
+ * supported country happens to sit at UTC+3 today; writing it this way is what
22
+ * stops that being an assumption baked into a deadline.
23
+ */
24
+ function timezoneForCountry(countryCode) {
25
+ var _a;
26
+ if (!countryCode)
27
+ return country_defaults_const_1.DEFAULT_TIMEZONE;
28
+ const config = supported_countries_const_1.SUPPORTED_COUNTRIES_BY_CODE[countryCode];
29
+ return (_a = config === null || config === void 0 ? void 0 : config.timezone) !== null && _a !== void 0 ? _a : country_defaults_const_1.DEFAULT_TIMEZONE;
30
+ }
31
+ /**
32
+ * The zone's UTC offset, in minutes, at a given instant.
33
+ *
34
+ * Derived through Intl rather than hard-coded, so a zone that observes daylight
35
+ * saving is handled correctly away from the transition itself. At the exact
36
+ * hour of a transition the result can be off by the shift; that is a documented
37
+ * limitation, and it does not arise for KE, UG or TZ, none of which observe DST.
38
+ */
39
+ function zoneOffsetMinutes(instant, timeZone) {
40
+ const formatter = new Intl.DateTimeFormat('en-US', {
41
+ timeZone,
42
+ hourCycle: 'h23',
43
+ year: 'numeric',
44
+ month: '2-digit',
45
+ day: '2-digit',
46
+ hour: '2-digit',
47
+ minute: '2-digit',
48
+ second: '2-digit',
49
+ });
50
+ const parts = {};
51
+ for (const part of formatter.formatToParts(instant)) {
52
+ if (part.type !== 'literal')
53
+ parts[part.type] = part.value;
54
+ }
55
+ const asUtc = Date.UTC(Number(parts.year), Number(parts.month) - 1, Number(parts.day), Number(parts.hour), Number(parts.minute), Number(parts.second));
56
+ return Math.round((asUtc - instant.getTime()) / 60000);
57
+ }
58
+ function zonedParts(instant, timeZone) {
59
+ const offset = zoneOffsetMinutes(instant, timeZone);
60
+ const shifted = new Date(instant.getTime() + offset * 60000);
61
+ const isoWeekday = shifted.getUTCDay() === 0 ? 7 : shifted.getUTCDay();
62
+ const year = shifted.getUTCFullYear();
63
+ const month = shifted.getUTCMonth() + 1;
64
+ const day = shifted.getUTCDate();
65
+ return {
66
+ year,
67
+ month,
68
+ day,
69
+ minuteOfDay: shifted.getUTCHours() * 60 + shifted.getUTCMinutes(),
70
+ isoWeekday,
71
+ isoDate: `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`,
72
+ };
73
+ }
74
+ /** The instant at which a given local wall-clock time occurs in a zone. */
75
+ function instantFromZonedWallTime(year, month, day, minuteOfDay, timeZone) {
76
+ const naive = Date.UTC(year, month - 1, day, 0, minuteOfDay);
77
+ // Two passes: the first offset is read at the naive instant, the second at
78
+ // the corrected one, which settles any case where the correction crosses a
79
+ // transition boundary.
80
+ let offset = zoneOffsetMinutes(new Date(naive), timeZone);
81
+ let instant = naive - offset * 60000;
82
+ offset = zoneOffsetMinutes(new Date(instant), timeZone);
83
+ instant = naive - offset * 60000;
84
+ return new Date(instant);
85
+ }
86
+ /** The calendar in force, falling back to the platform default. */
87
+ function resolveBusinessCalendar(calendar, countryCode) {
88
+ var _a, _b, _c, _d;
89
+ return {
90
+ workingDays: ((_a = calendar === null || calendar === void 0 ? void 0 : calendar.workingDays) === null || _a === void 0 ? void 0 : _a.length)
91
+ ? [...calendar.workingDays]
92
+ : [...support_defaults_const_1.SUPPORT_BUSINESS_CALENDAR_DEFAULTS.workingDays],
93
+ startMinuteOfDay: (_b = calendar === null || calendar === void 0 ? void 0 : calendar.startMinuteOfDay) !== null && _b !== void 0 ? _b : support_defaults_const_1.SUPPORT_BUSINESS_CALENDAR_DEFAULTS.startMinuteOfDay,
94
+ endMinuteOfDay: (_c = calendar === null || calendar === void 0 ? void 0 : calendar.endMinuteOfDay) !== null && _c !== void 0 ? _c : support_defaults_const_1.SUPPORT_BUSINESS_CALENDAR_DEFAULTS.endMinuteOfDay,
95
+ timezone: (_d = calendar === null || calendar === void 0 ? void 0 : calendar.timezone) !== null && _d !== void 0 ? _d : timezoneForCountry(countryCode),
96
+ holidays: (calendar === null || calendar === void 0 ? void 0 : calendar.holidays) ? [...calendar.holidays] : [],
97
+ };
98
+ }
99
+ function isWorkingDay(parts, calendar) {
100
+ if (!calendar.workingDays.includes(parts.isoWeekday))
101
+ return false;
102
+ return !calendar.holidays.includes(parts.isoDate);
103
+ }
104
+ /**
105
+ * Add working minutes to an instant.
106
+ *
107
+ * Walks day by day rather than doing arithmetic on a whole-week average,
108
+ * because holidays and a partial first day make the average wrong exactly when
109
+ * it matters - the ticket raised at 16:55 on the day before a public holiday.
110
+ *
111
+ * A calendar with no working days, or a zero-length window, degrades to
112
+ * calendar time rather than looping: a misconfigured calendar must not be able
113
+ * to hang the request that creates a ticket.
114
+ */
115
+ function addBusinessMinutes(start, minutes, calendar) {
116
+ if (minutes <= 0)
117
+ return new Date(start.getTime());
118
+ const windowLength = calendar.endMinuteOfDay - calendar.startMinuteOfDay;
119
+ if (windowLength <= 0 || calendar.workingDays.length === 0) {
120
+ return new Date(start.getTime() + minutes * 60000);
121
+ }
122
+ let remaining = minutes;
123
+ let cursor = new Date(start.getTime());
124
+ for (let guard = 0; guard < MAX_CALENDAR_DAYS; guard += 1) {
125
+ const parts = zonedParts(cursor, calendar.timezone);
126
+ if (!isWorkingDay(parts, calendar)) {
127
+ cursor = nextDayWindowStart(parts, calendar);
128
+ continue;
129
+ }
130
+ const dayStart = instantFromZonedWallTime(parts.year, parts.month, parts.day, calendar.startMinuteOfDay, calendar.timezone);
131
+ const dayEnd = instantFromZonedWallTime(parts.year, parts.month, parts.day, calendar.endMinuteOfDay, calendar.timezone);
132
+ if (cursor.getTime() < dayStart.getTime())
133
+ cursor = dayStart;
134
+ if (cursor.getTime() >= dayEnd.getTime()) {
135
+ cursor = nextDayWindowStart(parts, calendar);
136
+ continue;
137
+ }
138
+ const availableMinutes = (dayEnd.getTime() - cursor.getTime()) / 60000;
139
+ if (remaining <= availableMinutes) {
140
+ return new Date(cursor.getTime() + remaining * 60000);
141
+ }
142
+ remaining -= availableMinutes;
143
+ cursor = nextDayWindowStart(parts, calendar);
144
+ }
145
+ // Past the safety bound the calendar is unusable; do not silently return a
146
+ // wrong deadline, return an honest calendar-time one.
147
+ return new Date(start.getTime() + minutes * 60000);
148
+ }
149
+ function nextDayWindowStart(parts, calendar) {
150
+ const nextDay = new Date(Date.UTC(parts.year, parts.month - 1, parts.day + 1));
151
+ return instantFromZonedWallTime(nextDay.getUTCFullYear(), nextDay.getUTCMonth() + 1, nextDay.getUTCDate(), calendar.startMinuteOfDay, calendar.timezone);
152
+ }
153
+ /** Working minutes between two instants. Used to account for paused time. */
154
+ function businessMinutesBetween(from, to, calendar) {
155
+ if (to.getTime() <= from.getTime())
156
+ return 0;
157
+ const windowLength = calendar.endMinuteOfDay - calendar.startMinuteOfDay;
158
+ if (windowLength <= 0 || calendar.workingDays.length === 0) {
159
+ return (to.getTime() - from.getTime()) / 60000;
160
+ }
161
+ let total = 0;
162
+ let cursor = new Date(from.getTime());
163
+ for (let guard = 0; guard < MAX_CALENDAR_DAYS; guard += 1) {
164
+ if (cursor.getTime() >= to.getTime())
165
+ break;
166
+ const parts = zonedParts(cursor, calendar.timezone);
167
+ if (!isWorkingDay(parts, calendar)) {
168
+ cursor = nextDayWindowStart(parts, calendar);
169
+ continue;
170
+ }
171
+ const dayStart = instantFromZonedWallTime(parts.year, parts.month, parts.day, calendar.startMinuteOfDay, calendar.timezone);
172
+ const dayEnd = instantFromZonedWallTime(parts.year, parts.month, parts.day, calendar.endMinuteOfDay, calendar.timezone);
173
+ const segmentStart = Math.max(cursor.getTime(), dayStart.getTime());
174
+ const segmentEnd = Math.min(to.getTime(), dayEnd.getTime());
175
+ if (segmentEnd > segmentStart)
176
+ total += (segmentEnd - segmentStart) / 60000;
177
+ cursor = nextDayWindowStart(parts, calendar);
178
+ }
179
+ return total;
180
+ }
181
+ /** The targets in force for a priority: queue policy, then organization policy, then defaults. */
182
+ function resolveSlaTargets(priority, policies) {
183
+ var _a;
184
+ for (const policy of policies) {
185
+ const target = (_a = policy === null || policy === void 0 ? void 0 : policy.targets) === null || _a === void 0 ? void 0 : _a.find((candidate) => candidate.priority === priority);
186
+ if (target) {
187
+ return {
188
+ firstResponseMinutes: target.firstResponseMinutes,
189
+ resolutionMinutes: target.resolutionMinutes,
190
+ clock: target.clock,
191
+ };
192
+ }
193
+ }
194
+ return support_defaults_const_1.SUPPORT_SLA_DEFAULTS[priority];
195
+ }
196
+ /** When a target elapses, measured on the right clock. */
197
+ function computeSlaDueAt(start, minutes, clock, calendar) {
198
+ if (clock === support_sla_enum_1.SupportSlaClock.CALENDAR) {
199
+ return new Date(start.getTime() + minutes * 60000);
200
+ }
201
+ return addBusinessMinutes(start, minutes, calendar);
202
+ }
203
+ /**
204
+ * Where a clock stands right now.
205
+ *
206
+ * Pure, and takes `now` as an argument rather than reading the clock, so the
207
+ * scheduler and the read path can never disagree about what time it is and so
208
+ * the whole thing is testable without freezing time.
209
+ */
210
+ function evaluateSlaState(input) {
211
+ var _a, _b;
212
+ const { now, dueAt, metAt, paused, stopped } = input;
213
+ if (metAt)
214
+ return support_sla_enum_1.SupportSlaState.MET;
215
+ if (!dueAt)
216
+ return support_sla_enum_1.SupportSlaState.NOT_APPLICABLE;
217
+ if (stopped) {
218
+ return now.getTime() > dueAt.getTime() ? support_sla_enum_1.SupportSlaState.BREACHED : support_sla_enum_1.SupportSlaState.MET;
219
+ }
220
+ if (paused)
221
+ return support_sla_enum_1.SupportSlaState.PAUSED;
222
+ if (now.getTime() > dueAt.getTime())
223
+ return support_sla_enum_1.SupportSlaState.BREACHED;
224
+ const targetMinutes = (_a = input.targetMinutes) !== null && _a !== void 0 ? _a : null;
225
+ const ratio = (_b = input.warningRatio) !== null && _b !== void 0 ? _b : support_defaults_const_1.SUPPORT_SLA_WARNING_THRESHOLD_RATIO;
226
+ if (targetMinutes && targetMinutes > 0) {
227
+ const warningAt = dueAt.getTime() - targetMinutes * (1 - ratio) * 60000;
228
+ if (now.getTime() >= warningAt)
229
+ return support_sla_enum_1.SupportSlaState.WARNING;
230
+ }
231
+ return support_sla_enum_1.SupportSlaState.ON_TRACK;
232
+ }
233
+ /** Minutes left before a deadline; negative once it has passed. */
234
+ function minutesUntil(now, dueAt) {
235
+ if (!dueAt)
236
+ return null;
237
+ return Math.round((dueAt.getTime() - now.getTime()) / 60000);
238
+ }
239
+ //# sourceMappingURL=support-sla.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support-sla.util.js","sourceRoot":"","sources":["../../../../../src/modules/support/utils/support-sla.util.ts"],"names":[],"mappings":"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"}