rez_core 5.0.166 → 5.0.168

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 (420) hide show
  1. package/.idea/250218_nodejs_core.iml +11 -8
  2. package/.idea/codeStyles/Project.xml +58 -58
  3. package/.idea/codeStyles/codeStyleConfig.xml +4 -4
  4. package/.idea/inspectionProfiles/Project_Default.xml +1 -1
  5. package/.idea/modules.xml +7 -7
  6. package/.idea/prettier.xml +5 -5
  7. package/.idea/vcs.xml +5 -5
  8. package/.prettierrc +3 -3
  9. package/README.md +99 -99
  10. package/dist/module/auth/guards/role.guard.js +3 -3
  11. package/dist/module/dashboard/service/dashboard.service.js +1 -1
  12. package/dist/module/dashboard/service/dashboard.service.js.map +1 -1
  13. package/dist/module/filter/repository/saved-filter.repository.d.ts +4 -6
  14. package/dist/module/filter/repository/saved-filter.repository.js +43 -9
  15. package/dist/module/filter/repository/saved-filter.repository.js.map +1 -1
  16. package/dist/module/filter/service/filter.service.js +19 -19
  17. package/dist/module/integration/examples/usage.example.js +9 -9
  18. package/dist/module/listmaster/entity/list-master.entity.d.ts +1 -0
  19. package/dist/module/listmaster/entity/list-master.entity.js +4 -0
  20. package/dist/module/listmaster/entity/list-master.entity.js.map +1 -1
  21. package/dist/module/meta/dto/entity-table.dto.d.ts +1 -4
  22. package/dist/module/meta/repository/attribute-master.repository.js +8 -8
  23. package/dist/module/meta/service/entity-dynamic.service.js +17 -17
  24. package/dist/module/meta/service/entity-dynamic.service.js.map +1 -1
  25. package/dist/module/meta/service/entity-list.service.js +2 -2
  26. package/dist/module/meta/service/media-data.service.js +6 -6
  27. package/dist/module/meta/service/resolver.service.js +15 -15
  28. package/dist/module/module/controller/module-access.controller.d.ts +1 -1
  29. package/dist/module/module/controller/module-access.controller.js +6 -8
  30. package/dist/module/module/controller/module-access.controller.js.map +1 -1
  31. package/dist/module/module/repository/menu.repository.js +5 -5
  32. package/dist/module/module/repository/menu.repository.js.map +1 -1
  33. package/dist/module/module/service/module-access.service.d.ts +3 -4
  34. package/dist/module/module/service/module-access.service.js +7 -14
  35. package/dist/module/module/service/module-access.service.js.map +1 -1
  36. package/dist/module/notification/service/notification.service.js +6 -6
  37. package/dist/module/user/controller/login.controller.js +18 -18
  38. package/dist/module/workflow/repository/action.repository.js +2 -2
  39. package/dist/module/workflow/repository/stage.repository.js +8 -8
  40. package/dist/module/workflow/service/action-template-mapping.service.js +2 -2
  41. package/dist/module/workflow/service/action.service.js +5 -5
  42. package/dist/module/workflow/service/entity-modification.service.js +2 -2
  43. package/dist/module/workflow/service/task.service.js +8 -8
  44. package/dist/module/workflow-automation/service/schedule-handler.service.js +9 -9
  45. package/dist/tsconfig.build.tsbuildinfo +1 -1
  46. package/dist/utils/service/reflection-helper.service.js +2 -2
  47. package/docs/modules/event-driven-integration-design.md +91 -91
  48. package/docs/modules/integration.md +250 -250
  49. package/eslint.config.mjs +34 -34
  50. package/nest-cli.json +14 -14
  51. package/package.json +125 -125
  52. package/src/app.controller.ts +12 -12
  53. package/src/app.module.ts +68 -68
  54. package/src/app.service.ts +8 -8
  55. package/src/config/bull.config.ts +69 -69
  56. package/src/config/config.module.ts +17 -17
  57. package/src/config/database.config.ts +48 -48
  58. package/src/constant/global.constant.ts +67 -67
  59. package/src/core.module.ts +94 -94
  60. package/src/decorators/roles.decorator.ts +7 -7
  61. package/src/dtos/response.dto.ts +6 -6
  62. package/src/dtos/response.ts +5 -5
  63. package/src/index.ts +1 -1
  64. package/src/module/auth/auth.module.ts +49 -49
  65. package/src/module/auth/controller/auth.controller.ts +28 -28
  66. package/src/module/auth/guards/google-auth.guard.ts +9 -9
  67. package/src/module/auth/guards/jwt.guard.ts +22 -22
  68. package/src/module/auth/guards/role.guard.ts +68 -68
  69. package/src/module/auth/services/auth.service.ts +56 -56
  70. package/src/module/auth/services/jwt.service.ts +11 -11
  71. package/src/module/auth/strategies/google.strategy.ts +54 -54
  72. package/src/module/auth/strategies/jwt.strategy.ts +58 -58
  73. package/src/module/auth/strategies/local.strategy.ts +13 -13
  74. package/src/module/dashboard/controller/dashboard.controller.ts +36 -36
  75. package/src/module/dashboard/dashboard.module.ts +21 -21
  76. package/src/module/dashboard/entity/dashboard_page_data.entity.ts +27 -27
  77. package/src/module/dashboard/entity/widget_master.entity.ts +18 -18
  78. package/src/module/dashboard/repository/dashboard.repository.ts +51 -51
  79. package/src/module/dashboard/service/dashboard.service.ts +73 -73
  80. package/src/module/enterprise/controller/organization.controller.ts +36 -36
  81. package/src/module/enterprise/enterprise.module.ts +30 -30
  82. package/src/module/enterprise/entity/enterprise.entity.ts +37 -37
  83. package/src/module/enterprise/entity/organization-app-mapping.entity.ts +13 -13
  84. package/src/module/enterprise/entity/organization.entity.ts +92 -92
  85. package/src/module/enterprise/repository/enterprise.repository.ts +31 -31
  86. package/src/module/enterprise/repository/organization.repository.ts +26 -26
  87. package/src/module/enterprise/repository/school.repository.ts +272 -272
  88. package/src/module/enterprise/service/brand.service.ts +5 -5
  89. package/src/module/enterprise/service/enterprise.service.ts +16 -16
  90. package/src/module/enterprise/service/organization-app-mapping.service.ts +4 -4
  91. package/src/module/enterprise/service/organization.service.ts +145 -145
  92. package/src/module/entity_json/controller/entity_json.controller.ts +47 -47
  93. package/src/module/entity_json/entity/entityJson.entity.ts +39 -39
  94. package/src/module/entity_json/entity_json.module.ts +18 -18
  95. package/src/module/entity_json/service/entityJson.repository.ts +37 -37
  96. package/src/module/entity_json/service/entity_json.service.ts +242 -242
  97. package/src/module/export/controller/export.controller.ts +83 -83
  98. package/src/module/export/export.module.ts +14 -14
  99. package/src/module/export/service/export.service.ts +105 -105
  100. package/src/module/filter/controller/filter.controller.ts +84 -84
  101. package/src/module/filter/dto/filter-request.dto.ts +39 -39
  102. package/src/module/filter/entity/saved-filter-detail.entity.ts +41 -41
  103. package/src/module/filter/entity/saved-filter-master.entity.ts +32 -32
  104. package/src/module/filter/filter.module.ts +33 -33
  105. package/src/module/filter/repository/saved-filter.repository.ts +256 -200
  106. package/src/module/filter/repository/saved.filter-detail.repository.ts +19 -19
  107. package/src/module/filter/service/filter-evaluator.service.ts +82 -82
  108. package/src/module/filter/service/filter.service.ts +1319 -1319
  109. package/src/module/filter/service/saved-filter.service.ts +164 -164
  110. package/src/module/ics/controller/ics.controller.ts +21 -21
  111. package/src/module/ics/dto/ics.dto.ts +55 -55
  112. package/src/module/ics/ics.module.ts +13 -13
  113. package/src/module/ics/service/ics.service.ts +57 -57
  114. package/src/module/integration/controller/calender-event.controller.ts +31 -31
  115. package/src/module/integration/controller/integration.controller.ts +662 -662
  116. package/src/module/integration/controller/wrapper.controller.ts +37 -37
  117. package/src/module/integration/dto/create-config.dto.ts +526 -526
  118. package/src/module/integration/entity/integration-config.entity.ts +112 -112
  119. package/src/module/integration/entity/integration-entity-mapper.entity.ts +14 -14
  120. package/src/module/integration/entity/integration-source.entity.ts +17 -17
  121. package/src/module/integration/entity/user-integration.entity.ts +71 -71
  122. package/src/module/integration/examples/usage.example.ts +338 -338
  123. package/src/module/integration/factories/base.factory.ts +7 -7
  124. package/src/module/integration/factories/email.factory.ts +49 -49
  125. package/src/module/integration/factories/integration.factory.ts +121 -121
  126. package/src/module/integration/factories/sms.factory.ts +51 -51
  127. package/src/module/integration/factories/telephone.factory.ts +41 -41
  128. package/src/module/integration/factories/whatsapp.factory.ts +56 -56
  129. package/src/module/integration/integration.module.ts +110 -110
  130. package/src/module/integration/service/calendar-event.service.ts +118 -118
  131. package/src/module/integration/service/integration-entity-mapper.service.ts +17 -17
  132. package/src/module/integration/service/integration-queue.service.ts +229 -229
  133. package/src/module/integration/service/integration.service.ts +2634 -2634
  134. package/src/module/integration/service/oauth.service.ts +224 -224
  135. package/src/module/integration/service/wrapper.service.ts +753 -753
  136. package/src/module/integration/strategies/email/gmail-api.strategy.ts +280 -280
  137. package/src/module/integration/strategies/email/outlook-api.strategy.ts +44 -44
  138. package/src/module/integration/strategies/email/outlook.strategy.ts +64 -64
  139. package/src/module/integration/strategies/email/sendgrid-api.strategy.ts +260 -260
  140. package/src/module/integration/strategies/integration.strategy.ts +97 -97
  141. package/src/module/integration/strategies/sms/gupshup-sms.strategy.ts +146 -146
  142. package/src/module/integration/strategies/sms/msg91-sms.strategy.ts +164 -164
  143. package/src/module/integration/strategies/sms/tubelight-sms.strategy.ts +163 -163
  144. package/src/module/integration/strategies/telephone/ozonetel-voice.strategy.ts +238 -238
  145. package/src/module/integration/strategies/telephone/tubelight-voice.strategy.ts +210 -210
  146. package/src/module/integration/strategies/whatsapp/gupshup-whatsapp.strategy.ts +359 -359
  147. package/src/module/integration/strategies/whatsapp/tubelight-whatsapp.strategy.ts +372 -372
  148. package/src/module/integration/strategies/whatsapp/whatsapp-cloud.strategy.ts +403 -403
  149. package/src/module/integration/strategies/whatsapp/whatsapp.strategy.ts +57 -57
  150. package/src/module/layout/controller/layout.controller.ts +47 -47
  151. package/src/module/layout/entity/header-items.entity.ts +28 -28
  152. package/src/module/layout/entity/header-section.entity.ts +19 -19
  153. package/src/module/layout/layout.module.ts +21 -21
  154. package/src/module/layout/repository/header-items.repository.ts +18 -18
  155. package/src/module/layout/repository/header-section.repository.ts +22 -22
  156. package/src/module/layout/service/header-section.service.ts +25 -25
  157. package/src/module/layout_preference/controller/layout_preference.controller.ts +73 -73
  158. package/src/module/layout_preference/entity/layout_preference.entity.ts +28 -28
  159. package/src/module/layout_preference/layout_preference.module.ts +22 -22
  160. package/src/module/layout_preference/repository/layout_preference.repository.ts +65 -65
  161. package/src/module/layout_preference/service/layout_preference.service.ts +191 -191
  162. package/src/module/lead/controller/lead.controller.ts +30 -30
  163. package/src/module/lead/lead.module.ts +14 -14
  164. package/src/module/lead/repository/lead.repository.ts +41 -41
  165. package/src/module/lead/service/lead.service.ts +54 -54
  166. package/src/module/linked_attributes/controller/linked_attributes.controller.ts +37 -37
  167. package/src/module/linked_attributes/entity/linked_attribute.entity.ts +51 -51
  168. package/src/module/linked_attributes/linked_attributes.module.ts +16 -16
  169. package/src/module/linked_attributes/repository/linked_attribute.repository.ts +12 -12
  170. package/src/module/linked_attributes/service/linked_attributes.service.ts +75 -75
  171. package/src/module/listmaster/controller/list-master.controller.ts +230 -230
  172. package/src/module/listmaster/entity/list-master-items.entity.ts +43 -43
  173. package/src/module/listmaster/entity/list-master.entity.ts +33 -30
  174. package/src/module/listmaster/listmaster.module.ts +46 -46
  175. package/src/module/listmaster/repository/list-master-items.repository.ts +173 -173
  176. package/src/module/listmaster/repository/list-master.repository.ts +56 -56
  177. package/src/module/listmaster/service/list-master-engine.ts +19 -19
  178. package/src/module/listmaster/service/list-master-extension.interface.ts +4 -4
  179. package/src/module/listmaster/service/list-master-item.service.ts +281 -281
  180. package/src/module/listmaster/service/list-master-registry.ts +15 -15
  181. package/src/module/listmaster/service/list-master.service.ts +535 -535
  182. package/src/module/mapper/controller/field-mapper.controller.ts +76 -76
  183. package/src/module/mapper/controller/mapper.controller.ts +20 -20
  184. package/src/module/mapper/dto/field-mapper.dto.ts +14 -14
  185. package/src/module/mapper/entity/field-lovs.entity.ts +19 -19
  186. package/src/module/mapper/entity/field-mapper.entity.ts +53 -53
  187. package/src/module/mapper/entity/mapper.entity.ts +16 -16
  188. package/src/module/mapper/mapper.module.ts +35 -35
  189. package/src/module/mapper/repository/field-lovs.repository.ts +35 -35
  190. package/src/module/mapper/repository/field-mapper.repository.ts +42 -42
  191. package/src/module/mapper/repository/mapper.repository.ts +32 -32
  192. package/src/module/mapper/service/field-mapper.service.ts +269 -269
  193. package/src/module/mapper/service/mapper.service.ts +81 -81
  194. package/src/module/master/controller/master.controller.ts +74 -74
  195. package/src/module/master/service/master.service.ts +483 -483
  196. package/src/module/meta/controller/app-master.controller.ts +38 -38
  197. package/src/module/meta/controller/attribute-master.controller.ts +84 -84
  198. package/src/module/meta/controller/entity-dynamic.controller.ts +125 -125
  199. package/src/module/meta/controller/entity-master.controller.ts +41 -41
  200. package/src/module/meta/controller/entity-relation.controller.ts +36 -36
  201. package/src/module/meta/controller/entity.controller.ts +342 -342
  202. package/src/module/meta/controller/entity.public.controller.ts +75 -75
  203. package/src/module/meta/controller/media.controller.ts +135 -135
  204. package/src/module/meta/controller/meta.controller.ts +96 -96
  205. package/src/module/meta/controller/view-master.controller.ts +86 -86
  206. package/src/module/meta/dto/entity-list-data.dto.ts +6 -6
  207. package/src/module/meta/dto/entity-tab.dto.ts +4 -4
  208. package/src/module/meta/dto/entity-table.dto.ts +12 -12
  209. package/src/module/meta/entity/app-master.entity.ts +37 -37
  210. package/src/module/meta/entity/attribute-master.entity.ts +92 -92
  211. package/src/module/meta/entity/base-entity.entity.ts +75 -75
  212. package/src/module/meta/entity/entity-master.entity.ts +85 -85
  213. package/src/module/meta/entity/entity-relation-data.entity.ts +29 -29
  214. package/src/module/meta/entity/entity-relation.entity.ts +23 -23
  215. package/src/module/meta/entity/entity-table-column.entity.ts +61 -61
  216. package/src/module/meta/entity/entity-table.entity.ts +50 -50
  217. package/src/module/meta/entity/media-data.entity.ts +32 -32
  218. package/src/module/meta/entity/preference.entity.ts +62 -62
  219. package/src/module/meta/entity/view-master.entity.ts +41 -41
  220. package/src/module/meta/entity.module.ts +168 -168
  221. package/src/module/meta/repository/app-master.repository.ts +20 -20
  222. package/src/module/meta/repository/attribute-master.repository.ts +156 -156
  223. package/src/module/meta/repository/entity-attribute-update.repository.ts +48 -48
  224. package/src/module/meta/repository/entity-master.repository.ts +110 -110
  225. package/src/module/meta/repository/entity-relation.repository.ts +22 -22
  226. package/src/module/meta/repository/entity-table-column.repository.ts +39 -39
  227. package/src/module/meta/repository/entity-table.repository.ts +53 -53
  228. package/src/module/meta/repository/media-data.repository.ts +50 -50
  229. package/src/module/meta/repository/preference.repository.ts +20 -20
  230. package/src/module/meta/repository/user-app-mapping.repository.ts +28 -28
  231. package/src/module/meta/repository/view-master.repository.ts +42 -42
  232. package/src/module/meta/service/app-master.service.ts +37 -37
  233. package/src/module/meta/service/attribute-master.service.ts +130 -130
  234. package/src/module/meta/service/common.service.ts +9 -9
  235. package/src/module/meta/service/entity-attribute-update.service.ts +26 -26
  236. package/src/module/meta/service/entity-dynamic.service.ts +822 -822
  237. package/src/module/meta/service/entity-list.service.ts +201 -201
  238. package/src/module/meta/service/entity-master.service.ts +171 -171
  239. package/src/module/meta/service/entity-realation-data.service.ts +9 -9
  240. package/src/module/meta/service/entity-relation.service.ts +74 -74
  241. package/src/module/meta/service/entity-service-impl.service.ts +439 -439
  242. package/src/module/meta/service/entity-table-column.service.ts +39 -39
  243. package/src/module/meta/service/entity-table.service.ts +157 -157
  244. package/src/module/meta/service/entity-validation.service.ts +187 -187
  245. package/src/module/meta/service/entity.service.ts +59 -59
  246. package/src/module/meta/service/field-group.service.ts +103 -103
  247. package/src/module/meta/service/media-data.service.ts +591 -591
  248. package/src/module/meta/service/populate-meta.service.ts +222 -222
  249. package/src/module/meta/service/preference.service.ts +16 -16
  250. package/src/module/meta/service/resolver.service.ts +291 -291
  251. package/src/module/meta/service/section-master.service.ts +104 -104
  252. package/src/module/meta/service/update-form-json.service.ts +22 -22
  253. package/src/module/meta/service/user-app-mapping.service.ts +17 -17
  254. package/src/module/meta/service/view-master.service.ts +127 -127
  255. package/src/module/microservice-client/microservice-clients.module.ts +13 -13
  256. package/src/module/microservice-client/service/microservice-client-factory.ts +37 -37
  257. package/src/module/microservice-client/service/microservice-clients.ts +4 -4
  258. package/src/module/module/controller/menu.controller.ts +15 -15
  259. package/src/module/module/controller/module-access.controller.ts +133 -134
  260. package/src/module/module/entity/menu.entity.ts +43 -43
  261. package/src/module/module/entity/module-access.entity.ts +25 -25
  262. package/src/module/module/entity/module-action.entity.ts +17 -17
  263. package/src/module/module/entity/module.entity.ts +52 -52
  264. package/src/module/module/module.module.ts +42 -42
  265. package/src/module/module/repository/menu.repository.ts +186 -186
  266. package/src/module/module/repository/module-access.repository.ts +344 -344
  267. package/src/module/module/service/menu.service.ts +82 -82
  268. package/src/module/module/service/module-access.service.ts +189 -199
  269. package/src/module/notification/controller/notification.controller.ts +58 -58
  270. package/src/module/notification/controller/otp.controller.ts +117 -117
  271. package/src/module/notification/entity/notification.entity.ts +26 -26
  272. package/src/module/notification/entity/otp.entity.ts +28 -28
  273. package/src/module/notification/firebase-admin.config.ts +22 -22
  274. package/src/module/notification/notification.module.ts +69 -69
  275. package/src/module/notification/repository/otp.repository.ts +27 -27
  276. package/src/module/notification/service/email.service.ts +127 -127
  277. package/src/module/notification/service/notification.service.ts +164 -164
  278. package/src/module/notification/service/otp.service.ts +133 -133
  279. package/src/module/third-party-module/entity/third-party-api-registry.entity.ts +52 -52
  280. package/src/module/third-party-module/repository/third-party-api-registry.repository.ts +20 -20
  281. package/src/module/third-party-module/service/api-registry.service.ts +13 -13
  282. package/src/module/third-party-module/third-party.module.ts +12 -12
  283. package/src/module/user/controller/login.controller.ts +198 -198
  284. package/src/module/user/controller/user.controller.ts +40 -40
  285. package/src/module/user/dto/create-user.dto.ts +62 -62
  286. package/src/module/user/dto/update-user.dto.ts +4 -4
  287. package/src/module/user/entity/role.entity.ts +33 -33
  288. package/src/module/user/entity/user-role-mapping.entity.ts +38 -38
  289. package/src/module/user/entity/user-session.entity.ts +73 -73
  290. package/src/module/user/entity/user.entity.ts +59 -59
  291. package/src/module/user/repository/role.repository.ts +96 -96
  292. package/src/module/user/repository/user-role-mapping.repository.ts +126 -126
  293. package/src/module/user/repository/user.repository.ts +50 -50
  294. package/src/module/user/repository/userSession.repository.ts +33 -33
  295. package/src/module/user/service/login.service.ts +326 -326
  296. package/src/module/user/service/role.service.ts +197 -197
  297. package/src/module/user/service/user-role-mapping.service.ts +98 -98
  298. package/src/module/user/service/user-session.service.ts +200 -200
  299. package/src/module/user/service/user.service.ts +368 -368
  300. package/src/module/user/user.module.ts +65 -65
  301. package/src/module/workflow/controller/action-category.controller.ts +54 -54
  302. package/src/module/workflow/controller/action-resource-mapping.controller.ts +23 -23
  303. package/src/module/workflow/controller/action-template-mapping.controller.ts +35 -35
  304. package/src/module/workflow/controller/action.controller.ts +111 -111
  305. package/src/module/workflow/controller/activity-log.controller.ts +55 -55
  306. package/src/module/workflow/controller/comm-template.controller.ts +43 -43
  307. package/src/module/workflow/controller/entity-modification.controller.ts +35 -35
  308. package/src/module/workflow/controller/form-master.controller.ts +43 -43
  309. package/src/module/workflow/controller/stage-group.controller.ts +48 -48
  310. package/src/module/workflow/controller/stage.controller.ts +50 -50
  311. package/src/module/workflow/controller/task.controller.ts +77 -77
  312. package/src/module/workflow/controller/workflow-list-master.controller.ts +44 -44
  313. package/src/module/workflow/controller/workflow-meta.controller.ts +80 -80
  314. package/src/module/workflow/controller/workflow.controller.ts +67 -67
  315. package/src/module/workflow/entity/action-category.entity.ts +38 -38
  316. package/src/module/workflow/entity/action-data.entity.ts +55 -55
  317. package/src/module/workflow/entity/action-resources-mapping.entity.ts +29 -29
  318. package/src/module/workflow/entity/action-template-mapping.entity.ts +17 -17
  319. package/src/module/workflow/entity/action.entity.ts +53 -53
  320. package/src/module/workflow/entity/activity-log.entity.ts +43 -43
  321. package/src/module/workflow/entity/comm-template.entity.ts +43 -43
  322. package/src/module/workflow/entity/entity-modification.entity.ts +38 -38
  323. package/src/module/workflow/entity/form.entity.ts +25 -25
  324. package/src/module/workflow/entity/stage-action-mapping.entity.ts +17 -17
  325. package/src/module/workflow/entity/stage-group.entity.ts +23 -23
  326. package/src/module/workflow/entity/stage-movement-data.entity.ts +38 -38
  327. package/src/module/workflow/entity/stage.entity.ts +20 -20
  328. package/src/module/workflow/entity/task-data.entity.ts +88 -88
  329. package/src/module/workflow/entity/template-attach-mapper.entity.ts +30 -30
  330. package/src/module/workflow/entity/workflow-data.entity.ts +11 -11
  331. package/src/module/workflow/entity/workflow-level-mapping.entity.ts +18 -18
  332. package/src/module/workflow/entity/workflow.entity.ts +20 -20
  333. package/src/module/workflow/repository/action-category.repository.ts +79 -79
  334. package/src/module/workflow/repository/action-data.repository.ts +346 -346
  335. package/src/module/workflow/repository/action.repository.ts +339 -339
  336. package/src/module/workflow/repository/activity-log.repository.ts +148 -148
  337. package/src/module/workflow/repository/comm-template.repository.ts +157 -157
  338. package/src/module/workflow/repository/form-master.repository.ts +50 -50
  339. package/src/module/workflow/repository/stage-group.repository.ts +186 -186
  340. package/src/module/workflow/repository/stage-movement.repository.ts +257 -257
  341. package/src/module/workflow/repository/stage.repository.ts +160 -160
  342. package/src/module/workflow/repository/task.repository.ts +151 -151
  343. package/src/module/workflow/repository/workflow.repository.ts +42 -42
  344. package/src/module/workflow/service/action-category.service.ts +33 -33
  345. package/src/module/workflow/service/action-data.service.ts +62 -62
  346. package/src/module/workflow/service/action-resources-mapping.service.ts +10 -10
  347. package/src/module/workflow/service/action-template-mapping.service.ts +140 -140
  348. package/src/module/workflow/service/action.service.ts +302 -302
  349. package/src/module/workflow/service/activity-log.service.ts +107 -107
  350. package/src/module/workflow/service/comm-template.service.ts +180 -180
  351. package/src/module/workflow/service/entity-modification.service.ts +61 -61
  352. package/src/module/workflow/service/form-master.service.ts +35 -35
  353. package/src/module/workflow/service/populate-workflow.service.ts +320 -320
  354. package/src/module/workflow/service/stage-action-mapping.service.ts +5 -5
  355. package/src/module/workflow/service/stage-group.service.ts +344 -344
  356. package/src/module/workflow/service/stage.service.ts +207 -207
  357. package/src/module/workflow/service/task.service.ts +550 -550
  358. package/src/module/workflow/service/workflow-list-master.service.ts +68 -68
  359. package/src/module/workflow/service/workflow-meta.service.ts +639 -639
  360. package/src/module/workflow/service/workflow.service.ts +213 -213
  361. package/src/module/workflow/workflow.module.ts +180 -180
  362. package/src/module/workflow-automation/SCHEDULING_GUIDE.md +145 -145
  363. package/src/module/workflow-automation/controller/workflow-automation.controller.ts +43 -43
  364. package/src/module/workflow-automation/entity/workflow-automation-action.entity.ts +26 -26
  365. package/src/module/workflow-automation/entity/workflow-automation.entity.ts +40 -40
  366. package/src/module/workflow-automation/interface/action.decorator.ts +7 -7
  367. package/src/module/workflow-automation/interface/action.interface.ts +5 -5
  368. package/src/module/workflow-automation/service/action-registery.service.ts +35 -35
  369. package/src/module/workflow-automation/service/schedule-handler.service.ts +168 -168
  370. package/src/module/workflow-automation/service/workflow-automation-engine.service.ts +219 -219
  371. package/src/module/workflow-automation/service/workflow-automation.service.ts +515 -515
  372. package/src/module/workflow-automation/workflow-automation.module.ts +54 -54
  373. package/src/module/workflow-schedule/INSTALLATION.md +244 -244
  374. package/src/module/workflow-schedule/MULTI_PROJECT_GUIDE.md +196 -196
  375. package/src/module/workflow-schedule/README.md +422 -422
  376. package/src/module/workflow-schedule/constants/schedule.constants.ts +48 -48
  377. package/src/module/workflow-schedule/controller/workflow-schedule.controller.ts +255 -255
  378. package/src/module/workflow-schedule/docs/CLAUDE_CODE_GUIDE.md +510 -510
  379. package/src/module/workflow-schedule/docs/CLAUDE_CODE_PROMPT.md +362 -362
  380. package/src/module/workflow-schedule/docs/RUN_CLAUDE_CODE.sh +68 -68
  381. package/src/module/workflow-schedule/dto/create-schedule.dto.ts +147 -147
  382. package/src/module/workflow-schedule/dto/get-execution-logs.dto.ts +119 -119
  383. package/src/module/workflow-schedule/dto/update-schedule.dto.ts +96 -96
  384. package/src/module/workflow-schedule/entities/scheduled-workflow.entity.ts +148 -148
  385. package/src/module/workflow-schedule/entities/workflow-execution-log.entity.ts +154 -154
  386. package/src/module/workflow-schedule/interfaces/schedule-job-data.interface.ts +53 -53
  387. package/src/module/workflow-schedule/interfaces/workflow-schedule-options.interface.ts +12 -12
  388. package/src/module/workflow-schedule/processors/schedule.processor.ts +620 -620
  389. package/src/module/workflow-schedule/service/workflow-schedule.service.ts +598 -598
  390. package/src/module/workflow-schedule/workflow-schedule.module.ts +67 -67
  391. package/src/resources/dev.properties.yaml +31 -31
  392. package/src/resources/local.properties.yaml +27 -27
  393. package/src/resources/properties.module.ts +12 -12
  394. package/src/resources/properties.yaml.ts +11 -11
  395. package/src/resources/uat.properties.yaml +31 -31
  396. package/src/table.config.ts +133 -133
  397. package/src/utils/dto/excel-data.dto.ts +14 -14
  398. package/src/utils/dto/excelsheet-data.dto.ts +5 -5
  399. package/src/utils/service/base64util.service.ts +18 -18
  400. package/src/utils/service/clockIDGenUtil.service.ts +21 -21
  401. package/src/utils/service/codeGenerator.service.ts +22 -22
  402. package/src/utils/service/dateUtil.service.ts +17 -17
  403. package/src/utils/service/encryptUtil.service.ts +97 -97
  404. package/src/utils/service/excel-helper.service.ts +72 -72
  405. package/src/utils/service/excelUtil.service.ts +15 -15
  406. package/src/utils/service/file-util.service.ts +11 -11
  407. package/src/utils/service/json-util.service.ts +23 -23
  408. package/src/utils/service/loggingUtil.service.ts +88 -88
  409. package/src/utils/service/reflection-helper.service.ts +62 -62
  410. package/src/utils/service/wbsCodeGen.service.ts +8 -8
  411. package/src/utils/utils.module.ts +27 -27
  412. package/tsconfig.build.json +4 -4
  413. package/tsconfig.json +24 -24
  414. package/.claude/settings.local.json +0 -26
  415. package/.idea/copilot.data.migration.agent.xml +0 -6
  416. package/.idea/copilot.data.migration.ask.xml +0 -6
  417. package/.idea/copilot.data.migration.ask2agent.xml +0 -6
  418. package/.idea/copilot.data.migration.edit.xml +0 -6
  419. package/.idea/misc.xml +0 -6
  420. package/server.log +0 -850
