@solidxai/core 0.1.6-beta.9 → 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 (311) hide show
  1. package/.claude/settings.local.json +15 -0
  2. package/CHANGELOG.md +71 -0
  3. package/dist/controllers/dashboard-layout.controller.d.ts +47 -0
  4. package/dist/controllers/dashboard-layout.controller.d.ts.map +1 -0
  5. package/dist/controllers/dashboard-layout.controller.js +204 -0
  6. package/dist/controllers/dashboard-layout.controller.js.map +1 -0
  7. package/dist/dtos/create-dashboard-layout.dto.d.ts +8 -0
  8. package/dist/dtos/create-dashboard-layout.dto.d.ts.map +1 -0
  9. package/dist/dtos/create-dashboard-layout.dto.js +53 -0
  10. package/dist/dtos/create-dashboard-layout.dto.js.map +1 -0
  11. package/dist/dtos/create-dashboard-variable.dto.d.ts +1 -0
  12. package/dist/dtos/create-dashboard-variable.dto.d.ts.map +1 -1
  13. package/dist/dtos/create-dashboard-variable.dto.js +7 -1
  14. package/dist/dtos/create-dashboard-variable.dto.js.map +1 -1
  15. package/dist/dtos/update-dashboard-layout.dto.d.ts +8 -0
  16. package/dist/dtos/update-dashboard-layout.dto.d.ts.map +1 -0
  17. package/dist/dtos/update-dashboard-layout.dto.js +53 -0
  18. package/dist/dtos/update-dashboard-layout.dto.js.map +1 -0
  19. package/dist/dtos/update-dashboard-variable.dto.d.ts +1 -0
  20. package/dist/dtos/update-dashboard-variable.dto.d.ts.map +1 -1
  21. package/dist/dtos/update-dashboard-variable.dto.js +7 -1
  22. package/dist/dtos/update-dashboard-variable.dto.js.map +1 -1
  23. package/dist/entities/action-metadata.entity.d.ts.map +1 -1
  24. package/dist/entities/action-metadata.entity.js.map +1 -1
  25. package/dist/entities/ai-interaction.entity.d.ts.map +1 -1
  26. package/dist/entities/ai-interaction.entity.js +5 -4
  27. package/dist/entities/ai-interaction.entity.js.map +1 -1
  28. package/dist/entities/chatter-message-details.entity.d.ts.map +1 -1
  29. package/dist/entities/chatter-message-details.entity.js +4 -3
  30. package/dist/entities/chatter-message-details.entity.js.map +1 -1
  31. package/dist/entities/chatter-message.entity.d.ts.map +1 -1
  32. package/dist/entities/chatter-message.entity.js +4 -3
  33. package/dist/entities/chatter-message.entity.js.map +1 -1
  34. package/dist/entities/dashboard-layout.entity.d.ts +9 -0
  35. package/dist/entities/dashboard-layout.entity.d.ts.map +1 -0
  36. package/dist/entities/dashboard-layout.entity.js +41 -0
  37. package/dist/entities/dashboard-layout.entity.js.map +1 -0
  38. package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts.map +1 -1
  39. package/dist/entities/dashboard-question-sql-dataset-config.entity.js +5 -4
  40. package/dist/entities/dashboard-question-sql-dataset-config.entity.js.map +1 -1
  41. package/dist/entities/dashboard-question.entity.d.ts.map +1 -1
  42. package/dist/entities/dashboard-question.entity.js +5 -4
  43. package/dist/entities/dashboard-question.entity.js.map +1 -1
  44. package/dist/entities/dashboard-variable.entity.d.ts +1 -0
  45. package/dist/entities/dashboard-variable.entity.d.ts.map +1 -1
  46. package/dist/entities/dashboard-variable.entity.js +10 -4
  47. package/dist/entities/dashboard-variable.entity.js.map +1 -1
  48. package/dist/entities/dashboard.entity.d.ts +2 -0
  49. package/dist/entities/dashboard.entity.d.ts.map +1 -1
  50. package/dist/entities/dashboard.entity.js +9 -3
  51. package/dist/entities/dashboard.entity.js.map +1 -1
  52. package/dist/entities/email-attachment.entity.d.ts.map +1 -1
  53. package/dist/entities/email-attachment.entity.js +2 -1
  54. package/dist/entities/email-attachment.entity.js.map +1 -1
  55. package/dist/entities/email-template.entity.js +1 -1
  56. package/dist/entities/email-template.entity.js.map +1 -1
  57. package/dist/entities/export-transaction.entity.d.ts.map +1 -1
  58. package/dist/entities/export-transaction.entity.js +2 -1
  59. package/dist/entities/export-transaction.entity.js.map +1 -1
  60. package/dist/entities/field-metadata.entity.js +2 -2
  61. package/dist/entities/field-metadata.entity.js.map +1 -1
  62. package/dist/entities/import-transaction-error-log.entity.d.ts.map +1 -1
  63. package/dist/entities/import-transaction-error-log.entity.js +3 -2
  64. package/dist/entities/import-transaction-error-log.entity.js.map +1 -1
  65. package/dist/entities/import-transaction.entity.d.ts.map +1 -1
  66. package/dist/entities/import-transaction.entity.js +2 -1
  67. package/dist/entities/import-transaction.entity.js.map +1 -1
  68. package/dist/entities/mq-message-queue.entity.d.ts.map +1 -1
  69. package/dist/entities/mq-message-queue.entity.js.map +1 -1
  70. package/dist/entities/mq-message.entity.d.ts.map +1 -1
  71. package/dist/entities/mq-message.entity.js +5 -3
  72. package/dist/entities/mq-message.entity.js.map +1 -1
  73. package/dist/entities/saved-filters.entity.d.ts.map +1 -1
  74. package/dist/entities/saved-filters.entity.js +3 -2
  75. package/dist/entities/saved-filters.entity.js.map +1 -1
  76. package/dist/entities/security-rule.entity.d.ts.map +1 -1
  77. package/dist/entities/security-rule.entity.js +2 -1
  78. package/dist/entities/security-rule.entity.js.map +1 -1
  79. package/dist/entities/sms-template.entity.js +1 -1
  80. package/dist/entities/sms-template.entity.js.map +1 -1
  81. package/dist/entities/user-view-metadata.entity.d.ts.map +1 -1
  82. package/dist/entities/user-view-metadata.entity.js +2 -1
  83. package/dist/entities/user-view-metadata.entity.js.map +1 -1
  84. package/dist/entities/user.entity.d.ts.map +1 -1
  85. package/dist/entities/user.entity.js +2 -0
  86. package/dist/entities/user.entity.js.map +1 -1
  87. package/dist/entities/view-metadata.entity.d.ts.map +1 -1
  88. package/dist/entities/view-metadata.entity.js.map +1 -1
  89. package/dist/helpers/bootstrap.helper.d.ts +14 -0
  90. package/dist/helpers/bootstrap.helper.d.ts.map +1 -0
  91. package/dist/helpers/bootstrap.helper.js +132 -0
  92. package/dist/helpers/bootstrap.helper.js.map +1 -0
  93. package/dist/helpers/cache.helper.d.ts +2 -0
  94. package/dist/helpers/cache.helper.d.ts.map +1 -0
  95. package/dist/helpers/cache.helper.js +8 -0
  96. package/dist/helpers/cache.helper.js.map +1 -0
  97. package/dist/helpers/cors.helper.d.ts.map +1 -1
  98. package/dist/helpers/cors.helper.js +13 -4
  99. package/dist/helpers/cors.helper.js.map +1 -1
  100. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts +1 -0
  101. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
  102. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +8 -9
  103. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
  104. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts +2 -2
  105. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts.map +1 -1
  106. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js +8 -5
  107. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js.map +1 -1
  108. package/dist/helpers/solid-registry.d.ts +3 -0
  109. package/dist/helpers/solid-registry.d.ts.map +1 -1
  110. package/dist/helpers/solid-registry.js +7 -0
  111. package/dist/helpers/solid-registry.js.map +1 -1
  112. package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
  113. package/dist/helpers/typeorm-db-helper.js +21 -0
  114. package/dist/helpers/typeorm-db-helper.js.map +1 -1
  115. package/dist/index.d.ts +3 -0
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +3 -0
  118. package/dist/index.js.map +1 -1
  119. package/dist/interfaces.d.ts +2 -0
  120. package/dist/interfaces.d.ts.map +1 -1
  121. package/dist/interfaces.js.map +1 -1
  122. package/dist/jobs/chatter-queue-options.js +1 -1
  123. package/dist/jobs/chatter-queue-options.js.map +1 -1
  124. package/dist/jobs/chatter-queue-publisher.service.d.ts +9 -9
  125. package/dist/jobs/chatter-queue-publisher.service.d.ts.map +1 -1
  126. package/dist/jobs/chatter-queue-publisher.service.js +5 -5
  127. package/dist/jobs/chatter-queue-publisher.service.js.map +1 -1
  128. package/dist/jobs/chatter-queue-subscriber.service.d.ts +4 -4
  129. package/dist/jobs/chatter-queue-subscriber.service.d.ts.map +1 -1
  130. package/dist/jobs/chatter-queue-subscriber.service.js +11 -11
  131. package/dist/jobs/chatter-queue-subscriber.service.js.map +1 -1
  132. package/dist/jobs/computed-field-evaluation-queue-options.d.ts +2 -0
  133. package/dist/jobs/computed-field-evaluation-queue-options.d.ts.map +1 -1
  134. package/dist/jobs/computed-field-evaluation-queue-options.js +2 -0
  135. package/dist/jobs/computed-field-evaluation-queue-options.js.map +1 -1
  136. package/dist/jobs/database/chatter-queue-options-database.d.ts +8 -0
  137. package/dist/jobs/database/chatter-queue-options-database.d.ts.map +1 -0
  138. package/dist/jobs/database/chatter-queue-options-database.js +10 -0
  139. package/dist/jobs/database/chatter-queue-options-database.js.map +1 -0
  140. package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts +12 -0
  141. package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts.map +1 -0
  142. package/dist/jobs/database/chatter-queue-publisher-database.service.js +39 -0
  143. package/dist/jobs/database/chatter-queue-publisher-database.service.js.map +1 -0
  144. package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts +19 -0
  145. package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts.map +1 -0
  146. package/dist/jobs/database/chatter-queue-subscriber-database.service.js +62 -0
  147. package/dist/jobs/database/chatter-queue-subscriber-database.service.js.map +1 -0
  148. package/dist/repository/dashboard-layout.repository.d.ts +12 -0
  149. package/dist/repository/dashboard-layout.repository.d.ts.map +1 -0
  150. package/dist/repository/dashboard-layout.repository.js +34 -0
  151. package/dist/repository/dashboard-layout.repository.js.map +1 -0
  152. package/dist/repository/model-metadata.repository.d.ts +6 -1
  153. package/dist/repository/model-metadata.repository.d.ts.map +1 -1
  154. package/dist/repository/model-metadata.repository.js +41 -2
  155. package/dist/repository/model-metadata.repository.js.map +1 -1
  156. package/dist/seeders/module-metadata-seeder.service.js +4 -4
  157. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  158. package/dist/seeders/seed-data/solid-core-metadata.json +372 -32
  159. package/dist/services/chatter-message.service.d.ts +4 -4
  160. package/dist/services/chatter-message.service.d.ts.map +1 -1
  161. package/dist/services/chatter-message.service.js +33 -9
  162. package/dist/services/chatter-message.service.js.map +1 -1
  163. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts +7 -3
  164. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts.map +1 -1
  165. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js +61 -22
  166. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js.map +1 -1
  167. package/dist/services/crud.service.js +1 -1
  168. package/dist/services/crud.service.js.map +1 -1
  169. package/dist/services/dashboard-layout.service.d.ts +20 -0
  170. package/dist/services/dashboard-layout.service.d.ts.map +1 -0
  171. package/dist/services/dashboard-layout.service.js +120 -0
  172. package/dist/services/dashboard-layout.service.js.map +1 -0
  173. package/dist/services/dashboard.service.d.ts +2 -0
  174. package/dist/services/dashboard.service.d.ts.map +1 -1
  175. package/dist/services/dashboard.service.js +4 -0
  176. package/dist/services/dashboard.service.js.map +1 -1
  177. package/dist/services/model-metadata.service.d.ts +3 -1
  178. package/dist/services/model-metadata.service.d.ts.map +1 -1
  179. package/dist/services/model-metadata.service.js +21 -2
  180. package/dist/services/model-metadata.service.js.map +1 -1
  181. package/dist/services/permission-metadata.service.d.ts +5 -1
  182. package/dist/services/permission-metadata.service.d.ts.map +1 -1
  183. package/dist/services/permission-metadata.service.js +66 -20
  184. package/dist/services/permission-metadata.service.js.map +1 -1
  185. package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
  186. package/dist/services/queues/database-subscriber.service.js +6 -1
  187. package/dist/services/queues/database-subscriber.service.js.map +1 -1
  188. package/dist/services/queues/publisher-factory.service.js +0 -1
  189. package/dist/services/queues/publisher-factory.service.js.map +1 -1
  190. package/dist/services/queues/rabbitmq-publisher.service.d.ts +1 -0
  191. package/dist/services/queues/rabbitmq-publisher.service.d.ts.map +1 -1
  192. package/dist/services/queues/rabbitmq-publisher.service.js +6 -1
  193. package/dist/services/queues/rabbitmq-publisher.service.js.map +1 -1
  194. package/dist/services/queues/rabbitmq-subscriber.service.d.ts +5 -1
  195. package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
  196. package/dist/services/queues/rabbitmq-subscriber.service.js +84 -9
  197. package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
  198. package/dist/services/request-context.service.d.ts +2 -1
  199. package/dist/services/request-context.service.d.ts.map +1 -1
  200. package/dist/services/request-context.service.js.map +1 -1
  201. package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
  202. package/dist/services/scheduled-jobs/scheduler.service.js +20 -2
  203. package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
  204. package/dist/services/solid-introspect.service.d.ts +6 -1
  205. package/dist/services/solid-introspect.service.d.ts.map +1 -1
  206. package/dist/services/solid-introspect.service.js +27 -2
  207. package/dist/services/solid-introspect.service.js.map +1 -1
  208. package/dist/services/solid-ts-morph.service.d.ts +9 -0
  209. package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
  210. package/dist/services/solid-ts-morph.service.js +76 -0
  211. package/dist/services/solid-ts-morph.service.js.map +1 -1
  212. package/dist/solid-core.module.d.ts.map +1 -1
  213. package/dist/solid-core.module.js +16 -0
  214. package/dist/solid-core.module.js.map +1 -1
  215. package/dist/subscribers/audit.subscriber.d.ts +10 -7
  216. package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
  217. package/dist/subscribers/audit.subscriber.js +58 -85
  218. package/dist/subscribers/audit.subscriber.js.map +1 -1
  219. package/dist/subscribers/computed-entity-field.subscriber.js +3 -1
  220. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  221. package/dist/subscribers/created-by-updated-by.subscriber.d.ts +0 -1
  222. package/dist/subscribers/created-by-updated-by.subscriber.d.ts.map +1 -1
  223. package/dist/subscribers/created-by-updated-by.subscriber.js +3 -13
  224. package/dist/subscribers/created-by-updated-by.subscriber.js.map +1 -1
  225. package/dist/winston.logger.d.ts.map +1 -1
  226. package/dist/winston.logger.js +2 -1
  227. package/dist/winston.logger.js.map +1 -1
  228. package/package.json +3 -1
  229. package/sql/default/mariadb/proc_CleanupModelMetadata.sql +153 -0
  230. package/sql/default/mariadb/proc_CleanupModuleMetadata.sql +56 -0
  231. package/sql/default/mysql/proc_CleanupModelMetadata.sql +153 -0
  232. package/sql/default/mysql/proc_CleanupModuleMetadata.sql +56 -0
  233. package/src/controllers/dashboard-layout.controller.ts +106 -0
  234. package/src/dtos/create-dashboard-layout.dto.ts +31 -0
  235. package/src/dtos/create-dashboard-variable.dto.ts +4 -0
  236. package/src/dtos/update-dashboard-layout.dto.ts +30 -0
  237. package/src/dtos/update-dashboard-variable.dto.ts +5 -1
  238. package/src/entities/action-metadata.entity.ts +3 -2
  239. package/src/entities/ai-interaction.entity.ts +5 -4
  240. package/src/entities/chatter-message-details.entity.ts +4 -3
  241. package/src/entities/chatter-message.entity.ts +4 -3
  242. package/src/entities/dashboard-layout.entity.ts +18 -0
  243. package/src/entities/dashboard-question-sql-dataset-config.entity.ts +5 -4
  244. package/src/entities/dashboard-question.entity.ts +5 -4
  245. package/src/entities/dashboard-variable.entity.ts +9 -4
  246. package/src/entities/dashboard.entity.ts +7 -2
  247. package/src/entities/email-attachment.entity.ts +2 -1
  248. package/src/entities/email-template.entity.ts +1 -1
  249. package/src/entities/export-transaction.entity.ts +2 -1
  250. package/src/entities/field-metadata.entity.ts +2 -2
  251. package/src/entities/import-transaction-error-log.entity.ts +3 -2
  252. package/src/entities/import-transaction.entity.ts +2 -1
  253. package/src/entities/mq-message-queue.entity.ts +8 -8
  254. package/src/entities/mq-message.entity.ts +5 -3
  255. package/src/entities/saved-filters.entity.ts +3 -2
  256. package/src/entities/security-rule.entity.ts +2 -1
  257. package/src/entities/sms-template.entity.ts +1 -1
  258. package/src/entities/user-view-metadata.entity.ts +2 -1
  259. package/src/entities/user.entity.ts +37 -2
  260. package/src/entities/view-metadata.entity.ts +3 -0
  261. package/src/helpers/bootstrap.helper.ts +222 -0
  262. package/src/helpers/cache.helper.ts +5 -0
  263. package/src/helpers/cors.helper.ts +26 -6
  264. package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +9 -9
  265. package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +9 -6
  266. package/src/helpers/solid-registry.ts +10 -5
  267. package/src/helpers/typeorm-db-helper.ts +26 -0
  268. package/src/index.ts +3 -0
  269. package/src/interfaces.ts +3 -0
  270. package/src/jobs/chatter-queue-options.ts +1 -1
  271. package/src/jobs/chatter-queue-publisher.service.ts +11 -11
  272. package/src/jobs/chatter-queue-subscriber.service.ts +13 -8
  273. package/src/jobs/computed-field-evaluation-queue-options.ts +2 -0
  274. package/src/jobs/database/chatter-queue-options-database.ts +9 -0
  275. package/src/jobs/database/chatter-queue-publisher-database.service.ts +24 -0
  276. package/src/jobs/database/chatter-queue-subscriber-database.service.ts +53 -0
  277. package/src/repository/dashboard-layout.repository.ts +17 -0
  278. package/src/repository/model-metadata.repository.ts +45 -2
  279. package/src/seeders/module-metadata-seeder.service.ts +5 -5
  280. package/src/seeders/seed-data/solid-core-metadata.json +373 -33
  281. package/src/services/1.js +6 -0
  282. package/src/services/chatter-message.service.ts +41 -9
  283. package/src/services/computed-fields/entity/sequence-num-computed-field-provider.ts +79 -40
  284. package/src/services/crud.service.ts +1 -1
  285. package/src/services/dashboard-layout.service.ts +111 -0
  286. package/src/services/dashboard.service.ts +7 -0
  287. package/src/services/model-metadata.service.ts +22 -43
  288. package/src/services/permission-metadata.service.ts +73 -20
  289. package/src/services/queues/database-subscriber.service.ts +7 -1
  290. package/src/services/queues/publisher-factory.service.ts +1 -1
  291. package/src/services/queues/rabbitmq-publisher.service.ts +8 -2
  292. package/src/services/queues/rabbitmq-subscriber.service.ts +127 -10
  293. package/src/services/request-context.service.ts +2 -1
  294. package/src/services/scheduled-jobs/scheduler.service.ts +22 -4
  295. package/src/services/solid-introspect.service.ts +28 -0
  296. package/src/services/solid-ts-morph.service.ts +98 -0
  297. package/src/solid-core.module.ts +21 -2
  298. package/src/subscribers/audit.subscriber.ts +63 -271
  299. package/src/subscribers/computed-entity-field.subscriber.ts +3 -3
  300. package/src/subscribers/created-by-updated-by.subscriber.ts +22 -16
  301. package/src/winston.logger.ts +2 -1
  302. package/dist-tests/api/authenticate.spec.js +0 -119
  303. package/dist-tests/api/authenticate.spec.js.map +0 -1
  304. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +0 -97
  305. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +0 -1
  306. package/dist-tests/api/ping.spec.js +0 -21
  307. package/dist-tests/api/ping.spec.js.map +0 -1
  308. package/dist-tests/helpers/auth.js +0 -41
  309. package/dist-tests/helpers/auth.js.map +0 -1
  310. package/dist-tests/helpers/env.js +0 -11
  311. package/dist-tests/helpers/env.js.map +0 -1
