@solidxai/core 0.1.6 → 0.1.7

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 (357) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/dist/controllers/dashboard-layout.controller.d.ts +47 -0
  3. package/dist/controllers/dashboard-layout.controller.d.ts.map +1 -0
  4. package/dist/controllers/dashboard-layout.controller.js +204 -0
  5. package/dist/controllers/dashboard-layout.controller.js.map +1 -0
  6. package/dist/controllers/scheduled-job.controller.d.ts +1 -0
  7. package/dist/controllers/scheduled-job.controller.d.ts.map +1 -1
  8. package/dist/controllers/scheduled-job.controller.js +12 -0
  9. package/dist/controllers/scheduled-job.controller.js.map +1 -1
  10. package/dist/dtos/create-dashboard-layout.dto.d.ts +8 -0
  11. package/dist/dtos/create-dashboard-layout.dto.d.ts.map +1 -0
  12. package/dist/dtos/create-dashboard-layout.dto.js +53 -0
  13. package/dist/dtos/create-dashboard-layout.dto.js.map +1 -0
  14. package/dist/dtos/create-dashboard-variable.dto.d.ts +1 -0
  15. package/dist/dtos/create-dashboard-variable.dto.d.ts.map +1 -1
  16. package/dist/dtos/create-dashboard-variable.dto.js +7 -1
  17. package/dist/dtos/create-dashboard-variable.dto.js.map +1 -1
  18. package/dist/dtos/update-dashboard-layout.dto.d.ts +8 -0
  19. package/dist/dtos/update-dashboard-layout.dto.d.ts.map +1 -0
  20. package/dist/dtos/update-dashboard-layout.dto.js +53 -0
  21. package/dist/dtos/update-dashboard-layout.dto.js.map +1 -0
  22. package/dist/dtos/update-dashboard-variable.dto.d.ts +1 -0
  23. package/dist/dtos/update-dashboard-variable.dto.d.ts.map +1 -1
  24. package/dist/dtos/update-dashboard-variable.dto.js +7 -1
  25. package/dist/dtos/update-dashboard-variable.dto.js.map +1 -1
  26. package/dist/entities/action-metadata.entity.d.ts.map +1 -1
  27. package/dist/entities/action-metadata.entity.js.map +1 -1
  28. package/dist/entities/ai-interaction.entity.d.ts.map +1 -1
  29. package/dist/entities/ai-interaction.entity.js +5 -4
  30. package/dist/entities/ai-interaction.entity.js.map +1 -1
  31. package/dist/entities/chatter-message-details.entity.d.ts +1 -0
  32. package/dist/entities/chatter-message-details.entity.d.ts.map +1 -1
  33. package/dist/entities/chatter-message-details.entity.js +9 -4
  34. package/dist/entities/chatter-message-details.entity.js.map +1 -1
  35. package/dist/entities/chatter-message.entity.d.ts.map +1 -1
  36. package/dist/entities/chatter-message.entity.js +4 -3
  37. package/dist/entities/chatter-message.entity.js.map +1 -1
  38. package/dist/entities/common.entity.js +1 -1
  39. package/dist/entities/common.entity.js.map +1 -1
  40. package/dist/entities/dashboard-layout.entity.d.ts +9 -0
  41. package/dist/entities/dashboard-layout.entity.d.ts.map +1 -0
  42. package/dist/entities/dashboard-layout.entity.js +41 -0
  43. package/dist/entities/dashboard-layout.entity.js.map +1 -0
  44. package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts.map +1 -1
  45. package/dist/entities/dashboard-question-sql-dataset-config.entity.js +5 -4
  46. package/dist/entities/dashboard-question-sql-dataset-config.entity.js.map +1 -1
  47. package/dist/entities/dashboard-question.entity.d.ts.map +1 -1
  48. package/dist/entities/dashboard-question.entity.js +5 -4
  49. package/dist/entities/dashboard-question.entity.js.map +1 -1
  50. package/dist/entities/dashboard-variable.entity.d.ts +1 -0
  51. package/dist/entities/dashboard-variable.entity.d.ts.map +1 -1
  52. package/dist/entities/dashboard-variable.entity.js +10 -4
  53. package/dist/entities/dashboard-variable.entity.js.map +1 -1
  54. package/dist/entities/dashboard.entity.d.ts +2 -0
  55. package/dist/entities/dashboard.entity.d.ts.map +1 -1
  56. package/dist/entities/dashboard.entity.js +9 -3
  57. package/dist/entities/dashboard.entity.js.map +1 -1
  58. package/dist/entities/email-attachment.entity.d.ts.map +1 -1
  59. package/dist/entities/email-attachment.entity.js +2 -1
  60. package/dist/entities/email-attachment.entity.js.map +1 -1
  61. package/dist/entities/email-template.entity.js +1 -1
  62. package/dist/entities/email-template.entity.js.map +1 -1
  63. package/dist/entities/export-transaction.entity.d.ts.map +1 -1
  64. package/dist/entities/export-transaction.entity.js +2 -1
  65. package/dist/entities/export-transaction.entity.js.map +1 -1
  66. package/dist/entities/field-metadata.entity.js +2 -2
  67. package/dist/entities/field-metadata.entity.js.map +1 -1
  68. package/dist/entities/import-transaction-error-log.entity.d.ts.map +1 -1
  69. package/dist/entities/import-transaction-error-log.entity.js +3 -2
  70. package/dist/entities/import-transaction-error-log.entity.js.map +1 -1
  71. package/dist/entities/import-transaction.entity.d.ts.map +1 -1
  72. package/dist/entities/import-transaction.entity.js +2 -1
  73. package/dist/entities/import-transaction.entity.js.map +1 -1
  74. package/dist/entities/legacy-common.entity.d.ts.map +1 -1
  75. package/dist/entities/legacy-common.entity.js +1 -1
  76. package/dist/entities/legacy-common.entity.js.map +1 -1
  77. package/dist/entities/mq-message-queue.entity.d.ts.map +1 -1
  78. package/dist/entities/mq-message-queue.entity.js.map +1 -1
  79. package/dist/entities/mq-message.entity.d.ts.map +1 -1
  80. package/dist/entities/mq-message.entity.js +5 -3
  81. package/dist/entities/mq-message.entity.js.map +1 -1
  82. package/dist/entities/saved-filters.entity.d.ts.map +1 -1
  83. package/dist/entities/saved-filters.entity.js +3 -2
  84. package/dist/entities/saved-filters.entity.js.map +1 -1
  85. package/dist/entities/security-rule.entity.d.ts.map +1 -1
  86. package/dist/entities/security-rule.entity.js +2 -1
  87. package/dist/entities/security-rule.entity.js.map +1 -1
  88. package/dist/entities/sms-template.entity.js +1 -1
  89. package/dist/entities/sms-template.entity.js.map +1 -1
  90. package/dist/entities/user-view-metadata.entity.d.ts.map +1 -1
  91. package/dist/entities/user-view-metadata.entity.js +2 -1
  92. package/dist/entities/user-view-metadata.entity.js.map +1 -1
  93. package/dist/entities/user.entity.d.ts.map +1 -1
  94. package/dist/entities/user.entity.js +2 -0
  95. package/dist/entities/user.entity.js.map +1 -1
  96. package/dist/entities/view-metadata.entity.d.ts.map +1 -1
  97. package/dist/entities/view-metadata.entity.js.map +1 -1
  98. package/dist/helpers/bootstrap.helper.d.ts +14 -0
  99. package/dist/helpers/bootstrap.helper.d.ts.map +1 -0
  100. package/dist/helpers/bootstrap.helper.js +132 -0
  101. package/dist/helpers/bootstrap.helper.js.map +1 -0
  102. package/dist/helpers/cache.helper.d.ts +2 -0
  103. package/dist/helpers/cache.helper.d.ts.map +1 -0
  104. package/dist/helpers/cache.helper.js +8 -0
  105. package/dist/helpers/cache.helper.js.map +1 -0
  106. package/dist/helpers/cors.helper.d.ts.map +1 -1
  107. package/dist/helpers/cors.helper.js +13 -4
  108. package/dist/helpers/cors.helper.js.map +1 -1
  109. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts +2 -2
  110. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts.map +1 -1
  111. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js +8 -5
  112. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js.map +1 -1
  113. package/dist/helpers/solid-registry.d.ts +3 -0
  114. package/dist/helpers/solid-registry.d.ts.map +1 -1
  115. package/dist/helpers/solid-registry.js +7 -0
  116. package/dist/helpers/solid-registry.js.map +1 -1
  117. package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
  118. package/dist/helpers/typeorm-db-helper.js +21 -0
  119. package/dist/helpers/typeorm-db-helper.js.map +1 -1
  120. package/dist/index.d.ts +3 -0
  121. package/dist/index.d.ts.map +1 -1
  122. package/dist/index.js +3 -0
  123. package/dist/index.js.map +1 -1
  124. package/dist/interfaces.d.ts +6 -1
  125. package/dist/interfaces.d.ts.map +1 -1
  126. package/dist/interfaces.js.map +1 -1
  127. package/dist/jobs/chatter-queue-options.js +1 -1
  128. package/dist/jobs/chatter-queue-options.js.map +1 -1
  129. package/dist/jobs/chatter-queue-publisher.service.d.ts +9 -9
  130. package/dist/jobs/chatter-queue-publisher.service.d.ts.map +1 -1
  131. package/dist/jobs/chatter-queue-publisher.service.js +5 -5
  132. package/dist/jobs/chatter-queue-publisher.service.js.map +1 -1
  133. package/dist/jobs/chatter-queue-subscriber.service.d.ts +4 -4
  134. package/dist/jobs/chatter-queue-subscriber.service.d.ts.map +1 -1
  135. package/dist/jobs/chatter-queue-subscriber.service.js +11 -11
  136. package/dist/jobs/chatter-queue-subscriber.service.js.map +1 -1
  137. package/dist/jobs/computed-field-evaluation-queue-options.d.ts +2 -0
  138. package/dist/jobs/computed-field-evaluation-queue-options.d.ts.map +1 -1
  139. package/dist/jobs/computed-field-evaluation-queue-options.js +2 -0
  140. package/dist/jobs/computed-field-evaluation-queue-options.js.map +1 -1
  141. package/dist/jobs/database/chatter-queue-options-database.d.ts +8 -0
  142. package/dist/jobs/database/chatter-queue-options-database.d.ts.map +1 -0
  143. package/dist/jobs/database/chatter-queue-options-database.js +10 -0
  144. package/dist/jobs/database/chatter-queue-options-database.js.map +1 -0
  145. package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts +12 -0
  146. package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts.map +1 -0
  147. package/dist/jobs/database/chatter-queue-publisher-database.service.js +39 -0
  148. package/dist/jobs/database/chatter-queue-publisher-database.service.js.map +1 -0
  149. package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts +19 -0
  150. package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts.map +1 -0
  151. package/dist/jobs/database/chatter-queue-subscriber-database.service.js +62 -0
  152. package/dist/jobs/database/chatter-queue-subscriber-database.service.js.map +1 -0
  153. package/dist/repository/dashboard-layout.repository.d.ts +12 -0
  154. package/dist/repository/dashboard-layout.repository.d.ts.map +1 -0
  155. package/dist/repository/dashboard-layout.repository.js +34 -0
  156. package/dist/repository/dashboard-layout.repository.js.map +1 -0
  157. package/dist/repository/model-metadata.repository.d.ts +6 -1
  158. package/dist/repository/model-metadata.repository.d.ts.map +1 -1
  159. package/dist/repository/model-metadata.repository.js +41 -2
  160. package/dist/repository/model-metadata.repository.js.map +1 -1
  161. package/dist/seeders/module-metadata-seeder.service.js +4 -4
  162. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  163. package/dist/seeders/seed-data/solid-core-metadata.json +445 -35
  164. package/dist/services/authentication.service.d.ts.map +1 -1
  165. package/dist/services/authentication.service.js +45 -21
  166. package/dist/services/authentication.service.js.map +1 -1
  167. package/dist/services/chatter-message.service.d.ts +4 -4
  168. package/dist/services/chatter-message.service.d.ts.map +1 -1
  169. package/dist/services/chatter-message.service.js +59 -9
  170. package/dist/services/chatter-message.service.js.map +1 -1
  171. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts +7 -3
  172. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts.map +1 -1
  173. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js +61 -22
  174. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js.map +1 -1
  175. package/dist/services/crud.service.js +1 -1
  176. package/dist/services/crud.service.js.map +1 -1
  177. package/dist/services/dashboard-layout.service.d.ts +20 -0
  178. package/dist/services/dashboard-layout.service.d.ts.map +1 -0
  179. package/dist/services/dashboard-layout.service.js +120 -0
  180. package/dist/services/dashboard-layout.service.js.map +1 -0
  181. package/dist/services/dashboard-question.service.d.ts +4 -0
  182. package/dist/services/dashboard-question.service.d.ts.map +1 -1
  183. package/dist/services/dashboard-question.service.js +22 -8
  184. package/dist/services/dashboard-question.service.js.map +1 -1
  185. package/dist/services/dashboard.service.d.ts +2 -0
  186. package/dist/services/dashboard.service.d.ts.map +1 -1
  187. package/dist/services/dashboard.service.js +4 -0
  188. package/dist/services/dashboard.service.js.map +1 -1
  189. package/dist/services/model-metadata.service.d.ts +3 -1
  190. package/dist/services/model-metadata.service.d.ts.map +1 -1
  191. package/dist/services/model-metadata.service.js +122 -8
  192. package/dist/services/model-metadata.service.js.map +1 -1
  193. package/dist/services/permission-metadata.service.d.ts +5 -1
  194. package/dist/services/permission-metadata.service.d.ts.map +1 -1
  195. package/dist/services/permission-metadata.service.js +66 -20
  196. package/dist/services/permission-metadata.service.js.map +1 -1
  197. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts +2 -4
  198. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts.map +1 -1
  199. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js +2 -1
  200. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js.map +1 -1
  201. package/dist/services/question-data-providers/interfaces.d.ts +1 -0
  202. package/dist/services/question-data-providers/interfaces.d.ts.map +1 -0
  203. package/dist/services/question-data-providers/interfaces.js +1 -0
  204. package/dist/services/question-data-providers/interfaces.js.map +1 -0
  205. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts +2 -5
  206. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts.map +1 -1
  207. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js +2 -1
  208. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js.map +1 -1
  209. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts +2 -5
  210. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts.map +1 -1
  211. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js +2 -1
  212. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js.map +1 -1
  213. package/dist/services/queues/database-subscriber.service.d.ts +4 -2
  214. package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
  215. package/dist/services/queues/database-subscriber.service.js +15 -2
  216. package/dist/services/queues/database-subscriber.service.js.map +1 -1
  217. package/dist/services/queues/publisher-factory.service.d.ts.map +1 -1
  218. package/dist/services/queues/publisher-factory.service.js +4 -7
  219. package/dist/services/queues/publisher-factory.service.js.map +1 -1
  220. package/dist/services/queues/rabbitmq-publisher.service.d.ts +1 -0
  221. package/dist/services/queues/rabbitmq-publisher.service.d.ts.map +1 -1
  222. package/dist/services/queues/rabbitmq-publisher.service.js +6 -1
  223. package/dist/services/queues/rabbitmq-publisher.service.js.map +1 -1
  224. package/dist/services/queues/rabbitmq-subscriber.service.d.ts +9 -3
  225. package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
  226. package/dist/services/queues/rabbitmq-subscriber.service.js +93 -10
  227. package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
  228. package/dist/services/request-context.service.d.ts +2 -1
  229. package/dist/services/request-context.service.d.ts.map +1 -1
  230. package/dist/services/request-context.service.js.map +1 -1
  231. package/dist/services/scheduled-job.service.d.ts +6 -1
  232. package/dist/services/scheduled-job.service.d.ts.map +1 -1
  233. package/dist/services/scheduled-job.service.js +26 -2
  234. package/dist/services/scheduled-job.service.js.map +1 -1
  235. package/dist/services/scheduled-jobs/scheduler.interface.d.ts +2 -0
  236. package/dist/services/scheduled-jobs/scheduler.interface.d.ts.map +1 -1
  237. package/dist/services/scheduled-jobs/scheduler.interface.js.map +1 -1
  238. package/dist/services/scheduled-jobs/scheduler.service.d.ts +6 -2
  239. package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
  240. package/dist/services/scheduled-jobs/scheduler.service.js +75 -17
  241. package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
  242. package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.d.ts.map +1 -1
  243. package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js +4 -1
  244. package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js.map +1 -1
  245. package/dist/services/solid-introspect.service.d.ts +6 -1
  246. package/dist/services/solid-introspect.service.d.ts.map +1 -1
  247. package/dist/services/solid-introspect.service.js +27 -2
  248. package/dist/services/solid-introspect.service.js.map +1 -1
  249. package/dist/services/solid-ts-morph.service.d.ts +9 -0
  250. package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
  251. package/dist/services/solid-ts-morph.service.js +76 -0
  252. package/dist/services/solid-ts-morph.service.js.map +1 -1
  253. package/dist/solid-core.module.d.ts.map +1 -1
  254. package/dist/solid-core.module.js +16 -0
  255. package/dist/solid-core.module.js.map +1 -1
  256. package/dist/subscribers/audit.subscriber.d.ts +10 -7
  257. package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
  258. package/dist/subscribers/audit.subscriber.js +58 -85
  259. package/dist/subscribers/audit.subscriber.js.map +1 -1
  260. package/dist/subscribers/computed-entity-field.subscriber.js +3 -1
  261. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  262. package/dist/subscribers/created-by-updated-by.subscriber.d.ts +0 -1
  263. package/dist/subscribers/created-by-updated-by.subscriber.d.ts.map +1 -1
  264. package/dist/subscribers/created-by-updated-by.subscriber.js +3 -13
  265. package/dist/subscribers/created-by-updated-by.subscriber.js.map +1 -1
  266. package/dist/transformers/typeorm/local-date-time-transformer.d.ts +4 -4
  267. package/dist/transformers/typeorm/local-date-time-transformer.d.ts.map +1 -1
  268. package/dist/transformers/typeorm/local-date-time-transformer.js +25 -28
  269. package/dist/transformers/typeorm/local-date-time-transformer.js.map +1 -1
  270. package/dist/winston.logger.d.ts.map +1 -1
  271. package/dist/winston.logger.js +2 -1
  272. package/dist/winston.logger.js.map +1 -1
  273. package/package.json +3 -1
  274. package/sql/default/mariadb/proc_CleanupModelMetadata.sql +153 -0
  275. package/sql/default/mariadb/proc_CleanupModuleMetadata.sql +56 -0
  276. package/sql/default/mysql/proc_CleanupModelMetadata.sql +153 -0
  277. package/sql/default/mysql/proc_CleanupModuleMetadata.sql +56 -0
  278. package/src/controllers/dashboard-layout.controller.ts +106 -0
  279. package/src/controllers/scheduled-job.controller.ts +6 -0
  280. package/src/dtos/create-dashboard-layout.dto.ts +31 -0
  281. package/src/dtos/create-dashboard-variable.dto.ts +4 -0
  282. package/src/dtos/update-dashboard-layout.dto.ts +30 -0
  283. package/src/dtos/update-dashboard-variable.dto.ts +5 -1
  284. package/src/entities/action-metadata.entity.ts +3 -2
  285. package/src/entities/ai-interaction.entity.ts +5 -4
  286. package/src/entities/chatter-message-details.entity.ts +7 -3
  287. package/src/entities/chatter-message.entity.ts +4 -3
  288. package/src/entities/common.entity.ts +2 -2
  289. package/src/entities/dashboard-layout.entity.ts +18 -0
  290. package/src/entities/dashboard-question-sql-dataset-config.entity.ts +5 -4
  291. package/src/entities/dashboard-question.entity.ts +5 -4
  292. package/src/entities/dashboard-variable.entity.ts +9 -4
  293. package/src/entities/dashboard.entity.ts +7 -2
  294. package/src/entities/email-attachment.entity.ts +2 -1
  295. package/src/entities/email-template.entity.ts +1 -1
  296. package/src/entities/export-transaction.entity.ts +2 -1
  297. package/src/entities/field-metadata.entity.ts +2 -2
  298. package/src/entities/import-transaction-error-log.entity.ts +3 -2
  299. package/src/entities/import-transaction.entity.ts +2 -1
  300. package/src/entities/legacy-common.entity.ts +3 -4
  301. package/src/entities/mq-message-queue.entity.ts +8 -8
  302. package/src/entities/mq-message.entity.ts +5 -3
  303. package/src/entities/saved-filters.entity.ts +3 -2
  304. package/src/entities/security-rule.entity.ts +2 -1
  305. package/src/entities/sms-template.entity.ts +1 -1
  306. package/src/entities/user-view-metadata.entity.ts +2 -1
  307. package/src/entities/user.entity.ts +37 -2
  308. package/src/entities/view-metadata.entity.ts +3 -0
  309. package/src/helpers/bootstrap.helper.ts +222 -0
  310. package/src/helpers/cache.helper.ts +5 -0
  311. package/src/helpers/cors.helper.ts +26 -6
  312. package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +9 -6
  313. package/src/helpers/solid-registry.ts +10 -5
  314. package/src/helpers/typeorm-db-helper.ts +26 -0
  315. package/src/index.ts +3 -0
  316. package/src/interfaces.ts +10 -1
  317. package/src/jobs/chatter-queue-options.ts +1 -1
  318. package/src/jobs/chatter-queue-publisher.service.ts +11 -11
  319. package/src/jobs/chatter-queue-subscriber.service.ts +13 -8
  320. package/src/jobs/computed-field-evaluation-queue-options.ts +2 -0
  321. package/src/jobs/database/chatter-queue-options-database.ts +9 -0
  322. package/src/jobs/database/chatter-queue-publisher-database.service.ts +24 -0
  323. package/src/jobs/database/chatter-queue-subscriber-database.service.ts +53 -0
  324. package/src/repository/dashboard-layout.repository.ts +17 -0
  325. package/src/repository/model-metadata.repository.ts +45 -2
  326. package/src/seeders/module-metadata-seeder.service.ts +5 -5
  327. package/src/seeders/seed-data/solid-core-metadata.json +446 -36
  328. package/src/services/authentication.service.ts +47 -24
  329. package/src/services/chatter-message.service.ts +67 -9
  330. package/src/services/computed-fields/entity/sequence-num-computed-field-provider.ts +79 -40
  331. package/src/services/crud.service.ts +1 -1
  332. package/src/services/dashboard-layout.service.ts +111 -0
  333. package/src/services/dashboard-question.service.ts +23 -4
  334. package/src/services/dashboard.service.ts +7 -0
  335. package/src/services/model-metadata.service.ts +131 -50
  336. package/src/services/permission-metadata.service.ts +73 -20
  337. package/src/services/question-data-providers/chartjs-sql-data-provider.service.ts +3 -7
  338. package/src/services/question-data-providers/interfaces.ts +0 -0
  339. package/src/services/question-data-providers/prime-react-datatable-sql-data-provider.service.ts +4 -8
  340. package/src/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.ts +4 -8
  341. package/src/services/queues/database-subscriber.service.ts +19 -2
  342. package/src/services/queues/publisher-factory.service.ts +9 -7
  343. package/src/services/queues/rabbitmq-publisher.service.ts +8 -2
  344. package/src/services/queues/rabbitmq-subscriber.service.ts +139 -11
  345. package/src/services/request-context.service.ts +2 -1
  346. package/src/services/scheduled-job.service.ts +31 -2
  347. package/src/services/scheduled-jobs/scheduler.interface.ts +4 -1
  348. package/src/services/scheduled-jobs/scheduler.service.ts +82 -20
  349. package/src/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.ts +4 -1
  350. package/src/services/solid-introspect.service.ts +28 -0
  351. package/src/services/solid-ts-morph.service.ts +98 -0
  352. package/src/solid-core.module.ts +21 -2
  353. package/src/subscribers/audit.subscriber.ts +63 -271
  354. package/src/subscribers/computed-entity-field.subscriber.ts +3 -3
  355. package/src/subscribers/created-by-updated-by.subscriber.ts +22 -16
  356. package/src/transformers/typeorm/local-date-time-transformer.ts +41 -33
  357. package/src/winston.logger.ts +2 -1
