@futdevpro/nts-dynamo 1.15.41 → 1.15.43

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 (323) hide show
  1. package/.c8rc.json +26 -26
  2. package/.copilot/patterns.json +7 -7
  3. package/.cursor/rules/__assistant_guide.mdc +30 -30
  4. package/.cursor/rules/_ag_backend-structure.mdc +85 -85
  5. package/.cursor/rules/_ag_backend.mdc +16 -16
  6. package/.cursor/rules/_ag_frontend-structure.mdc +86 -86
  7. package/.cursor/rules/_ag_frontend.mdc +39 -39
  8. package/.cursor/rules/_ag_import-rules.mdc +44 -44
  9. package/.cursor/rules/_ag_naming.mdc +115 -115
  10. package/.cursor/rules/_ag_should-be.mdc +6 -6
  11. package/.cursor/rules/ai_development_guide.md +60 -60
  12. package/.cursor/rules/cursor-rules.md +160 -160
  13. package/.cursor/rules/default-command.mdc +464 -464
  14. package/.cursor/rules/error_code_pattern.md +39 -39
  15. package/.cursor/rules/saved rule mcp server use.md +15 -15
  16. package/.dynamo/logs/cicd-pipeline/output.log +2596 -0
  17. package/.dynamo/logs/cicd-pipeline/status.json +321 -0
  18. package/.github/workflows/main.yml +432 -432
  19. package/.vscode/settings.json +10 -10
  20. package/HOWTO.md +15 -15
  21. package/LICENSE +21 -21
  22. package/__documentations/nts-integration-tests-2026-03-17.md +26 -26
  23. package/_specifications/BACKLOG.md +92 -92
  24. package/_specifications/TODO.md +15 -15
  25. package/_specifications/agent.md +138 -138
  26. package/build/_models/control-models/endpoint-params.control-model.d.ts.map +1 -1
  27. package/build/_models/control-models/endpoint-params.control-model.js +20 -4
  28. package/build/_models/control-models/endpoint-params.control-model.js.map +1 -1
  29. package/eslint.config.js +3 -3
  30. package/nodemon.json +24 -24
  31. package/package.json +2 -2
  32. package/pnpm-workspace.yaml +8 -8
  33. package/scripts/run-coverage-tests.js +28 -28
  34. package/spec/support/helpers/spec-reporter-loader.js +359 -359
  35. package/spec/support/helpers/ts-node-helper.js +93 -93
  36. package/spec/support/jasmine.coverage.json +24 -24
  37. package/spec/support/jasmine.json +24 -24
  38. package/src/_collections/archive.util.spec.ts +57 -57
  39. package/src/_collections/archive.util.ts +18 -18
  40. package/src/_collections/atlas-default-db-options.const.ts +9 -9
  41. package/src/_collections/default-fallback-cache-max-age.const.spec.ts +11 -11
  42. package/src/_collections/default-fallback-cache-max-age.const.ts +2 -2
  43. package/src/_collections/default-not-found-page.const.spec.ts +19 -19
  44. package/src/_collections/default-not-found-page.const.ts +22 -22
  45. package/src/_collections/default-socket-path.const.spec.ts +12 -12
  46. package/src/_collections/default-socket-path.const.ts +2 -2
  47. package/src/_collections/get-environment-settings.util.spec.ts +210 -210
  48. package/src/_collections/get-environment-settings.util.ts +48 -48
  49. package/src/_collections/sample.env +21 -21
  50. package/src/_collections/star.controller.spec.ts +224 -224
  51. package/src/_collections/star.controller.ts +129 -129
  52. package/src/_enums/data-model-type.enum.ts +14 -14
  53. package/src/_enums/data-service-function.enum.ts +24 -24
  54. package/src/_enums/predefined-data-types.enum.ts +16 -16
  55. package/src/_enums/route-security.enum.ts +12 -12
  56. package/src/_models/control-models/api-call-params.control-model.spec.ts +152 -152
  57. package/src/_models/control-models/api-call-params.control-model.ts +142 -142
  58. package/src/_models/control-models/app-ext-system-controls.control-model.spec.ts +52 -52
  59. package/src/_models/control-models/app-ext-system-controls.control-model.ts +9 -9
  60. package/src/_models/control-models/app-params.control-model.spec.ts +225 -225
  61. package/src/_models/control-models/app-params.control-model.ts +136 -136
  62. package/src/_models/control-models/app-system-controls.control-model.spec.ts +31 -31
  63. package/src/_models/control-models/app-system-controls.control-model.ts +9 -9
  64. package/src/_models/control-models/endpoint-params.control-model.spec.ts +578 -578
  65. package/src/_models/control-models/endpoint-params.control-model.ts +542 -526
  66. package/src/_models/control-models/http-settings.control-model.spec.ts +77 -77
  67. package/src/_models/control-models/http-settings.control-model.ts +37 -37
  68. package/src/_models/control-models/system-control.control-model.spec.ts +27 -27
  69. package/src/_models/control-models/system-control.control-model.ts +12 -12
  70. package/src/_models/interfaces/certification-settings.interface.ts +7 -7
  71. package/src/_models/interfaces/environment-settings.interface.ts +59 -59
  72. package/src/_models/interfaces/global-log-settings.interface.ts +144 -144
  73. package/src/_models/interfaces/global-service-settings.interface.ts +47 -47
  74. package/src/_models/interfaces/routing-module-settings.interface.ts +21 -21
  75. package/src/_models/interfaces/static-client-settings.interface.spec.ts +29 -29
  76. package/src/_models/interfaces/static-client-settings.interface.ts +28 -28
  77. package/src/_models/types/db-update.type.ts +100 -100
  78. package/src/_modules/ai/_models/ai-input-interfaces.ts +117 -117
  79. package/src/_modules/ai/_models/ai-test-generation-result.interface.ts +16 -16
  80. package/src/_modules/ai/_modules/anthropic/_services/aai-user-key.control-service.ts +138 -138
  81. package/src/_modules/ai/_modules/anthropic/index.ts +5 -5
  82. package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.spec.ts +242 -242
  83. package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.ts +639 -639
  84. package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.spec.ts +209 -209
  85. package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.ts +85 -85
  86. package/src/_modules/ai/_modules/document-ai/_enums/dai-compare-result-type.enum.ts +7 -7
  87. package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-chunk.data-model.ts +146 -146
  88. package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-page.data-model.ts +162 -162
  89. package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-document.data-model.ts +99 -99
  90. package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-chunk-compare-result.interface.ts +18 -18
  91. package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-page-compare-result.interface.ts +19 -19
  92. package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-document-compare-result.interface.ts +25 -25
  93. package/src/_modules/ai/_modules/document-ai/index.ts +28 -28
  94. package/src/_modules/ai/_modules/fdp-ai/_services/fdpai-user-key.control-service.ts +189 -189
  95. package/src/_modules/ai/_modules/fdp-ai/index.ts +5 -5
  96. package/src/_modules/ai/_modules/open-ai/_collections/oai-global-settings.const.ts +9 -9
  97. package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests-hu.conts.ts +82 -82
  98. package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests.conts.ts +75 -75
  99. package/src/_modules/ai/_modules/open-ai/_enums/oai-gpt-message-role.enum.ts +45 -45
  100. package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-global-settings.interface.ts +7 -7
  101. package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-gpt-message.interface.ts +7 -7
  102. package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-llm-predefined-requests.interface.ts +57 -57
  103. package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-doc-chunk-data.service.ts +292 -292
  104. package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-document.data-service.spec.ts +342 -342
  105. package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.spec.ts +550 -550
  106. package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.ts +630 -630
  107. package/src/_modules/ai/_modules/open-ai/_services/oai-embedding.control-service.spec.ts +332 -332
  108. package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.spec.ts +462 -462
  109. package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.ts +634 -634
  110. package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.spec.ts +489 -489
  111. package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.tools.spec.ts +173 -173
  112. package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.ts +1033 -1033
  113. package/src/_modules/ai/_modules/open-ai/_services/oai-user-key.control-service.ts +157 -157
  114. package/src/_modules/ai/_services/ai-embedding.service-base.spec.ts +98 -98
  115. package/src/_modules/ai/_services/ai-embedding.service-base.ts +48 -48
  116. package/src/_modules/ai/_services/ai-llm-chat.service-base.spec.ts +229 -229
  117. package/src/_modules/ai/_services/ai-llm-chat.service-base.ts +68 -68
  118. package/src/_modules/ai/_services/ai-llm.service-base.spec.ts +250 -250
  119. package/src/_modules/ai/_services/ai-llm.service-base.ts +519 -519
  120. package/src/_modules/ai/_services/ai-provider.service-base.spec.ts +158 -158
  121. package/src/_modules/ai/_services/ai-user-key.service-base.ts +59 -59
  122. package/src/_modules/ai/index.ts +13 -13
  123. package/src/_modules/assistant/_collections/ass-global-settings.const.ts +13 -13
  124. package/src/_modules/assistant/_collections/ass.util.spec.ts +176 -176
  125. package/src/_modules/assistant/_collections/ass.util.ts +50 -50
  126. package/src/_modules/assistant/_models/ass-global-settings.interface.ts +15 -15
  127. package/src/_modules/assistant/_services/ass-io.control-service.spec.ts +140 -140
  128. package/src/_modules/assistant/_services/ass-main.control-service.spec.ts +192 -192
  129. package/src/_modules/assistant/_services/ass-main.control-service.ts +107 -107
  130. package/src/_modules/bot/_collections/bot-default-commands.const.ts +12 -12
  131. package/src/_modules/bot/_collections/bot-global-settings.const.ts +39 -39
  132. package/src/_modules/bot/_models/bot-channel-wrapper.interface.ts +62 -62
  133. package/src/_modules/bot/_models/bot-command.interface.ts +8 -8
  134. package/src/_modules/bot/_models/bot-global-settings.interface.ts +96 -96
  135. package/src/_modules/bot/_models/bot-last-mention-date.interface.ts +6 -6
  136. package/src/_modules/bot/_models/bot-last-message-date.interface.ts +5 -5
  137. package/src/_modules/bot/_models/bot-user-wrapper.interface.ts +41 -41
  138. package/src/_modules/bot/_modules/discord-bot/_models/dib-platform.types.ts +9 -9
  139. package/src/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.spec.ts +431 -431
  140. package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.spec.ts +160 -160
  141. package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.ts +55 -55
  142. package/src/_modules/bot/_modules/dynamo-bot/_models/dyb-platform.types.ts +15 -15
  143. package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.spec.ts +374 -374
  144. package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.ts +447 -447
  145. package/src/_modules/bot/_modules/dynamo-bot/index.ts +15 -15
  146. package/src/_modules/bot/_modules/slack-bot/_models/slb-platform.types.ts +9 -9
  147. package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.spec.ts +344 -344
  148. package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.ts +197 -197
  149. package/src/_modules/bot/_modules/teams-bot/_models/teb-platform.types.ts +9 -9
  150. package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.spec.ts +345 -345
  151. package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.ts +197 -197
  152. package/src/_modules/bot/_services/bot-commands.control-service.spec.ts +116 -116
  153. package/src/_modules/bot/_services/bot-io.control-service.spec.ts +285 -285
  154. package/src/_modules/bot/_services/bot-main.control-service.spec.ts +208 -208
  155. package/src/_modules/bot/_services/bot-messaging-provider.service-base.spec.ts +349 -349
  156. package/src/_modules/bot/_services/bot-routines.control-service.spec.ts +111 -111
  157. package/src/_modules/custom-data/custom-data.controller.spec.ts +49 -49
  158. package/src/_modules/custom-data/custom-data.controller.ts +67 -67
  159. package/src/_modules/custom-data/custom-data.data-service.spec.ts +54 -54
  160. package/src/_modules/custom-data/custom-data.data-service.ts +21 -21
  161. package/src/_modules/custom-data/get-custom-data-routing-module.util.spec.ts +28 -28
  162. package/src/_modules/custom-data/get-custom-data-routing-module.util.ts +24 -24
  163. package/src/_modules/custom-data/index.ts +9 -9
  164. package/src/_modules/defaults/_collections/default-endpoints.util.ts +487 -487
  165. package/src/_modules/defaults/_models/default-user.data-model.ts +72 -72
  166. package/src/_modules/defaults/_services/default-auth.service.spec.ts +269 -269
  167. package/src/_modules/defaults/_services/default-auth.service.ts +177 -177
  168. package/src/_modules/defaults/_services/default-socket-events.service.spec.ts +42 -42
  169. package/src/_modules/defaults/_services/default-socket-events.service.ts +61 -61
  170. package/src/_modules/defaults/_services/default-user.data-service.spec.ts +187 -187
  171. package/src/_modules/defaults/_services/default-user.data-service.ts +98 -98
  172. package/src/_modules/defaults/index.ts +17 -17
  173. package/src/_modules/discord-assistant/_collections/dias-global-settings.const.ts +19 -19
  174. package/src/_modules/discord-assistant/_collections/dias.util.spec.ts +366 -366
  175. package/src/_modules/discord-assistant/_collections/dias.util.ts +132 -132
  176. package/src/_modules/discord-assistant/_models/dias-global-settings.interface.ts +19 -19
  177. package/src/_modules/discord-assistant/_models/dias-knowledge.data-model.ts +52 -52
  178. package/src/_modules/discord-assistant/_services/dias-chunk.data-service.ts +177 -177
  179. package/src/_modules/discord-assistant/_services/dias-io.control-service.spec.ts +108 -108
  180. package/src/_modules/discord-assistant/_services/dias-io.control-service.ts +69 -69
  181. package/src/_modules/discord-assistant/_services/dias-main.control-service.spec.ts +22 -22
  182. package/src/_modules/discord-assistant/_services/dias-main.control-service.ts +27 -27
  183. package/src/_modules/discord-assistant/_services/dias.service-base.spec.ts +195 -195
  184. package/src/_modules/discord-assistant/_services/dias.service-base.ts +76 -76
  185. package/src/_modules/discord-assistant/index.ts +38 -38
  186. package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.spec.ts +34 -34
  187. package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.ts +11 -11
  188. package/src/_modules/discord-assistant-voiced/index.ts +36 -36
  189. package/src/_modules/discord-bot/_collections/dibo-default-commands.const.ts +16 -16
  190. package/src/_modules/discord-bot/_collections/dibo-global-settings.conts.ts +55 -55
  191. package/src/_modules/discord-bot/_collections/dibo-operations.util.spec.ts +214 -214
  192. package/src/_modules/discord-bot/_collections/dibo-operations.util.ts +387 -387
  193. package/src/_modules/discord-bot/_models/dibo-command.interface.ts +12 -12
  194. package/src/_modules/discord-bot/_models/dibo-global-settings.interface.ts +98 -98
  195. package/src/_modules/discord-bot/_models/dibo-last-mention-date.inteface.ts +7 -7
  196. package/src/_modules/discord-bot/_models/dibo-last-message-date.interface.ts +6 -6
  197. package/src/_modules/discord-bot/_services/dibo-commands.control-service.spec.ts +154 -154
  198. package/src/_modules/discord-bot/_services/dibo-commands.control-service.ts +153 -153
  199. package/src/_modules/discord-bot/_services/dibo-io.control-service.spec.ts +264 -264
  200. package/src/_modules/discord-bot/_services/dibo-io.control-service.ts +306 -306
  201. package/src/_modules/discord-bot/_services/dibo-main.control-service.spec.ts +408 -408
  202. package/src/_modules/discord-bot/_services/dibo-main.control-service.ts +487 -487
  203. package/src/_modules/discord-bot/_services/dibo-routines.control-service.spec.ts +105 -105
  204. package/src/_modules/discord-bot/index.ts +36 -36
  205. package/src/_modules/local-vector-search/_enums/lvs-search-mode.enum.ts +35 -35
  206. package/src/_modules/local-vector-search/_models/lvs-search-result.interface.ts +17 -17
  207. package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.spec.ts +418 -418
  208. package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.ts +276 -276
  209. package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.spec.ts +480 -480
  210. package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.ts +416 -416
  211. package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.spec.ts +393 -393
  212. package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.ts +220 -220
  213. package/src/_modules/local-vector-search/index.ts +11 -11
  214. package/src/_modules/messaging/README.md +354 -354
  215. package/src/_modules/messaging/_collections/get-messaging-routing-module.util.ts +26 -26
  216. package/src/_modules/messaging/_collections/msg-global-settings.const.ts +22 -22
  217. package/src/_modules/messaging/_collections/msg.util.spec.ts +226 -226
  218. package/src/_modules/messaging/_models/msg-global-settings.interface.ts +37 -37
  219. package/src/_modules/messaging/_services/msg-conversation.data-service.ts +146 -146
  220. package/src/_modules/messaging/_services/msg-events.service.spec.ts +219 -219
  221. package/src/_modules/messaging/_services/msg-events.service.ts +267 -267
  222. package/src/_modules/messaging/_services/msg-integration.control-service.ts +179 -179
  223. package/src/_modules/messaging/_services/msg-main.control-service.spec.ts +147 -147
  224. package/src/_modules/messaging/_services/msg-main.control-service.ts +571 -571
  225. package/src/_modules/messaging/_services/msg-message.data-service.ts +129 -129
  226. package/src/_modules/messaging/_services/msg.controller.spec.ts +201 -201
  227. package/src/_modules/messaging/index.ts +30 -30
  228. package/src/_modules/mock/app-extended-server.mock.ts +201 -201
  229. package/src/_modules/mock/app-integration-test.mock.ts +51 -51
  230. package/src/_modules/mock/app-params.mock.spec.ts +21 -21
  231. package/src/_modules/mock/app-params.mock.ts +9 -9
  232. package/src/_modules/mock/app-server.mock.ts +188 -188
  233. package/src/_modules/mock/auth-service.mock.spec.ts +47 -47
  234. package/src/_modules/mock/auth-service.mock.ts +28 -28
  235. package/src/_modules/mock/controller.mock.spec.ts +26 -26
  236. package/src/_modules/mock/controller.mock.ts +16 -16
  237. package/src/_modules/mock/data-model.mock.spec.ts +111 -111
  238. package/src/_modules/mock/data-model.mock.ts +82 -82
  239. package/src/_modules/mock/email-service-collection.mock.spec.ts +24 -24
  240. package/src/_modules/mock/email-service-collection.mock.ts +15 -15
  241. package/src/_modules/mock/email-service.mock.spec.ts +17 -17
  242. package/src/_modules/mock/email-service.mock.ts +20 -20
  243. package/src/_modules/mock/email-template.mock.html +14 -14
  244. package/src/_modules/mock/endpoint.mock.ts +91 -91
  245. package/src/_modules/mock/socket-client.mock.spec.ts +40 -40
  246. package/src/_modules/mock/socket-client.mock.ts +45 -45
  247. package/src/_modules/mock/socket-server.mock.spec.ts +44 -44
  248. package/src/_modules/mock/socket-server.mock.ts +46 -46
  249. package/src/_modules/oauth2/_routes/oauth2.controller.spec.ts +107 -107
  250. package/src/_modules/oauth2/_routes/oauth2.controller.ts +98 -98
  251. package/src/_modules/oauth2/_services/oauth2.auth-service.spec.ts +254 -254
  252. package/src/_modules/oauth2/_services/oauth2.auth-service.ts +232 -232
  253. package/src/_modules/oauth2/_services/oauth2.control-service.spec.ts +585 -585
  254. package/src/_modules/oauth2/_services/oauth2.control-service.ts +653 -653
  255. package/src/_modules/oauth2/index.ts +17 -17
  256. package/src/_modules/server/errors/errors.control-service.spec.ts +238 -238
  257. package/src/_modules/server/errors/errors.control-service.ts +85 -85
  258. package/src/_modules/server/errors/errors.controller.spec.ts +241 -241
  259. package/src/_modules/server/errors/errors.controller.ts +431 -431
  260. package/src/_modules/server/errors/errors.data-service.spec.ts +355 -355
  261. package/src/_modules/server/index.ts +30 -30
  262. package/src/_modules/server/server-status/server-status-snapshot.control-service.spec.ts +70 -70
  263. package/src/_modules/server/server-status/server-status-snapshot.control-service.ts +17 -17
  264. package/src/_modules/server/server-status/server-status-snapshot.data-service.spec.ts +77 -77
  265. package/src/_modules/server/server-status/server-status-snapshot.data-service.ts +37 -37
  266. package/src/_modules/server/server-status/server-status.control-service.spec.ts +524 -524
  267. package/src/_modules/server/server-status/server-status.control-service.ts +336 -336
  268. package/src/_modules/server/server-status/server-status.controller.spec.ts +162 -162
  269. package/src/_modules/server/server-status/server-status.controller.ts +131 -131
  270. package/src/_modules/socket/_enums/socket-security.enum.ts +11 -11
  271. package/src/_modules/socket/_models/socket-client-service-params.control-model.spec.ts +32 -32
  272. package/src/_modules/socket/_models/socket-client-service-params.control-model.ts +22 -22
  273. package/src/_modules/socket/_models/socket-presence.control-model.spec.ts +164 -164
  274. package/src/_modules/socket/_models/socket-presence.control-model.ts +210 -210
  275. package/src/_modules/socket/_models/socket-server-service-params.control-model.spec.ts +46 -46
  276. package/src/_modules/socket/_models/socket-server-service-params.control-model.ts +22 -22
  277. package/src/_modules/socket/_services/socket-client.service.spec.ts +15 -15
  278. package/src/_modules/socket/_services/socket-client.service.ts +260 -260
  279. package/src/_modules/socket/_services/socket-server.service.spec.ts +11 -11
  280. package/src/_modules/socket/app-extended.integration.spec.ts +85 -85
  281. package/src/_modules/socket/app-extended.server.ts +630 -630
  282. package/src/_modules/socket/index.ts +42 -42
  283. package/src/_modules/test/get-test-routing-module.util.spec.ts +28 -28
  284. package/src/_modules/test/get-test-routing-module.util.ts +23 -23
  285. package/src/_modules/test/index.ts +11 -11
  286. package/src/_modules/test/test.controller.spec.ts +72 -72
  287. package/src/_modules/test/test.controller.ts +115 -115
  288. package/src/_modules/usage/get-usage-routing-module.util.ts +22 -22
  289. package/src/_modules/usage/index.ts +15 -15
  290. package/src/_modules/usage/usage.controller.spec.ts +81 -81
  291. package/src/_modules/usage/usage.controller.ts +126 -126
  292. package/src/_modules/usage/usage.data-service.spec.ts +332 -332
  293. package/src/_modules/usage/usage.data-service.ts +185 -185
  294. package/src/_services/base/api.service-base.spec.ts +125 -125
  295. package/src/_services/base/api.service-base.ts +74 -74
  296. package/src/_services/base/archive-data.service.spec.ts +196 -196
  297. package/src/_services/base/archive-data.service.ts +216 -216
  298. package/src/_services/base/data.service.spec.ts +674 -674
  299. package/src/_services/base/data.service.ts +2719 -2719
  300. package/src/_services/base/db.service.spec.ts +73 -73
  301. package/src/_services/base/db.service.ts +1575 -1575
  302. package/src/_services/base/singleton.service-base.spec.ts +28 -28
  303. package/src/_services/base/singleton.service-base.ts +24 -24
  304. package/src/_services/base/singleton.service.spec.ts +114 -114
  305. package/src/_services/base/singleton.service.ts +38 -38
  306. package/src/_services/core/api.service.spec.ts +140 -140
  307. package/src/_services/core/auth.service.spec.ts +159 -159
  308. package/src/_services/core/auth.service.ts +174 -174
  309. package/src/_services/core/email.service.spec.ts +85 -85
  310. package/src/_services/core/email.service.ts +742 -742
  311. package/src/_services/core/global.service.spec.ts +275 -275
  312. package/src/_services/core/global.service.ts +461 -461
  313. package/src/_services/core/service-collection.service.spec.ts +46 -46
  314. package/src/_services/core/service-collection.service.ts +6 -6
  315. package/src/_services/route/controller.service.spec.ts +53 -53
  316. package/src/_services/route/controller.service.ts +148 -148
  317. package/src/_services/route/routing-module.service.spec.ts +98 -98
  318. package/src/_services/route/routing-module.service.ts +330 -330
  319. package/src/_services/shared.static-service.spec.ts +99 -99
  320. package/src/_services/shared.static-service.ts +78 -78
  321. package/src/index.ts +95 -95
  322. package/tsconfig.app.json +12 -12
  323. package/tsconfig.json +42 -42