@@ -1,753 +1,753 @@
1
- import { Injectable, Logger } from '@nestjs/common';
2
- import { GenericMessageDto, IntegrationService } from './integration.service';
3
- import { IcsMeetingService } from 'src/module/ics/service/ics.service';
4
- import { LoggingService } from 'src/utils/service/loggingUtil.service';
5
- import { ReflectionHelper } from '../../../utils/service/reflection-helper.service';
6
- import { MediaDataService } from 'src/module/meta/service/media-data.service';
7
- import axios from 'axios';
8
-
9
- @Injectable()
10
- export class WrapperService {
11
- private readonly logger = new Logger(WrapperService.name);
12
-
13
- constructor(
14
- private readonly integrationService: IntegrationService,
15
- private readonly icsService: IcsMeetingService,
16
- private readonly loggingService: LoggingService,
17
- private readonly reflectionHelper: ReflectionHelper,
18
- private readonly mediaService: MediaDataService,
19
- ) {}
20
-
21
- /**
22
- * Wrapper for sending mail
23
- */
24
- async sendMailWrapper(payload: any, loggedInUser: any) {
25
- try {
26
- this.loggingService.log(
27
- 'debug',
28
- 'wrapperService',
29
- 'sendMailWrapper',
30
- `sendMailWrapper called. User: ${JSON.stringify(
31
- loggedInUser,
32
- )}, Payload: ${JSON.stringify(payload)}`,
33
- [],
34
- [],
35
- );
36
-
37
- const { level_id, level_type, organization_id } = loggedInUser;
38
-
39
- // 1. Check for config at user’s level
40
- this.loggingService.log(
41
- 'debug',
42
- 'wrapperService',
43
- 'sendMailWrapper',
44
- `Fetching configs for level_id=${level_id}, level_type=${level_type}`,
45
- [],
46
- [],
47
- );
48
- const intergrationConfigRepo =
49
- this.reflectionHelper.getRepoService('IntegrationConfig');
50
- const configs = await intergrationConfigRepo.find({
51
- where: {
52
- level_id: level_id,
53
- level_type: level_type,
54
- status: 1,
55
- integration_type: 'EMAIL',
56
- },
57
- });
58
-
59
- this.loggingService.log(
60
- 'debug',
61
- 'wrapperService',
62
- 'sendMailWrapper',
63
- `Configs found: ${JSON.stringify(configs)}`,
64
- [],
65
- [],
66
- );
67
-
68
- let templateCode: string | undefined;
69
-
70
- if (payload.templateCode) {
71
- this.loggingService.log(
72
- 'debug',
73
- 'wrapperService',
74
- 'sendMailWrapper',
75
- `Looking up templateCode=${payload.templateCode} for current level`,
76
- [],
77
- [],
78
- );
79
-
80
- const templateRepo =
81
- this.reflectionHelper.getRepoService('CommTemplate');
82
-
83
- const template = await templateRepo.findOne({
84
- where: {
85
- code: payload.templateCode,
86
- level_id: level_id,
87
- level_type: level_type,
88
- },
89
- });
90
-
91
- this.loggingService.log(
92
- 'debug',
93
- 'wrapperService',
94
- 'sendMailWrapper',
95
- `Template lookup result: ${JSON.stringify(template)}`,
96
- [],
97
- [],
98
- );
99
-
100
- if (template) {
101
- templateCode = template.rich_text;
102
- } else {
103
- this.loggingService.log(
104
- 'warn',
105
- 'wrapperService',
106
- 'sendMailWrapper',
107
- `No template found for templateCode=${payload.templateCode} and current level`,
108
- [],
109
- [],
110
- );
111
- }
112
- }
113
-
114
- let payloadSendMail: GenericMessageDto;
115
-
116
- if (configs && configs.length > 0) {
117
- this.loggingService.log(
118
- 'debug',
119
- 'wrapperService',
120
- 'sendMailWrapper',
121
- `Using user-level configs`,
122
- [],
123
- [],
124
- );
125
-
126
- payloadSendMail = {
127
- levelId: level_id,
128
- levelType: level_type,
129
- app_code: 'DEFAULT', // Legacy wrapper default
130
- to: payload.to,
131
- message: payload.message,
132
- subject: payload.subject,
133
- type: 'EMAIL',
134
- cc: payload.cc,
135
- bcc: payload.bcc,
136
- html: payload.html,
137
- // attachments: payload.attachments,
138
- templateId: payload.templateId,
139
- variables: payload.variables,
140
- organization_id: loggedInUser.organization_id,
141
- };
142
- } else {
143
- this.loggingService.log(
144
- 'warn',
145
- 'wrapperService',
146
- 'sendMailWrapper',
147
- `No user-level configs found. Falling back to ORG-level`,
148
- [],
149
- [],
150
- );
151
-
152
- const fallbackConfigs = await intergrationConfigRepo.find({
153
- where: {
154
- level_type: 'ORG',
155
- integration_type: 'EMAIL',
156
- status: 1,
157
- },
158
- });
159
-
160
- this.loggingService.log(
161
- 'debug',
162
- 'wrapperService',
163
- 'sendMailWrapper',
164
- `ORG-level configs: ${JSON.stringify(fallbackConfigs)}`,
165
- [],
166
- [],
167
- );
168
-
169
- if (!fallbackConfigs || fallbackConfigs.length === 0) {
170
- this.loggingService.log(
171
- 'warn',
172
- 'wrapperService',
173
- 'sendMailWrapper',
174
- 'No active email communication config found',
175
- [],
176
- [],
177
- );
178
- }
179
-
180
- payloadSendMail = {
181
- levelId: 1,
182
- levelType: 'ORG',
183
- app_code: 'DEFAULT', // Legacy wrapper default
184
- to: payload.to,
185
- message: payload.message,
186
- subject: payload.subject,
187
- type: 'EMAIL',
188
- cc: payload.cc,
189
- bcc: payload.bcc,
190
- html: payload.html,
191
- // attachments: payload.attachments,
192
- // templateId: payload.templateId,
193
- variables: payload.variables,
194
- organization_id: loggedInUser.organization_id,
195
- };
196
- }
197
-
198
- this.loggingService.log(
199
- 'debug',
200
- 'wrapperService',
201
- 'sendMailWrapper',
202
- `Final payload for IntegrationService: ${JSON.stringify(
203
- payloadSendMail,
204
- )}`,
205
- [],
206
- [],
207
- );
208
-
209
- const result =
210
- await this.integrationService.sendGenericMessage(payloadSendMail);
211
-
212
- this.loggingService.log(
213
- 'log',
214
- 'wrapperService',
215
- 'sendMailWrapper',
216
- `sendMailWrapper SUCCESS. Result: ${JSON.stringify(result)}`,
217
- [],
218
- [],
219
- );
220
-
221
- return {
222
- success: true,
223
- data: result,
224
- };
225
- } catch (error: any) {
226
- this.loggingService.log(
227
- 'error',
228
- 'wrapperService',
229
- 'sendMailWrapper',
230
- `sendMailWrapper ERROR: ${error.message}`,
231
- [],
232
- [error.stack], // Sending stack trace as additional data
233
- );
234
- return {
235
- success: false,
236
- error: error.message,
237
- };
238
- }
239
- }
240
-
241
- /**
242
- * Wrapper for sending communication
243
- */
244
-
245
- async sendCommunicationWrapperService(entity: any, loggedInUser: any) {
246
- try {
247
- this.loggingService.log(
248
- 'log',
249
- 'wrapperService',
250
- 'sendCommunicationWrapperService',
251
- `sendCommunicationWrapper called. User: ${JSON.stringify(
252
- loggedInUser,
253
- )}, Payload: ${JSON.stringify(entity)}`,
254
- [],
255
- [],
256
- );
257
-
258
- const { level_id, level_type, appcode, organization_id } = loggedInUser;
259
-
260
- // Check if active configs exist for current user's level
261
- this.loggingService.log(
262
- 'debug',
263
- 'wrapperService',
264
- 'sendCommunicationWrapperService',
265
- `Checking active ${
266
- entity.type || 'EMAIL'
267
- } configs for level_id=${level_id}, level_type=${level_type}, app_code=${appcode}`,
268
- [],
269
- [],
270
- );
271
-
272
- let configs = await this.integrationService.getActiveConfigs(
273
- level_id,
274
- level_type,
275
- appcode,
276
- entity.type || 'EMAIL',
277
- );
278
-
279
- let effectiveLevelId = level_id;
280
- let effectiveLevelType = level_type;
281
-
282
- // Fallback to ORG-level if no configs found
283
- if (!configs || configs.length === 0) {
284
- this.loggingService.log(
285
- 'warn',
286
- 'wrapperService',
287
- 'sendCommunicationWrapperService',
288
- `No active configs found for ${level_type}:${level_id}, falling back to ORG-level`,
289
- [],
290
- [],
291
- );
292
-
293
- configs = await this.integrationService.getActiveConfigs(
294
- 1,
295
- 'ORG',
296
- appcode,
297
- entity.type || 'EMAIL',
298
- );
299
-
300
- effectiveLevelId = 1;
301
- effectiveLevelType = 'ORG';
302
- }
303
-
304
- if (!configs || configs.length === 0) {
305
- this.loggingService.log(
306
- 'error',
307
- 'wrapperService',
308
- 'sendCommunicationWrapperService',
309
- 'No active configurations found at any level.',
310
- [],
311
- [],
312
- );
313
- throw new Error('No active configurations found.');
314
- }
315
-
316
- // Template lookup if templateCode is provided
317
- let resolvedTemplateId = entity?.templateId;
318
-
319
- if (entity.template_code) {
320
- this.loggingService.log(
321
- 'debug',
322
- 'wrapperService',
323
- 'sendCommunicationWrapperService',
324
- `Looking up template for code=${entity.template_code}, level_id=${level_id}, level_type=${level_type}`,
325
- [],
326
- [],
327
- );
328
-
329
- // Try to find template at user's level first
330
- const commTemplateRepo =
331
- this.reflectionHelper.getRepoService('CommTemplate');
332
- let templates = await commTemplateRepo.find({
333
- where: {
334
- code: entity.template_code,
335
- level_id: level_id,
336
- level_type: level_type,
337
- },
338
- });
339
-
340
- // Fallback to ORG + organization_id if not found
341
- if (!templates || templates.length === 0) {
342
- this.loggingService.log(
343
- 'warn',
344
- 'wrapperService',
345
- 'sendCommunicationWrapperService',
346
- `No template found for ${entity.template_code} at provided level. Falling back to ORG-level.`,
347
- [],
348
- [],
349
- );
350
-
351
- templates = await commTemplateRepo.find({
352
- where: {
353
- code: entity.template_code,
354
- organization_id: organization_id,
355
- },
356
- });
357
- }
358
-
359
- if (templates && templates.length > 0) {
360
- resolvedTemplateId = templates[0]?.id;
361
- this.loggingService.log(
362
- 'debug',
363
- 'wrapperService',
364
- 'sendCommunicationWrapperService',
365
- `Template resolved for code=${entity.template_code}, id=${resolvedTemplateId}`,
366
- [],
367
- [],
368
- );
369
- } else {
370
- this.loggingService.log(
371
- 'warn',
372
- 'wrapperService',
373
- 'sendCommunicationWrapperService',
374
- `No template found for code=${entity.template_code} at any level.`,
375
- [],
376
- [],
377
- );
378
- }
379
- }
380
-
381
- // Step Prepare payload for Integration Service
382
- const mailPayload = {
383
- to: entity.to,
384
- subject: entity.subject,
385
- html: entity.message,
386
- cc: entity?.cc,
387
- bcc: entity?.bcc,
388
- templateId: resolvedTemplateId, // updated with resolved ID
389
- message: entity.message,
390
- type: entity.type || 'EMAIL',
391
- levelId: effectiveLevelId,
392
- levelType: effectiveLevelType,
393
- app_code: appcode,
394
- user_id: loggedInUser.id,
395
- entity_type: entity.entity_type,
396
- entity_id: entity.entity_id,
397
- attachments: entity.attachments,
398
- mediaUrl: entity.mediaUrl,
399
- organization_id: organization_id,
400
- } as any;
401
-
402
- this.loggingService.log(
403
- 'debug',
404
- 'wrapperService',
405
- 'sendCommunicationWrapperService',
406
- `Final payload for sendGenericMessage: ${JSON.stringify(mailPayload)}`,
407
- [],
408
- [],
409
- );
410
-
411
- // attachments: [1, 2, 3, 4]
412
-
413
- if (entity.attachments && entity.attachments.length > 0) {
414
- mailPayload.attachments = [];
415
-
416
- for (const attachmentId of entity.attachments) {
417
- // Step 1: Download or get media file
418
- const url = await this.mediaService.getMediaDownloadUrl(
419
- attachmentId,
420
- {},
421
- 60000,
422
- );
423
-
424
- if (!url?.signedUrl) continue;
425
-
426
- // Step 2: Fetch file content
427
- const response = await axios.get(url.signedUrl, {
428
- responseType: 'arraybuffer',
429
- });
430
-
431
- // Step 3: Convert to base64
432
- const base64Content = Buffer.from(response.data).toString('base64');
433
-
434
- // Step 4: Push formatted attachment
435
- mailPayload.attachments.push({
436
- content: base64Content,
437
- type:
438
- response.headers['content-type'] || 'application/octet-stream',
439
- filename: `attachment-${attachmentId}`,
440
- disposition: 'attachment',
441
- });
442
- }
443
- }
444
-
445
- // Step 5️⃣ Send via Integration Service
446
- const result =
447
- await this.integrationService.sendGenericMessage(mailPayload);
448
-
449
- this.loggingService.log(
450
- 'log',
451
- 'wrapperService',
452
- 'sendCommunicationWrapperService',
453
- `sendCommunicationWrapper SUCCESS. Result: ${JSON.stringify(result)}`,
454
- [],
455
- [],
456
- );
457
-
458
- return result;
459
- } catch (error: any) {
460
- this.loggingService.log(
461
- 'error',
462
- 'wrapperService',
463
- 'sendCommunicationWrapperService',
464
- `sendCommunicationWrapper ERROR: ${error.message}`,
465
- [],
466
- [error.stack],
467
- );
468
- return {
469
- success: false,
470
- error: error.message,
471
- };
472
- }
473
- }
474
-
475
- /**
476
- * Wrapper for scheduling meeting
477
- */
478
-
479
- async scheduleMeetingWrapper(
480
- payload: any,
481
- loggedInUser: any,
482
- mapped_entities?: any,
483
- ) {
484
- try {
485
- this.loggingService.log(
486
- 'log',
487
- 'wrapperService',
488
- 'scheduleMeetingWrapper',
489
- `scheduleMeetingWrapper called by user=${
490
- loggedInUser?.id || 'unknown'
491
- } Payload=${JSON.stringify(payload)}`,
492
- [],
493
- [],
494
- );
495
-
496
- // Normalize emails (to, cc, bcc → attendees)
497
- const cleanEmails = (arr: string[] = []) =>
498
- arr.filter((e) => e && e.trim() !== '').map((e) => e.trim());
499
-
500
- const toList = Array.isArray(payload.to) ? cleanEmails(payload.to) : [];
501
-
502
- payload.attendees = [
503
- ...toList.map((e) => ({ email: e })),
504
- ...(payload.attendees || []).flatMap((a) =>
505
- typeof a === 'string'
506
- ? [{ email: a }]
507
- : Array.isArray(a?.email)
508
- ? a.email.map((e) => ({ email: e }))
509
- : a?.email
510
- ? [{ email: a.email }]
511
- : [],
512
- ),
513
- ];
514
-
515
- let integrationConfig =
516
- await this.integrationService.getSingleActiveConfig(
517
- payload.level_id,
518
- payload.level_type,
519
- payload.app_code,
520
- 'EMAIL',
521
- );
522
-
523
- if (integrationConfig) {
524
- return {
525
- success: true,
526
- data: await this.sendIcsInvite(
527
- payload,
528
- payload.level_id,
529
- payload.level_type,
530
- payload.app_code,
531
- loggedInUser.organization_id,
532
- mapped_entities,
533
- ),
534
- };
535
- }
536
-
537
- // ---- Step 2: Check ORG-level configs ----
538
- this.loggingService.log(
539
- 'log',
540
- 'wrapperService',
541
- 'scheduleMeetingWrapper',
542
- `No user-level config found, checking ORG-level...`,
543
- [],
544
- [],
545
- );
546
-
547
- const integrationConfigRepo =
548
- this.reflectionHelper.getRepoService('IntegrationConfig');
549
-
550
- const orgConfigs = await integrationConfigRepo.find({
551
- where: {
552
- level_id: 1,
553
- level_type: 'ORG',
554
- integration_type: 'EMAIL',
555
- app_code: 'DEFAULT',
556
- status: 1,
557
- },
558
- });
559
-
560
- integrationConfig = await this.integrationService.getSingleActiveConfig(
561
- 1,
562
- 'ORG',
563
- 'DEFAULT',
564
- 'EMAIL',
565
- );
566
-
567
- this.loggingService.log(
568
- 'debug',
569
- 'wrapperService',
570
- 'scheduleMeetingWrapper',
571
- `ORG configs found: ${JSON.stringify(orgConfigs)}`,
572
- [],
573
- [],
574
- );
575
-
576
- if (integrationConfig) {
577
- return {
578
- success: true,
579
- data: await this.sendIcsInvite(
580
- payload,
581
- 1,
582
- 'ORG',
583
- 'DEFAULT',
584
- loggedInUser.organization_id,
585
- mapped_entities,
586
- ),
587
- };
588
- }
589
- } catch (error: any) {
590
- this.loggingService.log(
591
- 'error',
592
- 'wrapperService',
593
- 'scheduleMeetingWrapper',
594
- `scheduleMeetingWrapper ERROR: ${error.message}`,
595
- [],
596
- [error.stack],
597
- );
598
- return { success: false, error: error.message };
599
- }
600
- }
601
-
602
- /**
603
- * Fetch credentials JSON by config ID
604
- */
605
- private async getConfigCred(configId: number) {
606
- this.loggingService.log(
607
- 'debug',
608
- 'wrapperService',
609
- 'getConfigCred',
610
- `Fetching config JSON for configId=${configId}`,
611
- [],
612
- [],
613
- );
614
-
615
- const integrationConfigRepo =
616
- this.reflectionHelper.getRepoService('IntegrationConfig');
617
-
618
- const configRes = await integrationConfigRepo.findOne({
619
- where: {
620
- id: configId,
621
- },
622
- });
623
-
624
- this.loggingService.log(
625
- 'debug',
626
- 'wrapperService',
627
- 'getConfigCred',
628
- `Config fetch result: ${JSON.stringify(configRes)}`,
629
- [],
630
- [],
631
- );
632
- return configRes?.config_json || null;
633
- }
634
-
635
- private async sendIcsInvite(
636
- payload: any,
637
- levelId: number,
638
- levelType: string,
639
- appCode: string,
640
- organizationId: number,
641
- mapped_entities?: any,
642
- ) {
643
- this.loggingService.log(
644
- 'log',
645
- 'wrapperService',
646
- 'sendIcsInvite',
647
- `Generating ICS file. Payload: ${JSON.stringify(payload)}`,
648
- [],
649
- [],
650
- );
651
-
652
- if (payload.template_code) {
653
- const commTemplateRepo =
654
- this.reflectionHelper.getRepoService('CommTemplate');
655
- let templates = await commTemplateRepo.find({
656
- where: {
657
- code: payload.template_code,
658
- level_id: levelId,
659
- level_type: levelType,
660
- },
661
- });
662
-
663
- if (templates && templates.length > 0) {
664
- payload['templateId'] = templates[0].id;
665
- }
666
- }
667
-
668
- let activeConfig = await this.integrationService.getSingleActiveConfig(
669
- levelId,
670
- levelType,
671
- appCode,
672
- 'EMAIL',
673
- );
674
- const base64String = await this.icsService.generateIcs(
675
- payload,
676
- activeConfig?.config_json,
677
- );
678
- this.loggingService.log(
679
- 'debug',
680
- 'wrapperService',
681
- 'sendIcsInvite',
682
- `ICS generated (base64 length: ${base64String?.length})`,
683
- [],
684
- [],
685
- );
686
-
687
- // Normalize attendees
688
- const attendeeEmails =
689
- payload.attendees?.flatMap((a) =>
690
- Array.isArray(a.email) ? a.email : [a.email],
691
- ) || [];
692
-
693
- // Combine into one list (to + attendees)
694
- const toList = Array.from(
695
- new Set(
696
- [
697
- ...(Array.isArray(payload.to)
698
- ? payload.to
699
- : payload.to
700
- ? [payload.to]
701
- : []),
702
- ...attendeeEmails,
703
- ].map((email) => email.toLowerCase().trim()),
704
- ),
705
- );
706
-
707
- const payloadSendMail: GenericMessageDto = {
708
- levelId,
709
- levelType,
710
- app_code: appCode,
711
- to: toList,
712
- message: payload.message,
713
- subject: payload.subject,
714
- type: 'EMAIL',
715
- cc: payload.cc,
716
- bcc: payload.bcc,
717
- html: payload.html,
718
- attachments: [
719
- {
720
- content: base64String,
721
- type: 'text/calendar',
722
- filename: 'invite.ics',
723
- disposition: 'attachment',
724
- },
725
- ],
726
- templateId: payload.templateId,
727
- entity_id: payload.entity_id,
728
- entity_type: payload.entity_type,
729
- organization_id: organizationId,
730
- mapped_entities,
731
- };
732
-
733
- this.loggingService.log(
734
- 'debug',
735
- 'wrapperService',
736
- 'sendIcsInvite',
737
- `Final payload for ICS send: ${JSON.stringify(payloadSendMail)}`,
738
- [],
739
- [],
740
- );
741
- const result =
742
- await this.integrationService.sendGenericMessage(payloadSendMail);
743
- this.loggingService.log(
744
- 'log',
745
- 'wrapperService',
746
- 'sendIcsInvite',
747
- `ICS mail send result: ${JSON.stringify(result)}`,
748
- [],
749
- [],
750
- );
751
- return result;
752
- }
753
- }
1
+ import { Injectable, Logger } from '@nestjs/common';
2
+ import { GenericMessageDto, IntegrationService } from './integration.service';
3
+ import { IcsMeetingService } from 'src/module/ics/service/ics.service';
4
+ import { LoggingService } from 'src/utils/service/loggingUtil.service';
5
+ import { ReflectionHelper } from '../../../utils/service/reflection-helper.service';
6
+ import { MediaDataService } from 'src/module/meta/service/media-data.service';
7
+ import axios from 'axios';
8
+
9
+ @Injectable()
10
+ export class WrapperService {
11
+ private readonly logger = new Logger(WrapperService.name);
12
+
13
+ constructor(
14
+ private readonly integrationService: IntegrationService,
15
+ private readonly icsService: IcsMeetingService,
16
+ private readonly loggingService: LoggingService,
17
+ private readonly reflectionHelper: ReflectionHelper,
18
+ private readonly mediaService: MediaDataService,
19
+ ) {}
20
+
21
+ /**
22
+ * Wrapper for sending mail
23
+ */
24
+ async sendMailWrapper(payload: any, loggedInUser: any) {
25
+ try {
26
+ this.loggingService.log(
27
+ 'debug',
28
+ 'wrapperService',
29
+ 'sendMailWrapper',
30
+ `sendMailWrapper called. User: ${JSON.stringify(
31
+ loggedInUser,
32
+ )}, Payload: ${JSON.stringify(payload)}`,
33
+ [],
34
+ [],
35
+ );
36
+
37
+ const { level_id, level_type, organization_id } = loggedInUser;
38
+
39
+ // 1. Check for config at user’s level
40
+ this.loggingService.log(
41
+ 'debug',
42
+ 'wrapperService',
43
+ 'sendMailWrapper',
44
+ `Fetching configs for level_id=${level_id}, level_type=${level_type}`,
45
+ [],
46
+ [],
47
+ );
48
+ const intergrationConfigRepo =
49
+ this.reflectionHelper.getRepoService('IntegrationConfig');
50
+ const configs = await intergrationConfigRepo.find({
51
+ where: {
52
+ level_id: level_id,
53
+ level_type: level_type,
54
+ status: 1,
55
+ integration_type: 'EMAIL',
56
+ },
57
+ });
58
+
59
+ this.loggingService.log(
60
+ 'debug',
61
+ 'wrapperService',
62
+ 'sendMailWrapper',
63
+ `Configs found: ${JSON.stringify(configs)}`,
64
+ [],
65
+ [],
66
+ );
67
+
68
+ let templateCode: string | undefined;
69
+
70
+ if (payload.templateCode) {
71
+ this.loggingService.log(
72
+ 'debug',
73
+ 'wrapperService',
74
+ 'sendMailWrapper',
75
+ `Looking up templateCode=${payload.templateCode} for current level`,
76
+ [],
77
+ [],
78
+ );
79
+
80
+ const templateRepo =
81
+ this.reflectionHelper.getRepoService('CommTemplate');
82
+
83
+ const template = await templateRepo.findOne({
84
+ where: {
85
+ code: payload.templateCode,
86
+ level_id: level_id,
87
+ level_type: level_type,
88
+ },
89
+ });
90
+
91
+ this.loggingService.log(
92
+ 'debug',
93
+ 'wrapperService',
94
+ 'sendMailWrapper',
95
+ `Template lookup result: ${JSON.stringify(template)}`,
96
+ [],
97
+ [],
98
+ );
99
+
100
+ if (template) {
101
+ templateCode = template.rich_text;
102
+ } else {
103
+ this.loggingService.log(
104
+ 'warn',
105
+ 'wrapperService',
106
+ 'sendMailWrapper',
107
+ `No template found for templateCode=${payload.templateCode} and current level`,
108
+ [],
109
+ [],
110
+ );
111
+ }
112
+ }
113
+
114
+ let payloadSendMail: GenericMessageDto;
115
+
116
+ if (configs && configs.length > 0) {
117
+ this.loggingService.log(
118
+ 'debug',
119
+ 'wrapperService',
120
+ 'sendMailWrapper',
121
+ `Using user-level configs`,
122
+ [],
123
+ [],
124
+ );
125
+
126
+ payloadSendMail = {
127
+ levelId: level_id,
128
+ levelType: level_type,
129
+ app_code: 'DEFAULT', // Legacy wrapper default
130
+ to: payload.to,
131
+ message: payload.message,
132
+ subject: payload.subject,
133
+ type: 'EMAIL',
134
+ cc: payload.cc,
135
+ bcc: payload.bcc,
136
+ html: payload.html,
137
+ // attachments: payload.attachments,
138
+ templateId: payload.templateId,
139
+ variables: payload.variables,
140
+ organization_id: loggedInUser.organization_id,
141
+ };
142
+ } else {
143
+ this.loggingService.log(
144
+ 'warn',
145
+ 'wrapperService',
146
+ 'sendMailWrapper',
147
+ `No user-level configs found. Falling back to ORG-level`,
148
+ [],
149
+ [],
150
+ );
151
+
152
+ const fallbackConfigs = await intergrationConfigRepo.find({
153
+ where: {
154
+ level_type: 'ORG',
155
+ integration_type: 'EMAIL',
156
+ status: 1,
157
+ },
158
+ });
159
+
160
+ this.loggingService.log(
161
+ 'debug',
162
+ 'wrapperService',
163
+ 'sendMailWrapper',
164
+ `ORG-level configs: ${JSON.stringify(fallbackConfigs)}`,
165
+ [],
166
+ [],
167
+ );
168
+
169
+ if (!fallbackConfigs || fallbackConfigs.length === 0) {
170
+ this.loggingService.log(
171
+ 'warn',
172
+ 'wrapperService',
173
+ 'sendMailWrapper',
174
+ 'No active email communication config found',
175
+ [],
176
+ [],
177
+ );
178
+ }
179
+
180
+ payloadSendMail = {
181
+ levelId: 1,
182
+ levelType: 'ORG',
183
+ app_code: 'DEFAULT', // Legacy wrapper default
184
+ to: payload.to,
185
+ message: payload.message,
186
+ subject: payload.subject,
187
+ type: 'EMAIL',
188
+ cc: payload.cc,
189
+ bcc: payload.bcc,
190
+ html: payload.html,
191
+ // attachments: payload.attachments,
192
+ // templateId: payload.templateId,
193
+ variables: payload.variables,
194
+ organization_id: loggedInUser.organization_id,
195
+ };
196
+ }
197
+
198
+ this.loggingService.log(
199
+ 'debug',
200
+ 'wrapperService',
201
+ 'sendMailWrapper',
202
+ `Final payload for IntegrationService: ${JSON.stringify(
203
+ payloadSendMail,
204
+ )}`,
205
+ [],
206
+ [],
207
+ );
208
+
209
+ const result =
210
+ await this.integrationService.sendGenericMessage(payloadSendMail);
211
+
212
+ this.loggingService.log(
213
+ 'log',
214
+ 'wrapperService',
215
+ 'sendMailWrapper',
216
+ `sendMailWrapper SUCCESS. Result: ${JSON.stringify(result)}`,
217
+ [],
218
+ [],
219
+ );
220
+
221
+ return {
222
+ success: true,
223
+ data: result,
224
+ };
225
+ } catch (error: any) {
226
+ this.loggingService.log(
227
+ 'error',
228
+ 'wrapperService',
229
+ 'sendMailWrapper',
230
+ `sendMailWrapper ERROR: ${error.message}`,
231
+ [],
232
+ [error.stack], // Sending stack trace as additional data
233
+ );
234
+ return {
235
+ success: false,
236
+ error: error.message,
237
+ };
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Wrapper for sending communication
243
+ */
244
+
245
+ async sendCommunicationWrapperService(entity: any, loggedInUser: any) {
246
+ try {
247
+ this.loggingService.log(
248
+ 'log',
249
+ 'wrapperService',
250
+ 'sendCommunicationWrapperService',
251
+ `sendCommunicationWrapper called. User: ${JSON.stringify(
252
+ loggedInUser,
253
+ )}, Payload: ${JSON.stringify(entity)}`,
254
+ [],
255
+ [],
256
+ );
257
+
258
+ const { level_id, level_type, appcode, organization_id } = loggedInUser;
259
+
260
+ // Check if active configs exist for current user's level
261
+ this.loggingService.log(
262
+ 'debug',
263
+ 'wrapperService',
264
+ 'sendCommunicationWrapperService',
265
+ `Checking active ${
266
+ entity.type || 'EMAIL'
267
+ } configs for level_id=${level_id}, level_type=${level_type}, app_code=${appcode}`,
268
+ [],
269
+ [],
270
+ );
271
+
272
+ let configs = await this.integrationService.getActiveConfigs(
273
+ level_id,
274
+ level_type,
275
+ appcode,
276
+ entity.type || 'EMAIL',
277
+ );
278
+
279
+ let effectiveLevelId = level_id;
280
+ let effectiveLevelType = level_type;
281
+
282
+ // Fallback to ORG-level if no configs found
283
+ if (!configs || configs.length === 0) {
284
+ this.loggingService.log(
285
+ 'warn',
286
+ 'wrapperService',
287
+ 'sendCommunicationWrapperService',
288
+ `No active configs found for ${level_type}:${level_id}, falling back to ORG-level`,
289
+ [],
290
+ [],
291
+ );
292
+
293
+ configs = await this.integrationService.getActiveConfigs(
294
+ 1,
295
+ 'ORG',
296
+ appcode,
297
+ entity.type || 'EMAIL',
298
+ );
299
+
300
+ effectiveLevelId = 1;
301
+ effectiveLevelType = 'ORG';
302
+ }
303
+
304
+ if (!configs || configs.length === 0) {
305
+ this.loggingService.log(
306
+ 'error',
307
+ 'wrapperService',
308
+ 'sendCommunicationWrapperService',
309
+ 'No active configurations found at any level.',
310
+ [],
311
+ [],
312
+ );
313
+ throw new Error('No active configurations found.');
314
+ }
315
+
316
+ // Template lookup if templateCode is provided
317
+ let resolvedTemplateId = entity?.templateId;
318
+
319
+ if (entity.template_code) {
320
+ this.loggingService.log(
321
+ 'debug',
322
+ 'wrapperService',
323
+ 'sendCommunicationWrapperService',
324
+ `Looking up template for code=${entity.template_code}, level_id=${level_id}, level_type=${level_type}`,
325
+ [],
326
+ [],
327
+ );
328
+
329
+ // Try to find template at user's level first
330
+ const commTemplateRepo =
331
+ this.reflectionHelper.getRepoService('CommTemplate');
332
+ let templates = await commTemplateRepo.find({
333
+ where: {
334
+ code: entity.template_code,
335
+ level_id: level_id,
336
+ level_type: level_type,
337
+ },
338
+ });
339
+
340
+ // Fallback to ORG + organization_id if not found
341
+ if (!templates || templates.length === 0) {
342
+ this.loggingService.log(
343
+ 'warn',
344
+ 'wrapperService',
345
+ 'sendCommunicationWrapperService',
346
+ `No template found for ${entity.template_code} at provided level. Falling back to ORG-level.`,
347
+ [],
348
+ [],
349
+ );
350
+
351
+ templates = await commTemplateRepo.find({
352
+ where: {
353
+ code: entity.template_code,
354
+ organization_id: organization_id,
355
+ },
356
+ });
357
+ }
358
+
359
+ if (templates && templates.length > 0) {
360
+ resolvedTemplateId = templates[0]?.id;
361
+ this.loggingService.log(
362
+ 'debug',
363
+ 'wrapperService',
364
+ 'sendCommunicationWrapperService',
365
+ `Template resolved for code=${entity.template_code}, id=${resolvedTemplateId}`,
366
+ [],
367
+ [],
368
+ );
369
+ } else {
370
+ this.loggingService.log(
371
+ 'warn',
372
+ 'wrapperService',
373
+ 'sendCommunicationWrapperService',
374
+ `No template found for code=${entity.template_code} at any level.`,
375
+ [],
376
+ [],
377
+ );
378
+ }
379
+ }
380
+
381
+ // Step Prepare payload for Integration Service
382
+ const mailPayload = {
383
+ to: entity.to,
384
+ subject: entity.subject,
385
+ html: entity.message,
386
+ cc: entity?.cc,
387
+ bcc: entity?.bcc,
388
+ templateId: resolvedTemplateId, // updated with resolved ID
389
+ message: entity.message,
390
+ type: entity.type || 'EMAIL',
391
+ levelId: effectiveLevelId,
392
+ levelType: effectiveLevelType,
393
+ app_code: appcode,
394
+ user_id: loggedInUser.id,
395
+ entity_type: entity.entity_type,
396
+ entity_id: entity.entity_id,
397
+ attachments: entity.attachments,
398
+ mediaUrl: entity.mediaUrl,
399
+ organization_id: organization_id,
400
+ } as any;
401
+
402
+ this.loggingService.log(
403
+ 'debug',
404
+ 'wrapperService',
405
+ 'sendCommunicationWrapperService',
406
+ `Final payload for sendGenericMessage: ${JSON.stringify(mailPayload)}`,
407
+ [],
408
+ [],
409
+ );
410
+
411
+ // attachments: [1, 2, 3, 4]
412
+
413
+ if (entity.attachments && entity.attachments.length > 0) {
414
+ mailPayload.attachments = [];
415
+
416
+ for (const attachmentId of entity.attachments) {
417
+ // Step 1: Download or get media file
418
+ const url = await this.mediaService.getMediaDownloadUrl(
419
+ attachmentId,
420
+ {},
421
+ 60000,
422
+ );
423
+
424
+ if (!url?.signedUrl) continue;
425
+
426
+ // Step 2: Fetch file content
427
+ const response = await axios.get(url.signedUrl, {
428
+ responseType: 'arraybuffer',
429
+ });
430
+
431
+ // Step 3: Convert to base64
432
+ const base64Content = Buffer.from(response.data).toString('base64');
433
+
434
+ // Step 4: Push formatted attachment
435
+ mailPayload.attachments.push({
436
+ content: base64Content,
437
+ type:
438
+ response.headers['content-type'] || 'application/octet-stream',
439
+ filename: `attachment-${attachmentId}`,
440
+ disposition: 'attachment',
441
+ });
442
+ }
443
+ }
444
+
445
+ // Step 5️⃣ Send via Integration Service
446
+ const result =
447
+ await this.integrationService.sendGenericMessage(mailPayload);
448
+
449
+ this.loggingService.log(
450
+ 'log',
451
+ 'wrapperService',
452
+ 'sendCommunicationWrapperService',
453
+ `sendCommunicationWrapper SUCCESS. Result: ${JSON.stringify(result)}`,
454
+ [],
455
+ [],
456
+ );
457
+
458
+ return result;
459
+ } catch (error: any) {
460
+ this.loggingService.log(
461
+ 'error',
462
+ 'wrapperService',
463
+ 'sendCommunicationWrapperService',
464
+ `sendCommunicationWrapper ERROR: ${error.message}`,
465
+ [],
466
+ [error.stack],
467
+ );
468
+ return {
469
+ success: false,
470
+ error: error.message,
471
+ };
472
+ }
473
+ }
474
+
475
+ /**
476
+ * Wrapper for scheduling meeting
477
+ */
478
+
479
+ async scheduleMeetingWrapper(
480
+ payload: any,
481
+ loggedInUser: any,
482
+ mapped_entities?: any,
483
+ ) {
484
+ try {
485
+ this.loggingService.log(
486
+ 'log',
487
+ 'wrapperService',
488
+ 'scheduleMeetingWrapper',
489
+ `scheduleMeetingWrapper called by user=${
490
+ loggedInUser?.id || 'unknown'
491
+ } Payload=${JSON.stringify(payload)}`,
492
+ [],
493
+ [],
494
+ );
495
+
496
+ // Normalize emails (to, cc, bcc → attendees)
497
+ const cleanEmails = (arr: string[] = []) =>
498
+ arr.filter((e) => e && e.trim() !== '').map((e) => e.trim());
499
+
500
+ const toList = Array.isArray(payload.to) ? cleanEmails(payload.to) : [];
501
+
502
+ payload.attendees = [
503
+ ...toList.map((e) => ({ email: e })),
504
+ ...(payload.attendees || []).flatMap((a) =>
505
+ typeof a === 'string'
506
+ ? [{ email: a }]
507
+ : Array.isArray(a?.email)
508
+ ? a.email.map((e) => ({ email: e }))
509
+ : a?.email
510
+ ? [{ email: a.email }]
511
+ : [],
512
+ ),
513
+ ];
514
+
515
+ let integrationConfig =
516
+ await this.integrationService.getSingleActiveConfig(
517
+ payload.level_id,
518
+ payload.level_type,
519
+ payload.app_code,
520
+ 'EMAIL',
521
+ );
522
+
523
+ if (integrationConfig) {
524
+ return {
525
+ success: true,
526
+ data: await this.sendIcsInvite(
527
+ payload,
528
+ payload.level_id,
529
+ payload.level_type,
530
+ payload.app_code,
531
+ loggedInUser.organization_id,
532
+ mapped_entities,
533
+ ),
534
+ };
535
+ }
536
+
537
+ // ---- Step 2: Check ORG-level configs ----
538
+ this.loggingService.log(
539
+ 'log',
540
+ 'wrapperService',
541
+ 'scheduleMeetingWrapper',
542
+ `No user-level config found, checking ORG-level...`,
543
+ [],
544
+ [],
545
+ );
546
+
547
+ const integrationConfigRepo =
548
+ this.reflectionHelper.getRepoService('IntegrationConfig');
549
+
550
+ const orgConfigs = await integrationConfigRepo.find({
551
+ where: {
552
+ level_id: 1,
553
+ level_type: 'ORG',
554
+ integration_type: 'EMAIL',
555
+ app_code: 'DEFAULT',
556
+ status: 1,
557
+ },
558
+ });
559
+
560
+ integrationConfig = await this.integrationService.getSingleActiveConfig(
561
+ 1,
562
+ 'ORG',
563
+ 'DEFAULT',
564
+ 'EMAIL',
565
+ );
566
+
567
+ this.loggingService.log(
568
+ 'debug',
569
+ 'wrapperService',
570
+ 'scheduleMeetingWrapper',
571
+ `ORG configs found: ${JSON.stringify(orgConfigs)}`,
572
+ [],
573
+ [],
574
+ );
575
+
576
+ if (integrationConfig) {
577
+ return {
578
+ success: true,
579
+ data: await this.sendIcsInvite(
580
+ payload,
581
+ 1,
582
+ 'ORG',
583
+ 'DEFAULT',
584
+ loggedInUser.organization_id,
585
+ mapped_entities,
586
+ ),
587
+ };
588
+ }
589
+ } catch (error: any) {
590
+ this.loggingService.log(
591
+ 'error',
592
+ 'wrapperService',
593
+ 'scheduleMeetingWrapper',
594
+ `scheduleMeetingWrapper ERROR: ${error.message}`,
595
+ [],
596
+ [error.stack],
597
+ );
598
+ return { success: false, error: error.message };
599
+ }
600
+ }
601
+
602
+ /**
603
+ * Fetch credentials JSON by config ID
604
+ */
605
+ private async getConfigCred(configId: number) {
606
+ this.loggingService.log(
607
+ 'debug',
608
+ 'wrapperService',
609
+ 'getConfigCred',
610
+ `Fetching config JSON for configId=${configId}`,
611
+ [],
612
+ [],
613
+ );
614
+
615
+ const integrationConfigRepo =
616
+ this.reflectionHelper.getRepoService('IntegrationConfig');
617
+
618
+ const configRes = await integrationConfigRepo.findOne({
619
+ where: {
620
+ id: configId,
621
+ },
622
+ });
623
+
624
+ this.loggingService.log(
625
+ 'debug',
626
+ 'wrapperService',
627
+ 'getConfigCred',
628
+ `Config fetch result: ${JSON.stringify(configRes)}`,
629
+ [],
630
+ [],
631
+ );
632
+ return configRes?.config_json || null;
633
+ }
634
+
635
+ private async sendIcsInvite(
636
+ payload: any,
637
+ levelId: number,
638
+ levelType: string,
639
+ appCode: string,
640
+ organizationId: number,
641
+ mapped_entities?: any,
642
+ ) {
643
+ this.loggingService.log(
644
+ 'log',
645
+ 'wrapperService',
646
+ 'sendIcsInvite',
647
+ `Generating ICS file. Payload: ${JSON.stringify(payload)}`,
648
+ [],
649
+ [],
650
+ );
651
+
652
+ if (payload.template_code) {
653
+ const commTemplateRepo =
654
+ this.reflectionHelper.getRepoService('CommTemplate');
655
+ let templates = await commTemplateRepo.find({
656
+ where: {
657
+ code: payload.template_code,
658
+ level_id: levelId,
659
+ level_type: levelType,
660
+ },
661
+ });
662
+
663
+ if (templates && templates.length > 0) {
664
+ payload['templateId'] = templates[0].id;
665
+ }
666
+ }
667
+
668
+ let activeConfig = await this.integrationService.getSingleActiveConfig(
669
+ levelId,
670
+ levelType,
671
+ appCode,
672
+ 'EMAIL',
673
+ );
674
+ const base64String = await this.icsService.generateIcs(
675
+ payload,
676
+ activeConfig?.config_json,
677
+ );
678
+ this.loggingService.log(
679
+ 'debug',
680
+ 'wrapperService',
681
+ 'sendIcsInvite',
682
+ `ICS generated (base64 length: ${base64String?.length})`,
683
+ [],
684
+ [],
685
+ );
686
+
687
+ // Normalize attendees
688
+ const attendeeEmails =
689
+ payload.attendees?.flatMap((a) =>
690
+ Array.isArray(a.email) ? a.email : [a.email],
691
+ ) || [];
692
+
693
+ // Combine into one list (to + attendees)
694
+ const toList = Array.from(
695
+ new Set(
696
+ [
697
+ ...(Array.isArray(payload.to)
698
+ ? payload.to
699
+ : payload.to
700
+ ? [payload.to]
701
+ : []),
702
+ ...attendeeEmails,
703
+ ].map((email) => email.toLowerCase().trim()),
704
+ ),
705
+ );
706
+
707
+ const payloadSendMail: GenericMessageDto = {
708
+ levelId,
709
+ levelType,
710
+ app_code: appCode,
711
+ to: toList,
712
+ message: payload.message,
713
+ subject: payload.subject,
714
+ type: 'EMAIL',
715
+ cc: payload.cc,
716
+ bcc: payload.bcc,
717
+ html: payload.html,
718
+ attachments: [
719
+ {
720
+ content: base64String,
721
+ type: 'text/calendar',
722
+ filename: 'invite.ics',
723
+ disposition: 'attachment',
724
+ },
725
+ ],
726
+ templateId: payload.templateId,
727
+ entity_id: payload.entity_id,
728
+ entity_type: payload.entity_type,
729
+ organization_id: organizationId,
730
+ mapped_entities,
731
+ };
732
+
733
+ this.loggingService.log(
734
+ 'debug',
735
+ 'wrapperService',
736
+ 'sendIcsInvite',
737
+ `Final payload for ICS send: ${JSON.stringify(payloadSendMail)}`,
738
+ [],
739
+ [],
740
+ );
741
+ const result =
742
+ await this.integrationService.sendGenericMessage(payloadSendMail);
743
+ this.loggingService.log(
744
+ 'log',
745
+ 'wrapperService',
746
+ 'sendIcsInvite',
747
+ `ICS mail send result: ${JSON.stringify(result)}`,
748
+ [],
749
+ [],
750
+ );
751
+ return result;
752
+ }
753
+ }