@@ -94,6 +94,10 @@ import { Msg91SmsQueuePublisher } from './jobs/msg91-sms-publisher.service';
94
94
  import { Msg91SmsQueueSubscriber } from './jobs/msg91-sms-subscriber.service';
95
95
  import { SmtpEmailQueuePublisherRabbitmq } from './jobs/smtp-email-publisher.service';
96
96
  import { SmtpEmailQueueSubscriberRabbitmq } from './jobs/smtp-email-subscriber.service';
97
+ import { ChatterQueuePublisherRabbitmq } from './jobs/chatter-queue-publisher.service';
98
+ import { ChatterQueueSubscriberRabbitmq } from './jobs/chatter-queue-subscriber.service';
99
+ import { ChatterQueuePublisherDatabase } from './jobs/database/chatter-queue-publisher-database.service';
100
+ import { ChatterQueueSubscriberDatabase } from './jobs/database/chatter-queue-subscriber-database.service';
97
101
  import { TestQueuePublisher } from './jobs/test-queue-publisher.service';
98
102
  import { TestQueueSubscriber } from './jobs/test-queue-subscriber.service';
99
103
  import { UserRegistrationListener } from './listeners/user-registration.listener';
@@ -133,6 +137,8 @@ import { ChatterMessageController } from './controllers/chatter-message.controll
133
137
  import { DashboardQuestionSqlDatasetConfigController } from './controllers/dashboard-question-sql-dataset-config.controller';