@@ -1,572 +1,572 @@
1
- import { DyNTS_SingletonService } from '../../../_services/base/singleton.service';
2
- import { DyFM_Error, DyFM_Log } from '@futdevpro/fsm-dynamo';
3
- import {
4
- DyFM_Msg_Message,
5
- DyFM_Msg_Conversation,
6
- DyFM_Msg_Status,
7
- DyFM_Msg_Reaction,
8
- DyFM_Msg_Participant,
9
- DyFM_Msg_ParticipantRole,
10
- DyFM_Msg_Type,
11
- DyFM_Msg_ConversationType,
12
- } from '@futdevpro/fsm-dynamo/messaging';
13
-
14
- import { DyNTS_global_settings } from '../../../_collections/global-settings.const';
15
- import { DyNTS_Msg_Message_DataService } from './msg-message.data-service';
16
- import { DyNTS_Msg_Conversation_DataService } from './msg-conversation.data-service';
17
- import { DyNTS_Msg_Events_Service } from './msg-events.service';
18
-
19
- /**
20
- * Main Messaging Control Service
21
- * Handles all business logic for messaging operations
22
- */
23
- export class DyNTS_Msg_Main_ControlService extends DyNTS_SingletonService {
24
-
25
- static getInstance(): DyNTS_Msg_Main_ControlService {
26
- return DyNTS_Msg_Main_ControlService.getSingletonInstance();
27
- }
28
-
29
- private eventsService = DyNTS_Msg_Events_Service.getInstance();
30
-
31
- /**
32
- * Send a message
33
- */
34
- async sendMessage(
35
- conversationId: string,
36
- messageData: Partial<DyFM_Msg_Message>,
37
- senderId: string,
38
- issuer: string
39
- ): Promise<DyFM_Msg_Message> {
40
- try {
41
- if (!messageData?.content) {
42
- throw new Error('Message content is required');
43
- }
44
-
45
- // Create message
46
- const message = new DyFM_Msg_Message({
47
- conversationId: conversationId,
48
- senderId: senderId,
49
- content: messageData.content,
50
- type: messageData.type || DyFM_Msg_Type.text,
51
- status: DyFM_Msg_Status.sent,
52
- sentAt: new Date(),
53
- __createdBy: issuer,
54
- __lastModifiedBy: issuer,
55
- ...messageData,
56
- });
57
-
58
- // Save message
59
- const messageService = new DyNTS_Msg_Message_DataService({
60
- message,
61
- issuer,
62
- });
63
- await messageService.saveData(messageService.data, false, false);
64
-
65
- // Update conversation last message
66
- const conversationService = new DyNTS_Msg_Conversation_DataService({
67
- issuer,
68
- });
69
- await conversationService.updateLastMessage(
70
- conversationId,
71
- messageService.data._id!,
72
- message.content.substring(0, 100)
73
- );
74
-
75
- // Emit event
76
- this.eventsService.emitMessageSent(messageService.data, conversationId);
77
-
78
- return messageService.data;
79
- } catch (error) {
80
- throw new DyFM_Error({
81
- ...this.getDefaultErrorSettings('sendMessage', error, issuer),
82
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-SM`,
83
- userMessage: 'Failed to send message.',
84
- });
85
- }
86
- }
87
-
88
- /**
89
- * Edit a message
90
- */
91
- async editMessage(
92
- messageId: string,
93
- content: string,
94
- userId: string,
95
- issuer: string
96
- ): Promise<DyFM_Msg_Message> {
97
- try {
98
- const messageService = new DyNTS_Msg_Message_DataService({
99
- issuer,
100
- });
101
-
102
- const message = await messageService.getDataById(messageId);
103
-
104
- if (!message) {
105
- throw new Error('Message not found');
106
- }
107
-
108
- if (message.senderId !== userId) {
109
- throw new Error('Unauthorized: Only the message sender can edit it');
110
- }
111
-
112
- message.content = content;
113
- message.editedAt = new Date();
114
- message.status = DyFM_Msg_Status.sent; // Keep as sent since edited is not a status
115
- message.__lastModifiedBy = issuer;
116
-
117
- await messageService.saveData(message, false, false);
118
-
119
- // Emit event
120
- this.eventsService.emitMessageUpdated(messageService.data, message.conversationId);
121
-
122
- return messageService.data;
123
- } catch (error) {
124
- throw new DyFM_Error({
125
- ...this.getDefaultErrorSettings('editMessage', error, issuer),
126
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-EM`,
127
- userMessage: 'Failed to edit message.',
128
- });
129
- }
130
- }
131
-
132
- async modifyMessage(message: DyFM_Msg_Message, issuer: string): Promise<DyFM_Msg_Message> {
133
- try {
134
- const messageService = new DyNTS_Msg_Message_DataService({
135
- issuer,
136
- });
137
- await messageService.saveData(message);
138
-
139
- // Emit event
140
- this.eventsService.emitMessageUpdated(messageService.data, message.conversationId);
141
-
142
- return messageService.data;
143
- } catch (error) {
144
- throw new DyFM_Error({
145
- ...this.getDefaultErrorSettings('modifyMessage', error, issuer),
146
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-MM`,
147
- userMessage: 'Failed to modify message.',
148
- });
149
- }
150
- }
151
-
152
- /**
153
- * Delete a message
154
- */
155
- async deleteMessage(
156
- messageId: string,
157
- userId: string,
158
- issuer: string
159
- ): Promise<void> {
160
- try {
161
- const messageService = new DyNTS_Msg_Message_DataService({
162
- issuer,
163
- });
164
-
165
- const message = await messageService.getDataById(messageId);
166
-
167
- if (!message) {
168
- throw new Error('Message not found');
169
- }
170
-
171
- if (message.senderId !== userId) {
172
- throw new Error('Unauthorized: Only the message sender can delete it');
173
- }
174
-
175
- const conversationId = message.conversationId;
176
- await messageService.deleteData(messageId);
177
-
178
- // Emit event
179
- this.eventsService.emitMessageDeleted(messageId, conversationId);
180
- } catch (error) {
181
- throw new DyFM_Error({
182
- ...this.getDefaultErrorSettings('deleteMessage', error, issuer),
183
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-DM`,
184
- userMessage: 'Failed to delete message.',
185
- });
186
- }
187
- }
188
-
189
- /**
190
- * Mark messages as read
191
- */
192
- async markMessagesAsRead(
193
- messageIds: string[],
194
- userId: string,
195
- issuer: string
196
- ): Promise<{ success: boolean; count: number }> {
197
- try {
198
- const messageService = new DyNTS_Msg_Message_DataService({
199
- issuer,
200
- });
201
-
202
- for (const messageId of messageIds) {
203
- await messageService.markAsRead(messageId, userId);
204
-
205
- // Get message to get conversationId for event
206
- const message = await messageService.getDataById(messageId);
207
- this.eventsService.emitMessageRead(messageId, userId, message.conversationId);
208
- }
209
-
210
- return { success: true, count: messageIds.length };
211
- } catch (error) {
212
- throw new DyFM_Error({
213
- ...this.getDefaultErrorSettings('markMessagesAsRead', error, issuer),
214
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-MAR`,
215
- userMessage: 'Failed to mark messages as read.',
216
- });
217
- }
218
- }
219
-
220
- /**
221
- * Add reaction to message
222
- */
223
- async addReaction(
224
- messageId: string,
225
- emoji: string,
226
- userId: string,
227
- issuer: string
228
- ): Promise<DyFM_Msg_Message> {
229
- try {
230
- const messageService = new DyNTS_Msg_Message_DataService({
231
- issuer,
232
- });
233
-
234
- const message = await messageService.getDataById(messageId);
235
-
236
- if (!message) {
237
- throw new Error('Message not found');
238
- }
239
-
240
- if (!message.reactions) {
241
- message.reactions = [];
242
- }
243
-
244
- // Check if user already reacted with this emoji
245
- const existingReaction = message.reactions.find((r: any) => r.emoji === emoji && r.userId === userId);
246
-
247
- if (!existingReaction) {
248
- const newReaction = {
249
- emoji,
250
- userId,
251
- reactedAt: new Date(),
252
- } as any;
253
- message.reactions.push(newReaction);
254
-
255
- await messageService.saveData(message, false, false);
256
-
257
- // Emit event
258
- this.eventsService.emitReactionAdded(messageId, newReaction);
259
- }
260
-
261
- return messageService.data;
262
- } catch (error) {
263
- throw new DyFM_Error({
264
- ...this.getDefaultErrorSettings('addReaction', error, issuer),
265
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-AR`,
266
- userMessage: 'Failed to add reaction.',
267
- });
268
- }
269
- }
270
-
271
- /**
272
- * Remove reaction from message
273
- */
274
- async removeReaction(
275
- messageId: string,
276
- emoji: string,
277
- userId: string,
278
- issuer: string
279
- ): Promise<DyFM_Msg_Message> {
280
- try {
281
- const messageService = new DyNTS_Msg_Message_DataService({
282
- issuer,
283
- });
284
-
285
- const message = await messageService.getDataById(messageId);
286
-
287
- if (!message) {
288
- throw new Error('Message not found');
289
- }
290
-
291
- if (!message.reactions) {
292
- message.reactions = [];
293
- }
294
-
295
- // Remove user's reaction with this emoji
296
- const initialLength = message.reactions.length;
297
- message.reactions = message.reactions.filter((r: any) => !(r.emoji === emoji && r.userId === userId));
298
-
299
- if (message.reactions.length < initialLength) {
300
- await messageService.saveData(message, false, false);
301
-
302
- // Emit event
303
- this.eventsService.emitReactionRemoved(messageId, userId, emoji);
304
- }
305
-
306
- return messageService.data;
307
- } catch (error) {
308
- throw new DyFM_Error({
309
- ...this.getDefaultErrorSettings('removeReaction', error, issuer),
310
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-RR`,
311
- userMessage: 'Failed to remove reaction.',
312
- });
313
- }
314
- }
315
-
316
- /**
317
- * Create conversation
318
- */
319
- async createConversation(
320
- conversationData: Partial<DyFM_Msg_Conversation>,
321
- creatorId: string,
322
- issuer: string
323
- ): Promise<DyFM_Msg_Conversation> {
324
- try {
325
- // Ensure creator is in participants
326
- if (!conversationData.participants?.some(p => p.userId === creatorId)) {
327
- if (!conversationData.participants) {
328
- conversationData.participants = [];
329
- }
330
- conversationData.participants.push({
331
- userId: creatorId,
332
- role: DyFM_Msg_ParticipantRole.owner,
333
- joinedAt: new Date(),
334
- });
335
- }
336
-
337
- const conversation = new DyFM_Msg_Conversation({
338
- type: conversationData.type || DyFM_Msg_ConversationType.direct,
339
- participants: conversationData.participants || [],
340
- __createdBy: issuer,
341
- __lastModifiedBy: issuer,
342
- ...conversationData,
343
- });
344
-
345
- const conversationService = new DyNTS_Msg_Conversation_DataService({
346
- conversation,
347
- issuer,
348
- });
349
-
350
- await conversationService.saveData(conversationService.data, false, false);
351
-
352
- // Emit event
353
- const participantIds = conversationService.data.participants?.map(p => p.userId) || [];
354
- this.eventsService.emitConversationCreated(conversationService.data, participantIds);
355
-
356
- return conversationService.data;
357
- } catch (error) {
358
- throw new DyFM_Error({
359
- ...this.getDefaultErrorSettings('createConversation', error, issuer),
360
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-CC`,
361
- userMessage: 'Failed to create conversation.',
362
- });
363
- }
364
- }
365
-
366
- /**
367
- * Update conversation
368
- */
369
- async updateConversation(
370
- conversationId: string,
371
- updateData: Partial<DyFM_Msg_Conversation>,
372
- userId: string,
373
- issuer: string
374
- ): Promise<DyFM_Msg_Conversation> {
375
- try {
376
- const conversationService = new DyNTS_Msg_Conversation_DataService({
377
- issuer,
378
- });
379
-
380
- const conversation = await conversationService.getDataById(conversationId);
381
-
382
- if (!conversation) {
383
- throw new Error('Conversation not found');
384
- }
385
-
386
- // Check if user is participant
387
- const isParticipant = conversation.participants?.some(p => p.userId === userId);
388
- if (!isParticipant) {
389
- throw new Error('Unauthorized: User is not a participant in this conversation');
390
- }
391
-
392
- Object.assign(conversation, updateData);
393
- conversation.__lastModifiedBy = issuer;
394
-
395
- await conversationService.saveData(conversation, false, false);
396
-
397
- // Emit event
398
- this.eventsService.emitConversationUpdated(conversationService.data);
399
-
400
- return conversationService.data;
401
- } catch (error) {
402
- throw new DyFM_Error({
403
- ...this.getDefaultErrorSettings('updateConversation', error, issuer),
404
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-UC`,
405
- userMessage: 'Failed to update conversation.',
406
- });
407
- }
408
- }
409
-
410
- /**
411
- * Delete conversation
412
- */
413
- async deleteConversation(
414
- conversationId: string,
415
- userId: string,
416
- issuer: string
417
- ): Promise<void> {
418
- try {
419
- const conversationService = new DyNTS_Msg_Conversation_DataService({
420
- issuer,
421
- });
422
-
423
- const conversation = await conversationService.getDataById(conversationId);
424
-
425
- if (!conversation) {
426
- throw new Error('Conversation not found');
427
- }
428
-
429
- // Check if user is owner or admin
430
- const isOwnerOrAdmin = conversation.participants?.some(p =>
431
- p.userId === userId && (p.role === DyFM_Msg_ParticipantRole.owner || p.role === DyFM_Msg_ParticipantRole.admin)
432
- );
433
- if (!isOwnerOrAdmin) {
434
- throw new Error('Unauthorized: Only owners or admins can delete conversations');
435
- }
436
-
437
- await conversationService.deleteData(conversationId);
438
-
439
- // Emit event
440
- this.eventsService.emitConversationDeleted(conversationId);
441
- } catch (error) {
442
- throw new DyFM_Error({
443
- ...this.getDefaultErrorSettings('deleteConversation', error, issuer),
444
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-DC`,
445
- userMessage: 'Failed to delete conversation.',
446
- });
447
- }
448
- }
449
-
450
- /**
451
- * Add participant to conversation
452
- */
453
- async addParticipant(
454
- conversationId: string,
455
- newUserId: string,
456
- role: DyFM_Msg_ParticipantRole = DyFM_Msg_ParticipantRole.member,
457
- requesterId: string,
458
- issuer: string
459
- ): Promise<void> {
460
- try {
461
- const conversationService = new DyNTS_Msg_Conversation_DataService({
462
- issuer,
463
- });
464
-
465
- const conversation = await conversationService.getDataById(conversationId);
466
-
467
- if (!conversation) {
468
- throw new Error('Conversation not found');
469
- }
470
-
471
- // Check if requester is owner or admin
472
- const isOwnerOrAdmin = conversation.participants?.some(p =>
473
- p.userId === requesterId && (p.role === DyFM_Msg_ParticipantRole.owner || p.role === DyFM_Msg_ParticipantRole.admin)
474
- );
475
- if (!isOwnerOrAdmin) {
476
- throw new Error('Unauthorized: Only owners or admins can add participants');
477
- }
478
-
479
- const newParticipant: DyFM_Msg_Participant = {
480
- userId: newUserId,
481
- role,
482
- joinedAt: new Date(),
483
- };
484
-
485
- await conversationService.addParticipant(conversationId, newParticipant);
486
-
487
- // Emit event
488
- this.eventsService.emitParticipantAdded(conversationId, newUserId);
489
- } catch (error) {
490
- throw new DyFM_Error({
491
- ...this.getDefaultErrorSettings('addParticipant', error, issuer),
492
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-AP`,
493
- userMessage: 'Failed to add participant.',
494
- });
495
- }
496
- }
497
-
498
- /**
499
- * Remove participant from conversation
500
- */
501
- async removeParticipant(
502
- conversationId: string,
503
- userIdToRemove: string,
504
- requesterId: string,
505
- issuer: string
506
- ): Promise<void> {
507
- try {
508
- const conversationService = new DyNTS_Msg_Conversation_DataService({
509
- issuer,
510
- });
511
-
512
- const conversation = await conversationService.getDataById(conversationId);
513
-
514
- if (!conversation) {
515
- throw new Error('Conversation not found');
516
- }
517
-
518
- // Check if requester is owner or admin, or removing themselves
519
- const isOwnerOrAdmin = conversation.participants?.some(p =>
520
- p.userId === requesterId && (p.role === DyFM_Msg_ParticipantRole.owner || p.role === DyFM_Msg_ParticipantRole.admin)
521
- );
522
- const isSelfRemoval = requesterId === userIdToRemove;
523
-
524
- if (!isOwnerOrAdmin && !isSelfRemoval) {
525
- throw new Error('Unauthorized: Only owners, admins, or the user themselves can remove participants');
526
- }
527
-
528
- await conversationService.removeParticipant(conversationId, userIdToRemove);
529
-
530
- // Emit event
531
- this.eventsService.emitParticipantRemoved(conversationId, userIdToRemove);
532
- } catch (error) {
533
- throw new DyFM_Error({
534
- ...this.getDefaultErrorSettings('removeParticipant', error, issuer),
535
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-RP`,
536
- userMessage: 'Failed to remove participant.',
537
- });
538
- }
539
- }
540
-
541
- /**
542
- * Get agent process steps for a message
543
- */
544
- async getAgentProcessSteps(
545
- messageId: string,
546
- issuer: string
547
- ): Promise<any[]> {
548
- try {
549
- const messageService = new DyNTS_Msg_Message_DataService({
550
- issuer,
551
- });
552
-
553
- const message = await messageService.getDataById(messageId);
554
-
555
- if (!message) {
556
- throw new Error('Message not found');
557
- }
558
-
559
- if (!message.agentProcessSteps) {
560
- throw new Error('No agent process steps found for this message');
561
- }
562
-
563
- return message.agentProcessSteps;
564
- } catch (error) {
565
- throw new DyFM_Error({
566
- ...this.getDefaultErrorSettings('getAgentProcessSteps', error, issuer),
567
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-GAPS`,
568
- userMessage: 'Failed to get agent process steps.',
569
- });
570
- }
571
- }
1
+ import { DyNTS_SingletonService } from '../../../_services/base/singleton.service';
2
+ import { DyFM_Error, DyFM_Log } from '@futdevpro/fsm-dynamo';
3
+ import {
4
+ DyFM_Msg_Message,
5
+ DyFM_Msg_Conversation,
6
+ DyFM_Msg_Status,
7
+ DyFM_Msg_Reaction,
8
+ DyFM_Msg_Participant,
9
+ DyFM_Msg_ParticipantRole,
10
+ DyFM_Msg_Type,
11
+ DyFM_Msg_ConversationType,
12
+ } from '@futdevpro/fsm-dynamo/messaging';
13
+
14
+ import { DyNTS_global_settings } from '../../../_collections/global-settings.const';
15
+ import { DyNTS_Msg_Message_DataService } from './msg-message.data-service';
16
+ import { DyNTS_Msg_Conversation_DataService } from './msg-conversation.data-service';
17
+ import { DyNTS_Msg_Events_Service } from './msg-events.service';
18
+
19
+ /**
20
+ * Main Messaging Control Service
21
+ * Handles all business logic for messaging operations
22
+ */
23
+ export class DyNTS_Msg_Main_ControlService extends DyNTS_SingletonService {
24
+
25
+ static getInstance(): DyNTS_Msg_Main_ControlService {
26
+ return DyNTS_Msg_Main_ControlService.getSingletonInstance();
27
+ }
28
+
29
+ private eventsService = DyNTS_Msg_Events_Service.getInstance();
30
+
31
+ /**
32
+ * Send a message
33
+ */
34
+ async sendMessage(
35
+ conversationId: string,
36
+ messageData: Partial<DyFM_Msg_Message>,
37
+ senderId: string,
38
+ issuer: string
39
+ ): Promise<DyFM_Msg_Message> {
40
+ try {
41
+ if (!messageData?.content) {
42
+ throw new Error('Message content is required');
43
+ }
44
+
45
+ // Create message
46
+ const message = new DyFM_Msg_Message({
47
+ conversationId: conversationId,
48
+ senderId: senderId,
49
+ content: messageData.content,
50
+ type: messageData.type || DyFM_Msg_Type.text,
51
+ status: DyFM_Msg_Status.sent,
52
+ sentAt: new Date(),
53
+ __createdBy: issuer,
54
+ __lastModifiedBy: issuer,
55
+ ...messageData,
56
+ });
57
+
58
+ // Save message
59
+ const messageService = new DyNTS_Msg_Message_DataService({
60
+ message,
61
+ issuer,
62
+ });
63
+ await messageService.saveData(messageService.data, false, false);
64
+
65
+ // Update conversation last message
66
+ const conversationService = new DyNTS_Msg_Conversation_DataService({
67
+ issuer,
68
+ });
69
+ await conversationService.updateLastMessage(
70
+ conversationId,
71
+ messageService.data._id!,
72
+ message.content.substring(0, 100)
73
+ );
74
+
75
+ // Emit event
76
+ this.eventsService.emitMessageSent(messageService.data, conversationId);
77
+
78
+ return messageService.data;
79
+ } catch (error) {
80
+ throw new DyFM_Error({
81
+ ...this.getDefaultErrorSettings('sendMessage', error, issuer),
82
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-SM`,
83
+ userMessage: 'Failed to send message.',
84
+ });
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Edit a message
90
+ */
91
+ async editMessage(
92
+ messageId: string,
93
+ content: string,
94
+ userId: string,
95
+ issuer: string
96
+ ): Promise<DyFM_Msg_Message> {
97
+ try {
98
+ const messageService = new DyNTS_Msg_Message_DataService({
99
+ issuer,
100
+ });
101
+
102
+ const message = await messageService.getDataById(messageId);
103
+
104
+ if (!message) {
105
+ throw new Error('Message not found');
106
+ }
107
+
108
+ if (message.senderId !== userId) {
109
+ throw new Error('Unauthorized: Only the message sender can edit it');
110
+ }
111
+
112
+ message.content = content;
113
+ message.editedAt = new Date();
114
+ message.status = DyFM_Msg_Status.sent; // Keep as sent since edited is not a status
115
+ message.__lastModifiedBy = issuer;
116
+
117
+ await messageService.saveData(message, false, false);
118
+
119
+ // Emit event
120
+ this.eventsService.emitMessageUpdated(messageService.data, message.conversationId);
121
+
122
+ return messageService.data;
123
+ } catch (error) {
124
+ throw new DyFM_Error({
125
+ ...this.getDefaultErrorSettings('editMessage', error, issuer),
126
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-EM`,
127
+ userMessage: 'Failed to edit message.',
128
+ });
129
+ }
130
+ }
131
+
132
+ async modifyMessage(message: DyFM_Msg_Message, issuer: string): Promise<DyFM_Msg_Message> {
133
+ try {
134
+ const messageService = new DyNTS_Msg_Message_DataService({
135
+ issuer,
136
+ });
137
+ await messageService.saveData(message);
138
+
139
+ // Emit event
140
+ this.eventsService.emitMessageUpdated(messageService.data, message.conversationId);
141
+
142
+ return messageService.data;
143
+ } catch (error) {
144
+ throw new DyFM_Error({
145
+ ...this.getDefaultErrorSettings('modifyMessage', error, issuer),
146
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-MM`,
147
+ userMessage: 'Failed to modify message.',
148
+ });
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Delete a message
154
+ */
155
+ async deleteMessage(
156
+ messageId: string,
157
+ userId: string,
158
+ issuer: string
159
+ ): Promise<void> {
160
+ try {
161
+ const messageService = new DyNTS_Msg_Message_DataService({
162
+ issuer,
163
+ });
164
+
165
+ const message = await messageService.getDataById(messageId);
166
+
167
+ if (!message) {
168
+ throw new Error('Message not found');
169
+ }
170
+
171
+ if (message.senderId !== userId) {
172
+ throw new Error('Unauthorized: Only the message sender can delete it');
173
+ }
174
+
175
+ const conversationId = message.conversationId;
176
+ await messageService.deleteData(messageId);
177
+
178
+ // Emit event
179
+ this.eventsService.emitMessageDeleted(messageId, conversationId);
180
+ } catch (error) {
181
+ throw new DyFM_Error({
182
+ ...this.getDefaultErrorSettings('deleteMessage', error, issuer),
183
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-DM`,
184
+ userMessage: 'Failed to delete message.',
185
+ });
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Mark messages as read
191
+ */
192
+ async markMessagesAsRead(
193
+ messageIds: string[],
194
+ userId: string,
195
+ issuer: string
196
+ ): Promise<{ success: boolean; count: number }> {
197
+ try {
198
+ const messageService = new DyNTS_Msg_Message_DataService({
199
+ issuer,
200
+ });
201
+
202
+ for (const messageId of messageIds) {
203
+ await messageService.markAsRead(messageId, userId);
204
+
205
+ // Get message to get conversationId for event
206
+ const message = await messageService.getDataById(messageId);
207
+ this.eventsService.emitMessageRead(messageId, userId, message.conversationId);
208
+ }
209
+
210
+ return { success: true, count: messageIds.length };
211
+ } catch (error) {
212
+ throw new DyFM_Error({
213
+ ...this.getDefaultErrorSettings('markMessagesAsRead', error, issuer),
214
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-MAR`,
215
+ userMessage: 'Failed to mark messages as read.',
216
+ });
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Add reaction to message
222
+ */
223
+ async addReaction(
224
+ messageId: string,
225
+ emoji: string,
226
+ userId: string,
227
+ issuer: string
228
+ ): Promise<DyFM_Msg_Message> {
229
+ try {
230
+ const messageService = new DyNTS_Msg_Message_DataService({
231
+ issuer,
232
+ });
233
+
234
+ const message = await messageService.getDataById(messageId);
235
+
236
+ if (!message) {
237
+ throw new Error('Message not found');
238
+ }
239
+
240
+ if (!message.reactions) {
241
+ message.reactions = [];
242
+ }
243
+
244
+ // Check if user already reacted with this emoji
245
+ const existingReaction = message.reactions.find((r: any) => r.emoji === emoji && r.userId === userId);
246
+
247
+ if (!existingReaction) {
248
+ const newReaction = {
249
+ emoji,
250
+ userId,
251
+ reactedAt: new Date(),
252
+ } as any;
253
+ message.reactions.push(newReaction);
254
+
255
+ await messageService.saveData(message, false, false);
256
+
257
+ // Emit event
258
+ this.eventsService.emitReactionAdded(messageId, newReaction);
259
+ }
260
+
261
+ return messageService.data;
262
+ } catch (error) {
263
+ throw new DyFM_Error({
264
+ ...this.getDefaultErrorSettings('addReaction', error, issuer),
265
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-AR`,
266
+ userMessage: 'Failed to add reaction.',
267
+ });
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Remove reaction from message
273
+ */
274
+ async removeReaction(
275
+ messageId: string,
276
+ emoji: string,
277
+ userId: string,
278
+ issuer: string
279
+ ): Promise<DyFM_Msg_Message> {
280
+ try {
281
+ const messageService = new DyNTS_Msg_Message_DataService({
282
+ issuer,
283
+ });
284
+
285
+ const message = await messageService.getDataById(messageId);
286
+
287
+ if (!message) {
288
+ throw new Error('Message not found');
289
+ }
290
+
291
+ if (!message.reactions) {
292
+ message.reactions = [];
293
+ }
294
+
295
+ // Remove user's reaction with this emoji
296
+ const initialLength = message.reactions.length;
297
+ message.reactions = message.reactions.filter((r: any) => !(r.emoji === emoji && r.userId === userId));
298
+
299
+ if (message.reactions.length < initialLength) {
300
+ await messageService.saveData(message, false, false);
301
+
302
+ // Emit event
303
+ this.eventsService.emitReactionRemoved(messageId, userId, emoji);
304
+ }
305
+
306
+ return messageService.data;
307
+ } catch (error) {
308
+ throw new DyFM_Error({
309
+ ...this.getDefaultErrorSettings('removeReaction', error, issuer),
310
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-RR`,
311
+ userMessage: 'Failed to remove reaction.',
312
+ });
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Create conversation
318
+ */
319
+ async createConversation(
320
+ conversationData: Partial<DyFM_Msg_Conversation>,
321
+ creatorId: string,
322
+ issuer: string
323
+ ): Promise<DyFM_Msg_Conversation> {
324
+ try {
325
+ // Ensure creator is in participants
326
+ if (!conversationData.participants?.some(p => p.userId === creatorId)) {
327
+ if (!conversationData.participants) {
328
+ conversationData.participants = [];
329
+ }
330
+ conversationData.participants.push({
331
+ userId: creatorId,
332
+ role: DyFM_Msg_ParticipantRole.owner,
333
+ joinedAt: new Date(),
334
+ });
335
+ }
336
+
337
+ const conversation = new DyFM_Msg_Conversation({
338
+ type: conversationData.type || DyFM_Msg_ConversationType.direct,
339
+ participants: conversationData.participants || [],
340
+ __createdBy: issuer,
341
+ __lastModifiedBy: issuer,
342
+ ...conversationData,
343
+ });
344
+
345
+ const conversationService = new DyNTS_Msg_Conversation_DataService({
346
+ conversation,
347
+ issuer,
348
+ });
349
+
350
+ await conversationService.saveData(conversationService.data, false, false);
351
+
352
+ // Emit event
353
+ const participantIds = conversationService.data.participants?.map(p => p.userId) || [];
354
+ this.eventsService.emitConversationCreated(conversationService.data, participantIds);
355
+
356
+ return conversationService.data;
357
+ } catch (error) {
358
+ throw new DyFM_Error({
359
+ ...this.getDefaultErrorSettings('createConversation', error, issuer),
360
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-CC`,
361
+ userMessage: 'Failed to create conversation.',
362
+ });
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Update conversation
368
+ */
369
+ async updateConversation(
370
+ conversationId: string,
371
+ updateData: Partial<DyFM_Msg_Conversation>,
372
+ userId: string,
373
+ issuer: string
374
+ ): Promise<DyFM_Msg_Conversation> {
375
+ try {
376
+ const conversationService = new DyNTS_Msg_Conversation_DataService({
377
+ issuer,
378
+ });
379
+
380
+ const conversation = await conversationService.getDataById(conversationId);
381
+
382
+ if (!conversation) {
383
+ throw new Error('Conversation not found');
384
+ }
385
+
386
+ // Check if user is participant
387
+ const isParticipant = conversation.participants?.some(p => p.userId === userId);
388
+ if (!isParticipant) {
389
+ throw new Error('Unauthorized: User is not a participant in this conversation');
390
+ }
391
+
392
+ Object.assign(conversation, updateData);
393
+ conversation.__lastModifiedBy = issuer;
394
+
395
+ await conversationService.saveData(conversation, false, false);
396
+
397
+ // Emit event
398
+ this.eventsService.emitConversationUpdated(conversationService.data);
399
+
400
+ return conversationService.data;
401
+ } catch (error) {
402
+ throw new DyFM_Error({
403
+ ...this.getDefaultErrorSettings('updateConversation', error, issuer),
404
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-UC`,
405
+ userMessage: 'Failed to update conversation.',
406
+ });
407
+ }
408
+ }
409
+
410
+ /**
411
+ * Delete conversation
412
+ */
413
+ async deleteConversation(
414
+ conversationId: string,
415
+ userId: string,
416
+ issuer: string
417
+ ): Promise<void> {
418
+ try {
419
+ const conversationService = new DyNTS_Msg_Conversation_DataService({
420
+ issuer,
421
+ });
422
+
423
+ const conversation = await conversationService.getDataById(conversationId);
424
+
425
+ if (!conversation) {
426
+ throw new Error('Conversation not found');
427
+ }
428
+
429
+ // Check if user is owner or admin
430
+ const isOwnerOrAdmin = conversation.participants?.some(p =>
431
+ p.userId === userId && (p.role === DyFM_Msg_ParticipantRole.owner || p.role === DyFM_Msg_ParticipantRole.admin)
432
+ );
433
+ if (!isOwnerOrAdmin) {
434
+ throw new Error('Unauthorized: Only owners or admins can delete conversations');
435
+ }
436
+
437
+ await conversationService.deleteData(conversationId);
438
+
439
+ // Emit event
440
+ this.eventsService.emitConversationDeleted(conversationId);
441
+ } catch (error) {
442
+ throw new DyFM_Error({
443
+ ...this.getDefaultErrorSettings('deleteConversation', error, issuer),
444
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-DC`,
445
+ userMessage: 'Failed to delete conversation.',
446
+ });
447
+ }
448
+ }
449
+
450
+ /**
451
+ * Add participant to conversation
452
+ */
453
+ async addParticipant(
454
+ conversationId: string,
455
+ newUserId: string,
456
+ role: DyFM_Msg_ParticipantRole = DyFM_Msg_ParticipantRole.member,
457
+ requesterId: string,
458
+ issuer: string
459
+ ): Promise<void> {
460
+ try {
461
+ const conversationService = new DyNTS_Msg_Conversation_DataService({
462
+ issuer,
463
+ });
464
+
465
+ const conversation = await conversationService.getDataById(conversationId);
466
+
467
+ if (!conversation) {
468
+ throw new Error('Conversation not found');
469
+ }
470
+
471
+ // Check if requester is owner or admin
472
+ const isOwnerOrAdmin = conversation.participants?.some(p =>
473
+ p.userId === requesterId && (p.role === DyFM_Msg_ParticipantRole.owner || p.role === DyFM_Msg_ParticipantRole.admin)
474
+ );
475
+ if (!isOwnerOrAdmin) {
476
+ throw new Error('Unauthorized: Only owners or admins can add participants');
477
+ }
478
+
479
+ const newParticipant: DyFM_Msg_Participant = {
480
+ userId: newUserId,
481
+ role,
482
+ joinedAt: new Date(),
483
+ };
484
+
485
+ await conversationService.addParticipant(conversationId, newParticipant);
486
+
487
+ // Emit event
488
+ this.eventsService.emitParticipantAdded(conversationId, newUserId);
489
+ } catch (error) {
490
+ throw new DyFM_Error({
491
+ ...this.getDefaultErrorSettings('addParticipant', error, issuer),
492
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-AP`,
493
+ userMessage: 'Failed to add participant.',
494
+ });
495
+ }
496
+ }
497
+
498
+ /**
499
+ * Remove participant from conversation
500
+ */
501
+ async removeParticipant(
502
+ conversationId: string,
503
+ userIdToRemove: string,
504
+ requesterId: string,
505
+ issuer: string
506
+ ): Promise<void> {
507
+ try {
508
+ const conversationService = new DyNTS_Msg_Conversation_DataService({
509
+ issuer,
510
+ });
511
+
512
+ const conversation = await conversationService.getDataById(conversationId);
513
+
514
+ if (!conversation) {
515
+ throw new Error('Conversation not found');
516
+ }
517
+
518
+ // Check if requester is owner or admin, or removing themselves
519
+ const isOwnerOrAdmin = conversation.participants?.some(p =>
520
+ p.userId === requesterId && (p.role === DyFM_Msg_ParticipantRole.owner || p.role === DyFM_Msg_ParticipantRole.admin)
521
+ );
522
+ const isSelfRemoval = requesterId === userIdToRemove;
523
+
524
+ if (!isOwnerOrAdmin && !isSelfRemoval) {
525
+ throw new Error('Unauthorized: Only owners, admins, or the user themselves can remove participants');
526
+ }
527
+
528
+ await conversationService.removeParticipant(conversationId, userIdToRemove);
529
+
530
+ // Emit event
531
+ this.eventsService.emitParticipantRemoved(conversationId, userIdToRemove);
532
+ } catch (error) {
533
+ throw new DyFM_Error({
534
+ ...this.getDefaultErrorSettings('removeParticipant', error, issuer),
535
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-RP`,
536
+ userMessage: 'Failed to remove participant.',
537
+ });
538
+ }
539
+ }
540
+
541
+ /**
542
+ * Get agent process steps for a message
543
+ */
544
+ async getAgentProcessSteps(
545
+ messageId: string,
546
+ issuer: string
547
+ ): Promise<any[]> {
548
+ try {
549
+ const messageService = new DyNTS_Msg_Message_DataService({
550
+ issuer,
551
+ });
552
+
553
+ const message = await messageService.getDataById(messageId);
554
+
555
+ if (!message) {
556
+ throw new Error('Message not found');
557
+ }
558
+
559
+ if (!message.agentProcessSteps) {
560
+ throw new Error('No agent process steps found for this message');
561
+ }
562
+
563
+ return message.agentProcessSteps;
564
+ } catch (error) {
565
+ throw new DyFM_Error({
566
+ ...this.getDefaultErrorSettings('getAgentProcessSteps', error, issuer),
567
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-GAPS`,
568
+ userMessage: 'Failed to get agent process steps.',
569
+ });
570
+ }
571
+ }
572
572
  }