@futdevpro/nts-dynamo 1.15.127 → 1.15.129

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 (389) 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 +2852 -0
  17. package/.dynamo/logs/cicd-pipeline/status.json +74 -0
  18. package/.dynamo/pipeline.cicd.config.json +3 -1
  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/__documentations/plans/BEDROCK-HYPERPLAN.md +95 -95
  24. package/_specifications/BACKLOG.md +92 -92
  25. package/_specifications/TODO.md +15 -15
  26. package/_specifications/agent.md +138 -138
  27. package/build/_models/control-models/endpoint-params.control-model.d.ts.map +1 -1
  28. package/build/_models/control-models/endpoint-params.control-model.js +9 -0
  29. package/build/_models/control-models/endpoint-params.control-model.js.map +1 -1
  30. package/build/_modules/server/errors/errors.data-service.d.ts +6 -0
  31. package/build/_modules/server/errors/errors.data-service.d.ts.map +1 -1
  32. package/build/_modules/server/errors/errors.data-service.js +29 -3
  33. package/build/_modules/server/errors/errors.data-service.js.map +1 -1
  34. package/build/_services/core/event-loop-diag.service.d.ts +6 -0
  35. package/build/_services/core/event-loop-diag.service.d.ts.map +1 -1
  36. package/build/_services/core/event-loop-diag.service.js +19 -1
  37. package/build/_services/core/event-loop-diag.service.js.map +1 -1
  38. package/build/_services/core/request-hunter.service.d.ts +74 -0
  39. package/build/_services/core/request-hunter.service.d.ts.map +1 -0
  40. package/build/_services/core/request-hunter.service.js +123 -0
  41. package/build/_services/core/request-hunter.service.js.map +1 -0
  42. package/build/index.d.ts +1 -0
  43. package/build/index.d.ts.map +1 -1
  44. package/build/index.js +1 -0
  45. package/build/index.js.map +1 -1
  46. package/eslint.config.js +3 -3
  47. package/nodemon.json +24 -24
  48. package/package.json +2 -2
  49. package/pnpm-workspace.yaml +5 -5
  50. package/scripts/run-coverage-tests.js +28 -28
  51. package/spec/support/helpers/spec-reporter-loader.js +359 -359
  52. package/spec/support/helpers/ts-node-helper.js +93 -93
  53. package/spec/support/jasmine.coverage.json +24 -24
  54. package/spec/support/jasmine.json +24 -24
  55. package/src/_collections/archive.util.spec.ts +57 -57
  56. package/src/_collections/archive.util.ts +18 -18
  57. package/src/_collections/atlas-default-db-options.const.ts +9 -9
  58. package/src/_collections/default-fallback-cache-max-age.const.spec.ts +11 -11
  59. package/src/_collections/default-fallback-cache-max-age.const.ts +2 -2
  60. package/src/_collections/default-not-found-page.const.spec.ts +19 -19
  61. package/src/_collections/default-not-found-page.const.ts +22 -22
  62. package/src/_collections/default-socket-path.const.spec.ts +12 -12
  63. package/src/_collections/default-socket-path.const.ts +2 -2
  64. package/src/_collections/get-environment-settings.util.spec.ts +210 -210
  65. package/src/_collections/get-environment-settings.util.ts +48 -48
  66. package/src/_collections/global-settings.const.ts +126 -126
  67. package/src/_collections/sample.env +21 -21
  68. package/src/_collections/signed-url.util.spec.ts +198 -198
  69. package/src/_collections/signed-url.util.ts +170 -170
  70. package/src/_collections/star.controller.spec.ts +224 -224
  71. package/src/_collections/star.controller.ts +129 -129
  72. package/src/_enums/data-model-type.enum.ts +14 -14
  73. package/src/_enums/data-service-function.enum.ts +24 -24
  74. package/src/_enums/predefined-data-types.enum.ts +16 -16
  75. package/src/_enums/route-security.enum.ts +12 -12
  76. package/src/_models/control-models/api-call-params.control-model.spec.ts +152 -152
  77. package/src/_models/control-models/api-call-params.control-model.ts +142 -142
  78. package/src/_models/control-models/app-ext-system-controls.control-model.spec.ts +52 -52
  79. package/src/_models/control-models/app-ext-system-controls.control-model.ts +9 -9
  80. package/src/_models/control-models/app-params.control-model.spec.ts +225 -225
  81. package/src/_models/control-models/app-params.control-model.ts +136 -136
  82. package/src/_models/control-models/app-system-controls.control-model.spec.ts +31 -31
  83. package/src/_models/control-models/app-system-controls.control-model.ts +9 -9
  84. package/src/_models/control-models/endpoint-params.control-model.spec.ts +669 -669
  85. package/src/_models/control-models/endpoint-params.control-model.ts +664 -656
  86. package/src/_models/control-models/http-settings.control-model.spec.ts +77 -77
  87. package/src/_models/control-models/http-settings.control-model.ts +37 -37
  88. package/src/_models/control-models/system-control.control-model.spec.ts +27 -27
  89. package/src/_models/control-models/system-control.control-model.ts +12 -12
  90. package/src/_models/interfaces/certification-settings.interface.ts +7 -7
  91. package/src/_models/interfaces/environment-settings.interface.ts +59 -59
  92. package/src/_models/interfaces/global-log-settings.interface.ts +171 -171
  93. package/src/_models/interfaces/global-service-settings.interface.ts +47 -47
  94. package/src/_models/interfaces/global-settings.interface.ts +286 -286
  95. package/src/_models/interfaces/routing-module-settings.interface.ts +21 -21
  96. package/src/_models/interfaces/static-client-settings.interface.spec.ts +29 -29
  97. package/src/_models/interfaces/static-client-settings.interface.ts +36 -36
  98. package/src/_models/types/db-update.type.ts +100 -100
  99. package/src/_modules/ai/_models/ai-input-interfaces.ts +117 -117
  100. package/src/_modules/ai/_models/ai-test-generation-result.interface.ts +16 -16
  101. package/src/_modules/ai/_modules/ai-mock/_services/ai-embedding-mock.service.spec.ts +115 -115
  102. package/src/_modules/ai/_modules/ai-mock/_services/ai-embedding-mock.service.ts +233 -233
  103. package/src/_modules/ai/_modules/anthropic/_services/aai-user-key.control-service.ts +138 -138
  104. package/src/_modules/ai/_modules/anthropic/index.ts +5 -5
  105. package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.spec.ts +242 -242
  106. package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.ts +639 -639
  107. package/src/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.spec.ts +295 -295
  108. package/src/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.ts +518 -518
  109. package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.spec.ts +209 -209
  110. package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.ts +85 -85
  111. package/src/_modules/ai/_modules/document-ai/_enums/dai-compare-result-type.enum.ts +7 -7
  112. package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-chunk.data-model.ts +146 -146
  113. package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-page.data-model.ts +162 -162
  114. package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-document.data-model.ts +99 -99
  115. package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-code-chunk.interface.ts +68 -68
  116. package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-chunk-compare-result.interface.ts +18 -18
  117. package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-page-compare-result.interface.ts +19 -19
  118. package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-document-compare-result.interface.ts +25 -25
  119. package/src/_modules/ai/_modules/document-ai/index.ts +30 -30
  120. package/src/_modules/ai/_modules/fdp-ai/_services/fdpai-user-key.control-service.ts +189 -189
  121. package/src/_modules/ai/_modules/fdp-ai/index.ts +5 -5
  122. package/src/_modules/ai/_modules/open-ai/_collections/oai-global-settings.const.ts +9 -9
  123. package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests-hu.conts.ts +82 -82
  124. package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests.conts.ts +75 -75
  125. package/src/_modules/ai/_modules/open-ai/_enums/oai-gpt-message-role.enum.ts +45 -45
  126. package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-global-settings.interface.ts +7 -7
  127. package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-gpt-message.interface.ts +7 -7
  128. package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-llm-predefined-requests.interface.ts +57 -57
  129. package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-doc-chunk-data.service.ts +292 -292
  130. package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-document.data-service.spec.ts +342 -342
  131. package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.spec.ts +550 -550
  132. package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.ts +630 -630
  133. package/src/_modules/ai/_modules/open-ai/_services/oai-embedding.control-service.spec.ts +332 -332
  134. package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.spec.ts +462 -462
  135. package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.ts +634 -634
  136. package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.spec.ts +489 -489
  137. package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.tools.spec.ts +173 -173
  138. package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.ts +1085 -1085
  139. package/src/_modules/ai/_modules/open-ai/_services/oai-user-key.control-service.ts +157 -157
  140. package/src/_modules/ai/_services/ai-embedding-provider.registry.spec.ts +110 -110
  141. package/src/_modules/ai/_services/ai-embedding-provider.registry.ts +114 -114
  142. package/src/_modules/ai/_services/ai-embedding.service-base.spec.ts +98 -98
  143. package/src/_modules/ai/_services/ai-embedding.service-base.ts +48 -48
  144. package/src/_modules/ai/_services/ai-llm-chat.service-base.spec.ts +229 -229
  145. package/src/_modules/ai/_services/ai-llm-chat.service-base.ts +68 -68
  146. package/src/_modules/ai/_services/ai-llm.service-base.spec.ts +250 -250
  147. package/src/_modules/ai/_services/ai-llm.service-base.ts +599 -599
  148. package/src/_modules/ai/_services/ai-provider.service-base.spec.ts +158 -158
  149. package/src/_modules/ai/_services/ai-user-key.service-base.ts +59 -59
  150. package/src/_modules/ai/_services/lmstudio-embedding.control-service.spec.ts +197 -197
  151. package/src/_modules/ai/_services/lmstudio-embedding.control-service.ts +371 -371
  152. package/src/_modules/ai/index.ts +33 -33
  153. package/src/_modules/assistant/_collections/ass-global-settings.const.ts +13 -13
  154. package/src/_modules/assistant/_collections/ass.util.spec.ts +176 -176
  155. package/src/_modules/assistant/_collections/ass.util.ts +50 -50
  156. package/src/_modules/assistant/_models/ass-global-settings.interface.ts +15 -15
  157. package/src/_modules/assistant/_services/ass-io.control-service.spec.ts +140 -140
  158. package/src/_modules/assistant/_services/ass-main.control-service.spec.ts +192 -192
  159. package/src/_modules/assistant/_services/ass-main.control-service.ts +107 -107
  160. package/src/_modules/bot/_collections/bot-default-commands.const.ts +12 -12
  161. package/src/_modules/bot/_collections/bot-global-settings.const.ts +39 -39
  162. package/src/_modules/bot/_models/bot-channel-wrapper.interface.ts +62 -62
  163. package/src/_modules/bot/_models/bot-command.interface.ts +8 -8
  164. package/src/_modules/bot/_models/bot-global-settings.interface.ts +96 -96
  165. package/src/_modules/bot/_models/bot-last-mention-date.interface.ts +6 -6
  166. package/src/_modules/bot/_models/bot-last-message-date.interface.ts +5 -5
  167. package/src/_modules/bot/_models/bot-user-wrapper.interface.ts +41 -41
  168. package/src/_modules/bot/_modules/discord-bot/_models/dib-platform.types.ts +9 -9
  169. package/src/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.spec.ts +431 -431
  170. package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.spec.ts +160 -160
  171. package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.ts +55 -55
  172. package/src/_modules/bot/_modules/dynamo-bot/_models/dyb-platform.types.ts +15 -15
  173. package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.spec.ts +374 -374
  174. package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.ts +447 -447
  175. package/src/_modules/bot/_modules/dynamo-bot/index.ts +15 -15
  176. package/src/_modules/bot/_modules/slack-bot/_models/slb-platform.types.ts +9 -9
  177. package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.spec.ts +344 -344
  178. package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.ts +197 -197
  179. package/src/_modules/bot/_modules/teams-bot/_models/teb-platform.types.ts +9 -9
  180. package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.spec.ts +345 -345
  181. package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.ts +197 -197
  182. package/src/_modules/bot/_services/bot-commands.control-service.spec.ts +116 -116
  183. package/src/_modules/bot/_services/bot-io.control-service.spec.ts +285 -285
  184. package/src/_modules/bot/_services/bot-main.control-service.spec.ts +208 -208
  185. package/src/_modules/bot/_services/bot-messaging-provider.service-base.spec.ts +349 -349
  186. package/src/_modules/bot/_services/bot-routines.control-service.spec.ts +111 -111
  187. package/src/_modules/custom-data/custom-data.controller.spec.ts +49 -49
  188. package/src/_modules/custom-data/custom-data.controller.ts +67 -67
  189. package/src/_modules/custom-data/custom-data.data-service.spec.ts +54 -54
  190. package/src/_modules/custom-data/custom-data.data-service.ts +21 -21
  191. package/src/_modules/custom-data/get-custom-data-routing-module.util.spec.ts +28 -28
  192. package/src/_modules/custom-data/get-custom-data-routing-module.util.ts +24 -24
  193. package/src/_modules/custom-data/index.ts +9 -9
  194. package/src/_modules/data-readers/_collections/dynts-sqlite-reader.util.spec.ts +161 -161
  195. package/src/_modules/data-readers/_collections/dynts-sqlite-reader.util.ts +203 -203
  196. package/src/_modules/data-readers/_models/interfaces/dynts-sqlite-reader.interface.ts +33 -33
  197. package/src/_modules/data-readers/index.ts +11 -11
  198. package/src/_modules/defaults/_collections/default-endpoints.util.ts +487 -487
  199. package/src/_modules/defaults/_models/default-user.data-model.ts +72 -72
  200. package/src/_modules/defaults/_services/default-auth.service.spec.ts +269 -269
  201. package/src/_modules/defaults/_services/default-auth.service.ts +177 -177
  202. package/src/_modules/defaults/_services/default-socket-events.service.spec.ts +42 -42
  203. package/src/_modules/defaults/_services/default-socket-events.service.ts +61 -61
  204. package/src/_modules/defaults/_services/default-user.data-service.spec.ts +187 -187
  205. package/src/_modules/defaults/_services/default-user.data-service.ts +98 -98
  206. package/src/_modules/defaults/index.ts +17 -17
  207. package/src/_modules/discord-assistant/_collections/dias-global-settings.const.ts +19 -19
  208. package/src/_modules/discord-assistant/_collections/dias.util.spec.ts +366 -366
  209. package/src/_modules/discord-assistant/_collections/dias.util.ts +132 -132
  210. package/src/_modules/discord-assistant/_models/dias-global-settings.interface.ts +19 -19
  211. package/src/_modules/discord-assistant/_models/dias-knowledge.data-model.ts +52 -52
  212. package/src/_modules/discord-assistant/_services/dias-chunk.data-service.ts +177 -177
  213. package/src/_modules/discord-assistant/_services/dias-io.control-service.spec.ts +108 -108
  214. package/src/_modules/discord-assistant/_services/dias-io.control-service.ts +69 -69
  215. package/src/_modules/discord-assistant/_services/dias-main.control-service.spec.ts +22 -22
  216. package/src/_modules/discord-assistant/_services/dias-main.control-service.ts +27 -27
  217. package/src/_modules/discord-assistant/_services/dias.service-base.spec.ts +195 -195
  218. package/src/_modules/discord-assistant/_services/dias.service-base.ts +76 -76
  219. package/src/_modules/discord-assistant/index.ts +38 -38
  220. package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.spec.ts +34 -34
  221. package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.ts +11 -11
  222. package/src/_modules/discord-assistant-voiced/index.ts +36 -36
  223. package/src/_modules/discord-bot/_collections/dibo-default-commands.const.ts +16 -16
  224. package/src/_modules/discord-bot/_collections/dibo-global-settings.conts.ts +55 -55
  225. package/src/_modules/discord-bot/_collections/dibo-operations.util.spec.ts +214 -214
  226. package/src/_modules/discord-bot/_collections/dibo-operations.util.ts +387 -387
  227. package/src/_modules/discord-bot/_models/dibo-command.interface.ts +12 -12
  228. package/src/_modules/discord-bot/_models/dibo-global-settings.interface.ts +98 -98
  229. package/src/_modules/discord-bot/_models/dibo-last-mention-date.inteface.ts +7 -7
  230. package/src/_modules/discord-bot/_models/dibo-last-message-date.interface.ts +6 -6
  231. package/src/_modules/discord-bot/_services/dibo-commands.control-service.spec.ts +154 -154
  232. package/src/_modules/discord-bot/_services/dibo-commands.control-service.ts +153 -153
  233. package/src/_modules/discord-bot/_services/dibo-io.control-service.spec.ts +264 -264
  234. package/src/_modules/discord-bot/_services/dibo-io.control-service.ts +306 -306
  235. package/src/_modules/discord-bot/_services/dibo-main.control-service.spec.ts +408 -408
  236. package/src/_modules/discord-bot/_services/dibo-main.control-service.ts +487 -487
  237. package/src/_modules/discord-bot/_services/dibo-routines.control-service.spec.ts +105 -105
  238. package/src/_modules/discord-bot/index.ts +36 -36
  239. package/src/_modules/local-vector-search/_enums/lvs-search-mode.enum.ts +35 -35
  240. package/src/_modules/local-vector-search/_models/data-models/lvs-vector-persist.data-model.ts +59 -59
  241. package/src/_modules/local-vector-search/_models/lvs-search-result.interface.ts +17 -17
  242. package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.spec.ts +418 -418
  243. package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.ts +276 -276
  244. package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.spec.ts +480 -480
  245. package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.ts +416 -416
  246. package/src/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.spec.ts +214 -214
  247. package/src/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.ts +186 -186
  248. package/src/_modules/local-vector-search/_services/lvs-vector-persist.data-service.spec.ts +167 -167
  249. package/src/_modules/local-vector-search/_services/lvs-vector-persist.data-service.ts +130 -130
  250. package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.spec.ts +509 -509
  251. package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.ts +323 -323
  252. package/src/_modules/local-vector-search/index.ts +16 -16
  253. package/src/_modules/logs/index.ts +11 -11
  254. package/src/_modules/mcp/_models/interfaces/dynts-mcp.interface.ts +111 -111
  255. package/src/_modules/mcp/_services/dynts-mcp-server.service-base.spec.ts +142 -142
  256. package/src/_modules/mcp/_services/dynts-mcp-server.service-base.ts +120 -120
  257. package/src/_modules/mcp/_services/dynts-mcp.adapter.ts +168 -168
  258. package/src/_modules/mcp/index.ts +13 -13
  259. package/src/_modules/messaging/README.md +354 -354
  260. package/src/_modules/messaging/_collections/get-messaging-routing-module.util.ts +26 -26
  261. package/src/_modules/messaging/_collections/msg-global-settings.const.ts +22 -22
  262. package/src/_modules/messaging/_collections/msg.util.spec.ts +226 -226
  263. package/src/_modules/messaging/_models/msg-global-settings.interface.ts +37 -37
  264. package/src/_modules/messaging/_services/msg-conversation.data-service.ts +146 -146
  265. package/src/_modules/messaging/_services/msg-events.service.spec.ts +219 -219
  266. package/src/_modules/messaging/_services/msg-events.service.ts +267 -267
  267. package/src/_modules/messaging/_services/msg-integration.control-service.ts +179 -179
  268. package/src/_modules/messaging/_services/msg-main.control-service.spec.ts +147 -147
  269. package/src/_modules/messaging/_services/msg-main.control-service.ts +571 -571
  270. package/src/_modules/messaging/_services/msg-message.data-service.ts +129 -129
  271. package/src/_modules/messaging/_services/msg.controller.spec.ts +201 -201
  272. package/src/_modules/messaging/index.ts +30 -30
  273. package/src/_modules/mock/app-extended-server.mock.ts +201 -201
  274. package/src/_modules/mock/app-integration-test.mock.ts +51 -51
  275. package/src/_modules/mock/app-params.mock.spec.ts +21 -21
  276. package/src/_modules/mock/app-params.mock.ts +9 -9
  277. package/src/_modules/mock/app-server.mock.ts +188 -188
  278. package/src/_modules/mock/auth-service.mock.spec.ts +47 -47
  279. package/src/_modules/mock/auth-service.mock.ts +28 -28
  280. package/src/_modules/mock/controller.mock.spec.ts +26 -26
  281. package/src/_modules/mock/controller.mock.ts +16 -16
  282. package/src/_modules/mock/data-model.mock.spec.ts +111 -111
  283. package/src/_modules/mock/data-model.mock.ts +82 -82
  284. package/src/_modules/mock/email-service-collection.mock.spec.ts +24 -24
  285. package/src/_modules/mock/email-service-collection.mock.ts +15 -15
  286. package/src/_modules/mock/email-service.mock.spec.ts +17 -17
  287. package/src/_modules/mock/email-service.mock.ts +20 -20
  288. package/src/_modules/mock/email-template.mock.html +14 -14
  289. package/src/_modules/mock/endpoint.mock.ts +91 -91
  290. package/src/_modules/mock/socket-client.mock.spec.ts +40 -40
  291. package/src/_modules/mock/socket-client.mock.ts +45 -45
  292. package/src/_modules/mock/socket-server.mock.spec.ts +44 -44
  293. package/src/_modules/mock/socket-server.mock.ts +46 -46
  294. package/src/_modules/oauth2/_routes/oauth2.controller.spec.ts +107 -107
  295. package/src/_modules/oauth2/_routes/oauth2.controller.ts +98 -98
  296. package/src/_modules/oauth2/_services/oauth2.auth-service.spec.ts +254 -254
  297. package/src/_modules/oauth2/_services/oauth2.auth-service.ts +232 -232
  298. package/src/_modules/oauth2/_services/oauth2.control-service.spec.ts +585 -585
  299. package/src/_modules/oauth2/_services/oauth2.control-service.ts +653 -653
  300. package/src/_modules/oauth2/index.ts +17 -17
  301. package/src/_modules/scheduler/_models/scheduler-job.interface.ts +35 -35
  302. package/src/_modules/scheduler/get-scheduler-routing-module.util.ts +33 -33
  303. package/src/_modules/scheduler/index.ts +8 -8
  304. package/src/_modules/scheduler/scheduler.controller.spec.ts +42 -42
  305. package/src/_modules/scheduler/scheduler.controller.ts +69 -69
  306. package/src/_modules/scheduler/scheduler.service.spec.ts +141 -141
  307. package/src/_modules/scheduler/scheduler.service.ts +176 -176
  308. package/src/_modules/scoped-config/_enums/dynts-scoped-config-level.enum.ts +22 -22
  309. package/src/_modules/scoped-config/_models/data-models/dynts-scoped-config.data-model.ts +81 -81
  310. package/src/_modules/scoped-config/_models/interfaces/dynts-scoped-config.interface.ts +107 -107
  311. package/src/_modules/scoped-config/_services/dynts-scoped-config.control-service.spec.ts +306 -306
  312. package/src/_modules/scoped-config/_services/dynts-scoped-config.control-service.ts +295 -295
  313. package/src/_modules/scoped-config/_services/dynts-scoped-config.data-service.spec.ts +118 -118
  314. package/src/_modules/scoped-config/_services/dynts-scoped-config.data-service.ts +105 -105
  315. package/src/_modules/scoped-config/index.ts +17 -17
  316. package/src/_modules/server/errors/errors.control-service.spec.ts +238 -238
  317. package/src/_modules/server/errors/errors.control-service.ts +100 -100
  318. package/src/_modules/server/errors/errors.controller.spec.ts +268 -268
  319. package/src/_modules/server/errors/errors.controller.ts +515 -515
  320. package/src/_modules/server/errors/errors.data-service.spec.ts +480 -480
  321. package/src/_modules/server/errors/errors.data-service.ts +30 -3
  322. package/src/_modules/server/index.ts +30 -30
  323. package/src/_modules/server/server-status/server-status-snapshot.control-service.spec.ts +70 -70
  324. package/src/_modules/server/server-status/server-status-snapshot.control-service.ts +17 -17
  325. package/src/_modules/server/server-status/server-status-snapshot.data-service.spec.ts +77 -77
  326. package/src/_modules/server/server-status/server-status-snapshot.data-service.ts +37 -37
  327. package/src/_modules/server/server-status/server-status.control-service.spec.ts +672 -672
  328. package/src/_modules/server/server-status/server-status.control-service.ts +490 -490
  329. package/src/_modules/server/server-status/server-status.controller.spec.ts +276 -276
  330. package/src/_modules/server/server-status/server-status.controller.ts +336 -336
  331. package/src/_modules/socket/_enums/socket-security.enum.ts +11 -11
  332. package/src/_modules/socket/_models/socket-client-service-params.control-model.spec.ts +32 -32
  333. package/src/_modules/socket/_models/socket-client-service-params.control-model.ts +22 -22
  334. package/src/_modules/socket/_models/socket-presence.control-model.spec.ts +164 -164
  335. package/src/_modules/socket/_models/socket-presence.control-model.ts +210 -210
  336. package/src/_modules/socket/_models/socket-server-service-params.control-model.spec.ts +69 -69
  337. package/src/_modules/socket/_services/socket-client.service.spec.ts +15 -15
  338. package/src/_modules/socket/_services/socket-client.service.ts +260 -260
  339. package/src/_modules/socket/_services/socket-server.service.spec.ts +11 -11
  340. package/src/_modules/socket/app-extended.integration.spec.ts +85 -85
  341. package/src/_modules/socket/app-extended.server.ts +648 -648
  342. package/src/_modules/socket/index.ts +42 -42
  343. package/src/_modules/test/get-test-routing-module.util.spec.ts +28 -28
  344. package/src/_modules/test/get-test-routing-module.util.ts +23 -23
  345. package/src/_modules/test/index.ts +11 -11
  346. package/src/_modules/test/test.controller.spec.ts +72 -72
  347. package/src/_modules/test/test.controller.ts +115 -115
  348. package/src/_modules/usage/get-usage-routing-module.util.ts +22 -22
  349. package/src/_modules/usage/index.ts +15 -15
  350. package/src/_modules/usage/usage.controller.spec.ts +81 -81
  351. package/src/_modules/usage/usage.controller.ts +126 -126
  352. package/src/_modules/usage/usage.data-service.spec.ts +332 -332
  353. package/src/_modules/usage/usage.data-service.ts +185 -185
  354. package/src/_services/base/api.service-base.spec.ts +125 -125
  355. package/src/_services/base/api.service-base.ts +74 -74
  356. package/src/_services/base/archive-data.service.spec.ts +209 -209
  357. package/src/_services/base/archive-data.service.ts +223 -223
  358. package/src/_services/base/data.service.spec.ts +729 -729
  359. package/src/_services/base/data.service.ts +2758 -2758
  360. package/src/_services/base/db.service.spec.ts +160 -160
  361. package/src/_services/base/db.service.ts +1698 -1698
  362. package/src/_services/base/singleton.service-base.spec.ts +28 -28
  363. package/src/_services/base/singleton.service-base.ts +24 -24
  364. package/src/_services/base/singleton.service.spec.ts +114 -114
  365. package/src/_services/base/singleton.service.ts +38 -38
  366. package/src/_services/core/api.service.spec.ts +140 -140
  367. package/src/_services/core/auth.service.spec.ts +159 -159
  368. package/src/_services/core/auth.service.ts +174 -174
  369. package/src/_services/core/email.service.spec.ts +85 -85
  370. package/src/_services/core/email.service.ts +757 -757
  371. package/src/_services/core/event-loop-diag.service.ts +23 -1
  372. package/src/_services/core/global.service.spec.ts +292 -292
  373. package/src/_services/core/global.service.ts +487 -487
  374. package/src/_services/core/memory-guard.service.spec.ts +245 -245
  375. package/src/_services/core/memory-guard.service.ts +481 -481
  376. package/src/_services/core/request-hunter.service.spec.ts +124 -0
  377. package/src/_services/core/request-hunter.service.ts +157 -0
  378. package/src/_services/core/service-collection.service.spec.ts +46 -46
  379. package/src/_services/core/service-collection.service.ts +6 -6
  380. package/src/_services/route/controller.service.spec.ts +53 -53
  381. package/src/_services/route/controller.service.ts +148 -148
  382. package/src/_services/route/routing-module.service.spec.ts +98 -98
  383. package/src/_services/route/routing-module.service.ts +330 -330
  384. package/src/_services/server/app.server.ts +1985 -1985
  385. package/src/_services/shared.static-service.spec.ts +99 -99
  386. package/src/_services/shared.static-service.ts +78 -78
  387. package/src/index.ts +113 -112
  388. package/tsconfig.app.json +12 -12
  389. package/tsconfig.json +42 -42