134
138
  import { DashboardQuestionController } from './controllers/dashboard-question.controller';
135
139
  import { DashboardVariableController } from './controllers/dashboard-variable.controller';
140
+ import { DashboardLayoutController } from './controllers/dashboard-layout.controller';
141
+
136
142
  import { DashboardController } from './controllers/dashboard.controller';
137
143
  import { ExportTemplateController } from './controllers/export-template.controller';
138
144
  import { ExportTransactionController } from './controllers/export-transaction.controller';
@@ -156,6 +162,8 @@ import { ChatterMessage } from './entities/chatter-message.entity';
156
162
  import { DashboardQuestionSqlDatasetConfig } from './entities/dashboard-question-sql-dataset-config.entity';
157
163
  import { DashboardQuestion } from './entities/dashboard-question.entity';
158
164
  import { DashboardVariable } from './entities/dashboard-variable.entity';
165
+ import { DashboardLayout } from './entities/dashboard-layout.entity';
166
+
159
167
  import { Dashboard } from './entities/dashboard.entity';
160
168
  import { ExportTemplate } from './entities/export-template.entity';
161
169
  import { ExportTransaction } from './entities/export-transaction.entity';
@@ -221,6 +229,8 @@ import { DashboardQuestionSqlDatasetConfigRepository } from './repository/dashbo
221
229
  import { DashboardQuestionRepository } from './repository/dashboard-question.repository';
