grm-shared-library 1.1.201 → 1.1.203

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 +85 -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 +191 -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 +85 -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 +180 -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 +61 -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 +122 -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,180 @@
1
+ import { CountryCode } from '../../country/enums/country-code.enum';
2
+ import { IncidentAppId } from '../../incident/enums/incident-app-id.enum';
3
+ import { SupportProviderCode } from '../enums/support-provider-code.enum';
4
+ import { SupportRelatedEntityType } from '../enums/support-related-entity-type.enum';
5
+ import { SupportSlaState, SupportSlaTarget } from '../enums/support-sla.enum';
6
+ import { SupportTicketChannel, SupportTicketSource } from '../enums/support-ticket-channel.enum';
7
+ import { SupportTicketPriority } from '../enums/support-ticket-priority.enum';
8
+ import { SupportTicketStatus } from '../enums/support-ticket-status.enum';
9
+ /**
10
+ * A pointer to a record owned by another Clarion service.
11
+ *
12
+ * Type plus id, never a copy. `label` is a display string resolved at read time
13
+ * when the reader is allowed to see it, and is absent otherwise - so a ticket
14
+ * list never leaks the subject of an incident to somebody who could not open
15
+ * that incident directly.
16
+ */
17
+ export interface SupportRelatedEntityRef {
18
+ type: SupportRelatedEntityType;
19
+ /** Text because the owning services disagree on integer versus uuid. */
20
+ id: string;
21
+ /** Resolved for display; absent when it could not be resolved or may not be shown. */
22
+ label?: string | null;
23
+ }
24
+ /** Where one SLA clock stands, as shown on a ticket. */
25
+ export interface SupportSlaClockSnapshot {
26
+ target: SupportSlaTarget;
27
+ state: SupportSlaState;
28
+ /** When the target elapses. Null when no policy applies. */
29
+ dueAt?: string | null;
30
+ /** When it was actually met. Null while outstanding. */
31
+ metAt?: string | null;
32
+ /**
33
+ * Minutes left, negative once breached. Computed at read time from `dueAt`,
34
+ * so a client that caches a ticket does not have to recompute a deadline
35
+ * itself and get the paused case wrong.
36
+ */
37
+ remainingMinutes?: number | null;
38
+ /** Total minutes the clock has spent paused, so an agent can see why a deadline moved. */
39
+ pausedMinutes: number;
40
+ }
41
+ /**
42
+ * A support ticket as the API returns it.
43
+ *
44
+ * Clarion is authoritative for identity, tenancy and the local conversation
45
+ * record; a configured helpdesk is authoritative for agent workflow. The
46
+ * `external*` fields are the join between the two and are the only place a
47
+ * vendor's identifiers appear in a client-facing contract - never its payloads,
48
+ * never its URLs, never its credentials.
49
+ */
50
+ export interface SupportTicket {
51
+ /** Internal identifier. A uuid, so a ticket id is never guessable. */
52
+ id: string;
53
+ /** Human-readable and safe to quote: SUP-KE-2026-000123. */
54
+ ticketNumber: string;
55
+ organizationId: number;
56
+ controlCentreId?: number | null;
57
+ countryCode: CountryCode;
58
+ /** The client application the ticket came from, when it came from one. */
59
+ appId?: IncidentAppId | null;
60
+ /** Who raised it. An agent raising a ticket for a customer is not the customer. */
61
+ createdByUserId: number;
62
+ /** Whose ticket it is. The only user a customer-facing read path will match on. */
63
+ customerUserId: number;
64
+ assignedAgentId?: number | null;
65
+ assignedTeamId?: string | null;
66
+ queueId?: string | null;
67
+ categoryId?: string | null;
68
+ subject: string;
69
+ description: string;
70
+ status: SupportTicketStatus;
71
+ priority: SupportTicketPriority;
72
+ channel: SupportTicketChannel;
73
+ source: SupportTicketSource;
74
+ /** Free-text labels. Lower-cased and de-duplicated on write. */
75
+ tags: string[];
76
+ firstResponseDueAt?: string | null;
77
+ resolutionDueAt?: string | null;
78
+ firstRespondedAt?: string | null;
79
+ resolvedAt?: string | null;
80
+ closedAt?: string | null;
81
+ reopenedAt?: string | null;
82
+ firstResponseSlaState: SupportSlaState;
83
+ resolutionSlaState: SupportSlaState;
84
+ /** The policy in force. Null when none matched. */
85
+ slaPolicyId?: string | null;
86
+ lastCustomerMessageAt?: string | null;
87
+ lastAgentMessageAt?: string | null;
88
+ /** Count of customer-visible messages, so a list can show unread-ish state cheaply. */
89
+ messageCount: number;
90
+ /** How many times it has come back from CLOSED. */
91
+ reopenCount: number;
92
+ /** Which helpdesk holds the mirror, if any. */
93
+ externalProvider?: SupportProviderCode | null;
94
+ /** The helpdesk's own id. Opaque here - only its adapter knows the shape. */
95
+ externalTicketId?: string | null;
96
+ /** The helpdesk's human-readable number, when it publishes one. */
97
+ externalTicketNumber?: string | null;
98
+ /** Whether the mirror is currently in step. Derived from outstanding sync rows. */
99
+ externalSyncPending: boolean;
100
+ /** Set when at least one synchronization row for this ticket is dead-lettered. */
101
+ externalSyncFailed: boolean;
102
+ externalLastSyncedAt?: string | null;
103
+ /** What the ticket is about, when it is about something. */
104
+ relatedEntities: SupportRelatedEntityRef[];
105
+ /** Set only when the ticket was promoted from feedback. */
106
+ sourceFeedbackId?: string | null;
107
+ /** Non-sensitive diagnostic context captured at creation. Never credentials. */
108
+ metadata?: Record<string, unknown> | null;
109
+ /** Optimistic concurrency. A stale update is rejected rather than silently applied. */
110
+ version: number;
111
+ createdAt: string;
112
+ updatedAt: string;
113
+ }
114
+ /**
115
+ * The shape a list returns.
116
+ *
117
+ * A deliberate subset: `description`, `metadata` and the related entities are
118
+ * left out so a five-hundred-row page does not carry half a megabyte of prose,
119
+ * and so a queue view cannot become a way to bulk-read ticket bodies.
120
+ */
121
+ export interface SupportTicketSummary {
122
+ id: string;
123
+ ticketNumber: string;
124
+ organizationId: number;
125
+ controlCentreId?: number | null;
126
+ countryCode: CountryCode;
127
+ customerUserId: number;
128
+ /** Resolved for display in the admin. Absent on customer-facing lists. */
129
+ customerName?: string | null;
130
+ assignedAgentId?: number | null;
131
+ assignedAgentName?: string | null;
132
+ queueId?: string | null;
133
+ queueName?: string | null;
134
+ categoryId?: string | null;
135
+ categoryName?: string | null;
136
+ subject: string;
137
+ status: SupportTicketStatus;
138
+ priority: SupportTicketPriority;
139
+ channel: SupportTicketChannel;
140
+ firstResponseSlaState: SupportSlaState;
141
+ resolutionSlaState: SupportSlaState;
142
+ firstResponseDueAt?: string | null;
143
+ resolutionDueAt?: string | null;
144
+ lastCustomerMessageAt?: string | null;
145
+ lastAgentMessageAt?: string | null;
146
+ messageCount: number;
147
+ externalProvider?: SupportProviderCode | null;
148
+ externalSyncPending: boolean;
149
+ externalSyncFailed: boolean;
150
+ createdAt: string;
151
+ updatedAt: string;
152
+ }
153
+ /** One recorded status change, as shown on the ticket timeline. */
154
+ export interface SupportTicketStatusHistoryEntry {
155
+ id: string;
156
+ ticketId: string;
157
+ fromStatus?: SupportTicketStatus | null;
158
+ toStatus: SupportTicketStatus;
159
+ changedByUserId?: number | null;
160
+ changedByName?: string | null;
161
+ /** True when the change arrived from the helpdesk rather than from Clarion. */
162
+ fromProvider: boolean;
163
+ reason?: string | null;
164
+ createdAt: string;
165
+ }
166
+ /** One recorded assignment change. */
167
+ export interface SupportTicketAssignmentHistoryEntry {
168
+ id: string;
169
+ ticketId: string;
170
+ fromAgentId?: number | null;
171
+ toAgentId?: number | null;
172
+ fromTeamId?: string | null;
173
+ toTeamId?: string | null;
174
+ fromQueueId?: string | null;
175
+ toQueueId?: string | null;
176
+ changedByUserId?: number | null;
177
+ changedByName?: string | null;
178
+ reason?: string | null;
179
+ createdAt: string;
180
+ }
@@ -0,0 +1,23 @@
1
+ import { CustomerFeedbackSentiment, CustomerFeedbackType } from '../enums/support-feedback.enum';
2
+ /** Whether this kind of feedback carries a star rating. */
3
+ export declare function feedbackTypeRequiresRating(type: CustomerFeedbackType): boolean;
4
+ /**
5
+ * Derive sentiment from the feedback TYPE and rating.
6
+ *
7
+ * Never from the message text. An automated reading of "the guard never came"
8
+ * that lands on POSITIVE is worse than no reading at all, and a support desk
9
+ * that starts distrusting one column stops trusting the dashboard. When a real
10
+ * classifier is added it writes this same field, and the rule below becomes its
11
+ * fallback rather than being replaced.
12
+ */
13
+ export declare function deriveFeedbackSentiment(type: CustomerFeedbackType, rating?: number | null): CustomerFeedbackSentiment;
14
+ /** Whether a rating is inside the allowed range. */
15
+ export declare function isValidFeedbackRating(rating: unknown): boolean;
16
+ /**
17
+ * Whether a piece of feedback is the kind an agent should probably act on.
18
+ *
19
+ * Advisory only - it drives a hint in the admin, never an automatic conversion.
20
+ * Promoting somebody's complaint into a ticket without a human deciding is how a
21
+ * queue fills with work nobody chose to take on.
22
+ */
23
+ export declare function feedbackWarrantsTicket(type: CustomerFeedbackType, rating?: number | null): boolean;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Mask an identifier for logging: enough to correlate, never enough to reuse.
3
+ * `+254712345678` becomes `+254***5678`.
4
+ */
5
+ export declare function maskSupportIdentifier(value: string | null | undefined): string;
6
+ /**
7
+ * Reduce a URL to scheme and host.
8
+ *
9
+ * A helpdesk URL routinely carries an API token in its query string, and a URL
10
+ * is the single most-logged value in an HTTP client.
11
+ */
12
+ export declare function maskSupportUrl(value: string | null | undefined): string;
13
+ /**
14
+ * Replace anything credential- or PII-shaped in free text.
15
+ *
16
+ * Applied to every provider message before it is stored or logged. It is a
17
+ * belt-and-braces pass on top of key-based redaction: a helpdesk that puts a
18
+ * token in a prose error defeats key matching, and that message still ends up
19
+ * in a table an operator can read.
20
+ */
21
+ export declare function scrubSupportText(input: string | null | undefined): string;
22
+ /**
23
+ * Redact a payload by key before it is persisted on a synchronization row or an
24
+ * audit entry.
25
+ *
26
+ * Depth-bounded, because a provider can return an arbitrarily nested object and
27
+ * an audit writer must not be a place a stack overflow can happen. Anything
28
+ * past the bound is replaced with a marker rather than dropped silently.
29
+ */
30
+ export declare function sanitizeSupportPayload(value: unknown, depth?: number): unknown;
31
+ /**
32
+ * Trim a value to a limit without ever throwing.
33
+ *
34
+ * A support message that runs long is truncated and still sent. Refusing to
35
+ * record what a customer said because it exceeded a column width would lose the
36
+ * thing the whole domain exists to capture.
37
+ */
38
+ export declare function truncateForSupport(value: string | null | undefined, maxLength: number): string | undefined;
39
+ /**
40
+ * A one-line preview of a longer body, for list rows.
41
+ *
42
+ * Newlines collapse to spaces so a multi-line message cannot break a table row,
43
+ * and the result is ellipsised rather than hard-cut so a reader can tell there
44
+ * is more.
45
+ */
46
+ export declare function previewSupportText(value: string | null | undefined, maxLength?: number): string;
47
+ /** A provider response body reduced to something safe and small enough to keep. */
48
+ export declare function snapshotSupportPayload(body: unknown): Record<string, unknown> | null;
@@ -0,0 +1,50 @@
1
+ import { CountryCode } from '../../country/enums/country-code.enum';
2
+ import { IncidentAppId } from '../../incident/enums/incident-app-id.enum';
3
+ import { SupportRelatedEntityType } from '../enums/support-related-entity-type.enum';
4
+ import { SupportTicketChannel } from '../enums/support-ticket-channel.enum';
5
+ import { SupportTicketPriority } from '../enums/support-ticket-priority.enum';
6
+ import { SupportRoutingRule } from '../interfaces/support-configuration';
7
+ /** The facts a routing decision is made from. */
8
+ export interface SupportRoutingSubject {
9
+ organizationId: number;
10
+ controlCentreId?: number | null;
11
+ countryCode: CountryCode;
12
+ categoryId?: string | null;
13
+ priority: SupportTicketPriority;
14
+ channel: SupportTicketChannel;
15
+ appId?: IncidentAppId | null;
16
+ relatedEntityTypes: SupportRelatedEntityType[];
17
+ }
18
+ /** What a routing decision produced, and why. */
19
+ export interface SupportRoutingDecision {
20
+ queueId: string | null;
21
+ /** The rule that matched, so an operator can be shown why. */
22
+ ruleId: string | null;
23
+ ruleName: string | null;
24
+ /** A priority the rule forced, when it forced one. */
25
+ forcedPriority?: SupportTicketPriority | null;
26
+ }
27
+ /** Whether one rule matches one ticket. */
28
+ export declare function supportRoutingRuleMatches(rule: SupportRoutingRule, subject: SupportRoutingSubject): boolean;
29
+ /**
30
+ * Pick a queue.
31
+ *
32
+ * Rules are sorted by ascending `priority` and the FIRST match wins. No
33
+ * scoring, no weighting, no learning: an operator has to be able to answer "why
34
+ * did this land here?" by reading the table, and a routing decision nobody can
35
+ * explain is one nobody can fix at 2am.
36
+ *
37
+ * Ties on `priority` are broken by rule id, so the same inputs always produce
38
+ * the same answer - a routing engine whose output depends on row order is a
39
+ * routing engine that cannot be tested.
40
+ */
41
+ export declare function decideSupportQueue(rules: SupportRoutingRule[], subject: SupportRoutingSubject, fallbackQueueId?: string | null): SupportRoutingDecision;
42
+ /**
43
+ * The priority a new ticket should start at.
44
+ *
45
+ * A rule may raise a priority and never lower one. A customer who says their
46
+ * panic button is broken has told us something a routing table cannot know
47
+ * better than they do, and quietly downgrading them is the failure mode this
48
+ * rule exists to prevent.
49
+ */
50
+ export declare function applyForcedPriority(requested: SupportTicketPriority, forced: SupportTicketPriority | null | undefined, rank: Readonly<Record<SupportTicketPriority, number>>): SupportTicketPriority;
@@ -0,0 +1,69 @@
1
+ import { CountryCode } from '../../country/enums/country-code.enum';
2
+ import { SupportSlaTargetDefaults } from '../constants/support-defaults.const';
3
+ import { SupportSlaClock, SupportSlaState } from '../enums/support-sla.enum';
4
+ import { SupportTicketPriority } from '../enums/support-ticket-priority.enum';
5
+ import { SupportBusinessCalendar, SupportSlaPolicy } from '../interfaces/support-configuration';
6
+ /**
7
+ * The timezone a country's working hours are measured in.
8
+ *
9
+ * Read from the country configuration rather than from the server clock. Every
10
+ * supported country happens to sit at UTC+3 today; writing it this way is what
11
+ * stops that being an assumption baked into a deadline.
12
+ */
13
+ export declare function timezoneForCountry(countryCode: CountryCode | null | undefined): string;
14
+ /**
15
+ * A calendar with every field settled.
16
+ *
17
+ * Distinct from {@link SupportBusinessCalendar} because the stored shape allows
18
+ * a null timezone (meaning "take it from the country") and the arithmetic below
19
+ * cannot. Resolving once, here, is what keeps every caller from having to guess
20
+ * a fallback zone of its own.
21
+ */
22
+ export interface ResolvedSupportBusinessCalendar {
23
+ workingDays: number[];
24
+ startMinuteOfDay: number;
25
+ endMinuteOfDay: number;
26
+ timezone: string;
27
+ holidays: string[];
28
+ }
29
+ /** The calendar in force, falling back to the platform default. */
30
+ export declare function resolveBusinessCalendar(calendar: SupportBusinessCalendar | null | undefined, countryCode: CountryCode | null | undefined): ResolvedSupportBusinessCalendar;
31
+ /**
32
+ * Add working minutes to an instant.
33
+ *
34
+ * Walks day by day rather than doing arithmetic on a whole-week average,
35
+ * because holidays and a partial first day make the average wrong exactly when
36
+ * it matters - the ticket raised at 16:55 on the day before a public holiday.
37
+ *
38
+ * A calendar with no working days, or a zero-length window, degrades to
39
+ * calendar time rather than looping: a misconfigured calendar must not be able
40
+ * to hang the request that creates a ticket.
41
+ */
42
+ export declare function addBusinessMinutes(start: Date, minutes: number, calendar: ResolvedSupportBusinessCalendar): Date;
43
+ /** Working minutes between two instants. Used to account for paused time. */
44
+ export declare function businessMinutesBetween(from: Date, to: Date, calendar: ResolvedSupportBusinessCalendar): number;
45
+ /** The targets in force for a priority: queue policy, then organization policy, then defaults. */
46
+ export declare function resolveSlaTargets(priority: SupportTicketPriority, policies: (SupportSlaPolicy | null | undefined)[]): SupportSlaTargetDefaults;
47
+ /** When a target elapses, measured on the right clock. */
48
+ export declare function computeSlaDueAt(start: Date, minutes: number, clock: SupportSlaClock, calendar: ResolvedSupportBusinessCalendar): Date;
49
+ /**
50
+ * Where a clock stands right now.
51
+ *
52
+ * Pure, and takes `now` as an argument rather than reading the clock, so the
53
+ * scheduler and the read path can never disagree about what time it is and so
54
+ * the whole thing is testable without freezing time.
55
+ */
56
+ export declare function evaluateSlaState(input: {
57
+ now: Date;
58
+ dueAt?: Date | null;
59
+ metAt?: Date | null;
60
+ /** True while the ticket is waiting on the customer. */
61
+ paused: boolean;
62
+ /** True once the clocks have stopped for good without being met. */
63
+ stopped: boolean;
64
+ /** Total minutes the target allows, used to place the warning threshold. */
65
+ targetMinutes?: number | null;
66
+ warningRatio?: number;
67
+ }): SupportSlaState;
68
+ /** Minutes left before a deadline; negative once it has passed. */
69
+ export declare function minutesUntil(now: Date, dueAt: Date | null | undefined): number | null;
@@ -0,0 +1,44 @@
1
+ import { CustomerFeedbackStatus } from '../enums/support-feedback.enum';
2
+ import { SupportTicketStatus } from '../enums/support-ticket-status.enum';
3
+ /**
4
+ * Whether a ticket may move from one state to another.
5
+ *
6
+ * The single authority. Controllers, services, webhook handlers and the
7
+ * reconciliation job all ask this rather than each carrying their own idea of
8
+ * what is legal - which is what stops a provider webhook quietly doing
9
+ * something no Clarion user could do.
10
+ *
11
+ * A move to the SAME state is allowed and is a no-op, because a provider that
12
+ * re-sends its current status should not be an error.
13
+ */
14
+ export declare function canTransitionSupportTicket(from: SupportTicketStatus, to: SupportTicketStatus): boolean;
15
+ /** The states a ticket may legally move to right now. Drives the admin's buttons. */
16
+ export declare function allowedSupportTicketTransitions(from: SupportTicketStatus): readonly SupportTicketStatus[];
17
+ export declare function isTerminalSupportTicketStatus(status: SupportTicketStatus): boolean;
18
+ export declare function isActiveSupportTicketStatus(status: SupportTicketStatus): boolean;
19
+ /** True while an SLA clock should be stopped but may still resume. */
20
+ export declare function isSlaPausedStatus(status: SupportTicketStatus): boolean;
21
+ /** True once the clocks stop for good. */
22
+ export declare function isSlaStoppedStatus(status: SupportTicketStatus): boolean;
23
+ /**
24
+ * Whether a customer may reply on a ticket in this state.
25
+ *
26
+ * A CANCELLED ticket is closed to further conversation; everything else, CLOSED
27
+ * included, accepts a reply - and a reply to a closed ticket reopens it, which
28
+ * is what a customer expects and what stops them raising a duplicate.
29
+ */
30
+ export declare function customerMayReply(status: SupportTicketStatus): boolean;
31
+ /**
32
+ * The state a customer reply should move a ticket into, or null to leave it.
33
+ *
34
+ * CLOSED becomes REOPENED, which is counted. RESOLVED goes back to IN_PROGRESS,
35
+ * which is not - the ticket was never finished from the customer's point of
36
+ * view, and calling that a reopen would inflate the reopen rate with tickets
37
+ * that simply were not fixed yet. WAITING_ON_CUSTOMER becomes IN_PROGRESS,
38
+ * because the wait is over.
39
+ */
40
+ export declare function statusAfterCustomerReply(status: SupportTicketStatus): SupportTicketStatus | null;
41
+ /** Whether a piece of feedback may move from one state to another. */
42
+ export declare function canTransitionCustomerFeedback(from: CustomerFeedbackStatus, to: CustomerFeedbackStatus): boolean;
43
+ /** The states a piece of feedback may legally move to right now. */
44
+ export declare function allowedCustomerFeedbackTransitions(from: CustomerFeedbackStatus): readonly CustomerFeedbackStatus[];
@@ -0,0 +1,76 @@
1
+ import { SupportSyncFailureReason } from '../enums/support-sync.enum';
2
+ /**
3
+ * Translate a helpdesk HTTP status into the shared failure taxonomy.
4
+ *
5
+ * The single place the retry policy is decided, because "should we call the
6
+ * helpdesk again?" must not be answered differently by the Zammad adapter and
7
+ * the Freshdesk one. Anything unrecognised is TRANSIENT: a support message that
8
+ * arrives late is recoverable, one dropped because an unfamiliar status looked
9
+ * fatal is not.
10
+ *
11
+ * The one place that reasoning inverts is a 2xx nobody could parse. The
12
+ * provider accepted the request, so re-sending would create a second ticket or
13
+ * show the customer the same reply twice - see UNREADABLE_SUCCESS, which the
14
+ * adapter raises directly rather than through this function.
15
+ */
16
+ export declare function classifySupportHttpStatus(status: number | undefined): SupportSyncFailureReason;
17
+ /**
18
+ * Whether a failure can ever succeed on a retry.
19
+ *
20
+ * AUTHENTICATION_FAILED is deliberately NOT permanent: a rotated credential
21
+ * that has not propagated to every pod yet fails this way, and refusing to try
22
+ * again would strand every queued reply until somebody noticed. It is capped by
23
+ * `maxAttempts` like anything else.
24
+ */
25
+ export declare function isPermanentSupportSyncFailure(reason: SupportSyncFailureReason): boolean;
26
+ /**
27
+ * When to try again, with exponential backoff and jitter.
28
+ *
29
+ * The jitter matters more than it looks: when a helpdesk comes back after an
30
+ * outage, every queued row is due at once, and a synchronized stampede is how a
31
+ * recovering server is knocked over a second time.
32
+ *
33
+ * `randomFraction` is injected rather than read from Math.random so the
34
+ * function stays pure and its tests stay deterministic.
35
+ */
36
+ export declare function computeSupportRetryDelaySeconds(attempts: number, options?: {
37
+ baseSeconds?: number;
38
+ maxSeconds?: number;
39
+ jitterRatio?: number;
40
+ /** A value in [0,1). Defaults to no jitter. */
41
+ randomFraction?: number;
42
+ /** Honour a provider's Retry-After, when it sends one. */
43
+ retryAfterSeconds?: number | null;
44
+ }): number;
45
+ /** The instant of the next attempt. */
46
+ export declare function computeSupportNextAttemptAt(now: Date, attempts: number, options?: Parameters<typeof computeSupportRetryDelaySeconds>[1]): Date;
47
+ /**
48
+ * A stable fingerprint of an outbound payload.
49
+ *
50
+ * Deliberately not cryptographic. It exists to answer "is this the same request
51
+ * we already sent?" and to let a reconciliation job tell "never sent" from
52
+ * "sent and did not take" - neither of which is a security decision. Using a
53
+ * real digest here would pull a Node-only dependency into a package the
54
+ * frontend build also consumes.
55
+ */
56
+ export declare function fingerprintSupportPayload(payload: unknown): string;
57
+ /** State of the per-provider circuit breaker, kept small enough to live in Redis. */
58
+ export interface SupportCircuitState {
59
+ consecutiveFailures: number;
60
+ /** ISO instant the breaker may next allow a probe. Null when closed. */
61
+ openUntil?: string | null;
62
+ }
63
+ /**
64
+ * Whether an outbound call may proceed.
65
+ *
66
+ * The breaker protects the helpdesk and this service's own worker from
67
+ * hammering a dead endpoint; it never causes data loss, because a call refused
68
+ * by an open breaker leaves its row PENDING with a CIRCUIT_OPEN reason and is
69
+ * retried when the breaker closes.
70
+ */
71
+ export declare function isSupportCircuitOpen(state: SupportCircuitState | null | undefined, now: Date): boolean;
72
+ /** The breaker state after one outcome. */
73
+ export declare function nextSupportCircuitState(state: SupportCircuitState | null | undefined, outcome: 'success' | 'failure', now: Date, options?: {
74
+ failureThreshold?: number;
75
+ openSeconds?: number;
76
+ }): SupportCircuitState;
@@ -0,0 +1,39 @@
1
+ import { CountryCode } from '../../country/enums/country-code.enum';
2
+ /** The parts of a ticket number, once parsed. */
3
+ export interface ParsedSupportTicketNumber {
4
+ prefix: string;
5
+ countryCode: CountryCode;
6
+ year: number;
7
+ sequence: number;
8
+ }
9
+ /**
10
+ * Render a ticket number: SUP-KE-2026-000123.
11
+ *
12
+ * Human-readable and safe to read out over the phone, which is the whole point
13
+ * of it existing alongside the uuid primary key. It is never the primary key:
14
+ * it embeds a country and a year, and anything that embeds business meaning
15
+ * will eventually need changing.
16
+ *
17
+ * The sequence is allocated per (country, year) by the database, so this
18
+ * function only formats - it never decides what the next number is.
19
+ */
20
+ export declare function formatSupportTicketNumber(countryCode: CountryCode, year: number, sequence: number): string;
21
+ /**
22
+ * Read a ticket number back, for search.
23
+ *
24
+ * Returns null rather than throwing on anything unrecognised: this runs on a
25
+ * search box, where the input is whatever somebody pasted, and a 500 from a bad
26
+ * paste is a worse answer than no results.
27
+ *
28
+ * A sequence longer than the configured width still parses - the width is a
29
+ * display minimum, and refusing to find ticket 1,000,000 because it has seven
30
+ * digits would be a bug that only appears once it is too late.
31
+ */
32
+ export declare function parseSupportTicketNumber(value: string | null | undefined): ParsedSupportTicketNumber | null;
33
+ /**
34
+ * Whether a search term looks like somebody typing a ticket number.
35
+ *
36
+ * Used to route a search straight at the ticket-number index instead of running
37
+ * a full-text scan for a string that can only ever match one row.
38
+ */
39
+ export declare function looksLikeSupportTicketNumber(value: string | null | undefined): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grm-shared-library",
3
- "version": "1.1.201",
3
+ "version": "1.1.203",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/types/index.d.ts",