@@ -1,20 +1,28 @@
1
+ import { classify } from "@angular-devkit/core/src/utils/strings";
1
2
  import { Injectable } from "@nestjs/common";
2
3
  import { InjectDataSource } from "@nestjs/typeorm";
4
+ import { ComputedFieldTriggerOperation } from "src/dtos/create-field-metadata.dto";
3
5
  import { ComputedFieldProvider } from "src/decorators/computed-field-provider.decorator";
4
6
  import { CommonEntity } from "src/entities/common.entity";
5
7
  import { ModelSequence } from "src/entities/model-sequence.entity";
6
8
  import { ComputedFieldMetadata } from "src/helpers/solid-registry";
7
- import { IEntityPreComputeFieldProvider } from "src/interfaces";
8
- import { DataSource, EntityTarget } from "typeorm";
9
+ import { IEntityPostComputeFieldProvider } from "src/interfaces";
10
+ import { DataSource, EntityManager } from "typeorm";
9
11
 
10
12
 
11
13
  export interface SequenceNumComputedFieldContext {
12
- sequenceName: string; // The separator to use between concatenated values
14
+ sequenceName: string;
15
+ /**
16
+ * - `'counter'` (default): increments the sequence's `currentValue` and uses it as the number.
17
+ * - `'entityId'`: uses the entity's own `id` as the number; does not update the counter.
18
+ * Only valid on `afterInsert` events.
19
+ */
20
+ mode?: 'counter' | 'entityId';
13
21
  }