222
230
  import { DashboardVariableRepository } from './repository/dashboard-variable.repository';
223
231
  import { DashboardRepository } from './repository/dashboard.repository';
232
+ import { DashboardLayoutRepository } from './repository/dashboard-layout.repository';
233
+
224
234
  import { EmailTemplateRepository } from './repository/email-template.repository';
225
235
  import { ExportTemplateRepository } from './repository/export-template.repository';
226
236
  import { ExportTransactionRepository } from './repository/export-transaction.repository';
@@ -263,6 +273,8 @@ import { DashboardVariableSQLDynamicProvider } from './services/dashboard-select
263
273
  import { DasbhoardVariableTestDynamicProvider } from './services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service';
264
274
  import { DashboardVariableService } from './services/dashboard-variable.service';
265
275
  import { DashboardService } from './services/dashboard.service';
276
+ import { DashboardLayoutService } from './services/dashboard-layout.service';
277
+
266
278
  import { ExcelService } from './services/excel.service';
267
279
  import { ExportTemplateService } from './services/export-template.service';
268
280
  import { ExportTransactionService } from './services/export-transaction.service';
@@ -329,6 +341,7 @@ import { ImageEncodingService } from './helpers/image-encoding.helper';
329
341
  import { SolidMicroserviceAdapter } from './helpers/solid-microservice-adapter.service';
330
342
  import { InfoCommand } from './commands/info.command';
331
343
  import { ListOfRolesSelectionProvider } from './services/selection-providers/list-of-roles-selectionproviders.service';
344
+ import { Entity } from 'typeorm';
332
345
 
333
346
 
334
347
  @Global()
@@ -343,6 +356,7 @@ import { ListOfRolesSelectionProvider } from './services/selection-providers/lis
343
356
  DashboardQuestion,
344
357
  DashboardQuestionSqlDatasetConfig,
345
358
  DashboardVariable,
359
+ DashboardLayout,
346
360
  EmailAttachment,
347
361
  EmailTemplate,
348
362
  ExportTemplate,
