@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
@@ -6,6 +6,17 @@ import { MqMessageQueueService } from '../mq-message-queue.service';
6
6
  import { MqMessageService } from '../mq-message.service';
7
7
  import { buildNamespacedQueueName } from './common';
8
8
 
9
+ class ConsumerProcessingTimeoutError extends Error {
10
+ constructor(
11
+ readonly queueName: string,
12
+ readonly messageId: string,
13
+ readonly timeoutMs: number,
14
+ ) {
15
+ super(`Subscriber processing timed out after ${timeoutMs}ms for queue ${queueName} and messageId ${messageId}`);
16
+ this.name = 'ConsumerProcessingTimeoutError';
17
+ }
18
+ }
19
+
9
20
 
10
21
  export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscriber<T> { // TODO This can be made a generic type for better type visibility
11
22
  private _loggerInstance?: Logger;
@@ -45,6 +56,10 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
45
56
 
46
57
  abstract options(): QueuesModuleOptions;
47
58
 
59
+ protected shouldPersistToDatabase(): boolean {
60
+ return this.options().persistToDatabase ?? true;
61
+ }
62
+
48
63
  async establishConnection(): Promise<amqp.Connection> {
49
64
 
50
65
  const url = new URL(this.url);
@@ -73,9 +88,15 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
73
88
  const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'rabbitmq';
74
89
  const solidCliRunning = process.env.SOLID_CLI_RUNNING || "false";
75
90
  const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();
91
+ const roleAllowed = ['both', 'subscriber'].includes(this.serviceRole);
92
+
93
+ if (!roleAllowed) {
94
+ this.logger.log(`RabbitMqSubscriber is disabled because QUEUES_SERVICE_ROLE is "${this.serviceRole}". Expected "both" or "subscriber".`);
95
+ return;
96
+ }
76
97
 
77
98
  // we will start subscriber only if the current service role is subscriber.
78
- if (this.url && ['both', 'subscriber'].includes(this.serviceRole) && solidCliRunning === "false" && defaultBroker === 'rabbitmq') {
99
+ if (this.url && solidCliRunning === "false" && defaultBroker === 'rabbitmq') {
79
100
  const options = this.options();
80
101
  const queueName = options.queueName;
81
102
 
@@ -113,6 +134,10 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
113
134
  if (prefetch < 1) {
114
135
  throw new Error(`RabbitMqSubscriber prefetch must be >= 1 for queue ${queueName}`);
115
136
  }
137
+ const processingTimeoutMs = this.resolveProcessingTimeoutMs();
138
+ if (processingTimeoutMs > 0) {
139
+ this.logger.log(`RabbitMqSubscriber using processing timeout ${processingTimeoutMs}ms for queue ${queueName}`);
140
+ }
116
141
 
117
142
  let connection: amqp.Connection;
118
143
  try {
@@ -197,7 +222,7 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
197
222
  if (!message.currentRetry) message.currentRetry = 0;
198
223
 
199
224
  try {
200
- await this.processMessage(message, rawMessage, channel);
225
+ await this.processMessage(message, rawMessage, channel, queueName);
201
226
  } catch (error) {
202
227
  await this.handleProcessingError(message, rawMessage, channel, error, queueName);
203
228
  }
@@ -212,10 +237,12 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
212
237
  // Retry flow: update DB -> increment retry -> send to retry queue with per-message expiration -> ack original.
213
238
  private async handleProcessingError(message: QueueMessage<T>, rawMessage: amqp.ConsumeMessage, channel: amqp.Channel, error: any, queueName: string): Promise<void> {
214
239
  const errorMessage = (error as Error)?.message || String(error);
215
- this.logger.error(`Error processing message on queue ${queueName}: ${errorMessage}`);
240
+ this.logger.error(`Error processing message on queue ${queueName}: ${errorMessage}`, (error as Error)?.stack);
216
241
 
217
242
  if (message.currentRetry < message.retryCount) {
218
- await this.updateStatusInDatabase('retrying', message);
243
+ if (this.shouldPersistToDatabase()) {
244
+ await this.updateStatusInDatabase('retrying', message);
245
+ }
219
246
 
220
247
  message.currentRetry++;
221
248
  const retryQueue = `${queueName}.retry`;
@@ -233,8 +260,9 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
233
260
  this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms on queue ${queueName}`);
234
261
  return;
235
262
  }
236
-
237
- await this.updateStatusInDatabase('failed', message, errorMessage, '');
263
+ if (this.shouldPersistToDatabase()) {
264
+ await this.updateStatusInDatabase('failed', message, errorMessage, '');
265
+ }
238
266
  channel.ack(rawMessage);
239
267
  await this.publishToFailedQueue(queueName, Buffer.from(JSON.stringify(message)), channel, error);
240
268
  this.logger.error(`Message failed after ${message.retryCount} attempts on queue ${queueName}: ${errorMessage}`);
@@ -333,17 +361,21 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
333
361
  /**
334
362
  * Abstract method for message processing logic.
335
363
  */
336
- protected async processMessage(message: QueueMessage<T>, rawMessage, channel): Promise<void> {
337
- await this.updateStatusInDatabase('started', message);
364
+ protected async processMessage(message: QueueMessage<T>, rawMessage, channel, queueName: string): Promise<void> {
365
+ if (this.shouldPersistToDatabase()) {
366
+ await this.updateStatusInDatabase('started', message);
367
+ }
338
368
 
339
369
  // Capture the results of handling the task.
340
- const result = await this.subscribe(message);
370
+ const result = await this.subscribeWithTimeout(message, queueName);
341
371
 
342
372
  // Ack the message.
343
373
  channel.ack(rawMessage);
344
374
 
345
375
  // Persist success output and timing.
346
- await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');
376
+ if (this.shouldPersistToDatabase()) {
377
+ await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');
378
+ }
347
379
 
348
380
  }
349
381
 
@@ -381,4 +413,89 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
381
413
 
382
414
  }
383
415
 
416
+ private resolveProcessingTimeoutMs(): number {
417
+ // Broker-side delivery-ack timeout (ms). If not provided, assume RabbitMQ default
418
+ // behavior used in this project: 30 minutes.
419
+ // Example (RabbitMQ broker):
420
+ // - Broker ack timeout: 30m => 1,800,000ms (QUEUES_RABBITMQ_CONSUMER_ACK_TIMEOUT_MS)
421
+ // - App soft timeout should be slightly lower, e.g. 29m30s => 1,770,000ms
422
+ // (QUEUES_RABBITMQ_SUBSCRIBER_PROCESSING_TIMEOUT_MS), so application code fails first,
423
+ // records DB state/error, and avoids broker-forced channel close as primary failure signal.
424
+ const brokerTimeoutMs = this.parsePositiveInt(process.env.QUEUES_RABBITMQ_CONSUMER_ACK_TIMEOUT_MS, 30 * 60 * 1000);
425
+
426
+ // Soft timeout should fire *before* broker timeout so we can fail explicitly,
427
+ // persist status/error, and avoid broker-forced channel closure as primary signal.
428
+ // Keep at least 1s to avoid zero/negative values when broker timeout is very small.
429
+ const defaultSoftTimeoutMs = Math.max(1_000, brokerTimeoutMs - 30_000);
430
+
431
+ // Final timeout precedence:
432
+ // 1) QUEUES_RABBITMQ_SUBSCRIBER_PROCESSING_TIMEOUT_MS (if valid positive int)
433
+ // 2) Derived defaultSoftTimeoutMs (broker timeout - 30s)
434
+ return this.parsePositiveInt(process.env.QUEUES_RABBITMQ_SUBSCRIBER_PROCESSING_TIMEOUT_MS, defaultSoftTimeoutMs);
435
+ }
436
+
437
+ private parsePositiveInt(value: string | undefined, fallback: number): number {
438
+ // Shared env parsing helper:
439
+ // - missing/invalid/non-positive => fallback
440
+ // - valid positive integer => parsed value
441
+ if (!value) return fallback;
442
+ const parsed = Number.parseInt(value, 10);
443
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
444
+ }
445
+
446
+ private async subscribeWithTimeout(message: QueueMessage<T>, queueName: string): Promise<any> {
447
+ const timeoutMs = this.resolveProcessingTimeoutMs();
448
+ const messageId = message?.messageId || 'unknown';
449
+
450
+ // Allow an escape hatch: non-positive timeout means run without a soft timeout.
451
+ if (timeoutMs <= 0) {
452
+ return this.subscribe(message);
453
+ }
454
+
455
+ let timedOut = false;
456
+ let timeoutHandle: NodeJS.Timeout | null = null;
457
+
458
+ // Main subscriber work promise.
459
+ // If timeout has already fired, suppress rethrow to avoid unhandled rejection noise
460
+ // (the timeout error is already the authoritative failure we track).
461
+ const subscribePromise = this.subscribe(message).catch((error) => {
462
+ if (timedOut) {
463
+ this.logger.error(
464
+ `Subscriber promise rejected after timeout for queue ${queueName} and messageId ${messageId}: ${(error as Error)?.message || String(error)}`,
465
+ (error as Error)?.stack,
466
+ );
467
+ return undefined;
468
+ }
469
+ throw error;
470
+ });
471
+
472
+ // Timeout promise rejects after timeoutMs with an explicit domain-specific error.
473
+ const timeoutPromise = new Promise<never>((_, reject) => {
474
+ timeoutHandle = setTimeout(() => {
475
+ timedOut = true;
476
+ reject(new ConsumerProcessingTimeoutError(queueName, messageId, timeoutMs));
477
+ }, timeoutMs);
478
+ });
479
+
480
+ try {
481
+ // Promise.race settles as soon as the *first* promise settles.
482
+ // - If subscribePromise resolves/rejects first, we use that outcome.
483
+ // - If timeoutPromise rejects first, we fail fast with timeout error.
484
+ // This ensures we mark DB status via normal error handling before broker ack-timeout.
485
+ return await Promise.race([subscribePromise, timeoutPromise]);
486
+ } catch (error) {
487
+ const errorMessage = (error as Error)?.message || String(error);
488
+ this.logger.error(
489
+ `Subscriber execution failed for queue ${queueName} and messageId ${messageId}: ${errorMessage}`,
490
+ (error as Error)?.stack,
491
+ );
492
+ throw error;
493
+ } finally {
494
+ // Always clear timer once race settles to avoid timer leaks.
495
+ if (timeoutHandle) {
496
+ clearTimeout(timeoutHandle);
497
+ }
498
+ }
499
+ }
500
+
384
501
  }
@@ -2,6 +2,7 @@ import { Injectable } from "@nestjs/common";
2
2
  import { ClsService } from "nestjs-cls";
3
3
  import { REQUEST_USER_KEY } from "src/constants";
4
4
  import { BasicFilterDto } from "src/dtos/basic-filters.dto";
5
+ import { ActiveUserData } from "src/interfaces/active-user-data.interface";
5
6
 
6
7
  @Injectable()
7
8
  export class RequestContextService {
@@ -9,7 +10,7 @@ export class RequestContextService {
9
10
  }
10
11
 
11
12
  // This method i.e getActiveUser() will fetch the user from the request object in the context
12
- getActiveUser() {
13
+ getActiveUser(): ActiveUserData | undefined {
13
14
  return this.cls.get(REQUEST_USER_KEY);
14
15
  }
15
16
 
@@ -24,13 +24,23 @@ export class SchedulerServiceImpl implements ISchedulerService {
24
24
  async runScheduledJobs(): Promise<void> {
25
25
  const solidSchedulerEnabled = process.env.SOLID_SCHEDULER_ENABLED || "true";
26
26
  if (solidSchedulerEnabled.toLowerCase() !== "true") {
27
- // this.logger.debug('Solid scheduler is disabled via environment variable');
27
+ this.logger.debug('Solid scheduler is disabled via environment variable');
28
28
  return;
29
29
  }
30
30
  const solidCliRunning = process.env.SOLID_CLI_RUNNING || "false";
31
31
  if (solidCliRunning === "true") {
32
32
  return;
33
33
  }
34
+ const jobsRegexToEnable = (process.env.SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE || '').trim();
35
+ let jobsRegex: RegExp | null = null;
36
+ if (jobsRegexToEnable && jobsRegexToEnable !== "all") {
37
+ try {
38
+ jobsRegex = new RegExp(jobsRegexToEnable);
39
+ } catch (error) {
40
+ this.logger.error(`Invalid SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE regex "${jobsRegexToEnable}". Scheduler loop will skip this run.`);
41
+ return;
42
+ }
43
+ }
34
44
 
35
45
  const now = new Date();
36
46
 
@@ -53,6 +63,12 @@ export class SchedulerServiceImpl implements ISchedulerService {
53
63
 
54
64
  for (const job of dueJobs) {
55
65
  const jobKey = String(job.id ?? job.scheduleName ?? job.job);
66
+ const jobName = String(job.job ?? '');
67
+
68
+ if (jobsRegex && !jobsRegex.test(jobName)) {
69
+ this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${jobName} because it does not match SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE=${jobsRegexToEnable}`);
70
+ continue;
71
+ }
56
72
 
57
73
  if (this.runningJobs.has(jobKey)) {
58
74
  this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${job.job} because a run is already in progress`);
@@ -194,16 +210,18 @@ export class SchedulerServiceImpl implements ISchedulerService {
194
210
  tz: 'UTC'
195
211
  });
196
212
  const nextRun = interval.next().toDate();
213
+ const runAfterNext = interval.next().toDate();
197
214
 
198
- // Validate minimum 1 minute interval
199
- if (nextRun.getTime() - from.getTime() < 60000) {
215
+ // Validate minimum 1 minute cadence between consecutive runs.
216
+ // Comparing nextRun to "from" is incorrect near minute boundaries.
217
+ if (runAfterNext.getTime() - nextRun.getTime() < 60000) {
200
218
  throw new Error('Cron expression interval must be at least 1 minute');
201
219
  }
202
220
 
203
221
  this.logger.log(`Custom cron '${job.cronExpression}' next run: ${nextRun}`);
204
222
  return nextRun;
205
223
  } catch (error) {
206
- this.logger.error(`Invalid cron expression for job ${job.scheduleName}: ${job.cronExpression}`, error);
224
+ this.logger.error(`Invalid cron expression for job ${job.scheduleName}: ${job.cronExpression}. Reason: ${(error as Error).message}`);
207
225
  // Fallback to daily if cron parsing fails
208
226
  return new Date(base.getTime() + 24 * 60 * 60 * 1000);
209
227
  }
@@ -1,6 +1,8 @@
1
1
  import { classify } from '@angular-devkit/core/src/utils/strings';
2
2
  import { Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common';
3
3
  import { DiscoveryService, MetadataScanner, ModuleRef, Reflector } from '@nestjs/core';
4
+ import { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';
5
+ import { ModelMetadataRepository } from 'src/repository/model-metadata.repository';
4
6
  import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
5
7
  import { getDataSourceToken } from '@nestjs/typeorm';
6
8
  import { IS_COMPUTED_FIELD_PROVIDER } from 'src/decorators/computed-field-provider.decorator';
@@ -40,6 +42,8 @@ export class SolidIntrospectService implements OnApplicationBootstrap {
40
42
  private readonly solidRegistry: SolidRegistry,
41
43
  private readonly moduleRef: ModuleRef,
42
44
  private readonly settingService: SettingService,
45
+ private readonly modelMetadataRepo: ModelMetadataRepository,
46
+ private readonly modelMetadataHelperService: ModelMetadataHelperService,
43
47
  ) { }
44
48
 
45
49
  private readonly logger = new Logger(SolidIntrospectService.name);
@@ -142,9 +146,33 @@ export class SolidIntrospectService implements OnApplicationBootstrap {
142
146
 
143
147
  // Register the core subscribers against all the configured database modules / datasources
144
148
  await this.bootstrapCoreTypeOrmSubscribers(solidDatabaseModules);
149
+ await this.cacheAuditableModels();
145
150
  await this.settingService.updateSettingsCache();
146
151
  }
147
152
 
153
+ private async cacheAuditableModels(): Promise<void> {
154
+ const models = await this.modelMetadataRepo.find({
155
+ where: { enableAuditTracking: true },
156
+ relations: { fields: true, module: true },
157
+ });
158
+
159
+ const auditableSet = new Set<string>();
160
+ for (const model of models) {
161
+ const allFields = await this.modelMetadataHelperService.loadFieldHierarchy(model.singularName);
162
+ const hasAuditableField = allFields.some(field =>
163
+ field.enableAuditTracking &&
164
+ !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&
165
+ !(field.type === 'relation' && field.relationType === 'one-to-many')
166
+ );
167
+ if (hasAuditableField) {
168
+ auditableSet.add(model.singularName.toLowerCase());
169
+ }
170
+ }
171
+
172
+ this.solidRegistry.registerAuditableModels(auditableSet);
173
+ this.logger.debug(`Cached ${auditableSet.size} auditable model(s): ${[...auditableSet].join(', ')}`);
174
+ }
175
+
148
176
  async bootstrapCoreTypeOrmSubscribers(dbModules: Array<InstanceWrapper<any>>): Promise<void> {
149
177
  // Register core subscribers for each Solid database module
150
178
  for (const wrapper of dbModules) {
@@ -324,6 +324,104 @@ export class SolidTsMorphService {
324
324
  return { staged: true, overwritten: false, skipped: false };
325
325
  }
326
326
 
327
+
328
+ //Removes all import declarations from a file whose module specifier matches the given predicate.
329
+ //Returns the set of identifier names that were imported by the removed declarations.
330
+ removeImports(
331
+ filePath: string,
332
+ filter: (moduleSpecifier: string) => boolean
333
+ ): { removedIdentifiers: Set<string>; staged: boolean; skipped: boolean } {
334
+ const abs = this.resolveRepoPath(filePath);
335
+ if (!existsSync(abs)) {
336
+ this.logger.warn(`removeImport: file not found at ${filePath}, skipping.`);
337
+ return { removedIdentifiers: new Set(), staged: false, skipped: true };
338
+ }
339
+
340
+ const existing = this.project.getSourceFile(abs);
341
+ const sourceFile = existing
342
+ ? existing
343
+ : this.project.createSourceFile(abs, readFileSync(abs, "utf8"), { overwrite: true });
344
+
345
+ const importsToRemove = sourceFile.getImportDeclarations().filter(decl => {
346
+ const spec = decl.getModuleSpecifierValue().replace(/\\/g, "/");
347
+ return filter(spec);
348
+ });
349
+
350
+ if (importsToRemove.length === 0) {
351
+ return { removedIdentifiers: new Set(), staged: false, skipped: true };
352
+ }
353
+
354
+ const removedIdentifiers = new Set<string>();
355
+ for (const decl of importsToRemove) {
356
+ for (const named of decl.getNamedImports()) {
357
+ removedIdentifiers.add(named.getAliasNode()?.getText() ?? named.getName());
358
+ }
359
+ const defaultImport = decl.getDefaultImport();
360
+ if (defaultImport) removedIdentifiers.add(defaultImport.getText());
361
+ decl.remove();
362
+ }
363
+
364
+ this.dirtySourceFiles.add(abs);
365
+ this.logger.log(`Staged removal of ${importsToRemove.length} import(s) in: ${this.rel(abs)}`);
366
+ return { removedIdentifiers, staged: true, skipped: false };
367
+ }
368
+
369
+ //Removes the given identifier names from all @Module decorator array properties
370
+ removeModuleMembers(
371
+ filePath: string,
372
+ names: Set<string> | string[]
373
+ ): { staged: boolean; skipped: boolean } {
374
+ const abs = this.resolveRepoPath(filePath);
375
+ if (!existsSync(abs)) {
376
+ this.logger.warn(`removeImportMembers: file not found at ${filePath}, skipping.`);
377
+ return { staged: false, skipped: true };
378
+ }
379
+
380
+ const identifiers = names instanceof Set ? names : new Set(names);
381
+ if (identifiers.size === 0) return { staged: false, skipped: true };
382
+
383
+ const existing = this.project.getSourceFile(abs);
384
+ const sourceFile = existing
385
+ ? existing
386
+ : this.project.createSourceFile(abs, readFileSync(abs, "utf8"), { overwrite: true });
387
+
388
+ const nestModuleClass = sourceFile.getClasses().find(cls =>
389
+ cls.getDecorators().some(dec => dec.getName() === "Module")
390
+ );
391
+ if (!nestModuleClass) {
392
+ this.logger.warn(`removeImportMembers: no @Module() class found in ${filePath}`);
393
+ return { staged: false, skipped: true };
394
+ }
395
+
396
+ const moduleDec = nestModuleClass.getDecorators().find(dec => dec.getName() === "Module");
397
+ const arg0 = moduleDec?.getCallExpression()?.getArguments()[0];
398
+ if (!arg0 || !Node.isObjectLiteralExpression(arg0)) return { staged: false, skipped: true };
399
+
400
+ const meta = arg0 as ObjectLiteralExpression;
401
+ for (const propName of ["imports", "providers", "controllers", "exports"] as const) {
402
+ const prop = meta.getProperty(propName);
403
+ if (!prop || !Node.isPropertyAssignment(prop)) continue;
404
+ const init = prop.getInitializer();
405
+ if (!init || !Node.isArrayLiteralExpression(init)) continue;
406
+ const arr = init as ArrayLiteralExpression;
407
+ const elements = arr.getElements();
408
+ for (let i = elements.length - 1; i >= 0; i--) {
409
+ const elemText = elements[i].getText().trim();
410
+ // Match direct identifiers (e.g. TestService) or call expressions that reference them (e.g. TypeOrmModule.forFeature([Test])).
411
+ const shouldRemove = identifiers.has(elemText) ||
412
+ [...identifiers].some(id => new RegExp(`\\b${id}\\b`).test(elemText));
413
+ if (shouldRemove) {
414
+ arr.removeElement(i);
415
+ }
416
+ }
417
+ }
418
+
419
+ this.dirtySourceFiles.add(abs);
420
+ this.logger.log(`Staged removal of [${[...identifiers].join(", ")}] from @Module arrays in: ${this.rel(abs)}`);
421
+ return { staged: true, skipped: false };
422
+ }
423
+
424
+
327
425
  addImport(
328
426
  filePath: string,
329
427
  importLine: string
@@ -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,