14
22
 
15
23
  @ComputedFieldProvider()
16
24
  @Injectable()
17
- export class SequenceNumComputedFieldProvider<T extends CommonEntity> implements IEntityPreComputeFieldProvider<T, SequenceNumComputedFieldContext> {
25
+ export class SequenceNumComputedFieldProvider<T extends CommonEntity> implements IEntityPostComputeFieldProvider<T, SequenceNumComputedFieldContext> {
18
26
  constructor(
19
27
  @InjectDataSource()
20
28
  private readonly dataSource: DataSource
@@ -25,23 +33,21 @@ export class SequenceNumComputedFieldProvider<T extends CommonEntity> implements
25
33
  }
26
34
 
27
35
  help(): string {
28
- return "Computed field provider used to create fields whose value is based on some prefix, padding & sequence number.";
36
+ return "Computed field provider used to create fields whose value is based on some prefix, padding & sequence number. " +
37
+ "Use mode='counter' (default) to auto-increment the sequence's currentValue. " +
38
+ "Use mode='entityId' to use the entity's own id as the number (afterInsert only, does not update the counter).";
29
39
  }
30
40
 
31
- async preComputeValue(triggerEntity: T, computedFieldMetadata: ComputedFieldMetadata<SequenceNumComputedFieldContext>) {
32
- const { sequenceName } =
33
- computedFieldMetadata.computedFieldValueProviderCtxt ?? {};
34
-
35
- if (!sequenceName) {
36
- throw new Error("sequenceName is required for sequence computation");
37
- }
41
+ private buildSequenceString(modelSequence: ModelSequence, numericValue: number): string {
42
+ const prefix = modelSequence.prefix ?? "";
43
+ const separator = modelSequence.separator ?? "";
44
+ const padded = String(numericValue).padStart(modelSequence.padding ?? 5, "0");
45
+ return `${prefix}${separator}${padded}`;
46
+ }
38
47
 
39
- await this.dataSource.transaction(async (manager) => {
40
- /**
41
- * 1️⃣ Lock sequence row (prevents race conditions)
42
- */
43
- // 1️⃣ Fetch sequence row
44
- const modelSequenceRepo = manager.getRepository(ModelSequence)
48
+ private async generateCounterSequenceValue(sequenceName: string, manager?: EntityManager): Promise<{ sequenceString: string; currentValue: number; modelSingularName: string }> {
49
+ const run = async (mgr: EntityManager) => {
50
+ const modelSequenceRepo = mgr.getRepository(ModelSequence);
45
51
  const modelSequence = await modelSequenceRepo.findOne({
46
52
  where: { sequenceName },
47
53
  lock: { mode: "pessimistic_write" }
@@ -51,36 +57,69 @@ export class SequenceNumComputedFieldProvider<T extends CommonEntity> implements
51
57
  throw new Error(`ModelSequence not found for ${sequenceName}`);
52
58
  }
53
59
 
54
- // 2️⃣ Generate next sequence value
55
60
  const nextValue = modelSequence.currentValue + 1;
61
+ const sequenceString = this.buildSequenceString(modelSequence, nextValue);
56
62
 
57
- const paddedValue = String(nextValue).padStart(modelSequence.padding ?? 5, "0");
63
+ modelSequence.currentValue = nextValue;
64
+ await modelSequenceRepo.save(modelSequence);
58
65
 
59
- const prefix = modelSequence.prefix ?? "";
60
- const separator = modelSequence.separator ?? "";
66
+ // Load model relation in a separate query to avoid FOR UPDATE on joined relation.
67
+ const modelSequenceWithModel = await modelSequenceRepo.findOne({
68
+ where: { id: modelSequence.id },
69
+ relations: { model: true },
70
+ });
71
+ const modelSingularName = modelSequenceWithModel?.model?.singularName;
72
+ if (!modelSingularName) {
73
+ throw new Error(`Model singularName not found for sequence ${sequenceName}`);
74
+ }
61
75
 
62
- const sequenceString = `${prefix}${separator}${paddedValue}`;
76
+ return { sequenceString, currentValue: nextValue, modelSingularName };
77
+ };
63
78
 
64
- // 3️⃣ Duplicate check on TARGET ENTITY (extra safety)
65
- const entityRepo = manager.getRepository(triggerEntity.constructor as any);
79
+ return manager ? run(manager) : this.dataSource.transaction(run);
80
+ }
66
81
 
67
- const existing = await entityRepo.findOne({
68
- where: {
69
- [computedFieldMetadata.fieldName]: sequenceString,
70
- },
71
- });
82
+ private async generateEntityIdSequenceValue(sequenceName: string, entityId: number): Promise<{ sequenceString: string; modelSingularName: string }> {
83
+ const modelSequenceRepo = this.dataSource.manager.getRepository(ModelSequence);
84
+ const modelSequence = await modelSequenceRepo.findOne({
85
+ where: { sequenceName },
86
+ relations: { model: true },
87
+ });
72
88
 
73
- if (existing) {
74
- throw new Error(`Duplicate Sequence generated: ${sequenceString}`);
75
- }
89
+ if (!modelSequence) {
90
+ throw new Error(`ModelSequence not found for ${sequenceName}`);
91
+ }
76
92
 
77
- // 4️⃣ set the computed field on the entity
78
- (triggerEntity as any)[computedFieldMetadata.fieldName] = sequenceString;
93
+ const modelSingularName = modelSequence.model?.singularName;
94
+ if (!modelSingularName) {
95
+ throw new Error(`Model singularName not found for sequence ${sequenceName}`);
96
+ }
79
97
 
80
- // 5️⃣ Persist updated sequence current value
81
- modelSequence.currentValue = nextValue;
82
- await modelSequenceRepo.save(modelSequence);
83
- });
98
+ return { sequenceString: this.buildSequenceString(modelSequence, entityId), modelSingularName };
84
99
  }
85
100
 
86
- }
101
+ async postComputeAndSaveValue(triggerEntity: T, computedFieldMetadata: ComputedFieldMetadata<SequenceNumComputedFieldContext>): Promise<void> {
102
+ const { sequenceName, mode = 'counter' } = computedFieldMetadata.computedFieldValueProviderCtxt ?? {};
103
+
104
+ if (!sequenceName) {
105
+ throw new Error("sequenceName is required for sequence computation");
106
+ }
107
+
108
+ let sequenceString: string;
109
+ let modelSingularName: string;
110
+
111
+ if (mode === 'entityId') {
112
+ const eventType = computedFieldMetadata.eventContext?.eventType;
113
+ if (eventType !== ComputedFieldTriggerOperation.afterInsert) {
114
+ throw new Error(`SequenceNumComputedFieldProvider with mode='entityId' only supports "${ComputedFieldTriggerOperation.afterInsert}" events, but received "${eventType}"`);
115
+ }
116
+ ({ sequenceString, modelSingularName } = await this.generateEntityIdSequenceValue(sequenceName, triggerEntity.id));
117
+ } else {
118
+ ({ sequenceString, modelSingularName } = await this.generateCounterSequenceValue(sequenceName));
119
+ }
120
+
121
+ const entityName = classify(modelSingularName);
122
+ const entityRepo = this.dataSource.manager.getRepository(entityName);
123
+ await entityRepo.update(triggerEntity.id, { [computedFieldMetadata.fieldName]: sequenceString });
124
+ }
125
+ }
@@ -432,7 +432,7 @@ export class CRUDService<T extends CommonEntity> { // Add two generic value i.e
432
432
  // dataSource: string; // The name of the selection provider
433
433
  // filterSchema : json // This is a custom json object that every data source will handle accordingly. We could validate the query against the selection provider
434
434
  // values : string[]; // The values returned by the selection provider
435
- const options = { ...commonOptions, selectionDynamicProvider: fieldMetadata.selectionDynamicProvider, selectionDynamicProviderCtxt: fieldMetadata.selectionDynamicProviderCtxt, selectionValueType: fieldMetadata.selectionValueType as SelectionValueType, discoveryService: this.discoveryService, isMultiSelect: fieldMetadata.isMultiSelect };
435
+ const options = { ...commonOptions, selectionDynamicProvider: fieldMetadata.selectionDynamicProvider, selectionDynamicProviderCtxt: JSON.parse(fieldMetadata.selectionDynamicProviderCtxt), selectionValueType: fieldMetadata.selectionValueType as SelectionValueType, discoveryService: this.discoveryService, isMultiSelect: fieldMetadata.isMultiSelect };
436
436
  return new SelectionDynamicFieldCrudManager(options);
437
437
  }
438
438
  case SolidFieldType.uuid: {
@@ -0,0 +1,111 @@
1
+ import { Injectable, Logger } from '@nestjs/common';
2
+ import { ModuleRef } from "@nestjs/core";
3
+ import { InjectEntityManager } from '@nestjs/typeorm';
4
+ import { EntityManager } from 'typeorm';
5
+
6
+ import { CRUDService } from 'src/services/crud.service';
7
+ import { DashboardLayout } from 'src/entities/dashboard-layout.entity';
8
+ import { DashboardLayoutRepository } from 'src/repository/dashboard-layout.repository';
9
+ import { CreateDashboardLayoutDto } from 'src/dtos/create-dashboard-layout.dto';
10
+ import { RequestContextService } from './request-context.service';
11
+
12
+
13
+ @Injectable()
14
+ export class DashboardLayoutService extends CRUDService<DashboardLayout> {
15
+ private readonly logger = new Logger(this.constructor.name);
16
+ constructor(
17
+ @InjectEntityManager()
18
+ readonly entityManager: EntityManager,
19
+ readonly repo: DashboardLayoutRepository,
20
+ readonly requestContextService: RequestContextService,
21
+ readonly moduleRef: ModuleRef,
22
+ ) {
23
+ super(entityManager, repo, 'dashboardLayout', 'solid-core', moduleRef);
24
+ }
25
+
26
+ async upsertUserDashboardLayout(createDtos: CreateDashboardLayoutDto) {
27
+ const activeUser = this.requestContextService.getActiveUser();
28
+
29
+ if (!activeUser) {
30
+ throw new Error('User not found');
31
+ }
32
+
33
+ let userId = null;
34
+ if (activeUser.roles.includes('Admin')) {
35
+ userId = null;
36
+ } else {
37
+ userId = activeUser?.sub;
38
+ }
39
+ const existingLayout = await this.repo.findOne({
40
+ where: {
41
+ user: { id: userId },
42
+ dashboard: {
43
+ id: createDtos.dashboardId
44
+ }
45
+ },
46
+ relations: {
47
+ user: true,
48
+ dashboard: true,
49
+ }
50
+ });
51
+
52
+ if (existingLayout) {
53
+ return super.update(existingLayout.id, { layout: createDtos.layout }, [], true);
54
+ } else {
55
+ const createDto = {
56
+ layout: createDtos.layout,
57
+ dashboardId: createDtos.dashboardId,
58
+ uesrId: userId
59
+ }
60
+ return super.create(createDto, []);
61
+ }
62
+ }
63
+
64
+ async getUserDashboardLayoutByDashboardId(dashboardId: any) {
65
+ const activeUser = this.requestContextService.getActiveUser();
66
+
67
+ if (!activeUser) {
68
+ throw new Error('User not found');
69
+ }
70
+ const userId = activeUser?.sub;
71
+ const existingUserLayout = await this.repo.findOne({
72
+ where: {
73
+ user: { id: userId },
74
+ dashboard: {
75
+ id: dashboardId
76
+ }
77
+ },
78
+ relations: {
79
+ user: true,
80
+ dashboard: true,
81
+ }
82
+ });
83
+ if (existingUserLayout) {
84
+ // if dahsboard for userid exists
85
+ return existingUserLayout;
86
+ }
87
+
88
+ // if not then check for default dashboard
89
+ const defaultLayout = await this.repo.findOne({
90
+ where: {
91
+ user: { id: null },
92
+ dashboard: {
93
+ id: dashboardId
94
+ }
95
+ },
96
+ relations: {
97
+ user: true,
98
+ dashboard: true,
99
+ }
100
+ });
101
+ if (defaultLayout) {
102
+ // if default layout exists return it
103
+ return defaultLayout;
104
+ } else {
105
+ // if default layout does not exist return empty layout
106
+ return {
107
+ layout: null
108
+ }
109
+ }
110
+ }
111
+ }
@@ -15,6 +15,7 @@ import { SolidRegistry } from 'src/helpers/solid-registry';
15
15
  import { DashboardMapper } from 'src/mappers/dashboard-mapper';
16
16
  import { DashboardRepository } from 'src/repository/dashboard.repository';
17
17
  import { Dashboard } from '../entities/dashboard.entity';
18
+ import { CreateDashboardDto } from 'src/dtos/create-dashboard.dto';
18
19
 
19
20
 
20
21
  export const SQL_DYNAMIC_PROVIDER_NAME = 'DashboardVariableSQLDynamicProvider';
@@ -33,6 +34,12 @@ export class DashboardService extends CRUDService<Dashboard> {
33
34
  super(entityManager, repo, 'dashboard', 'solid-core', moduleRef);
34
35
  }
35
36
 
37
+
38
+ async create(createDto: CreateDashboardDto, files: Express.Multer.File[]) {
39
+ createDto.name = createDto.name.trim().replace(/\s+/g, '-').toLowerCase();
40
+ return super.create(createDto, files);
41
+ }
42
+
36
43
  async getSelectionDynamicValues(query: DashboardVariableSelectionDynamicQueryDto) {
37
44
  // Get the dashboard variable repo
38
45
  const dashboardVariable = await this.loadDashboardVariable(query.variableId);
@@ -1,6 +1,7 @@
1
1
  import { BadRequestException, forwardRef, Inject, Injectable, Logger, NotFoundException } from '@nestjs/common';
2
2
  import { InjectDataSource } from '@nestjs/typeorm';
3
3
  import * as fs from 'fs/promises'; // Use the Promise-based version of fs for async/await
4
+ import * as path from 'path';
4
5
  import { DataSource, EntityManager, In, Repository, SelectQueryBuilder } from 'typeorm';
5
6
  import { CreateModelMetadataDto } from '../dtos/create-model-metadata.dto';
6
7
  import { ModelMetadata } from '../entities/model-metadata.entity';
@@ -33,6 +34,7 @@ import { RoleMetadataService } from './role-metadata.service';
33
34
  import { NavigationDto } from 'src/dtos/navigation.dto';
34
35
  import { SolidIntrospectService } from './solid-introspect.service';
35
36
  import { CRUDService } from './crud.service';
37
+ import { SolidTsMorphService } from './solid-ts-morph.service';
36
38
 
37
39
  @Injectable()
38
40
  export class ModelMetadataService {
@@ -54,8 +56,9 @@ export class ModelMetadataService {
54
56
  private readonly roleService: RoleMetadataService,
55
57
  private readonly moduleMetadataHelperService: ModuleMetadataHelperService,
56
58
  readonly introspectService: SolidIntrospectService,
59
+ private readonly solidTsMorphService: SolidTsMorphService,
57
60
 
58
- // No longer used.
61
+ // No longer used.
59
62
  // private readonly generateCodePublihser: GenerateCodePublisherDatabase,
60
63
  ) { }
61
64
 
@@ -707,48 +710,24 @@ export class ModelMetadataService {
707
710
  await fs.writeFile(filePath, updatedContent);
708
711
  }
709
712
 
710
- // <moduleName>.module.ts | Remove all references and imports of the above files. | Manual (X)
711
- // const moduleFilePath = path.resolve(modulePath, `${dasherize(modelEntity.module.name)}.module.ts`);
712
-
713
- // this.logger.log(`Working on module file ${moduleFilePath}`);
714
- // const project = new Project();
715
- // const sourceFile = project.addSourceFileAtPath(moduleFilePath);
716
-
717
- // // Remove import declarations related to deleted files
718
- // sourceFile.getImportDeclarations().forEach(importDecl => {
719
- // const moduleSpecifier = importDecl.getModuleSpecifierValue();
720
- // const resolvedPath = importDecl.getModuleSpecifierSourceFile()?.getFilePath() || '';
721
- // if (filesToDelete.some(file => resolvedPath.endsWith(file))) {
722
- // importDecl.remove();
723
- // }
724
- // });
725
-
726
- // // Remove identifiers from `@Module` metadata (imports, providers, controllers)
727
- // const moduleDecorator = sourceFile.getFirstDescendantByKind(SyntaxKind.Decorator);
728
- // const objectLiteral = moduleDecorator?.getCallExpression()?.getArguments()?.[0];
729
-
730
- // if (objectLiteral && objectLiteral.getKind() === SyntaxKind.ObjectLiteralExpression) {
731
- // const objectLiteralExpr = objectLiteral.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
732
-
733
- // for (const propName of ['imports', 'providers', 'controllers', 'exports']) {
734
- // const prop = objectLiteralExpr.getProperty(propName);
735
- // if (prop && prop.getKind() === SyntaxKind.PropertyAssignment) {
736
- // const elements = prop.getFirstDescendantByKind(SyntaxKind.ArrayLiteralExpression);
737
- // elements?.getElements().forEach(el => {
738
- // const text = el.getText();
739
- // if (filesToDelete.some(file => text.toLowerCase().includes(file.split('.')[0]))) {
740
- // // @ts-ignore
741
- // el.remove();
742
- // }
743
- // });
744
- // }
745
- // }
746
- // }
747
-
748
- // // Save changes
749
- // sourceFile.saveSync();
750
-
751
- // Run seeder to reflect the removal.
713
+ // <moduleName>.module.ts | Remove all references and imports of the deleted model files. | Automatic
714
+ if (modulePath) {
715
+ const moduleFilePath = path.resolve(modulePath, `${dasherize(modelEntity.module?.name)}.module.ts`);
716
+ this.logger.log(`Removing model '${modelEntity.singularName}' references from module file: ${moduleFilePath}`);
717
+ try {
718
+ this.solidTsMorphService.begin();
719
+ const modelPathSegment = `/${dasherize(modelEntity.singularName)}.`;
720
+ const { removedIdentifiers } = this.solidTsMorphService.removeImports(
721
+ moduleFilePath,
722
+ spec => spec.includes(modelPathSegment)
723
+ );
724
+ this.solidTsMorphService.removeModuleMembers(moduleFilePath, removedIdentifiers);
725
+ await this.solidTsMorphService.commit();
726
+ } catch (error) {
727
+ this.solidTsMorphService.rollback();
728
+ this.logger.error(`Failed to clean up module file for model '${modelEntity.singularName}':`, error);
729
+ }
730
+ }
752
731
 
753
732
  // - | Drop database table | Removes the database table from the DB, this is a very risky step. Best to review all relations to other models etc and then do this manually | Manual (X)
754
733
 
@@ -1,7 +1,10 @@
1
- import { Injectable } from '@nestjs/common';
1
+ import { Inject, Injectable, Logger } from '@nestjs/common';
2
+ import { CACHE_MANAGER } from '@nestjs/cache-manager';
2
3
  import { ModuleRef } from "@nestjs/core";
3
4
  import { InjectEntityManager } from '@nestjs/typeorm';
5
+ import { Cache } from 'cache-manager';
4
6
  import { CRUDService } from 'src/services/crud.service';
7
+ import { shouldUseCache } from 'src/helpers/cache.helper';
5
8
  import { EntityManager, In } from 'typeorm';
6
9
 
7
10
 
@@ -10,42 +13,92 @@ import { PermissionMetadata } from '../entities/permission-metadata.entity';
10
13
 
11
14
  @Injectable()
12
15
  export class PermissionMetadataService extends CRUDService<PermissionMetadata> {
16
+ private readonly logger = new Logger(PermissionMetadataService.name);
13
17
  constructor(
14
18
  @InjectEntityManager()
15
19
  readonly entityManager: EntityManager,
16
20
  // @InjectRepository(PermissionMetadata, 'default')
17
21
  // readonly repo: Repository<PermissionMetadata>,
18
22
  readonly repo: PermissionMetadataRepository,
19
- readonly moduleRef: ModuleRef
20
-
23
+ readonly moduleRef: ModuleRef,
24
+ @Inject(CACHE_MANAGER) private readonly cacheManager: Cache,
21
25
  ) {
22
26
  super(entityManager, repo, 'permissionMetadata', 'solid-core',moduleRef);
23
27
  }
24
28
 
29
+ private buildPermissionsByRoleCacheKey(roleName: string): string {
30
+ return `permissions:role:${roleName}`;
31
+ }
32
+
33
+ async findAllUsingRoles(roles: string[]): Promise<PermissionMetadata[]> {
34
+ const useCache = shouldUseCache();
35
+ const cached: PermissionMetadata[] = [];
36
+ const uncachedRoles: string[] = [];
25
37
 
26
- findAllUsingRoles(roles: string[]) {
27
- return this.repo.find({
28
- where: {
29
- roles: {
30
- name: In(roles)
38
+ if (useCache) {
39
+ for (const role of roles) {
40
+ const cacheKey = this.buildPermissionsByRoleCacheKey(role);
41
+ const hit = await this.cacheManager.get<PermissionMetadata[]>(cacheKey);
42
+ if (hit) {
43
+ // this.logger.debug(`Cache hit for findAllUsingRoles: key=${cacheKey}`);
44
+ cached.push(...hit);
45
+ } else {
46
+ // this.logger.debug(`Cache miss for findAllUsingRoles: key=${cacheKey}`);
47
+ uncachedRoles.push(role);
31
48
  }
32
- },
33
- relations: {}
49
+ }
50
+ } else {
51
+ uncachedRoles.push(...roles);
52
+ }
53
+
54
+ if (uncachedRoles.length === 0) {
55
+ return cached;
56
+ }
57
+
58
+ const fromDb = await this.repo.find({
59
+ where: { roles: { name: In(uncachedRoles) } },
60
+ relations: { roles: true },
61
+ });
62
+
63
+ if (useCache) {
64
+ for (const role of uncachedRoles) {
65
+ const permsForRole = fromDb.filter(p => p.roles?.some(r => r.name === role));
66
+ await this.cacheManager.set(this.buildPermissionsByRoleCacheKey(role), permsForRole);
67
+ }
68
+ }
69
+
70
+ const seen = new Set<number>();
71
+ return [...cached, ...fromDb].filter(p => {
72
+ if (seen.has(p.id)) return false;
73
+ seen.add(p.id);
74
+ return true;
34
75
  });
35
76
  }
36
77
 
37
- permissionExistsInRole(role: string, permission: string,) {
38
- return this.repo.find({
39
- where: {
40
- name: permission,
41
- roles: {
42
- name: role
43
- }
44
- },
45
- relations: {}
78
+ async permissionExistsInRole(role: string, permission: string): Promise<PermissionMetadata[]> {
79
+ const useCache = shouldUseCache();
80
+ const cacheKey = this.buildPermissionsByRoleCacheKey(role);
81
+
82
+ if (useCache) {
83
+ const hit = await this.cacheManager.get<PermissionMetadata[]>(cacheKey);
84
+ if (hit) {
85
+ // this.logger.debug(`Cache hit for permissionExistsInRole: key=${cacheKey}`);
86
+ return hit.filter(p => p.name === permission);
87
+ }
88
+ // this.logger.debug(`Cache miss for permissionExistsInRole: key=${cacheKey}`);
89
+ }
90
+
91
+ const fromDb = await this.repo.find({
92
+ where: { roles: { name: role } },
93
+ relations: { roles: true },
46
94
  });
95
+
96
+ if (useCache) {
97
+ await this.cacheManager.set(cacheKey, fromDb);
98
+ }
99
+
100
+ return fromDb.filter(p => p.name === permission);
47
101
  }
48
102
 
49
103
  }
50
104
 
51
-
@@ -89,9 +89,15 @@ export abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscr
89
89
  const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'database';
90
90
  const solidCliRunning = process.env.SOLID_CLI_RUNNING || "false";
91
91
  const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();
92
+ const roleAllowed = ['both', 'subscriber'].includes(this.serviceRole);
93
+
94
+ if (!roleAllowed) {
95
+ this.logger.log(`DatabaseSubscriber is disabled because QUEUES_SERVICE_ROLE is "${this.serviceRole}". Expected "both" or "subscriber".`);
96
+ return;
97
+ }
92
98
 
93
99
  // we will start subscriber only if the current service role is subscriber.
94
- if (['both', 'subscriber'].includes(this.serviceRole) && defaultBroker === 'database' && solidCliRunning === "false") {
100
+ if (defaultBroker === 'database' && solidCliRunning === "false") {
95
101
  const options = this.options();
96
102
  const queueName = options.queueName;
97
103
 
@@ -37,7 +37,7 @@ export class PublisherFactory<T> {
37
37
 
38
38
  // type safe
39
39
  const typedActualPublisher: QueuePublisher<T> = actualPublisherToUse.instance;
40
- this.logger.debug(`Resolved publisher with name ${actualPublisherToUse.name}, and with options: ${JSON.stringify(typedActualPublisher.options())}`);
40
+ // this.logger.debug(`Resolved publisher with name ${actualPublisherToUse.name}, and with options: ${JSON.stringify(typedActualPublisher.options())}`);
41
41
 
42
42
  return typedActualPublisher.publish(message);
43
43
  }
@@ -34,6 +34,10 @@ export abstract class RabbitMqPublisher<T> implements OnModuleDestroy, QueuePubl
34
34
 
35
35
  abstract options(): QueuesModuleOptions;
36
36
 
37
+ protected shouldPersistToDatabase(): boolean {
38
+ return this.options().persistToDatabase ?? true;
39
+ }
40
+
37
41
  private async ensureConnectionAndChannel(): Promise<amqp.Channel> {
38
42
  if (this.channel) {
39
43
  return this.channel;
@@ -170,7 +174,9 @@ export abstract class RabbitMqPublisher<T> implements OnModuleDestroy, QueuePubl
170
174
  message.messageId = uuidv4();
171
175
 
172
176
  // Save the message to the DB so that we can then change its status in the subscriber...
173
- await this.persistToDatabase(namespacedQueueName, message);
177
+ if (this.shouldPersistToDatabase()) {
178
+ await this.persistToDatabase(namespacedQueueName, message);
179
+ }
174
180
 
175
181
  // wait for the channel to confirm
176
182
  try {
@@ -199,7 +205,7 @@ export abstract class RabbitMqPublisher<T> implements OnModuleDestroy, QueuePubl
199
205
 
200
206
  private async persistToDatabase(queueName: string, message: QueueMessage<T>) {
201
207
 
202
- // TODO: make an entry in the relevant database table, generate a unique id earlier.
208
+ // make an entry in the relevant database table, generate a unique id earlier.
203
209
  try {
204
210
  // 1. resolve the queue first
205
211
  const mqMessageQueue = await this.mqMessageQueueService.resolveQueue(queueName);