@@ -414,6 +428,7 @@ import { ListOfRolesSelectionProvider } from './services/selection-providers/lis
414
428
  DashboardQuestionController,
415
429
  DashboardQuestionSqlDatasetConfigController,
416
430
  DashboardVariableController,
431
+ DashboardLayoutController,
417
432
  EmailTemplateController,
418
433
  ExportTemplateController,
419
434
  ExportTransactionController,
@@ -584,8 +599,10 @@ import { ListOfRolesSelectionProvider } from './services/selection-providers/lis
584
599
  TestQueuePublisher,
585
600
  TestQueueSubscriber,
586
601
 
587
- // ChatterQueuePublisher,
588
- // ChatterQueueSubscriber,
602
+ ChatterQueuePublisherRabbitmq,
603
+ ChatterQueueSubscriberRabbitmq,
604
+ ChatterQueuePublisherDatabase,
605
+ ChatterQueueSubscriberDatabase,
589
606
 
590
607
  TestQueuePublisherDatabase,
591
608
  TestQueueSubscriberDatabase,
@@ -638,6 +655,7 @@ import { ListOfRolesSelectionProvider } from './services/selection-providers/lis
638
655
  UserActivityHistoryService,
639
656
  DashboardService,
640
657
  DashboardVariableService,
658
+ DashboardLayoutService,
641
659
  DashboardQuestionService,
642
660
  DashboardVariableSQLDynamicProvider,
643
661
  DasbhoardVariableTestDynamicProvider,
@@ -682,6 +700,7 @@ import { ListOfRolesSelectionProvider } from './services/selection-providers/lis
682
700
  DashboardQuestionSqlDatasetConfigRepository,
683
701
  DashboardQuestionRepository,
684
702
  DashboardVariableRepository,
703
+ DashboardLayoutRepository,
685
704
  EmailTemplateRepository,
686
705
  ExportTemplateRepository,
687
706
  ExportTransactionRepository,