@@ -1,491 +1,491 @@
1
-
2
-
3
- import {
4
- DyFM_Metadata, DyFM_RelativeDate, DyFM_Time, DyFM_ServerStatus, DyFM_ErrorLevel, DyFM_Log,
5
- DyFM_Error, DyFM_Error_Statistics, DyFM_Errors,
6
- DyFM_Paged,
7
- hour, minute,
8
- DyFM_ServerConnectionCheckResult,
9
- DyFM_ServerConnection_Status,
10
- DyFM_Array
11
- } from '@futdevpro/fsm-dynamo';
12
- import { Subscription, timer } from 'rxjs';
13
- import * as mongoose from 'mongoose';
14
-
15
- import { version as _serverVersion } from '../../../../package.json';
16
- import { DyNTS_SingletonService } from '../../../_services/base/singleton.service';
17
- import { DyNTS_DbStats, DyNTS_DbStats_Util } from '../../../_services/core/db-stats.service';
18
- import { DyNTS_Diagnostics, DyNTS_DoctorReport } from '../../../_services/core/diagnostics.service';
19
- import { DyNTS_global_settings } from '../../../_collections/global-settings.const';
20
- import { DyNTS_Errors_ControlService } from '../errors/errors.control-service';
21
- import { DyNTS_ServerStatusSnapshot_ControlService } from './server-status-snapshot.control-service';
22
- import { DyNTS_GlobalService } from '../../../_services/core/global.service';
23
- import { DyNTS_ApiService_Base } from '../../../_services/base/api.service-base';
24
-
25
- export interface DyNTS_ServerConnection {
26
- name: string,
27
- apiService: DyNTS_ApiService_Base,
28
- accessible?: boolean,
29
- lastCheck?: Date,
30
- }
31
-
32
- /**
33
- * A readiness-probe ({@link DyNTS_ServerStatus_ControlService.checkDbReadiness}) eredménye.
34
- * `ready=true` CSAK ha a DB-connection él (readyState=1) ÉS a valós ping round-trip sikerült.
35
- */
36
- export interface DyNTS_DbReadiness {
37
- /** ready: a DB elérhető (readyState=1 + sikeres ping). Erre adjon az endpoint 200-at, különben 503-at. */
38
- ready: boolean;
39
- /** mongoose connection.readyState: 0=disconnected, 1=connected, 2=connecting, 3=disconnecting. */
40
- dbReadyState: number;
41
- /** Sikerült-e a valós DB ping round-trip (csak readyState=1-nél próbáljuk). */
42
- dbPingOk: boolean;
43
- /** A szerver uptime ms-ban. */
44
- uptime: number;
45
- /** A BEDROCK (nts-dynamo) verziója — NEM az app sajátja. */
46
- serverVersion: string;
47
- /** AZ APP saját verziója (`DyNTS_global_settings.systemVersion`) — deploy-verifikációhoz. */
48
- appVersion?: string;
49
-
50
- // --- DIAGNOSZTIKA (2026-07-22) — a flotta-szintű "readiness 503, de az app kiszolgál" lelet miatt ---
51
- // Élesben mérve: az adventor / token-service / master-prompter MIND `dbReadyState:0`-t adott, miközben
52
- // kiszolgáltak, a Mongo bizonyítottan élt, és a reconnect-guard (amely UGYANEZT a readyState-et olvassa)
53
- // egyetlen warningot sem logolt. Öt hipotézist zártunk ki méréssel (több replika · két mongoose-példány ·
54
- // esModule default-export · leszármazott-override · halott DB) — a gyökér-ok NEM dőlt el. Ezek a mezők
55
- // teszik a KÖVETKEZŐ mérést döntővé, találgatás nélkül. Mind ADDITÍV + opcionális → nem törnek meg semmit.
56
-
57
- /** Hány mongoose-connection létezik ebben a process-ben (`mongoose.connections.length`). >1 → nem a default-on megy a data-layer. */
58
- dbConnectionCount?: number;
59
- /** A default connection cél-hosztja (`connection.host`) — üres/undefined, ha a connect sosem futott le rajta. */
60
- dbHost?: string;
61
- /** A default connection adatbázis-neve (`connection.name`). */
62
- dbName?: string;
63
- /** Hány model van a default connectionre regisztrálva. 0 → a data-layer NEM ezt a connectiont használja. */
64
- dbModelCount?: number;
65
- /** A NEM-default connectionök readyState-jei — ha itt van 1-es, a probe rossz handle-t mér. */
66
- dbOtherReadyStates?: number[];
67
- }
68
-
69
- export abstract class DyNTS_ServerStatus_ControlService<
70
- T_ServerStatus extends DyFM_ServerStatus,
71
- T_Error extends DyFM_Error,
72
- T_Errors extends DyFM_Errors<T_Error>,
73
- T_Errors_ControlService extends DyNTS_Errors_ControlService<T_Error, T_Errors>,
74
- T_ServerStatusSnapshot extends DyFM_ServerStatus,
75
- T_ServerStatusSnapshot_ControlService extends DyNTS_ServerStatusSnapshot_ControlService<T_ServerStatusSnapshot>
76
- > extends DyNTS_SingletonService {
77
-
78
- protected abstract getErrorControlService?(
79
- set?: { data?: T_Errors, issuer?: string }
80
- ): T_Errors_ControlService;
81
-
82
- protected abstract getServerStatusSnapshotControlService?(
83
- set?: { data?: T_ServerStatus, issuer?: string }
84
- ): T_ServerStatusSnapshot_ControlService;
85
-
86
- protected readonly up: Date = new Date();
87
-
88
- protected readonly _serverVersionNumeric: number = this.getVersionNumeric(_serverVersion);
89
- /**
90
- * A BEDROCK (nts-dynamo) verzioja — a package.json-bol importalva.
91
- * FIGYELEM: ez NEM az app sajat verzioja! (Lasd `appVersion`.)
92
- */
93
- get serverVersion(): string { return _serverVersion; }
94
- get serverVersionNumeric(): number { return this._serverVersionNumeric; }
95
-
96
- /**
97
- * AZ APP sajat verzioja (2026-07-20) — a `DyNTS_App_Params.version`-bol, amit az
98
- * app-params a `DyNTS_global_settings.systemVersion`-be tolt (app-params.control-model).
99
- *
100
- * MIERT KELLETT: a `serverVersion` az nts-dynamo package.json-jabol jon, ezert a TELJES
101
- * flottan UGYANAZT az erteket adja (pl. 01.15.104), fuggetlenul attol, hogy az app melyik
102
- * verzioja fut. Emiatt minden verzio-alapu deploy-ellenorzes vak volt:
103
- * - a CI/CD `deploy-verify` polling SOHA nem egyezne (app 01.15.142 vs serverVersion 01.15.104),
104
- * - az Overseer verzio-drift monitorozasa nem latja az ELAVULT app-deployt,
105
- * - a `fdp deploy-service --skip-if-version` gate mindig eltérést lát → sosem skippel.
106
- *
107
- * ADDITIV mezo: a `serverVersion` szemantikaja VALTOZATLAN marad (nulla regresszio a
108
- * meglevo fogyasztoknal / e2e-knel); az uj fogyasztok az `appVersion`-t olvassak.
109
- */
110
- get appVersion(): string { return DyNTS_global_settings.systemVersion; }
111
-
112
- protected _latestClientVersion: string;
113
- protected _latestClientVersionNumeric: number;
114
- get latestClientVersion(): string { return this._latestClientVersion; }
115
- get latestClientVersionNumeric(): number { return this._latestClientVersionNumeric; }
116
-
117
- protected abstract requiredServerConnections: DyNTS_ServerConnection[];
118
- protected connectionMaxCheckFrequency = 15 * minute;
119
-
120
- override readonly defaultErrorUserMsg = 'Something went wrong';
121
-
122
- readonly overseerTickTime = 6 * hour;
123
- overseer: Subscription;
124
-
125
- protected constructor() {
126
- super();
127
-
128
- /* if (DyNTS_global_settings.log_settings.setup) {
129
- DyFM_Log.log(
130
- 'Required server connections:', JSON.stringify(this.requiredServerConnections.map(
131
- (connection: DyNTS_ServerConnection): { name: string, baseUrl: string, testEndpoint: string } => ({
132
- name: connection.name,
133
- baseUrl: connection.apiService.baseUrl,
134
- testEndpoint: connection.apiService.testEndpoint ?? '',
135
- })
136
- ), null, 2)
137
- );
138
- } */
139
-
140
- this.overseer = timer(this.overseerTickTime, this.overseerTickTime).subscribe(async () => {
141
- try {
142
- await this.triggerCreateSnapshot('overseer-system-tick');
143
- } catch (error) {
144
- DyFM_Error.logSimple(' ! Error in overseer (server status):', error);
145
- DyNTS_GlobalService.globalErrorHandler(
146
- new DyFM_Error({
147
- ...this.getDefaultErrorSettings('overseer tick', error, 'overseer-system-tick'),
148
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSCS-OT0`,
149
- })
150
- ).catch();
151
- }
152
- });
153
- }
154
-
155
- async getServerStatus(issuer: string, clientVersion?: string): Promise<DyFM_ServerStatus> {
156
- try {
157
- return {
158
- status: 'ready',
159
-
160
- systemName: DyNTS_global_settings.systemName,
161
- systemShortCode: DyNTS_global_settings.systemShortCodeName,
162
-
163
- clientVersionOk: clientVersion ? this.clientVersionIsLatest(clientVersion) : false,
164
- latestClientVersion: this.latestClientVersion,
165
- latestClientVersionNumeric: this.latestClientVersionNumeric,
166
-
167
- serverVersion: this.serverVersion,
168
- serverNumericVersion: this.serverVersionNumeric,
169
- // Az APP sajat verzioja (a serverVersion a bedrock-e) — deploy-verifikaciohoz.
170
- appVersion: this.appVersion,
171
-
172
- uptime: +new Date() - +this.up,
173
-
174
- memoryUsage: process.memoryUsage(),
175
- cpuUsage: process.cpuUsage(),
176
- serverConnections: await this.checkServerConnections(issuer),
177
- }
178
- } catch (error) {
179
- throw new DyFM_Error({
180
- ...this.getDefaultErrorSettings('getServerStatus', error, issuer),
181
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSCS-GSS0`,
182
- });
183
- }
184
- }
185
-
186
- async checkServerConnections(issuer: string): Promise<DyFM_ServerConnectionCheckResult> {
187
- try {
188
- const connections: DyFM_ServerConnectionCheckResult = {};
189
-
190
- await DyFM_Array.asyncForEachAllAtOnce(
191
- this.requiredServerConnections,
192
- async (connection: DyNTS_ServerConnection) => {
193
- if (!connection.accessible || Date.now() - connection.lastCheck.getTime() > this.connectionMaxCheckFrequency) {
194
- await connection.apiService.checkServerAvailability(issuer).catch((error) => {
195
- DyFM_Error.logSimple(
196
- `(checkServerConnections) "${connection.name}" server is not available` +
197
- `\n baseUrl: ${connection.apiService.baseUrl}` +
198
- `\n testEndpoint: ${connection.apiService.testEndpoint ?? ''}`,
199
- error
200
- );
201
- connection.accessible = false;
202
- }).then(() => {
203
- connection.accessible = true;
204
- });
205
- connection.accessible = true;
206
- connection.lastCheck = new Date();
207
- }
208
-
209
- connections[connection.name] = connection.accessible ? DyFM_ServerConnection_Status.accessible : DyFM_ServerConnection_Status.unaccessible;
210
- }
211
- )
212
-
213
- return connections;
214
- } catch (error) {
215
- throw new DyFM_Error({
216
- ...this.getDefaultErrorSettings('checkServerConnections', error, issuer),
217
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSCS-CC0`,
218
- });
219
- }
220
- }
221
-
222
- /**
223
- * A mongoose default-connection. Külön metódus = teszt-seam (spy-jal felülírható, hogy a
224
- * {@link checkDbReadiness} DB nélkül is tesztelhető legyen).
225
- */
226
- /** BFR-OVERSEER-004 — stats-only DB-diagnosztika a `/server/db-stats` endpointnak (metaadat-only). */
227
- async getDbStats(): Promise<DyNTS_DbStats> {
228
- return DyNTS_DbStats_Util.collect(this.getMongooseConnection());
229
- }
230
-
231
- /** BFR-AM-015 — aggregált doctor-riport a `/server/doctor` endpointnak (sosem dob). */
232
- async runDoctor(): Promise<DyNTS_DoctorReport> {
233
- return DyNTS_Diagnostics.runDoctor({ connection: this.getMongooseConnection() });
234
- }
235
-
236
- protected getMongooseConnection(): mongoose.Connection {
237
- // FIX (2026-07-22) — a `mongoose.connection` NEM feltetlenul az a handle, amit a data-layer hasznal.
238
- //
239
- // ELESBEN MERVE (adventor, a diagnosztikai mezokkel): `dbConnectionCount: 1`, `dbModelCount: 0`,
240
- // `dbOtherReadyStates: [1]` — azaz letezik EGY KAPCSOLODOTT (readyState=1) connection, de a
241
- // `mongoose.connection` **nem az**: az disconnected (0), NULLA modellel, `host`/`name` nelkul
242
- // (sosem csatlakozott). Emiatt a readiness flotta-szinten **hamis 503**-at adott (adventor,
243
- // token-service, master-prompter), mikozben a DB vegig egeszseges volt es az appok kiszolgaltak.
244
- //
245
- // Ezert a valos, KAPCSOLODOTT connectiont keressuk meg a `mongoose.connections`-bol, es csak
246
- // fallbackkent hasznaljuk a `mongoose.connection`-t. Ez minden esetben helyes:
247
- // - ha van elo connection -> azt merjuk (readyState=1 + valos ping) -> a readiness igazat mond,
248
- // - ha a DB tenyleg halott -> egyik sem 1 -> fallback -> tovabbra is helyesen NEM-ready.
249
- // Vagyis a valodi DB-kiesest NEM maszkolja el, csak a hamis-negativot szunteti meg.
250
- const all: mongoose.Connection[] = mongoose.connections ?? [];
251
- const live: mongoose.Connection | undefined =
252
- all.find((c: mongoose.Connection): boolean => c?.readyState === 1);
253
-
254
- return live ?? mongoose.connection;
255
- }
256
-
257
- /**
258
- * Readiness-probe: a `/health` (liveness — "a process fut + kiszolgál") MELLETT a DB-elérhetőséget
259
- * ellenőrzi. A readyState (mongoose driver-állapot) + egy valós `ping` round-trip → így a "connected
260
- * de a DB nem válaszol" eset is kibukik. **Sosem dob** (a probe-nak determinisztikusan kell válaszolnia);
261
- * hiba esetén `ready=false`. Az endpoint 503-at adjon, ha nem ready → az orchestrátor (k8s/docker/LB)
262
- * ne irányítson forgalmat a DB-vesztett instance-ra.
263
- */
264
- async checkDbReadiness(): Promise<DyNTS_DbReadiness> {
265
- let dbReadyState: number = 0;
266
- let dbPingOk: boolean = false;
267
-
268
- try {
269
- const connection: mongoose.Connection = this.getMongooseConnection();
270
- // readyState: 0=disconnected, 1=connected, 2=connecting, 3=disconnecting
271
- dbReadyState = connection?.readyState ?? 0;
272
-
273
- if (dbReadyState === 1) {
274
- await connection.db?.admin().ping();
275
- dbPingOk = true;
276
- }
277
- } catch (error) {
278
- DyFM_Log.warn('(checkDbReadiness) DB readiness check failed', error);
279
- dbPingOk = false;
280
- }
281
-
282
- // DIAGNOSZTIKA (2026-07-22): sosem dobhat — a probe-nak determinisztikusan kell válaszolnia,
283
- // ezért a diag-gyűjtés SAJÁT try-ban van (ha bármelyik mező kiolvasása elszáll, a readiness
284
- // válasz attól még ép marad).
285
- let diagnostics: Partial<DyNTS_DbReadiness> = {};
286
- try {
287
- const conn: mongoose.Connection = this.getMongooseConnection();
288
- const all: mongoose.Connection[] = mongoose.connections ?? [];
289
-
290
- diagnostics = {
291
- dbConnectionCount: all.length,
292
- dbHost: conn?.host,
293
- dbName: conn?.name,
294
- dbModelCount: Object.keys(conn?.models ?? {}).length,
295
- // a default connectiont kihagyjuk — csak a "van-e MÁSIK, élő handle" kérdés érdekes
296
- dbOtherReadyStates: all.filter((c: mongoose.Connection): boolean => c !== conn)
297
- .map((c: mongoose.Connection): number => c?.readyState ?? -1),
298
- };
299
- } catch (error) {
300
- DyFM_Log.warn('(checkDbReadiness) diagnostics collection failed (non-fatal)', error);
301
- }
302
-
303
- return {
304
- ready: dbReadyState === 1 && dbPingOk,
305
- dbReadyState: dbReadyState,
306
- dbPingOk: dbPingOk,
307
- uptime: +new Date() - +this.up,
308
- serverVersion: this.serverVersion,
309
- appVersion: this.appVersion,
310
- ...diagnostics,
311
- };
312
- }
313
-
314
- async getErrorStatistics(
315
- range: DyFM_RelativeDate,
316
- issuer: string
317
- ): Promise<DyFM_Error_Statistics> {
318
- try {
319
- const error_DS: T_Errors_ControlService =
320
- this.getErrorControlService({ issuer: issuer });
321
- /* new DyNTS_Error_DataService({ issuer: issuer }); */
322
-
323
- const from: Date = DyFM_Time.getDateByRelativeDate(range);
324
- const errorsPaged: DyFM_Paged<T_Errors> = await error_DS.getErrorsFromDate(from, issuer);
325
- const errors: T_Errors[] = errorsPaged.items;
326
-
327
- return {
328
- range: range,
329
-
330
- allErrors: errors.length,
331
- allAllErrors: errors.reduce(
332
- (sum: number, error: T_Errors): number => sum + error.count,
333
- 0
334
- ),
335
-
336
- serverErrors:
337
- errors.filter(
338
- (error: T_Errors): boolean => error.source.includes('SERVER')
339
- ).length,
340
- clientErrors:
341
- errors.filter(
342
- (error: T_Errors): boolean => !error.source.includes('SERVER')
343
- ).length,
344
- allServerErrors:
345
- errors.filter(
346
- (error: T_Errors): boolean => error.source.includes('SERVER')
347
- ).reduce(
348
- (sum: number, error: T_Errors): number => sum + error.count, 0
349
- ),
350
- allClientErrors:
351
- errors.filter(
352
- (error: T_Errors): boolean => !error.source.includes('SERVER')
353
- ).reduce(
354
- (sum: number, error: T_Errors): number => sum + error.count, 0
355
- ),
356
-
357
- infoErrors:
358
- errors.filter(
359
- (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.info
360
- ).length,
361
- warningErrors:
362
- errors.filter(
363
- (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.warning
364
- ).length,
365
- errorErrors:
366
- errors.filter(
367
- (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.error
368
- ).length,
369
- criticalErrors:
370
- errors.filter(
371
- (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.critical
372
- ).length,
373
-
374
- allInfoErrors:
375
- errors.filter(
376
- (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.info
377
- ).reduce(
378
- (sum: number, error: T_Errors): number => sum + error.count, 0
379
- ),
380
- allWarningErrors:
381
- errors.filter(
382
- (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.warning
383
- ).reduce(
384
- (sum: number, error: T_Errors): number => sum + error.count, 0
385
- ),
386
- allErrorErrors:
387
- errors.filter(
388
- (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.error
389
- ).reduce(
390
- (sum: number, error: T_Errors): number => sum + error.count, 0
391
- ),
392
- allCriticalErrors:
393
- errors.filter(
394
- (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.critical
395
- ).reduce(
396
- (sum: number, error: T_Errors): number => sum + error.count, 0
397
- ),
398
- } as DyFM_Error_Statistics;
399
- } catch (error) {
400
- throw new DyFM_Error({
401
- ...this.getDefaultErrorSettings(
402
- 'getMatchStatistics',
403
- error?.response?.data ?? error,
404
- issuer
405
- ),
406
-
407
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSS-GES0`,
408
- });
409
- }
410
- }
411
-
412
- protected getVersionNumeric(version: string): number {
413
- return +version.replace('v', '')
414
- .replace('.', '')
415
- .replace('.', '')
416
- .replace('-alpha', '')
417
- .replace('-beta', '')
418
- .replace('-test', '')
419
- .replace('-dev', '');
420
- }
421
-
422
- protected clientVersionIsLatest(clientVersion: string): boolean {
423
- const thisClientVersionNumeric: number = this.getVersionNumeric(clientVersion);
424
-
425
- if (!this._latestClientVersionNumeric) {
426
- this.setLatestClientVersion(clientVersion, thisClientVersionNumeric);
427
-
428
- return true;
429
-
430
- } else if (thisClientVersionNumeric === this._latestClientVersionNumeric) {
431
- return true;
432
-
433
- } else if (thisClientVersionNumeric < this._latestClientVersionNumeric) {
434
- return false;
435
-
436
- } else if (this._latestClientVersionNumeric < thisClientVersionNumeric) {
437
- this.setLatestClientVersion(clientVersion, thisClientVersionNumeric);
438
-
439
- return true;
440
- }
441
-
442
- DyFM_Log.error(
443
- 'Something went wrong, invalid version:', clientVersion,
444
- thisClientVersionNumeric, _serverVersion, this.serverVersionNumeric
445
- );
446
-
447
- return false;
448
- }
449
-
450
- protected setLatestClientVersion(clientVersion: string, clientVersionNumeric: number): void {
451
- if (!clientVersion.includes('test') && !clientVersion.includes('dev')) {
452
- this._latestClientVersion = clientVersion;
453
- this._latestClientVersionNumeric = clientVersionNumeric;
454
- }
455
- }
456
-
457
- protected async triggerCreateSnapshot(issuer: string): Promise<void> {
458
- try {
459
- const snapshot: T_ServerStatusSnapshot = await this.getServerStatusSnapshot(issuer);
460
- const serverStatusSnapshot_CS: T_ServerStatusSnapshot_ControlService =
461
- this.getServerStatusSnapshotControlService({ issuer: issuer });
462
-
463
- await serverStatusSnapshot_CS.saveSnapshot(snapshot, issuer);
464
-
465
- DyFM_Log.info('ServerStatus snapshot created');
466
- } catch (error) {
467
- throw new DyFM_Error({
468
- ...this.getDefaultErrorSettings('triggerCreateSnapshot', error, 'system-tick'),
469
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSCS-TCS0`,
470
- });
471
- }
472
- }
473
-
474
- async getServerStatusSnapshot(issuer: string): Promise<T_ServerStatusSnapshot> {
475
- try {
476
- return ({
477
- ...(await this.getServerStatus(issuer)),
478
- }) as T_ServerStatusSnapshot;
479
- } catch (error) {
480
- throw new DyFM_Error({
481
- ...this.getDefaultErrorSettings(
482
- 'getServerStatusSnapshot',
483
- error?.response?.data ?? error,
484
- issuer
485
- ),
486
-
487
- errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSCS-GSS0`,
488
- });
489
- }
490
- }
1
+
2
+
3
+ import {
4
+ DyFM_Metadata, DyFM_RelativeDate, DyFM_Time, DyFM_ServerStatus, DyFM_ErrorLevel, DyFM_Log,
5
+ DyFM_Error, DyFM_Error_Statistics, DyFM_Errors,
6
+ DyFM_Paged,
7
+ hour, minute,
8
+ DyFM_ServerConnectionCheckResult,
9
+ DyFM_ServerConnection_Status,
10
+ DyFM_Array
11
+ } from '@futdevpro/fsm-dynamo';
12
+ import { Subscription, timer } from 'rxjs';
13
+ import * as mongoose from 'mongoose';
14
+
15
+ import { version as _serverVersion } from '../../../../package.json';
16
+ import { DyNTS_SingletonService } from '../../../_services/base/singleton.service';
17
+ import { DyNTS_DbStats, DyNTS_DbStats_Util } from '../../../_services/core/db-stats.service';
18
+ import { DyNTS_Diagnostics, DyNTS_DoctorReport } from '../../../_services/core/diagnostics.service';
19
+ import { DyNTS_global_settings } from '../../../_collections/global-settings.const';
20
+ import { DyNTS_Errors_ControlService } from '../errors/errors.control-service';
21
+ import { DyNTS_ServerStatusSnapshot_ControlService } from './server-status-snapshot.control-service';
22
+ import { DyNTS_GlobalService } from '../../../_services/core/global.service';
23
+ import { DyNTS_ApiService_Base } from '../../../_services/base/api.service-base';
24
+
25
+ export interface DyNTS_ServerConnection {
26
+ name: string,
27
+ apiService: DyNTS_ApiService_Base,
28
+ accessible?: boolean,
29
+ lastCheck?: Date,
30
+ }
31
+
32
+ /**
33
+ * A readiness-probe ({@link DyNTS_ServerStatus_ControlService.checkDbReadiness}) eredménye.
34
+ * `ready=true` CSAK ha a DB-connection él (readyState=1) ÉS a valós ping round-trip sikerült.
35
+ */
36
+ export interface DyNTS_DbReadiness {
37
+ /** ready: a DB elérhető (readyState=1 + sikeres ping). Erre adjon az endpoint 200-at, különben 503-at. */
38
+ ready: boolean;
39
+ /** mongoose connection.readyState: 0=disconnected, 1=connected, 2=connecting, 3=disconnecting. */
40
+ dbReadyState: number;
41
+ /** Sikerült-e a valós DB ping round-trip (csak readyState=1-nél próbáljuk). */
42
+ dbPingOk: boolean;
43
+ /** A szerver uptime ms-ban. */
44
+ uptime: number;
45
+ /** A BEDROCK (nts-dynamo) verziója — NEM az app sajátja. */
46
+ serverVersion: string;
47
+ /** AZ APP saját verziója (`DyNTS_global_settings.systemVersion`) — deploy-verifikációhoz. */
48
+ appVersion?: string;
49
+
50
+ // --- DIAGNOSZTIKA (2026-07-22) — a flotta-szintű "readiness 503, de az app kiszolgál" lelet miatt ---
51
+ // Élesben mérve: az adventor / token-service / master-prompter MIND `dbReadyState:0`-t adott, miközben
52
+ // kiszolgáltak, a Mongo bizonyítottan élt, és a reconnect-guard (amely UGYANEZT a readyState-et olvassa)
53
+ // egyetlen warningot sem logolt. Öt hipotézist zártunk ki méréssel (több replika · két mongoose-példány ·
54
+ // esModule default-export · leszármazott-override · halott DB) — a gyökér-ok NEM dőlt el. Ezek a mezők
55
+ // teszik a KÖVETKEZŐ mérést döntővé, találgatás nélkül. Mind ADDITÍV + opcionális → nem törnek meg semmit.
56
+
57
+ /** Hány mongoose-connection létezik ebben a process-ben (`mongoose.connections.length`). >1 → nem a default-on megy a data-layer. */
58
+ dbConnectionCount?: number;
59
+ /** A default connection cél-hosztja (`connection.host`) — üres/undefined, ha a connect sosem futott le rajta. */
60
+ dbHost?: string;
61
+ /** A default connection adatbázis-neve (`connection.name`). */
62
+ dbName?: string;
63
+ /** Hány model van a default connectionre regisztrálva. 0 → a data-layer NEM ezt a connectiont használja. */
64
+ dbModelCount?: number;
65
+ /** A NEM-default connectionök readyState-jei — ha itt van 1-es, a probe rossz handle-t mér. */
66
+ dbOtherReadyStates?: number[];
67
+ }
68
+
69
+ export abstract class DyNTS_ServerStatus_ControlService<
70
+ T_ServerStatus extends DyFM_ServerStatus,
71
+ T_Error extends DyFM_Error,
72
+ T_Errors extends DyFM_Errors<T_Error>,
73
+ T_Errors_ControlService extends DyNTS_Errors_ControlService<T_Error, T_Errors>,
74
+ T_ServerStatusSnapshot extends DyFM_ServerStatus,
75
+ T_ServerStatusSnapshot_ControlService extends DyNTS_ServerStatusSnapshot_ControlService<T_ServerStatusSnapshot>
76
+ > extends DyNTS_SingletonService {
77
+
78
+ protected abstract getErrorControlService?(
79
+ set?: { data?: T_Errors, issuer?: string }
80
+ ): T_Errors_ControlService;
81
+
82
+ protected abstract getServerStatusSnapshotControlService?(
83
+ set?: { data?: T_ServerStatus, issuer?: string }
84
+ ): T_ServerStatusSnapshot_ControlService;
85
+
86
+ protected readonly up: Date = new Date();
87
+
88
+ protected readonly _serverVersionNumeric: number = this.getVersionNumeric(_serverVersion);
89
+ /**
90
+ * A BEDROCK (nts-dynamo) verzioja — a package.json-bol importalva.
91
+ * FIGYELEM: ez NEM az app sajat verzioja! (Lasd `appVersion`.)
92
+ */
93
+ get serverVersion(): string { return _serverVersion; }
94
+ get serverVersionNumeric(): number { return this._serverVersionNumeric; }
95
+
96
+ /**
97
+ * AZ APP sajat verzioja (2026-07-20) — a `DyNTS_App_Params.version`-bol, amit az
98
+ * app-params a `DyNTS_global_settings.systemVersion`-be tolt (app-params.control-model).
99
+ *
100
+ * MIERT KELLETT: a `serverVersion` az nts-dynamo package.json-jabol jon, ezert a TELJES
101
+ * flottan UGYANAZT az erteket adja (pl. 01.15.104), fuggetlenul attol, hogy az app melyik
102
+ * verzioja fut. Emiatt minden verzio-alapu deploy-ellenorzes vak volt:
103
+ * - a CI/CD `deploy-verify` polling SOHA nem egyezne (app 01.15.142 vs serverVersion 01.15.104),
104
+ * - az Overseer verzio-drift monitorozasa nem latja az ELAVULT app-deployt,
105
+ * - a `fdp deploy-service --skip-if-version` gate mindig eltérést lát → sosem skippel.
106
+ *
107
+ * ADDITIV mezo: a `serverVersion` szemantikaja VALTOZATLAN marad (nulla regresszio a
108
+ * meglevo fogyasztoknal / e2e-knel); az uj fogyasztok az `appVersion`-t olvassak.
109
+ */
110
+ get appVersion(): string { return DyNTS_global_settings.systemVersion; }
111
+
112
+ protected _latestClientVersion: string;
113
+ protected _latestClientVersionNumeric: number;
114
+ get latestClientVersion(): string { return this._latestClientVersion; }
115
+ get latestClientVersionNumeric(): number { return this._latestClientVersionNumeric; }
116
+
117
+ protected abstract requiredServerConnections: DyNTS_ServerConnection[];
118
+ protected connectionMaxCheckFrequency = 15 * minute;
119
+
120
+ override readonly defaultErrorUserMsg = 'Something went wrong';
121
+
122
+ readonly overseerTickTime = 6 * hour;
123
+ overseer: Subscription;
124
+
125
+ protected constructor() {
126
+ super();
127
+
128
+ /* if (DyNTS_global_settings.log_settings.setup) {
129
+ DyFM_Log.log(
130
+ 'Required server connections:', JSON.stringify(this.requiredServerConnections.map(
131
+ (connection: DyNTS_ServerConnection): { name: string, baseUrl: string, testEndpoint: string } => ({
132
+ name: connection.name,
133
+ baseUrl: connection.apiService.baseUrl,
134
+ testEndpoint: connection.apiService.testEndpoint ?? '',
135
+ })
136
+ ), null, 2)
137
+ );
138
+ } */
139
+
140
+ this.overseer = timer(this.overseerTickTime, this.overseerTickTime).subscribe(async () => {
141
+ try {
142
+ await this.triggerCreateSnapshot('overseer-system-tick');
143
+ } catch (error) {
144
+ DyFM_Error.logSimple(' ! Error in overseer (server status):', error);
145
+ DyNTS_GlobalService.globalErrorHandler(
146
+ new DyFM_Error({
147
+ ...this.getDefaultErrorSettings('overseer tick', error, 'overseer-system-tick'),
148
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSCS-OT0`,
149
+ })
150
+ ).catch();
151
+ }
152
+ });
153
+ }
154
+
155
+ async getServerStatus(issuer: string, clientVersion?: string): Promise<DyFM_ServerStatus> {
156
+ try {
157
+ return {
158
+ status: 'ready',
159
+
160
+ systemName: DyNTS_global_settings.systemName,
161
+ systemShortCode: DyNTS_global_settings.systemShortCodeName,
162
+
163
+ clientVersionOk: clientVersion ? this.clientVersionIsLatest(clientVersion) : false,
164
+ latestClientVersion: this.latestClientVersion,
165
+ latestClientVersionNumeric: this.latestClientVersionNumeric,
166
+
167
+ serverVersion: this.serverVersion,
168
+ serverNumericVersion: this.serverVersionNumeric,
169
+ // Az APP sajat verzioja (a serverVersion a bedrock-e) — deploy-verifikaciohoz.
170
+ appVersion: this.appVersion,
171
+
172
+ uptime: +new Date() - +this.up,
173
+
174
+ memoryUsage: process.memoryUsage(),
175
+ cpuUsage: process.cpuUsage(),
176
+ serverConnections: await this.checkServerConnections(issuer),
177
+ }
178
+ } catch (error) {
179
+ throw new DyFM_Error({
180
+ ...this.getDefaultErrorSettings('getServerStatus', error, issuer),
181
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSCS-GSS0`,
182
+ });
183
+ }
184
+ }
185
+
186
+ async checkServerConnections(issuer: string): Promise<DyFM_ServerConnectionCheckResult> {
187
+ try {
188
+ const connections: DyFM_ServerConnectionCheckResult = {};
189
+
190
+ await DyFM_Array.asyncForEachAllAtOnce(
191
+ this.requiredServerConnections,
192
+ async (connection: DyNTS_ServerConnection) => {
193
+ if (!connection.accessible || Date.now() - connection.lastCheck.getTime() > this.connectionMaxCheckFrequency) {
194
+ await connection.apiService.checkServerAvailability(issuer).catch((error) => {
195
+ DyFM_Error.logSimple(
196
+ `(checkServerConnections) "${connection.name}" server is not available` +
197
+ `\n baseUrl: ${connection.apiService.baseUrl}` +
198
+ `\n testEndpoint: ${connection.apiService.testEndpoint ?? ''}`,
199
+ error
200
+ );
201
+ connection.accessible = false;
202
+ }).then(() => {
203
+ connection.accessible = true;
204
+ });
205
+ connection.accessible = true;
206
+ connection.lastCheck = new Date();
207
+ }
208
+
209
+ connections[connection.name] = connection.accessible ? DyFM_ServerConnection_Status.accessible : DyFM_ServerConnection_Status.unaccessible;
210
+ }
211
+ )
212
+
213
+ return connections;
214
+ } catch (error) {
215
+ throw new DyFM_Error({
216
+ ...this.getDefaultErrorSettings('checkServerConnections', error, issuer),
217
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSCS-CC0`,
218
+ });
219
+ }
220
+ }
221
+
222
+ /**
223
+ * A mongoose default-connection. Külön metódus = teszt-seam (spy-jal felülírható, hogy a
224
+ * {@link checkDbReadiness} DB nélkül is tesztelhető legyen).
225
+ */
226
+ /** BFR-OVERSEER-004 — stats-only DB-diagnosztika a `/server/db-stats` endpointnak (metaadat-only). */
227
+ async getDbStats(): Promise<DyNTS_DbStats> {
228
+ return DyNTS_DbStats_Util.collect(this.getMongooseConnection());
229
+ }
230
+
231
+ /** BFR-AM-015 — aggregált doctor-riport a `/server/doctor` endpointnak (sosem dob). */
232
+ async runDoctor(): Promise<DyNTS_DoctorReport> {
233
+ return DyNTS_Diagnostics.runDoctor({ connection: this.getMongooseConnection() });
234
+ }
235
+
236
+ protected getMongooseConnection(): mongoose.Connection {
237
+ // FIX (2026-07-22) — a `mongoose.connection` NEM feltetlenul az a handle, amit a data-layer hasznal.
238
+ //
239
+ // ELESBEN MERVE (adventor, a diagnosztikai mezokkel): `dbConnectionCount: 1`, `dbModelCount: 0`,
240
+ // `dbOtherReadyStates: [1]` — azaz letezik EGY KAPCSOLODOTT (readyState=1) connection, de a
241
+ // `mongoose.connection` **nem az**: az disconnected (0), NULLA modellel, `host`/`name` nelkul
242
+ // (sosem csatlakozott). Emiatt a readiness flotta-szinten **hamis 503**-at adott (adventor,
243
+ // token-service, master-prompter), mikozben a DB vegig egeszseges volt es az appok kiszolgaltak.
244
+ //
245
+ // Ezert a valos, KAPCSOLODOTT connectiont keressuk meg a `mongoose.connections`-bol, es csak
246
+ // fallbackkent hasznaljuk a `mongoose.connection`-t. Ez minden esetben helyes:
247
+ // - ha van elo connection -> azt merjuk (readyState=1 + valos ping) -> a readiness igazat mond,
248
+ // - ha a DB tenyleg halott -> egyik sem 1 -> fallback -> tovabbra is helyesen NEM-ready.
249
+ // Vagyis a valodi DB-kiesest NEM maszkolja el, csak a hamis-negativot szunteti meg.
250
+ const all: mongoose.Connection[] = mongoose.connections ?? [];
251
+ const live: mongoose.Connection | undefined =
252
+ all.find((c: mongoose.Connection): boolean => c?.readyState === 1);
253
+
254
+ return live ?? mongoose.connection;
255
+ }
256
+
257
+ /**
258
+ * Readiness-probe: a `/health` (liveness — "a process fut + kiszolgál") MELLETT a DB-elérhetőséget
259
+ * ellenőrzi. A readyState (mongoose driver-állapot) + egy valós `ping` round-trip → így a "connected
260
+ * de a DB nem válaszol" eset is kibukik. **Sosem dob** (a probe-nak determinisztikusan kell válaszolnia);
261
+ * hiba esetén `ready=false`. Az endpoint 503-at adjon, ha nem ready → az orchestrátor (k8s/docker/LB)
262
+ * ne irányítson forgalmat a DB-vesztett instance-ra.
263
+ */
264
+ async checkDbReadiness(): Promise<DyNTS_DbReadiness> {
265
+ let dbReadyState: number = 0;
266
+ let dbPingOk: boolean = false;
267
+
268
+ try {
269
+ const connection: mongoose.Connection = this.getMongooseConnection();
270
+ // readyState: 0=disconnected, 1=connected, 2=connecting, 3=disconnecting
271
+ dbReadyState = connection?.readyState ?? 0;
272
+
273
+ if (dbReadyState === 1) {
274
+ await connection.db?.admin().ping();
275
+ dbPingOk = true;
276
+ }
277
+ } catch (error) {
278
+ DyFM_Log.warn('(checkDbReadiness) DB readiness check failed', error);
279
+ dbPingOk = false;
280
+ }
281
+
282
+ // DIAGNOSZTIKA (2026-07-22): sosem dobhat — a probe-nak determinisztikusan kell válaszolnia,
283
+ // ezért a diag-gyűjtés SAJÁT try-ban van (ha bármelyik mező kiolvasása elszáll, a readiness
284
+ // válasz attól még ép marad).
285
+ let diagnostics: Partial<DyNTS_DbReadiness> = {};
286
+ try {
287
+ const conn: mongoose.Connection = this.getMongooseConnection();
288
+ const all: mongoose.Connection[] = mongoose.connections ?? [];
289
+
290
+ diagnostics = {
291
+ dbConnectionCount: all.length,
292
+ dbHost: conn?.host,
293
+ dbName: conn?.name,
294
+ dbModelCount: Object.keys(conn?.models ?? {}).length,
295
+ // a default connectiont kihagyjuk — csak a "van-e MÁSIK, élő handle" kérdés érdekes
296
+ dbOtherReadyStates: all.filter((c: mongoose.Connection): boolean => c !== conn)
297
+ .map((c: mongoose.Connection): number => c?.readyState ?? -1),
298
+ };
299
+ } catch (error) {
300
+ DyFM_Log.warn('(checkDbReadiness) diagnostics collection failed (non-fatal)', error);
301
+ }
302
+
303
+ return {
304
+ ready: dbReadyState === 1 && dbPingOk,
305
+ dbReadyState: dbReadyState,
306
+ dbPingOk: dbPingOk,
307
+ uptime: +new Date() - +this.up,
308
+ serverVersion: this.serverVersion,
309
+ appVersion: this.appVersion,
310
+ ...diagnostics,
311
+ };
312
+ }
313
+
314
+ async getErrorStatistics(
315
+ range: DyFM_RelativeDate,
316
+ issuer: string
317
+ ): Promise<DyFM_Error_Statistics> {
318
+ try {
319
+ const error_DS: T_Errors_ControlService =
320
+ this.getErrorControlService({ issuer: issuer });
321
+ /* new DyNTS_Error_DataService({ issuer: issuer }); */
322
+
323
+ const from: Date = DyFM_Time.getDateByRelativeDate(range);
324
+ const errorsPaged: DyFM_Paged<T_Errors> = await error_DS.getErrorsFromDate(from, issuer);
325
+ const errors: T_Errors[] = errorsPaged.items;
326
+
327
+ return {
328
+ range: range,
329
+
330
+ allErrors: errors.length,
331
+ allAllErrors: errors.reduce(
332
+ (sum: number, error: T_Errors): number => sum + error.count,
333
+ 0
334
+ ),
335
+
336
+ serverErrors:
337
+ errors.filter(
338
+ (error: T_Errors): boolean => error.source.includes('SERVER')
339
+ ).length,
340
+ clientErrors:
341
+ errors.filter(
342
+ (error: T_Errors): boolean => !error.source.includes('SERVER')
343
+ ).length,
344
+ allServerErrors:
345
+ errors.filter(
346
+ (error: T_Errors): boolean => error.source.includes('SERVER')
347
+ ).reduce(
348
+ (sum: number, error: T_Errors): number => sum + error.count, 0
349
+ ),
350
+ allClientErrors:
351
+ errors.filter(
352
+ (error: T_Errors): boolean => !error.source.includes('SERVER')
353
+ ).reduce(
354
+ (sum: number, error: T_Errors): number => sum + error.count, 0
355
+ ),
356
+
357
+ infoErrors:
358
+ errors.filter(
359
+ (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.info
360
+ ).length,
361
+ warningErrors:
362
+ errors.filter(
363
+ (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.warning
364
+ ).length,
365
+ errorErrors:
366
+ errors.filter(
367
+ (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.error
368
+ ).length,
369
+ criticalErrors:
370
+ errors.filter(
371
+ (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.critical
372
+ ).length,
373
+
374
+ allInfoErrors:
375
+ errors.filter(
376
+ (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.info
377
+ ).reduce(
378
+ (sum: number, error: T_Errors): number => sum + error.count, 0
379
+ ),
380
+ allWarningErrors:
381
+ errors.filter(
382
+ (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.warning
383
+ ).reduce(
384
+ (sum: number, error: T_Errors): number => sum + error.count, 0
385
+ ),
386
+ allErrorErrors:
387
+ errors.filter(
388
+ (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.error
389
+ ).reduce(
390
+ (sum: number, error: T_Errors): number => sum + error.count, 0
391
+ ),
392
+ allCriticalErrors:
393
+ errors.filter(
394
+ (error: T_Errors): boolean => error.level === DyFM_ErrorLevel.critical
395
+ ).reduce(
396
+ (sum: number, error: T_Errors): number => sum + error.count, 0
397
+ ),
398
+ } as DyFM_Error_Statistics;
399
+ } catch (error) {
400
+ throw new DyFM_Error({
401
+ ...this.getDefaultErrorSettings(
402
+ 'getMatchStatistics',
403
+ error?.response?.data ?? error,
404
+ issuer
405
+ ),
406
+
407
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSS-GES0`,
408
+ });
409
+ }
410
+ }
411
+
412
+ protected getVersionNumeric(version: string): number {
413
+ return +version.replace('v', '')
414
+ .replace('.', '')
415
+ .replace('.', '')
416
+ .replace('-alpha', '')
417
+ .replace('-beta', '')
418
+ .replace('-test', '')
419
+ .replace('-dev', '');
420
+ }
421
+
422
+ protected clientVersionIsLatest(clientVersion: string): boolean {
423
+ const thisClientVersionNumeric: number = this.getVersionNumeric(clientVersion);
424
+
425
+ if (!this._latestClientVersionNumeric) {
426
+ this.setLatestClientVersion(clientVersion, thisClientVersionNumeric);
427
+
428
+ return true;
429
+
430
+ } else if (thisClientVersionNumeric === this._latestClientVersionNumeric) {
431
+ return true;
432
+
433
+ } else if (thisClientVersionNumeric < this._latestClientVersionNumeric) {
434
+ return false;
435
+
436
+ } else if (this._latestClientVersionNumeric < thisClientVersionNumeric) {
437
+ this.setLatestClientVersion(clientVersion, thisClientVersionNumeric);
438
+
439
+ return true;
440
+ }
441
+
442
+ DyFM_Log.error(
443
+ 'Something went wrong, invalid version:', clientVersion,
444
+ thisClientVersionNumeric, _serverVersion, this.serverVersionNumeric
445
+ );
446
+
447
+ return false;
448
+ }
449
+
450
+ protected setLatestClientVersion(clientVersion: string, clientVersionNumeric: number): void {
451
+ if (!clientVersion.includes('test') && !clientVersion.includes('dev')) {
452
+ this._latestClientVersion = clientVersion;
453
+ this._latestClientVersionNumeric = clientVersionNumeric;
454
+ }
455
+ }
456
+
457
+ protected async triggerCreateSnapshot(issuer: string): Promise<void> {
458
+ try {
459
+ const snapshot: T_ServerStatusSnapshot = await this.getServerStatusSnapshot(issuer);
460
+ const serverStatusSnapshot_CS: T_ServerStatusSnapshot_ControlService =
461
+ this.getServerStatusSnapshotControlService({ issuer: issuer });
462
+
463
+ await serverStatusSnapshot_CS.saveSnapshot(snapshot, issuer);
464
+
465
+ DyFM_Log.info('ServerStatus snapshot created');
466
+ } catch (error) {
467
+ throw new DyFM_Error({
468
+ ...this.getDefaultErrorSettings('triggerCreateSnapshot', error, 'system-tick'),
469
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSCS-TCS0`,
470
+ });
471
+ }
472
+ }
473
+
474
+ async getServerStatusSnapshot(issuer: string): Promise<T_ServerStatusSnapshot> {
475
+ try {
476
+ return ({
477
+ ...(await this.getServerStatus(issuer)),
478
+ }) as T_ServerStatusSnapshot;
479
+ } catch (error) {
480
+ throw new DyFM_Error({
481
+ ...this.getDefaultErrorSettings(
482
+ 'getServerStatusSnapshot',
483
+ error?.response?.data ?? error,
484
+ issuer
485
+ ),
486
+
487
+ errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-SSCS-GSS0`,
488
+ });
489
+ }
490
+ }
491
491
  }