@@ -1,32 +1,20 @@
1
- import { forwardRef, Inject, Injectable, Scope } from '@nestjs/common';
2
- import { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';
1
+ import { Injectable, Logger, Scope } from '@nestjs/common';
3
2
  import { lowerFirst } from 'src/helpers/string.helper';
4
- import { ModelMetadataRepository } from 'src/repository/model-metadata.repository';
3
+ import { SolidRegistry } from 'src/helpers/solid-registry';
5
4
  import { DataSource, EntityMetadata, EntitySubscriberInterface, InsertEvent, RemoveEvent, UpdateEvent } from 'typeorm';
6
- import { ChatterMessageService } from '../services/chatter-message.service';
7
-
8
-
9
- type DeferredCall =
10
- | { kind: 'insert'; args: Parameters<ChatterMessageService['postAuditMessageOnInsert']> }
11
- | { kind: 'update'; args: Parameters<ChatterMessageService['postAuditMessageOnUpdate']> }
12
- | { kind: 'delete'; args: Parameters<ChatterMessageService['postAuditMessageOnDelete']> };
5
+ import { AuditQueuePayload } from 'src/jobs/chatter-queue-publisher.service';
6
+ import { RequestContextService } from 'src/services/request-context.service';
7
+ import { PublisherFactory } from 'src/services/queues/publisher-factory.service';
13
8
 
14
9
  @Injectable({scope: Scope.TRANSIENT})
15
- // @EventSubscriber()
16
10
  export class AuditSubscriber implements EntitySubscriberInterface {
11
+ private readonly logger = new Logger(AuditSubscriber.name);
17
12
  private dataSource: DataSource;
18
13
  constructor(
19
- // @InjectDataSource()
20
- // private readonly dataSource: DataSource,
21
- private readonly chatterMessageService: ChatterMessageService,
22
- // @InjectRepository(ModelMetadata)
23
- // private readonly modelMetadataRepo: Repository<ModelMetadata>,
24
- @Inject(forwardRef(() => ModelMetadataRepository))
25
- private readonly modelMetadataRepo: ModelMetadataRepository,
26
- private readonly modelMetadataHelperService: ModelMetadataHelperService,
27
- ) {
28
- // this.dataSource.subscribers.push(this);
29
- }
14
+ private readonly publisherFactory: PublisherFactory<AuditQueuePayload>,
15
+ private readonly solidRegistry: SolidRegistry,
16
+ private readonly requestContextService: RequestContextService,
17
+ ) { }
30
18
 
31
19
  bindToDataSource(dataSource: DataSource) {
32
20
  this.dataSource = dataSource;
@@ -34,90 +22,61 @@ export class AuditSubscriber implements EntitySubscriberInterface {
34
22
  }
35
23
 
36
24
  // Per-transaction buffer (auto-GC when queryRunner is gone)
37
- private perTxn = new WeakMap<any, DeferredCall[]>();
25
+ private perTxn = new WeakMap<any, AuditQueuePayload[]>();
38
26
 
39
- private enqueue(event: { queryRunner: any }, call: DeferredCall) {
27
+ private enqueue(event: { queryRunner: any }, payload: AuditQueuePayload) {
40
28
  const qr = event.queryRunner;
41
29
  const arr = this.perTxn.get(qr) ?? [];
42
- arr.push(call);
30
+ arr.push(payload);
43
31
  this.perTxn.set(qr, arr);
44
32
  }
45
33
 
46
- private async shouldTrackAudit(entity: any, metadata: EntityMetadata): Promise<boolean> {
47
- const model = await this.modelMetadataRepo.findOne({
48
- where: {
49
- singularName: lowerFirst(metadata.name)
50
- },
51
- relations: {
52
- fields: true,
53
- module: true
54
- }
55
- });
56
-
57
- if (!model || !model.enableAuditTracking) {
58
- return false;
59
- }
60
-
61
- const modelFields = await this.modelMetadataHelperService.loadFieldHierarchy(model.singularName)
62
-
63
- const auditFields = modelFields.filter(field =>
64
- field.enableAuditTracking &&
65
- !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&
66
- !(field.type === 'relation' && field.relationType === 'one-to-many')
67
- );
68
-
69
- if (auditFields.length === 0) {
70
- return false;
71
- }
72
-
73
- // if (!entity) {
74
- // console.warn(`[AuditSubscriber] Skipping audit for ${metadata.name} – entity is undefined or null`);
75
- // return false;
76
- // }
34
+ private shouldTrackAudit(metadata: EntityMetadata): boolean {
35
+ return this.solidRegistry.isAuditableModel(lowerFirst(metadata.name));
36
+ }
77
37
 
78
- return entity && auditFields.some(field => {
79
- const fieldValue = entity[field.name];
80
- return fieldValue !== undefined && fieldValue !== null;
81
- });
38
+ private activeUserId(): number | null {
39
+ return this.requestContextService.getActiveUser()?.sub ?? null;
82
40
  }
83
41
 
84
42
  async afterInsert(event: InsertEvent<any>) {
85
- if (await this.shouldTrackAudit(event.entity, event.metadata)) {
86
- // await this.chatterMessageService.postAuditMessageOnInsert(event.entity, event.metadata);
87
- this.enqueue(event, {
88
- kind: 'insert',
89
- args: [event.entity, event.metadata] as Parameters<ChatterMessageService['postAuditMessageOnInsert']>,
90
- });
91
- }
43
+ if (!this.shouldTrackAudit(event.metadata)) return;
44
+ this.enqueue(event, {
45
+ eventType: 'insert',
46
+ modelName: event.metadata.name,
47
+ entityId: event.entity?.id ?? null,
48
+ occurredAt: new Date().toISOString(),
49
+ after: event.entity ?? null,
50
+ userId: this.activeUserId(),
51
+ });
92
52
  }
93
53
 
94
54
  async afterUpdate(event: UpdateEvent<any>) {
95
- if (await this.shouldTrackAudit(event.entity, event.metadata)) {
96
- // await this.chatterMessageService.postAuditMessageOnUpdate(event.entity, event.metadata, event.databaseEntity, event.updatedColumns || []);
97
- this.enqueue(event, {
98
- kind: 'update',
99
- args: [
100
- event.entity, // entity (after)
101
- event.metadata,
102
- event.databaseEntity, // entity (before)
103
- event.updatedColumns ?? [],
104
- ] as Parameters<ChatterMessageService['postAuditMessageOnUpdate']>,
105
- });
106
- }
55
+ if (!this.shouldTrackAudit(event.metadata)) return;
56
+ this.enqueue(event, {
57
+ eventType: 'update',
58
+ modelName: event.metadata.name,
59
+ entityId: event.entity?.id ?? null,
60
+ occurredAt: new Date().toISOString(),
61
+ after: event.entity ?? null,
62
+ // databaseEntity is only populated when the entity was fetched first (save() path).
63
+ // QueryBuilder update() leaves this undefined; postAuditMessageOnUpdate guards for it.
64
+ before: event.databaseEntity ?? null,
65
+ updatedColumnNames: (event.updatedColumns ?? []).map(c => c.propertyName),
66
+ userId: this.activeUserId(),
67
+ });
107
68
  }
108
69
 
109
70
  async afterRemove(event: RemoveEvent<any>) {
110
- if (await this.shouldTrackAudit(event.entity, event.metadata)) {
111
- // await this.chatterMessageService.postAuditMessageOnDelete(event.entity, event.metadata, event.databaseEntity);
112
- this.enqueue(event, {
113
- kind: 'delete',
114
- args: [
115
- event.entity,
116
- event.metadata,
117
- event.databaseEntity,
118
- ] as Parameters<ChatterMessageService['postAuditMessageOnDelete']>,
119
- });
120
- }
71
+ if (!this.shouldTrackAudit(event.metadata)) return;
72
+ this.enqueue(event, {
73
+ eventType: 'delete',
74
+ modelName: event.metadata.name,
75
+ entityId: event.databaseEntity?.id ?? null,
76
+ occurredAt: new Date().toISOString(),
77
+ before: event.databaseEntity,
78
+ userId: this.activeUserId(),
79
+ });
121
80
  }
122
81
 
123
82
  // --------- transaction lifecycle ----------
@@ -125,191 +84,24 @@ export class AuditSubscriber implements EntitySubscriberInterface {
125
84
  const batch = this.perTxn.get(event.queryRunner) ?? [];
126
85
  this.perTxn.delete(event.queryRunner);
127
86
 
128
- // Now we’re OUTSIDE the DB transaction — safe to do I/O/DB writes inside chatter service.
129
- for (const item of batch) {
130
- try {
131
- switch (item.kind) {
132
- case 'insert': await this.chatterMessageService.postAuditMessageOnInsert(...item.args); break;
133
- case 'update': await this.chatterMessageService.postAuditMessageOnUpdate(...item.args); break;
134
- case 'delete': await this.chatterMessageService.postAuditMessageOnDelete(...item.args); break;
135
- }
136
- } catch (e) {
137
- // Best effort: log and continue; your core txn was already committed
138
- // Optionally: send to a generic error logger/metric here
87
+ // Now outside the DB transaction — safe to publish to the queue.
88
+ // allSettled: publish in parallel; a single failure does not block the rest.
89
+ const results = await Promise.allSettled(
90
+ batch.map(payload => this.publisherFactory.publish({ payload }, 'ChatterQueuePublisher'))
91
+ );
92
+
93
+ results.forEach((result, i) => {
94
+ if (result.status === 'rejected') {
95
+ this.logger.error(
96
+ `Failed to publish audit event for ${batch[i].modelName}#${batch[i].entityId}`,
97
+ result.reason,
98
+ );
139
99
  }
140
- }
100
+ });
141
101
  }
142
102
 
143
103
  afterTransactionRollback(event: { queryRunner: any }) {
144
- // Drop buffered calls; the write never happened
104
+ // Drop buffered payloads; the write never happened.
145
105
  this.perTxn.delete(event.queryRunner);
146
106
  }
147
107
  }
148
-
149
- // import { DataSource, EntityMetadata, EntitySubscriberInterface, EventSubscriber, InsertEvent, RemoveEvent, UpdateEvent } from 'typeorm';
150
- // import { Injectable } from '@nestjs/common';
151
- // import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
152
- // import { Repository } from 'typeorm';
153
- // import { ModelMetadata } from '../entities/model-metadata.entity';
154
- // import { lowerFirst } from 'src/helpers/string.helper';
155
- // import { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';
156
- // import { ChatterMessagePayload } from 'src/jobs/chatter-queue-publisher.service';
157
- // import { RequestContextService } from 'src/services/request-context.service';
158
- // import { PublisherFactory } from 'src/services/queues/publisher-factory.service';
159
-
160
- // @EventSubscriber()
161
- // @Injectable()
162
- // export class AuditSubscriber implements EntitySubscriberInterface {
163
- // private perTxn = new WeakMap<any, ChatterMessagePayload[]>();
164
-
165
- // constructor(
166
- // @InjectDataSource() private readonly dataSource: DataSource,
167
- // @InjectRepository(ModelMetadata) private readonly modelMetadataRepo: Repository<ModelMetadata>,
168
- // private readonly modelMetadataHelperService: ModelMetadataHelperService,
169
- // private readonly requestContext: RequestContextService,
170
- // private readonly publisherFactory: PublisherFactory<any>
171
- // ) {
172
- // this.dataSource.subscribers.push(this);
173
- // }
174
-
175
- // // --- small cache to avoid metadata queries on every row ---
176
- // private modelCache = new Map<string, { enable: boolean; fields: Array<{ name: string; enableAuditTracking: boolean; type: string; relationType?: string }>; ts: number }>();
177
- // private cacheTTLms = 60_000;
178
-
179
- // private async shouldTrackAudit(entity: any, metadata: EntityMetadata): Promise<{ enable: boolean; auditFields?: string[] }> {
180
- // const key = metadata.name;
181
- // const now = Date.now();
182
- // const cached = this.modelCache.get(key);
183
- // if (cached && (now - cached.ts) < this.cacheTTLms) {
184
- // if (!cached.enable) return { enable: false };
185
- // const fields = cached.fields.filter(f =>
186
- // f.enableAuditTracking &&
187
- // !['mediaSingle', 'mediaMultiple', 'computed', 'richText', 'json'].includes(f.type) &&
188
- // !(f.type === 'relation' && f.relationType === 'one-to-many')
189
- // );
190
- // const present = fields.map(f => f.name).filter(n => entity?.[n] !== undefined);
191
- // return { enable: present.length > 0, auditFields: present };
192
- // }
193
-
194
- // const model = await this.modelMetadataRepo.findOne({
195
- // where: { singularName: lowerFirst(metadata.name) },
196
- // relations: { fields: true, module: true },
197
- // });
198
- // const enable = !!model?.enableAuditTracking;
199
- // const fields = model?.fields ?? [];
200
- // this.modelCache.set(key, { enable, fields, ts: now });
201
-
202
- // if (!enable) return { enable: false };
203
- // const filtered = fields.filter(f =>
204
- // f.enableAuditTracking &&
205
- // !['mediaSingle', 'mediaMultiple', 'computed', 'richText', 'json'].includes(f.type) &&
206
- // !(f.type === 'relation' && f.relationType === 'one-to-many')
207
- // );
208
- // const present = filtered.map(f => f.name).filter(n => entity?.[n] !== undefined);
209
- // return { enable: present.length > 0, auditFields: present };
210
- // }
211
-
212
- // private push(event: { queryRunner: any }, msg: ChatterMessagePayload) {
213
- // const arr = this.perTxn.get(event.queryRunner) ?? [];
214
- // arr.push(msg);
215
- // this.perTxn.set(event.queryRunner, arr);
216
- // }
217
-
218
- // async afterInsert(event: InsertEvent<any>) {
219
- // if (!event.entity) return;
220
- // const enable = await this.shouldTrackAudit(event.entity, event.metadata);
221
- // if (!enable) return;
222
-
223
- // const payload: ChatterMessagePayload = {
224
- // eventType: 'insert',
225
- // model: event.metadata.name,
226
- // entityId: String(event.entity.id ?? event.entity.uuid ?? ''),
227
- // occurredAt: new Date().toISOString(),
228
- // after: this.safeCopy(event.entity),
229
- // userId: this.getUserId(),
230
- // };
231
- // this.push(event, payload);
232
- // }
233
-
234
- // async afterUpdate(event: UpdateEvent<any>) {
235
- // // Updated entity may be null if you used raw query; fall back to databaseEntity
236
- // const current = event.entity ?? {};
237
- // const before = event.databaseEntity ?? {};
238
- // const { enable, auditFields } = await this.shouldTrackAudit(current, event.metadata);
239
- // if (!enable) return;
240
-
241
- // const changedCols = (event.updatedColumns || []).map(c => c.propertyName);
242
- // const payload: ChatterMessagePayload = {
243
- // eventType: 'update',
244
- // model: event.metadata.name,
245
- // entityId: String((current as any).id ?? (before as any).id ?? ''),
246
- // occurredAt: new Date().toISOString(),
247
- // before: this.pick(before, auditFields || changedCols),
248
- // after: this.pick(current, auditFields || changedCols),
249
- // diff: changedCols,
250
- // userId: this.getUserId(),
251
- // };
252
- // this.push(event, payload);
253
- // }
254
-
255
- // async afterRemove(event: RemoveEvent<any>) {
256
- // const base = event.entity ?? event.databaseEntity;
257
- // if (!base) return;
258
-
259
- // const { enable } = await this.shouldTrackAudit(base, event.metadata);
260
- // if (!enable) return;
261
-
262
- // const payload: ChatterMessagePayload = {
263
- // eventType: 'delete',
264
- // model: event.metadata.name,
265
- // entityId: String((base as any).id ?? ''),
266
- // occurredAt: new Date().toISOString(),
267
- // before: this.safeCopy(base),
268
- // userId: this.getUserId(),
269
- // };
270
- // this.push(event, payload);
271
- // }
272
-
273
- // // Publish AFTER the transaction commits -> no idle-in-transaction
274
- // async afterTransactionCommit(event: { queryRunner: any }) {
275
- // const batch = this.perTxn.get(event.queryRunner) ?? [];
276
- // this.perTxn.delete(event.queryRunner);
277
- // for (const msg of batch) {
278
- // try {
279
- // await this.publisherFactory.publish({ payload: msg, parentEntity: msg.model, parentEntityId: msg.entityId }, 'ChatterQueuePublisher');
280
- // } catch (err) {
281
- // // log + optionally send to a DLQ or retry queue
282
- // // do NOT throw; commit already happened
283
- // // your RabbitMqPublisher likely tracks failures in MqMessage tables anyway
284
- // }
285
- // }
286
- // }
287
-
288
- // afterTransactionRollback(event: { queryRunner: any }) {
289
- // this.perTxn.delete(event.queryRunner);
290
- // }
291
-
292
- // // --- small helpers to keep payloads JSON-safe and small ---
293
- // private safeCopy(obj: any) {
294
- // try {
295
- // return JSON.parse(JSON.stringify(obj));
296
- // } catch {
297
- // return {}; // strip circular refs
298
- // }
299
- // }
300
-
301
- // private pick(obj: any, keys: string[]) {
302
- // const out: any = {};
303
- // for (const k of keys) out[k] = obj?.[k];
304
- // return this.safeCopy(out);
305
- // }
306
-
307
- // private getUserId(): string | null {
308
-
309
- // const activeUser = this.requestContext.getActiveUser();
310
- // if (activeUser?.sub)
311
- // return String(activeUser.sub);
312
- // }
313
-
314
-
315
- // }
@@ -78,9 +78,9 @@ export class ComputedEntityFieldSubscriber implements EntitySubscriberInterface
78
78
  modelName
79
79
  );
80
80
  //TODO: We can add a feature i.e dependsOn, where we can check if the computed field depends on other computed fields and evaluate them first
81
- await Promise.all(
82
- computedFieldsTobeEvaluated.map(c => this.evaluateComputedField(this.attachContext(c, eventContext), entity, currentOperation))
83
- )
81
+ for (const computedField of computedFieldsTobeEvaluated) {
82
+ await this.evaluateComputedField(this.attachContext(computedField, eventContext), entity, currentOperation);
83
+ }
84
84
  }
85
85
 
86
86
  private handleComputedFieldEvaluationJob(entity: any, currentOperation: ComputedFieldTriggerOperation, modelName: string, eventContext?: TypeOrmEventContext) {
@@ -1,11 +1,9 @@
1
1
  import { Injectable, Scope } from "@nestjs/common";
2
2
  import { InjectDataSource } from "@nestjs/typeorm";
3
- import { User } from "src/entities/user.entity";
4
- import { ActiveUserData } from "src/interfaces/active-user-data.interface";
5
3
  import { RequestContextService } from "src/services/request-context.service";
6
- import { DataSource, EntitySubscriberInterface, EventSubscriber, InsertEvent, UpdateEvent } from "typeorm";
4
+ import { DataSource, EntitySubscriberInterface, InsertEvent, UpdateEvent } from "typeorm";
7
5
 
8
- @Injectable({scope: Scope.TRANSIENT})
6
+ @Injectable({ scope: Scope.TRANSIENT })
9
7
  // @EventSubscriber()
10
8
  export class CreatedByUpdatedBySubscriber implements EntitySubscriberInterface {
11
9
  private dataSource: DataSource;
@@ -30,7 +28,7 @@ export class CreatedByUpdatedBySubscriber implements EntitySubscriberInterface {
30
28
  await this.stampUserField(event, false);
31
29
  }
32
30
 
33
- private async stampUserField(event: InsertEvent<any> | UpdateEvent<any>, isInsert: boolean){
31
+ private async stampUserField(event: InsertEvent<any> | UpdateEvent<any>, isInsert: boolean) {
34
32
  if (!event.entity) {
35
33
  return;
36
34
  }
@@ -40,21 +38,29 @@ export class CreatedByUpdatedBySubscriber implements EntitySubscriberInterface {
40
38
  return;
41
39
  }
42
40
 
43
- const loadedUser = await this.loadUser(activeUserOrUndefined as unknown as ActiveUserData);
41
+ // const loadedUser = await this.loadUser(activeUserOrUndefined as unknown as ActiveUserData);
42
+ // if (isInsert) {
43
+ // event.entity.createdBy = loadedUser?.id;
44
+ // event.entity.updatedBy = loadedUser?.id; // For insert, we set both createdBy and updatedBy to the same user
45
+ // }
46
+ // else {
47
+ // event.entity.updatedBy = loadedUser?.id;
48
+ // }
49
+
44
50
  if (isInsert) {
45
- event.entity.createdBy = loadedUser?.id;
46
- event.entity.updatedBy = loadedUser?.id; // For insert, we set both createdBy and updatedBy to the same user
51
+ event.entity.createdBy = activeUserOrUndefined?.sub;
52
+ event.entity.updatedBy = activeUserOrUndefined?.sub; // For insert, we set both createdBy and updatedBy to the same user
47
53
  }
48
54
  else {
49
- event.entity.updatedBy = loadedUser?.id;
55
+ event.entity.updatedBy = activeUserOrUndefined?.sub;
50
56
  }
51
57
  }
52
58
 
53
- private async loadUser(activeUser: ActiveUserData): Promise<User> {
54
- const userRepo = this.defaultDataSource.getRepository(User); // Assuming 'User' is the entity name for users in your application
55
- const loadedUser = await userRepo.findOne({
56
- where: { id: activeUser.sub }, // Assuming 'sub' is the user ID in the JWT token
57
- });
58
- return loadedUser;;
59
- }
59
+ // private async loadUser(activeUser: ActiveUserData): Promise<User> {
60
+ // const userRepo = this.defaultDataSource.getRepository(User); // Assuming 'User' is the entity name for users in your application
61
+ // const loadedUser = await userRepo.findOne({
62
+ // where: { id: activeUser.sub }, // Assuming 'sub' is the user ID in the JWT token
63
+ // });
64
+ // return loadedUser;;
65
+ // }
60
66
  }
@@ -20,59 +20,67 @@ function dateToUtcComponentString(d: Date): string {
20
20
  const ss = pad(d.getUTCSeconds());
21
21
  const ms = pad(d.getUTCMilliseconds(), 3);
22
22
 
23
- // A naive timestamp string representing the DB wall-clock components
23
+ // A "naive" timestamp string representing the DB wall-clock components
24
24
  return `${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}.${ms}`;
25
25
  }
26
26
 
27
- export const LocalDateTimeTransformer: ValueTransformer & { utc: ValueTransformer } = {
28
- // DB → Entity
29
- from(value: Date | string | null | undefined): Date | null | undefined {
27
+ function getWallClockConfig(): { tz: string; wallTimeMode: boolean } {
28
+ return {
29
+ tz: process.env.SOLIDX_WALL_TIME_TIMEZONE || process.env.SOLIDX_TIMEZONE || "UTC",
30
+ wallTimeMode: (process.env.SOLIDX_TIME_STORED_AS_WALL_TIME || "").toLowerCase() === "true",
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Returns a dayjs instance positioned at the wall-clock time for the given Date.
36
+ * - Wall-clock mode ON: dayjs in the configured timezone (components = wall-clock components)
37
+ * - Wall-clock mode OFF: dayjs in UTC
38
+ * Counterpart to serializeDate — use this to format/display a date value correctly.
39
+ */
40
+ export function parseDate(date: Date): dayjs.Dayjs {
41
+ const { tz, wallTimeMode } = getWallClockConfig();
42
+ if (!wallTimeMode) return dayjs.utc(date);
43
+ return dayjs(date).tz(tz);
44
+ }
30
45
 
31
- const SOLIDX_WALL_TIME_TZ = process.env.SOLIDX_WALL_TIME_TIMEZONE || process.env.SOLIDX_TIMEZONE || "UTC";
32
- const SOLIDX_TIME_STORED_AS_WALL_TIME = (process.env.SOLIDX_TIME_STORED_AS_WALL_TIME || "").toLowerCase() === "true";
46
+ /**
47
+ * Converts a Date to a string for storage in plain text columns (e.g. audit values).
48
+ * - Wall-clock mode ON: "YYYY-MM-DD HH:mm:ss.SSS" in the configured timezone (no Z suffix)
49
+ * - Wall-clock mode OFF: ISO 8601 UTC string with Z suffix
50
+ * The presence/absence of the Z suffix lets consumers distinguish the two cases.
51
+ */
52
+ export function serializeDate(date: Date): string {
53
+ const { wallTimeMode } = getWallClockConfig();
54
+ if (!wallTimeMode) return date.toISOString();
55
+ return parseDate(date).format("YYYY-MM-DD HH:mm:ss.SSS");
56
+ }
33
57
 
34
- // critical... super important to return undefined here
58
+ export const LocalDateTimeTransformer: ValueTransformer = {
59
+ // DB -> Entity
60
+ from(value: Date | string | null | undefined): Date | null | undefined {
61
+ // critical... super important to return undefined here
35
62
  if (value === undefined) return undefined;
36
63
  if (value === null) return null;
37
64
 
38
- if (!SOLIDX_TIME_STORED_AS_WALL_TIME) {
65
+ const { tz, wallTimeMode } = getWallClockConfig();
66
+
67
+ if (!wallTimeMode) {
39
68
  return dayjs(value).toDate();
40
69
  }
41
70
 
42
71
  const naive = value instanceof Date ? dateToUtcComponentString(value) : String(value);
43
- return dayjs.tz(naive, SOLIDX_WALL_TIME_TZ).utc().toDate();
72
+ return dayjs.tz(naive, tz).utc().toDate();
44
73
  },
45
74
 
46
- // Entity DB
75
+ // Entity -> DB
47
76
  to(value: Date | null | undefined): Date | null | undefined {
48
-
49
- const SOLIDX_WALL_TIME_TZ = process.env.SOLIDX_WALL_TIME_TIMEZONE || process.env.SOLIDX_TIMEZONE || "UTC";
50
- const SOLIDX_TIME_STORED_AS_WALL_TIME = (process.env.SOLIDX_TIME_STORED_AS_WALL_TIME || "").toLowerCase() === "true";
51
-
52
- // critical... super important to return undefined here
77
+ // critical... super important to return undefined here
53
78
  if (value === undefined) return undefined;
54
79
  if (value === null) return null;
55
80
 
56
- if (!SOLIDX_TIME_STORED_AS_WALL_TIME) {
57
- return dayjs(value).toDate();
58
- }
59
-
60
- const wallTimeStr = dayjs(value).tz(SOLIDX_WALL_TIME_TZ).format("YYYY-MM-DD HH:mm:ss.SSS");
81
+ const wallTimeStr = serializeDate(value);
61
82
  return dayjs.utc(wallTimeStr).toDate();
62
83
  },
63
84
 
64
- utc: {
65
- from(value: Date | string | null | undefined): Date | null | undefined {
66
- if (value === undefined) return undefined;
67
- if (value === null) return null;
68
- return dayjs(value).toDate();
69
- },
70
- to(value: Date | null | undefined): Date | null | undefined {
71
- if (value === undefined) return undefined;
72
- if (value === null) return null;
73
- return dayjs(value).toDate();
74
- }
75
- }
76
85
  };
77
86
 
78
- export const UtcDateTimeTransformer = LocalDateTimeTransformer.utc;