@wildo-ai/saas-backend-lib 1.1.0 → 1.1.2

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 (265) hide show
  1. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts +14 -3
  2. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts.map +1 -1
  3. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js +115 -22
  4. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js.map +1 -1
  5. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts +3 -1
  6. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts.map +1 -1
  7. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js +8 -3
  8. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js.map +1 -1
  9. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts +11 -0
  10. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts.map +1 -1
  11. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js +11 -2
  12. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js.map +1 -1
  13. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts +1 -0
  14. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts.map +1 -1
  15. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js +6 -1
  16. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js.map +1 -1
  17. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.d.ts.map +1 -1
  18. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js +16 -0
  19. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js.map +1 -1
  20. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts +20 -6
  21. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts.map +1 -1
  22. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js +88 -32
  23. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js.map +1 -1
  24. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts +3 -1
  25. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts.map +1 -1
  26. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js +32 -7
  27. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js.map +1 -1
  28. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts +8 -5
  29. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts.map +1 -1
  30. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.js.map +1 -1
  31. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts +31 -0
  32. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts.map +1 -1
  33. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js +127 -5
  34. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js.map +1 -1
  35. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts +71 -1
  36. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts.map +1 -1
  37. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js +62 -2
  38. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js.map +1 -1
  39. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts +21 -0
  40. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts.map +1 -1
  41. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js +126 -4
  42. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js.map +1 -1
  43. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts +3 -26
  44. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts.map +1 -1
  45. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js +3 -68
  46. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js.map +1 -1
  47. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
  48. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +4 -2
  49. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
  50. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js +6 -6
  51. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js.map +1 -1
  52. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts +38 -0
  53. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts.map +1 -1
  54. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js +40 -0
  55. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js.map +1 -1
  56. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts +20 -0
  57. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts.map +1 -1
  58. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js +28 -0
  59. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js.map +1 -1
  60. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts +12 -0
  61. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -0
  62. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js +118 -0
  63. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js.map +1 -0
  64. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts.map +1 -1
  65. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js +8 -5
  66. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js.map +1 -1
  67. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.d.ts.map +1 -1
  68. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js +14 -0
  69. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js.map +1 -1
  70. package/dist/esm/config/custom/application-config-controller.backend.service.d.ts.map +1 -1
  71. package/dist/esm/config/custom/application-config-controller.backend.service.js +7 -1
  72. package/dist/esm/config/custom/application-config-controller.backend.service.js.map +1 -1
  73. package/dist/esm/config/models/app-config.backend.schemas.d.ts +4 -0
  74. package/dist/esm/config/models/app-config.backend.schemas.d.ts.map +1 -1
  75. package/dist/esm/config/services/app-configuration.backend.utils.d.ts +10 -1
  76. package/dist/esm/config/services/app-configuration.backend.utils.d.ts.map +1 -1
  77. package/dist/esm/config/services/app-configuration.backend.utils.js +13 -2
  78. package/dist/esm/config/services/app-configuration.backend.utils.js.map +1 -1
  79. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.d.ts +2 -2
  80. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js +2 -2
  81. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js.map +1 -1
  82. package/dist/esm/databases/models/filter.backend.schemas.js +2 -2
  83. package/dist/esm/databases/models/filter.backend.schemas.js.map +1 -1
  84. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.d.ts.map +1 -1
  85. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js +20 -1
  86. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js.map +1 -1
  87. package/dist/esm/databases/services/redis.service.d.ts +27 -0
  88. package/dist/esm/databases/services/redis.service.d.ts.map +1 -1
  89. package/dist/esm/databases/services/redis.service.js +29 -0
  90. package/dist/esm/databases/services/redis.service.js.map +1 -1
  91. package/dist/esm/errors/services/error-handler.backend.service.d.ts.map +1 -1
  92. package/dist/esm/errors/services/error-handler.backend.service.js +5 -0
  93. package/dist/esm/errors/services/error-handler.backend.service.js.map +1 -1
  94. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts +41 -0
  95. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts.map +1 -0
  96. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js +40 -0
  97. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js.map +1 -0
  98. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts +64 -0
  99. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts.map +1 -0
  100. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js +193 -0
  101. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js.map +1 -0
  102. package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts +13 -2
  103. package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts.map +1 -1
  104. package/dist/esm/external-data/external-data-pipeline-run.backend.service.js +8 -2
  105. package/dist/esm/external-data/external-data-pipeline-run.backend.service.js.map +1 -1
  106. package/dist/esm/external-data/external-data-transform.backend.d.ts.map +1 -1
  107. package/dist/esm/external-data/external-data-transform.backend.js +7 -1
  108. package/dist/esm/external-data/external-data-transform.backend.js.map +1 -1
  109. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts +2 -0
  110. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts.map +1 -1
  111. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js +13 -0
  112. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js.map +1 -1
  113. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +14 -0
  114. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
  115. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +6 -0
  116. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
  117. package/dist/esm/files/controllers/file.controller.d.ts +24 -1
  118. package/dist/esm/files/controllers/file.controller.d.ts.map +1 -1
  119. package/dist/esm/files/controllers/file.controller.js +66 -2
  120. package/dist/esm/files/controllers/file.controller.js.map +1 -1
  121. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts +17 -0
  122. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts.map +1 -0
  123. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js +1 -0
  124. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js.map +1 -0
  125. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts +5 -1
  126. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts.map +1 -1
  127. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js +42 -3
  128. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js.map +1 -1
  129. package/dist/esm/files/services/file-operation-handler.backend.service.d.ts +18 -0
  130. package/dist/esm/files/services/file-operation-handler.backend.service.d.ts.map +1 -1
  131. package/dist/esm/files/services/file-operation-handler.backend.service.js +36 -28
  132. package/dist/esm/files/services/file-operation-handler.backend.service.js.map +1 -1
  133. package/dist/esm/files/services/file-upload-grant.backend.service.d.ts +163 -0
  134. package/dist/esm/files/services/file-upload-grant.backend.service.d.ts.map +1 -0
  135. package/dist/esm/files/services/file-upload-grant.backend.service.js +442 -0
  136. package/dist/esm/files/services/file-upload-grant.backend.service.js.map +1 -0
  137. package/dist/esm/files/services/files.backend.service.d.ts +19 -0
  138. package/dist/esm/files/services/files.backend.service.d.ts.map +1 -1
  139. package/dist/esm/files/services/files.backend.service.js +78 -15
  140. package/dist/esm/files/services/files.backend.service.js.map +1 -1
  141. package/dist/esm/files/utils/file-uploader.utils.d.ts.map +1 -1
  142. package/dist/esm/files/utils/file-uploader.utils.js +12 -0
  143. package/dist/esm/files/utils/file-uploader.utils.js.map +1 -1
  144. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js +5 -5
  145. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js.map +1 -1
  146. package/dist/esm/flows-actors/services/agents.backend.service.d.ts +79 -0
  147. package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
  148. package/dist/esm/flows-actors/services/agents.backend.service.js +319 -42
  149. package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
  150. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts +151 -41
  151. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
  152. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +300 -139
  153. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
  154. package/dist/esm/index.d.ts +4 -1
  155. package/dist/esm/index.d.ts.map +1 -1
  156. package/dist/esm/index.js +14 -1
  157. package/dist/esm/index.js.map +1 -1
  158. package/dist/esm/inject/models/container.d.ts.map +1 -1
  159. package/dist/esm/inject/models/container.js +4 -0
  160. package/dist/esm/inject/models/container.js.map +1 -1
  161. package/dist/esm/inject/models/service-types.d.ts +3 -0
  162. package/dist/esm/inject/models/service-types.d.ts.map +1 -1
  163. package/dist/esm/inject/models/service-types.js +2 -0
  164. package/dist/esm/inject/models/service-types.js.map +1 -1
  165. package/dist/esm/mcp/controllers/mcp.controller.d.ts.map +1 -1
  166. package/dist/esm/mcp/controllers/mcp.controller.js +12 -4
  167. package/dist/esm/mcp/controllers/mcp.controller.js.map +1 -1
  168. package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts +34 -0
  169. package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts.map +1 -1
  170. package/dist/esm/mcp/models/mcp-tool.backend.schemas.js +42 -0
  171. package/dist/esm/mcp/models/mcp-tool.backend.schemas.js.map +1 -1
  172. package/dist/esm/mcp/services/mcp-server.backend.service.d.ts +29 -1
  173. package/dist/esm/mcp/services/mcp-server.backend.service.d.ts.map +1 -1
  174. package/dist/esm/mcp/services/mcp-server.backend.service.js +131 -3
  175. package/dist/esm/mcp/services/mcp-server.backend.service.js.map +1 -1
  176. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts +64 -2
  177. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts.map +1 -1
  178. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js +130 -6
  179. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js.map +1 -1
  180. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts +9 -0
  181. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts.map +1 -1
  182. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js +11 -36
  183. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js.map +1 -1
  184. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.d.ts.map +1 -1
  185. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js +9 -7
  186. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js.map +1 -1
  187. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts +5 -5
  188. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts.map +1 -1
  189. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js +14 -13
  190. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js.map +1 -1
  191. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts +2 -1
  192. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts.map +1 -1
  193. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js +2 -2
  194. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js.map +1 -1
  195. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.d.ts.map +1 -1
  196. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js +9 -7
  197. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js.map +1 -1
  198. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.d.ts.map +1 -1
  199. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js +4 -1
  200. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js.map +1 -1
  201. package/dist/esm/requests/service/websocket.service.d.ts.map +1 -1
  202. package/dist/esm/requests/service/websocket.service.js +56 -7
  203. package/dist/esm/requests/service/websocket.service.js.map +1 -1
  204. package/dist/esm/resources/models/custom-service-implementations.backend.definition.d.ts.map +1 -1
  205. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js +2 -0
  206. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js.map +1 -1
  207. package/dist/esm/resources/services/resource-id.backend.service.js +3 -3
  208. package/dist/esm/resources/services/resource-id.backend.service.js.map +1 -1
  209. package/dist/esm/resources/services/resources-registry.backend.service.js +1 -1
  210. package/dist/esm/resources/services/resources-registry.backend.service.js.map +1 -1
  211. package/dist/esm/runtime/services/execution-context-creator.backend.service.d.ts.map +1 -1
  212. package/dist/esm/runtime/services/execution-context-creator.backend.service.js +13 -7
  213. package/dist/esm/runtime/services/execution-context-creator.backend.service.js.map +1 -1
  214. package/dist/esm/runtime/services/start-application.backend.service.d.ts +28 -0
  215. package/dist/esm/runtime/services/start-application.backend.service.d.ts.map +1 -1
  216. package/dist/esm/runtime/services/start-application.backend.service.js +82 -0
  217. package/dist/esm/runtime/services/start-application.backend.service.js.map +1 -1
  218. package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts +3 -23
  219. package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts.map +1 -1
  220. package/dist/esm/security/authentications/models/jwt.backend.schemas.js +20 -45
  221. package/dist/esm/security/authentications/models/jwt.backend.schemas.js.map +1 -1
  222. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts +9 -1
  223. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts.map +1 -1
  224. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js +9 -1
  225. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js.map +1 -1
  226. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.d.ts.map +1 -1
  227. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js +5 -3
  228. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js.map +1 -1
  229. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts +25 -1
  230. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts.map +1 -1
  231. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js +55 -4
  232. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js.map +1 -1
  233. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.d.ts.map +1 -1
  234. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js +24 -1
  235. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js.map +1 -1
  236. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts +117 -0
  237. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts.map +1 -0
  238. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js +104 -0
  239. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js.map +1 -0
  240. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts +101 -6
  241. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts.map +1 -1
  242. package/dist/esm/security/authorizations/services/authorizations.backend.service.js +210 -30
  243. package/dist/esm/security/authorizations/services/authorizations.backend.service.js.map +1 -1
  244. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts +18 -1
  245. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts.map +1 -1
  246. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js +110 -74
  247. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js.map +1 -1
  248. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts +22 -0
  249. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts.map +1 -0
  250. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js +22 -0
  251. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js.map +1 -0
  252. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts +17 -3
  253. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts.map +1 -1
  254. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js +12 -0
  255. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js.map +1 -1
  256. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts +20 -0
  257. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts.map +1 -1
  258. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js +58 -5
  259. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js.map +1 -1
  260. package/dist/esm/security/jwt/services/jwt.backend.service.d.ts.map +1 -1
  261. package/dist/esm/security/jwt/services/jwt.backend.service.js +1 -18
  262. package/dist/esm/security/jwt/services/jwt.backend.service.js.map +1 -1
  263. package/dist/tsconfig.build.tsbuildinfo +1 -1
  264. package/package.json +15 -9
  265. package/dist/esm/.builder.pid +0 -9
@@ -1 +1 @@
1
- {"version":3,"file":"notifications-dispatcher.backend.service.js","sourceRoot":"","sources":["../../../../../src/notifications/services/notifications-dispatcher.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { inject, injectable, optional } from 'inversify';\nimport type { ExecutionContextCreatorBackendService } from '~wildo-backend-lib/runtime/services/execution-context-creator.backend.service';\nimport { createHash, randomUUID } from 'node:crypto';\nimport { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport {\n ResourceConfiguration_Operation,\n ResourcePrimaryScope,\n CoreM2MNotificationChannel,\n CoreUserNotificationChannel,\n CoreUserNotificationTarget,\n UserNotificationDefinition,\n UserNotificationDefinition_EmailSchema,\n UserNotificationDefinition_FrontEndSuccessSchema,\n M2MNotificationDefinition,\n NotificationBadgeOperation,\n NotificationBadgeSourceKind,\n CoreResourceOperation,\n CoreWebSocketEvent,\n WS_ResourceNotificationPayload,\n WS_ResourceUpdatedPayload,\n WS_ResourceDeletedPayload,\n WS_ResourceSyncUpdatedPayload,\n WS_ResourceUpdateNotificationPayload,\n ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n EmailTemplateType,\n ResourceAction,\n NotificationLevel,\n CORE_APP_ROLES,\n CORE_ORG_ROLES,\n CoreResourceType,\n OrganizationMemberStatus,\n ResourcesConfigOperationsUrlsBuilderUtils,\n ResourcesConfig_OperationPathUtils,\n ResourceOperationVariantType,\n WebSocketResourceDeliveryTarget,\n ErrorType,\n ErrorCustomMessageReference,\n} from '@wildo-ai/saas-models';\nimport { BrandAssetComposition, BrandAssetPurpose } from '@wildo-ai/saas-models';\nimport type { FieldMetaEntry, OrganizationMember, UserPreferences, UserProfile } from '@wildo-ai/saas-models';\nimport type { z } from 'zod';\nimport { AvailableLanguage } from '@wildo-ai/presets-components-models';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport { describeCaughtError, projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { WebSocketService, WebSocketMessage } from '~wildo-backend-lib/requests/service/websocket.service';\nimport { NotificationBadgeBackendService } from './notification-badge.backend.service';\nimport {\n type EmailBackendService,\n type EmailSendResult,\n} from '~wildo-backend-lib/notifications/email/services/email.backend.service';\n// Internal callers go through the path alias (`@wildo-ai/saas-backend-lib/custom-batch-manifests`\n// is the public spec-layer subpath; self-imports through the public package name are not\n// wired in this workspace's tsconfig path map).\nimport { EMAIL_BATCH_SEND_BATCH_REF } from '~wildo-backend-lib/base-classes/services/batches/engine-custom-batch-manifests';\nimport type { QueueBackendService } from '~wildo-backend-lib/queue/queue.backend.service';\nimport { AppConfigurationService } from '~wildo-backend-lib/config/services/app-configuration.backend.service';\nimport { getConfiguredPrimaryLanguage } from '~wildo-backend-lib/config/services/app-configuration.backend.utils';\nimport { AuthControllerUtils } from '~wildo-backend-lib/security/authentications/services/utils/auth-controller.utils';\nimport { RepositoriesRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/repositories/repositories-registry-handler.backend.service';\nimport { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport { M2MWebhookDispatcherBackendService } from '~wildo-backend-lib/notifications/webhooks/outbound/services/m2m-webhook-dispatcher.backend.service';\n\n/**\n * Notification Dispatcher Service\n *\n * Handles dispatching of all notification types based on resource operation configurations:\n * - Notification badge operations (incrementing/decrementing/resetting badge counts)\n * - User notifications (email, SMS, push, WebSocket, frontend success)\n * - M2M (Machine-to-Machine) notifications (webhooks)\n * - Resource room notifications (path-independent collaboration)\n */\n/** Batch threshold for email sending - above this, use queue */\nconst EMAIL_BATCH_THRESHOLD = 10;\n\n/**\n * Canonical template identity for operation-authored email notifications.\n *\n * Startup validation and runtime dispatch must use the same derivation;\n * otherwise an application can boot against one template reference and fail\n * only after a mutation commits because delivery derived another.\n */\nexport function buildUserNotificationEmailTemplateRef(\n operation: {\n resourceIdentifier: string;\n operationIdentifier: string;\n variantKey?: string;\n },\n notification: {\n identifier: string;\n target?: string;\n customNotificationRef?: string;\n },\n): string {\n const targetKebab =\n (notification.target || notification.identifier)\n .toLowerCase()\n .replace(/_/g, '-');\n const refParts = [\n 'email',\n operation.resourceIdentifier,\n operation.operationIdentifier,\n ];\n if (operation.variantKey) {\n refParts.push(operation.variantKey);\n }\n refParts.push(targetKebab);\n const baseRef = refParts.join('.');\n return notification.customNotificationRef\n ? `${baseRef}_${notification.customNotificationRef}`\n : baseRef;\n}\n\n/**\n * Optional identity source for post-commit email submissions.\n *\n * Token-backed operation dispatch passes the committed token ID. The\n * dispatcher derives one deterministic provider identity per concrete\n * notification and recipient, so a fan-out cannot accidentally deduplicate\n * distinct emails while a repeated logical send remains provider-idempotent\n * where the selected adapter supports it.\n */\nexport interface NotificationDispatchOptions {\n emailSubmissionSourceId?: string;\n}\n\n/**\n * Derive a fixed-size provider submission identity without exposing recipient\n * data in transport headers. A new token ID produces a new identity, so an\n * explicit RESEND is intentionally a new logical email.\n */\nexport function deriveEmailNotificationSubmissionId(\n sourceId: string,\n notificationIdentifier: string,\n templateRef: string,\n recipientIdentity: { email?: string; userId?: string },\n): string {\n return createHash('sha256')\n .update(JSON.stringify({\n sourceId,\n notificationIdentifier,\n templateRef,\n recipientIdentity,\n }))\n .digest('hex');\n}\n\ntype CachedRoutePaths = { url: string; parameters: { fieldIdentifier: string; resourceType: string }[] }[];\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Normalise a mutated-object slot (`currentObject` / `previousObject`) to the list of plain rows a\n * derived-badge recompute must read its `scopeField` from.\n *\n * A single write yields one object; a bulk write yields an array; `undefined` (CREATE has no\n * pre-image; a slot may be absent) yields nothing. Non-record array entries and bulk-result blobs\n * (`{ updatedIds: [...] }`) are dropped — they carry no per-row field truth.\n */\nfunction toDerivedBadgeRowArray(value: unknown): Record<string, unknown>[] {\n if (Array.isArray(value)) {\n return value.filter(isPlainRecord);\n }\n return isPlainRecord(value) ? [value] : [];\n}\n\nfunction normalizeResourceId(value: unknown): string | undefined {\n if (typeof value === 'string' && value.length > 0) {\n return value;\n }\n\n if (\n typeof value === 'object'\n && value !== null\n && typeof (value as { toString?: () => string }).toString === 'function'\n ) {\n const normalized = value.toString();\n if (normalized.length > 0 && normalized !== '[object Object]') {\n return normalized;\n }\n }\n\n return undefined;\n}\n\nfunction resolveResourceObjectForSync(\n currentObject: unknown,\n resourceId: string,\n affectedIds: string[],\n): Record<string, unknown> | undefined {\n if (Array.isArray(currentObject)) {\n return currentObject.find((candidate): candidate is Record<string, unknown> => (\n // `_id` ONLY — `id` is Mongoose's built-in virtual (surrogate-PK resources only) and does not\n // exist on PostgreSQL. The arm was dead, since `_id` is always present and evaluated first.\n isPlainRecord(candidate) && normalizeResourceId(candidate._id) === resourceId\n ));\n }\n\n if (!isPlainRecord(currentObject)) {\n return undefined;\n }\n\n if (typeof currentObject._id === 'string' && currentObject._id !== resourceId) {\n return undefined;\n }\n\n // A shared bulk result blob (e.g. { updatedIds: [...] }) is not authoritative\n // per-resource replay truth for sync-grade room payloads.\n if (affectedIds.length > 1 && typeof currentObject._id !== 'string') {\n return undefined;\n }\n\n return currentObject;\n}\n\nfunction splitResourceObjectForWebSocket(resourceObject: Record<string, unknown>): {\n cleanedResourceData: Record<string, unknown>;\n fieldMeta?: Record<string, FieldMetaEntry>;\n version?: number;\n} {\n const { _field_meta, ...rest } = resourceObject;\n return {\n cleanedResourceData: rest,\n fieldMeta: _field_meta as Record<string, FieldMetaEntry> | undefined,\n version: resourceObject._version as number | undefined,\n };\n}\n\nexport function shouldOmitResourceUrlForOperation(\n effectiveOperation: CoreResourceOperation | undefined,\n): boolean {\n return effectiveOperation === CoreResourceOperation.DELETE\n || effectiveOperation === CoreResourceOperation.DELETE_MANY;\n}\n\nexport function buildResourceRoomSyncPayload(params: {\n resourceType: string;\n resourceId: string;\n contextResourceIdentifiers: Record<string, string>;\n action: ResourceAction;\n affectedIds: string[];\n operationIdentifier: string;\n operationPathKey?: string;\n variantType?: ResourceOperationVariantType;\n isOperationDefault?: boolean;\n isBulkOperation?: boolean;\n variantKey?: string;\n initiatorUserId?: string;\n currentObject: unknown;\n timestamp?: Date;\n}): WS_ResourceSyncUpdatedPayload | WS_ResourceDeletedPayload | null {\n const timestamp = params.timestamp ?? new Date();\n\n if (params.action === ResourceAction.DELETED) {\n return {\n deliveryTarget: WebSocketResourceDeliveryTarget.RESOURCE_ROOM_SYNC,\n resourceType: params.resourceType,\n resourceId: params.resourceId,\n contextResourceIdentifiers: params.contextResourceIdentifiers,\n action: ResourceAction.DELETED,\n affectedIds: params.affectedIds,\n operationIdentifier: params.operationIdentifier,\n operationPathKey: params.operationPathKey,\n variantType: params.variantType,\n isOperationDefault: params.isOperationDefault,\n isBulkOperation: params.isBulkOperation,\n variantKey: params.variantKey,\n initiatorUserId: params.initiatorUserId,\n timestamp,\n };\n }\n\n const resourceObject = resolveResourceObjectForSync(\n params.currentObject,\n params.resourceId,\n params.affectedIds,\n );\n if (!resourceObject) {\n return null;\n }\n\n const {\n cleanedResourceData,\n fieldMeta,\n version,\n } = splitResourceObjectForWebSocket(resourceObject);\n\n if (version == null) {\n return null;\n }\n\n // Sync-grade resource-room events are the only websocket payloads allowed to\n // carry authoritative replay data for a specific resource. If we cannot prove\n // both the per-resource object body and its authoritative version, callers\n // must fall back to a notification-grade stale hint instead.\n return {\n deliveryTarget: WebSocketResourceDeliveryTarget.RESOURCE_ROOM_SYNC,\n resourceType: params.resourceType,\n resourceId: params.resourceId,\n contextResourceIdentifiers: params.contextResourceIdentifiers,\n action: params.action,\n affectedIds: params.affectedIds,\n operationIdentifier: params.operationIdentifier,\n operationPathKey: params.operationPathKey,\n variantType: params.variantType,\n isOperationDefault: params.isOperationDefault,\n isBulkOperation: params.isBulkOperation,\n variantKey: params.variantKey,\n initiatorUserId: params.initiatorUserId,\n timestamp,\n version,\n resourceData: cleanedResourceData,\n fieldMeta,\n };\n}\n\nexport function buildScopeRoomNotificationPayload(params: {\n resourceType: string;\n resourceId: string;\n contextResourceIdentifiers: Record<string, string>;\n action: ResourceAction;\n affectedIds: string[];\n operationIdentifier: string;\n operationPathKey?: string;\n variantType?: ResourceOperationVariantType;\n isOperationDefault?: boolean;\n isBulkOperation?: boolean;\n variantKey?: string;\n initiatorUserId?: string;\n currentObject: unknown;\n timestamp?: Date;\n}): WS_ResourceUpdateNotificationPayload {\n const timestamp = params.timestamp ?? new Date();\n // Scope rooms are collection/list invalidation surfaces. For multi-id writes\n // they must not overstate single-resource replay truth, so replay-like fields\n // are only included when the payload still represents one authoritative row.\n const shouldIncludeReplayLikeFields = params.affectedIds.length <= 1;\n const resourceObject = resolveResourceObjectForSync(\n params.currentObject,\n params.resourceId,\n params.affectedIds,\n );\n const splitResourceObject = shouldIncludeReplayLikeFields && resourceObject\n ? splitResourceObjectForWebSocket(resourceObject)\n : null;\n\n return {\n deliveryTarget: WebSocketResourceDeliveryTarget.SCOPE_ROOM_NOTIFICATION,\n resourceType: params.resourceType,\n resourceId: params.resourceId,\n contextResourceIdentifiers: params.contextResourceIdentifiers,\n action: params.action,\n affectedIds: params.affectedIds,\n operationIdentifier: params.operationIdentifier,\n operationPathKey: params.operationPathKey,\n variantType: params.variantType,\n isOperationDefault: params.isOperationDefault,\n isBulkOperation: params.isBulkOperation,\n variantKey: params.variantKey,\n initiatorUserId: params.initiatorUserId,\n timestamp,\n version: splitResourceObject?.version,\n resourceData: splitResourceObject?.cleanedResourceData,\n fieldMeta: splitResourceObject?.fieldMeta,\n };\n}\n\nexport function buildResourceRoomStaleHintPayload(params: {\n resourceType: string;\n resourceId: string;\n contextResourceIdentifiers: Record<string, string>;\n action: ResourceAction;\n affectedIds: string[];\n operationIdentifier: string;\n operationPathKey?: string;\n variantType?: ResourceOperationVariantType;\n isOperationDefault?: boolean;\n isBulkOperation?: boolean;\n variantKey?: string;\n initiatorUserId?: string;\n timestamp?: Date;\n}): WS_ResourceUpdateNotificationPayload {\n const timestamp = params.timestamp ?? new Date();\n return {\n deliveryTarget: WebSocketResourceDeliveryTarget.RESOURCE_ROOM_NOTIFICATION,\n resourceType: params.resourceType,\n resourceId: params.resourceId,\n contextResourceIdentifiers: params.contextResourceIdentifiers,\n action: params.action,\n affectedIds: params.affectedIds,\n operationIdentifier: params.operationIdentifier,\n operationPathKey: params.operationPathKey,\n variantType: params.variantType,\n isOperationDefault: params.isOperationDefault,\n isBulkOperation: params.isBulkOperation,\n variantKey: params.variantKey,\n initiatorUserId: params.initiatorUserId,\n timestamp,\n };\n}\n\n@injectable()\nexport class NotificationDispatcherService {\n\n protected logDebug: (message: string, context?: Record<string, unknown>) => void;\n\n private readRoutePathsCache = new Map<string, CachedRoutePaths | null>();\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) private logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.WebSocketService) private webSocketService: WebSocketService,\n @inject(SAAS_SERVICE_TYPES.NotificationBadgeService) private badgeService: NotificationBadgeBackendService,\n @inject(SAAS_SERVICE_TYPES.EmailService) private emailService: EmailBackendService,\n @inject(SAAS_SERVICE_TYPES.QueueBackendService) private queueService: QueueBackendService,\n @inject(SAAS_SERVICE_TYPES.AppConfigService) private appConfigService: AppConfigurationService,\n @inject(SAAS_SERVICE_TYPES.RepositoriesRegistryHandlerService) private repositoriesRegistry: RepositoriesRegistryHandlerBackendService,\n @inject(SAAS_SERVICE_TYPES.ResourceRegistryService) private resourcesRegistry: ResourcesRegistryBackendService,\n @inject(SAAS_SERVICE_TYPES.M2MWebhookDispatcherService)\n private m2mWebhookDispatcher: M2MWebhookDispatcherBackendService,\n // Appended LAST so positional construction in tests keeps working, and `@optional()` so a\n // minimal container still builds: the only consumer degrades to the caller's context, which is\n // the pre-existing behaviour.\n @inject(SAAS_SERVICE_TYPES.ExecutionContextCreatorBackendService) @optional()\n private readonly executionContextCreator?: ExecutionContextCreatorBackendService,\n ) {\n this.logDebug = this.logger.debugByType('NotificationDispatcherService');\n this.logger.setDebugTypeLogging('NotificationDispatcherService', false);\n }\n\n /**\n * Dispatch notifications based on operation configuration\n *\n * @param executionContext - The execution context containing operation details and user information\n * @param functionParameters - Parameters containing input data, current object, and context\n */\n async dispatchNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n options?: NotificationDispatchOptions,\n ): Promise<void> {\n const operation = executionContext.operation;\n\n try {\n const results = await Promise.allSettled([\n this.dispatchConfiguredNotifications(\n executionContext,\n functionParameters,\n options,\n ),\n this.dispatchResourceRoomNotifications(executionContext, functionParameters),\n ]);\n\n for (const result of results) {\n if (result.status === 'rejected') {\n this.logger.error('Error dispatching notifications', {\n ...projectCaughtErrorLogFields(result.reason),\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n });\n }\n }\n } catch (error) {\n this.logger.error('Failed to dispatch notifications', {\n ...projectCaughtErrorLogFields(error),\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n });\n }\n }\n\n async dispatchConfiguredNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n options?: NotificationDispatchOptions,\n ): Promise<void> {\n const operation = executionContext.operation;\n\n try {\n // Dispatch authored notification types in parallel. Resource-room\n // synchronization can be invoked independently from this path when the\n // caller only has post-write object truth and not a full computation context.\n const results = await Promise.allSettled([\n // 1. Notification badge operations (EVENT_COUNTER: authored per-op increments)\n this.dispatchNotificationBadgeOperations(executionContext, functionParameters),\n\n // 2. User notifications (email, SMS, push, WebSocket, frontend success)\n this.dispatchUserNotifications(\n executionContext,\n functionParameters,\n options?.emailSubmissionSourceId,\n ),\n\n // 3. M2M notifications (webhooks)\n this.dispatchM2MNotifications(executionContext, functionParameters),\n\n // 4. DERIVED_QUERY badge recomputes: any badge whose source resource was\n // just mutated is re-counted from the source collection (never drifts).\n this.dispatchDerivedBadgeRecomputes(executionContext, functionParameters),\n ]);\n\n for (const result of results) {\n if (result.status === 'rejected') {\n this.logger.error('Error dispatching notifications', {\n ...projectCaughtErrorLogFields(result.reason),\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n });\n }\n }\n\n this.logDebug('All notifications dispatched successfully', {\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n userNotificationCount: (operation.userNotifications || []).length,\n badgeOperationsCount: (operation.notificationBadgeOperations || []).length,\n m2mNotificationsCount: (operation.m2mNotifications || []).length,\n });\n\n } catch (error) {\n // Log but don't throw - notifications should not break the main operation\n this.logger.error('Error dispatching notifications', {\n ...projectCaughtErrorLogFields(error),\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n });\n }\n }\n\n /**\n * Dispatch notification badge operations\n *\n * @param executionContext - The execution context\n * @param functionParameters - Function parameters with data context\n * @private\n */\n private async dispatchNotificationBadgeOperations<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters\n ): Promise<void> {\n const operation = executionContext.operation;\n const badgeOperations = operation.notificationBadgeOperations || [];\n\n if (badgeOperations.length === 0) {\n return;\n }\n\n // Determine the scope and scopeId based on operation's primary scope\n const { scope, scopeId } = this.determineBadgeScope(executionContext);\n if (!scope || !scopeId) {\n this.logDebug('Cannot determine badge scope, skipping badge operations', {\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n });\n return;\n }\n\n // Execute each badge operation\n for (const badgeOp of badgeOperations) {\n try {\n await this.badgeService.executeBadgeOperation(\n executionContext,\n scope,\n scopeId,\n badgeOp.identifier,\n badgeOp.operation as NotificationBadgeOperation,\n 1 // Default value (can be extended to support custom values)\n );\n\n this.logDebug('Badge operation executed', {\n identifier: badgeOp.identifier,\n operation: badgeOp.operation,\n scope,\n scopeId,\n });\n } catch (error) {\n this.logger.warn('Failed to execute badge operation', {\n identifier: badgeOp.identifier,\n operation: badgeOp.operation,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n }\n\n /**\n * Recompute every DERIVED_QUERY badge whose source resource is the one just\n * mutated (R5). Reads the registered `notificationBadgeDefinitions`, filters to\n * derived badges pointing at `operation.resourceIdentifier`, resolves the badge's\n * scopeId from the initiator, and asks the badge service to re-count + emit.\n *\n * Runs on the same write-time dispatch as event badges. Read operations don't\n * reach here (notifications dispatch is post-write), and the recompute is\n * idempotent regardless. Per-badge failures are logged and never abort siblings.\n */\n private async dispatchDerivedBadgeRecomputes<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n ): Promise<void> {\n const operation = executionContext.operation;\n const definitions = this.resourcesRegistry.getResourcesRegistry().notificationBadgeDefinitions ?? [];\n\n const derivedForThisResource = definitions.filter(\n (definition) =>\n definition.source.kind === NotificationBadgeSourceKind.DERIVED_QUERY &&\n definition.source.resourceType === operation.resourceIdentifier,\n );\n if (derivedForThisResource.length === 0) {\n return;\n }\n\n // The scopeId of a derived badge is the VALUE of its `scopeField` on the MUTATED ROW — never\n // the actor. A derived \"incomplete todos assigned to me\" badge is scoped by the todo's\n // `assignedToUserId`; when an admin assigns/reassigns/completes a todo on a member's behalf,\n // it is the MEMBER's badge that changed, and the admin never had a stake in it. Resolving the\n // scope from `executionContext.initiatorIds` (the previous behaviour) silently skipped EVERY\n // cross-user mutation — the affected user's count stayed stale until a reconnect reseeded it.\n //\n // Both the post-write row (`currentObject`) and, when the framework captured one, the pre-image\n // (`previousObject`) are consulted: a reassignment moves TWO scopes — the row leaves the prior\n // holder's set (pre-image) and joins the new holder's (post-image). A completion or a same-scope\n // edit moves ONE, which the post-image alone covers. `recomputeDerivedBadge` SETs the\n // authoritative count for each scope from the source collection, so recomputing a scope that did\n // not actually change is harmless (it re-derives the same number) — the correctness requirement\n // is only that no affected scope is MISSED.\n const affectedRows = [\n ...toDerivedBadgeRowArray(functionParameters.currentObject),\n ...toDerivedBadgeRowArray(functionParameters.previousObject),\n ];\n\n for (const definition of derivedForThisResource) {\n const source = definition.source;\n if (source.kind !== NotificationBadgeSourceKind.DERIVED_QUERY) {\n continue; // narrowed by the filter above; re-checked for the type guard on `scopeField`.\n }\n\n const scopeIds = new Set<string>();\n for (const row of affectedRows) {\n const value = row[source.scopeField];\n if (typeof value === 'string' && value.length > 0) {\n scopeIds.add(value);\n }\n }\n\n if (scopeIds.size === 0) {\n // No affected scope carries the badge's scopeField (e.g. a todo with no assignee) — nothing\n // to recompute. This is normal, not an error: no user's count could have changed.\n this.logDebug('No affected scopeId for derived badge, skipping', {\n identifier: definition.identifier,\n scopeField: source.scopeField,\n });\n continue;\n }\n\n for (const scopeId of scopeIds) {\n try {\n await this.badgeService.recomputeDerivedBadge(executionContext, definition, scopeId);\n } catch (error) {\n this.logger.warn('Failed to recompute derived badge', {\n identifier: definition.identifier,\n resourceType: operation.resourceIdentifier,\n scopeId,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n }\n }\n\n /**\n * Determine the badge scope and scopeId from execution context.\n *\n * Only USER_SELF and ORGANIZATIONS are supported badge scopes after the\n * polymorphism refactor (`.cursor/plans/notification-badges-polymorphism-refactor.md`):\n * the APPLICATION variant was dropped (no canonical badges declared at app\n * scope and no resource type backs it anymore). An operation whose\n * `resourcePrimaryScope` is APPLICATION (or any other unsupported value)\n * yields `{ scope: null, scopeId: null }` so the caller logs and skips\n * cleanly — never silently dispatches into the badge service where\n * `resolveRepository(APPLICATION)` would throw.\n *\n * The fallback (org-then-user from `initiatorIds`) is retained for the\n * `undefined` / unscoped operation case so badge effects on operations that\n * happen to share an org/user context still fire.\n */\n private determineBadgeScope<TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>>(\n executionContext: ExecutionContext<TResourceConfigOperation>\n ): { scope: ResourcePrimaryScope | null; scopeId: string | null } {\n const operation = executionContext.operation;\n const primaryScope = operation.resourcePrimaryScope;\n const initiatorIds = executionContext.initiatorIds;\n\n switch (primaryScope) {\n case ResourcePrimaryScope.USER_SELF:\n return { scope: ResourcePrimaryScope.USER_SELF, scopeId: initiatorIds?.userId || null };\n\n case ResourcePrimaryScope.ORGANIZATIONS:\n return { scope: ResourcePrimaryScope.ORGANIZATIONS, scopeId: initiatorIds?.organizationId || null };\n\n // APPLICATION (and ANONYMOUS) intentionally fall through to the\n // unscoped-fallback branch below: see JSDoc above.\n\n default:\n // Fallback to organization if available, otherwise user.\n // Note: APPLICATION-scoped operations land here too — they take the\n // org/user path if those identifiers are available, otherwise the\n // dispatcher logs \"Cannot determine badge scope, skipping\".\n if (initiatorIds?.organizationId) {\n return { scope: ResourcePrimaryScope.ORGANIZATIONS, scopeId: initiatorIds.organizationId };\n }\n if (initiatorIds?.userId) {\n return { scope: ResourcePrimaryScope.USER_SELF, scopeId: initiatorIds.userId };\n }\n return { scope: null, scopeId: null };\n }\n }\n\n /**\n * Dispatch user notifications\n *\n * @param executionContext - The execution context\n * @param functionParameters - Function parameters with data context\n * @private\n */\n private async dispatchUserNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n emailSubmissionSourceId?: string,\n ): Promise<EmailSendResult[]> {\n const operation = executionContext.operation;\n const userNotifications = operation.userNotifications || [];\n\n if (userNotifications.length === 0) {\n return [];\n }\n\n const emailResults: EmailSendResult[] = [];\n for (const notification of userNotifications) {\n // Config-declared side-effect gate: skip a notification whose `condition` evaluates falsy\n // against the post-operation context. Evaluated here — before channel resolution and the\n // email-by-address path — so it gates every channel uniformly. Canonical use: the org-member\n // invite email fires only for INVITED rows, never for an ACTIVE direct-add (founder / SSO-JIT /\n // SCIM), whose denormalized `userEmail` is the member's OWN address. Absent = always dispatch.\n if (notification.condition && !notification.condition(functionParameters)) {\n this.logDebug('Skipping user notification: condition not met', {\n identifier: notification.identifier,\n channel: notification.channel,\n target: notification.target,\n });\n continue;\n }\n try {\n const notificationEmailResults = await this.dispatchSingleUserNotification(\n executionContext,\n functionParameters,\n notification,\n emailSubmissionSourceId,\n );\n emailResults.push(...notificationEmailResults);\n } catch (error) {\n this.logger.warn('Failed to dispatch user notification', {\n identifier: notification.identifier,\n channel: notification.channel,\n target: notification.target,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n return emailResults;\n }\n\n /**\n * Dispatch a single user notification based on its channel\n */\n private async dispatchSingleUserNotification<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n emailSubmissionSourceId?: string,\n ): Promise<EmailSendResult[]> {\n const channel = notification.channel;\n\n switch (channel) {\n case CoreUserNotificationChannel.WEBSOCKET:\n await this.dispatchWebSocketUserNotification(executionContext, functionParameters, notification);\n return [];\n\n case CoreUserNotificationChannel.EMAIL:\n case CoreUserNotificationChannel.SMS:\n case CoreUserNotificationChannel.PUSH:\n // Email/SMS/Push notifications require recipient userContext fetching\n return this.dispatchEmailSmsPushUserNotification(\n executionContext,\n functionParameters,\n notification,\n emailSubmissionSourceId,\n );\n\n case CoreUserNotificationChannel.FRONT_END_SUCCESS:\n // Frontend success notifications are handled client-side\n // We can optionally send them via WebSocket for SPAs\n await this.dispatchWebSocketUserNotification(executionContext, functionParameters, notification);\n return [];\n\n default:\n this.logDebug('Unknown notification channel', {\n channel,\n identifier: notification.identifier,\n });\n return [];\n }\n }\n\n /**\n * Dispatch Email/SMS/Push user notifications\n * These channels require recipient userContext fetching for template rendering\n */\n private async dispatchEmailSmsPushUserNotification<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n emailSubmissionSourceId?: string,\n ): Promise<EmailSendResult[]> {\n const target = notification.target;\n const channel = notification.channel;\n\n // Email-by-address: when an EMAIL notification declares `recipientEmailField`, the\n // recipient is a raw address read from the current object — a party who is NOT a\n // platform user (an organization-invitation invitee, an inbound lead). There is no\n // `userId` to resolve, so this bypasses `getUserIdsForTarget` entirely.\n const recipientEmailField = channel === CoreUserNotificationChannel.EMAIL\n ? (notification as z.infer<typeof UserNotificationDefinition_EmailSchema>).recipientEmailField\n : undefined;\n if (recipientEmailField) {\n return this.dispatchEmailToRecipientAddress(\n executionContext,\n functionParameters,\n notification,\n recipientEmailField,\n emailSubmissionSourceId,\n );\n }\n\n // Get user IDs based on target\n const userIds = await this.getUserIdsForTarget(\n executionContext,\n functionParameters,\n notification,\n target,\n );\n\n if (userIds.length === 0) {\n this.logDebug('No user IDs found for notification', {\n identifier: notification.identifier,\n target,\n channel,\n });\n return [];\n }\n\n // Handle by channel type\n switch (channel) {\n case CoreUserNotificationChannel.EMAIL:\n return this.dispatchEmailNotifications(\n executionContext,\n functionParameters,\n notification,\n userIds,\n emailSubmissionSourceId,\n );\n\n case CoreUserNotificationChannel.SMS:\n case CoreUserNotificationChannel.PUSH:\n // SMS and Push not yet implemented\n this.logDebug('SMS/Push notifications not yet implemented', {\n identifier: notification.identifier,\n channel,\n userCount: userIds.length,\n });\n return [];\n }\n }\n\n /**\n * Build the shared email-dispatch context for a user notification: the resolved\n * `templateRef`, the app default `locale`, and the `baseContext` (object + additional\n * context, including the token `acceptUrl` enricher). These are computed ONCE per\n * notification (recipient-independent), so both the user-id recipient path\n * (`dispatchEmailNotifications`) and the email-by-address path\n * (`dispatchEmailToRecipientAddress`) render from identical context.\n */\n private async buildEmailNotificationContext<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n ) {\n const operation = executionContext.operation;\n\n // Build template reference from executionContext.operation (guaranteed correct after doOperation corrections)\n const templateRef = buildUserNotificationEmailTemplateRef(\n {\n resourceIdentifier: String(operation.resourceIdentifier),\n operationIdentifier: String(operation.operationIdentifier),\n ...(operation.variantKey && {\n variantKey: String(operation.variantKey),\n }),\n },\n notification,\n );\n\n // Determine the app primary locale from backend configuration.\n const locale = this.getDefaultLocale();\n\n // Get app identity and ID from config.\n // Slice 3.7 (F-53) terminology pin: `appIdentity.appName` is the\n // canonical id (from `WildoSaasConfig.name`), `appIdentity.displayName`\n // is the UI label. Notifications want the UI label, so we resolve a\n // local `appDisplayLabel` from `displayName ?? appName ?? 'Application'`\n // and pass it under the template prop name `appName` (existing\n // template contract — renaming the prop would ripple to every email\n // template, tracked separately).\n const appConfig = this.appConfigService.config as Record<string, unknown>;\n const appIdentity = appConfig.appIdentity as { appName?: string; displayName?: string } | undefined;\n const applicationId = this.appConfigService.applicationId || 'unknown';\n const appDisplayLabel = appIdentity?.displayName || appIdentity?.appName || 'Application';\n\n // Resolve dashboard URL — scope/target-aware (admin targets → APP_ADMIN, else MAIN_APP)\n const dashboardUrl = this.resolveDashboardUrlForNotification(\n operation as unknown as ResourceConfiguration_Operation<any, any, any>, notification\n );\n\n // Fetch initiator name when user-initiated (for \"X added you\" style personalization)\n const initiatorUserId = executionContext.initiatorIds?.userId;\n const initiatorContext = initiatorUserId ? await this.fetchUserContext(initiatorUserId) : undefined;\n const initiatorName = initiatorContext?.firstName ?? initiatorContext?.name ?? undefined;\n\n // Resolve organization name from executionContext (org-scoped resources only)\n const organizationName = await this.resolveOrganizationName(\n operation as unknown as ResourceConfiguration_Operation<any, any, any>, executionContext\n );\n\n // Resolve direct resource URL (e.g. /organizations/:orgId/todos/:todoId → full link)\n const resourceUrl = this.resolveResourceUrl(\n operation as unknown as ResourceConfiguration_Operation<any, any, any>,\n functionParameters.currentObject as Record<string, unknown> | undefined,\n executionContext,\n dashboardUrl\n );\n\n // Build base context from function parameters\n const baseContext = {\n currentObject: functionParameters.currentObject,\n objectContext: {\n primaryScopeContext: {\n appName: appDisplayLabel,\n applicationId,\n organizationName: organizationName ?? undefined,\n // App brand logo for the email header. Resolve the email-optimised\n // lockup from config brandAssets; `resolveBrandAsset` falls back\n // (EMAIL → DEFAULT theme → PRIMARY), and the resolver returns\n // undefined when no brand asset was generated yet. ABSOLUTE variant:\n // email clients can't fetch a same-origin `/brand/<ref>.png`, so a\n // relative brand-asset path is prefixed with the app public base URL.\n logoUrl: this.appConfigService.resolveBrandLogoAbsoluteUrl({\n composition: BrandAssetComposition.LOCKUP,\n purpose: BrandAssetPurpose.EMAIL,\n }) ?? undefined,\n },\n },\n additionalContext: {\n operationType: String(operation.operationIdentifier),\n resourceType: String(operation.resourceIdentifier),\n dashboardUrl: dashboardUrl ?? undefined,\n initiatorName: initiatorName ?? undefined,\n resourceUrl: resourceUrl ?? undefined,\n // Token-consume link for token-bearing emails (e.g. invitation accept):\n // <frontendBase><emailLinkPath>?token=<tokenValue> when the op generated a\n // token and declares `tokenGeneration.emailLinkPath`. Undefined otherwise.\n acceptUrl: this.resolveTokenAcceptUrl(\n operation as unknown as ResourceConfiguration_Operation<any, any, any>,\n functionParameters,\n dashboardUrl,\n ) ?? undefined,\n },\n };\n\n return { templateRef, locale, baseContext };\n }\n\n /**\n * Dispatch email notifications to a list of users.\n * Uses direct sending for small lists, batch queue for larger lists.\n */\n private async dispatchEmailNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n userIds: string[],\n emailSubmissionSourceId?: string,\n ): Promise<EmailSendResult[]> {\n const { templateRef, locale, baseContext } = await this.buildEmailNotificationContext(\n executionContext,\n functionParameters,\n notification,\n );\n\n if (userIds.length > EMAIL_BATCH_THRESHOLD) {\n await this.enqueueEmailBatch(\n templateRef,\n locale,\n userIds,\n baseContext,\n notification,\n emailSubmissionSourceId,\n );\n return [];\n }\n\n // Direct sending for smaller lists\n const results: EmailSendResult[] = [];\n for (const userId of userIds) {\n try {\n const recipientUserContext = await this.fetchUserContext(userId);\n\n if (!recipientUserContext?.email) {\n this.logger.warn('No email address for user, skipping notification', {\n userId,\n identifier: notification.identifier,\n });\n continue;\n }\n\n const recipientLocale = this.resolveRecipientLocale(recipientUserContext, locale);\n const result = await this.emailService.send({\n ...(emailSubmissionSourceId && {\n submissionId: deriveEmailNotificationSubmissionId(\n emailSubmissionSourceId,\n notification.identifier,\n templateRef,\n { userId },\n ),\n }),\n templateRef,\n locale: recipientLocale,\n type: EmailTemplateType.TRANSACTIONAL,\n to: recipientUserContext.email,\n context: {\n ...baseContext,\n userContext: {\n userId,\n email: recipientUserContext.email,\n name: recipientUserContext.name,\n firstName: recipientUserContext.firstName,\n },\n },\n });\n results.push(result);\n\n this.logDebug('Email notification sent', {\n identifier: notification.identifier,\n userId,\n success: result.success,\n submissionId: result.submissionId,\n outcome: result.outcome,\n providerMessageIds: result.providerMessageIds,\n });\n } catch (error) {\n this.logger.warn('Failed to send email notification', {\n userId,\n identifier: notification.identifier,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n return results;\n }\n\n /**\n * Deliver a single email to a raw address read from the current object — the\n * email-by-address path selected when an EMAIL notification declares\n * `recipientEmailField` (see `dispatchEmailSmsPushUserNotification`).\n *\n * The recipient is `currentObject[recipientEmailField]` (a top-level string field,\n * e.g. `email`) — a party who is NOT a platform user (an invitation invitee, an\n * inbound lead), so there is no `userId` and no user preferences. The app default\n * locale is used, and the shared notification context is reused verbatim, so\n * token-bearing emails still carry their `acceptUrl`. Best-effort: a missing address\n * or a send failure is logged and swallowed, never thrown into the operation pipeline.\n */\n private async dispatchEmailToRecipientAddress<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n recipientEmailField: string,\n emailSubmissionSourceId?: string,\n ): Promise<EmailSendResult[]> {\n const operation = executionContext.operation;\n const currentObject = functionParameters.currentObject as Record<string, unknown> | undefined;\n const rawAddress = currentObject?.[recipientEmailField];\n const recipientEmail = typeof rawAddress === 'string' ? rawAddress.trim() : '';\n\n if (!recipientEmail) {\n this.logger.warn('Email-by-address notification has no recipient address on the current object; skipping', {\n identifier: notification.identifier,\n recipientEmailField,\n resourceType: String(operation.resourceIdentifier),\n operationIdentifier: String(operation.operationIdentifier),\n });\n return [];\n }\n\n const { templateRef, locale, baseContext } = await this.buildEmailNotificationContext(\n executionContext,\n functionParameters,\n notification,\n );\n\n try {\n const result = await this.emailService.send({\n ...(emailSubmissionSourceId && {\n submissionId: deriveEmailNotificationSubmissionId(\n emailSubmissionSourceId,\n notification.identifier,\n templateRef,\n { email: recipientEmail },\n ),\n }),\n templateRef,\n locale,\n type: EmailTemplateType.TRANSACTIONAL,\n to: recipientEmail,\n context: {\n ...baseContext,\n // Non-user recipient: only the address is known. `userId: ''` is the explicit\n // \"no platform user\" sentinel for the required `EmailUserContext.userId` field.\n userContext: {\n userId: '',\n email: recipientEmail,\n },\n },\n });\n\n this.logDebug('Email-by-address notification sent', {\n identifier: notification.identifier,\n recipientEmailField,\n success: result.success,\n submissionId: result.submissionId,\n outcome: result.outcome,\n providerMessageIds: result.providerMessageIds,\n });\n return [result];\n } catch (error) {\n this.logger.warn('Failed to send email-by-address notification', {\n identifier: notification.identifier,\n recipientEmailField,\n ...projectCaughtErrorLogFields(error),\n });\n return [];\n }\n }\n\n /**\n * Enqueue a batch of emails for asynchronous sending.\n * Used for large recipient lists (above EMAIL_BATCH_THRESHOLD).\n */\n private async enqueueEmailBatch(\n templateRef: string,\n locale: AvailableLanguage,\n userIds: string[],\n baseContext: Record<string, unknown>,\n notification: UserNotificationDefinition,\n emailSubmissionSourceId?: string,\n ): Promise<void> {\n // Fetch all user contexts first\n const emailItems: Array<{\n submissionId: string;\n templateRef: string;\n locale: string;\n type: string;\n to: string;\n context: Record<string, unknown>;\n }> = [];\n\n for (const userId of userIds) {\n try {\n const recipientUserContext = await this.fetchUserContext(userId);\n\n if (!recipientUserContext?.email) {\n continue;\n }\n\n emailItems.push({\n submissionId: emailSubmissionSourceId\n ? deriveEmailNotificationSubmissionId(\n emailSubmissionSourceId,\n notification.identifier,\n templateRef,\n { userId },\n )\n : randomUUID(),\n templateRef,\n locale: this.resolveRecipientLocale(recipientUserContext, locale),\n type: EmailTemplateType.TRANSACTIONAL,\n to: recipientUserContext.email,\n context: {\n ...baseContext,\n userContext: {\n userId,\n email: recipientUserContext.email,\n name: recipientUserContext.name,\n firstName: recipientUserContext.firstName,\n },\n },\n });\n } catch (error) {\n this.logger.warn('Failed to fetch user context for batch', {\n userId,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n\n if (emailItems.length === 0) {\n this.logDebug('No valid email recipients for batch', {\n identifier: notification.identifier,\n });\n return;\n }\n\n // Enqueue the batch\n const { jobId } = await this.queueService.enqueueCustomBatch(\n EMAIL_BATCH_SEND_BATCH_REF,\n {\n batchId: `${notification.identifier}-${randomUUID()}`,\n emails: emailItems,\n retryOnFailure: true,\n maxRetries: 3,\n }\n );\n\n this.logDebug('Email batch enqueued', {\n identifier: notification.identifier,\n jobId,\n emailCount: emailItems.length,\n });\n }\n\n /**\n * Get default locale from app config\n */\n private getDefaultLocale(): AvailableLanguage {\n return getConfiguredPrimaryLanguage(this.appConfigService.config);\n }\n\n private resolveRecipientLocale(\n recipientUserContext: { preferredLanguage?: AvailableLanguage } | undefined,\n fallbackLocale: AvailableLanguage,\n ): AvailableLanguage {\n return recipientUserContext?.preferredLanguage || fallbackLocale;\n }\n\n private normalizeAvailableLanguage(value: unknown): AvailableLanguage | undefined {\n return Object.values(AvailableLanguage).includes(value as AvailableLanguage)\n ? value as AvailableLanguage\n : undefined;\n }\n\n private async fetchUserPreferences(userId: string): Promise<UserPreferences | undefined> {\n try {\n const userPreferencesRepository = this.repositoriesRegistry.getRepository(CoreResourceType.USER_PREFERENCES);\n if (!userPreferencesRepository) {\n this.logDebug('No user preferences repository available for recipient locale resolution', { userId });\n return undefined;\n }\n\n return await userPreferencesRepository.read<UserPreferences>(\n { operation: { resourceIdentifier: CoreResourceType.USER_PREFERENCES, operationIdentifier: 'read' } } as any,\n { userId },\n { excludeContextualFilter: true },\n ) ?? undefined;\n } catch {\n this.logDebug('Failed to fetch user preferences for recipient locale resolution', { userId });\n return undefined;\n }\n }\n\n /**\n * Resolve the recipient's profile (`USER_PROFILES`, 1:1 with `USERS` via a\n * unique `userId` FK — read context-addressed by `{ userId }`, exactly like\n * {@link fetchUserPreferences}). This is where the human name fields live\n * (`firstName` / `lastName` / `displayName`); the `USERS` row carries none of\n * them. Best-effort: a missing repository or read failure degrades to\n * `undefined` so the caller can fall back to the email address.\n */\n private async fetchUserProfile(userId: string): Promise<UserProfile | undefined> {\n try {\n const userProfilesRepository = this.repositoriesRegistry.getRepository(CoreResourceType.USER_PROFILES);\n if (!userProfilesRepository) {\n this.logDebug('No user profiles repository available for recipient name resolution', { userId });\n return undefined;\n }\n\n return await userProfilesRepository.read<UserProfile>(\n { operation: { resourceIdentifier: CoreResourceType.USER_PROFILES, operationIdentifier: 'read' } } as any,\n { userId },\n { excludeContextualFilter: true },\n ) ?? undefined;\n } catch {\n this.logDebug('Failed to fetch user profile for recipient name resolution', { userId });\n return undefined;\n }\n }\n\n /**\n * Get user IDs for a notification target\n * Handles both fixed targets and custom userIdsSelector\n */\n private async getUserIdsForTarget<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n target: string\n ): Promise<string[]> {\n // Custom user targeting via userIdsSelector\n if (target === CoreUserNotificationTarget.USERS_CUSTOM && notification.userIdsSelector) {\n // Ensure objectContext has the expected structure (parents/children)\n const objectContext = functionParameters.objectContext || {};\n const normalizedObjectContext = {\n parents: (objectContext as any)?.parents || {},\n children: (objectContext as any)?.children || {}\n };\n\n return Array.from(new Set(notification.userIdsSelector({\n currentObject: functionParameters.currentObject,\n inputDto: functionParameters.inputDto,\n objectContext: normalizedObjectContext,\n initiatorIds: functionParameters.initiatorIds\n })));\n }\n\n // Fixed targets - extract from executionContext.initiatorIds\n const initiatorIds = executionContext.initiatorIds;\n\n switch (target) {\n case CoreUserNotificationTarget.USER_SELF:\n return initiatorIds?.userId ? [initiatorIds.userId] : [];\n\n case CoreUserNotificationTarget.ORGANIZATION:\n case CoreUserNotificationTarget.ORGANIZATION_USERS:\n return this.getOrganizationRecipientUserIds(executionContext, initiatorIds?.organizationId);\n\n case CoreUserNotificationTarget.ORGANIZATION_BILLING:\n case CoreUserNotificationTarget.ORGANIZATION_USER_MANAGEMENT:\n case CoreUserNotificationTarget.ORGANIZATION_ADMINISTRATIVE:\n case CoreUserNotificationTarget.ORGANIZATION_SECURITY:\n return this.getOrganizationRecipientUserIds(\n executionContext,\n initiatorIds?.organizationId,\n this.mapOrganizationTargetToRoles(target as CoreUserNotificationTarget, notification),\n );\n\n default:\n // Other targets (role-based, application-level) would also need user ID lookup\n this.logDebug('Target requires user ID lookup', { target });\n return [];\n }\n }\n\n /**\n * Resolve the per-recipient context consumed by every greeting surface (email\n * subject/body, the `initiatorName` personalization, batch/direct sends).\n *\n * The human name fields (`firstName` / `lastName` / `displayName`) live on\n * `USER_PROFILES`, NOT on the `USERS` row — `UserSchema` carries only the email\n * identity anchor, status, roles and timestamps. Reading `firstName`/`name`\n * off the `USERS` row (as this method historically did) therefore resolved to\n * `undefined` for EVERY user, so greetings rendered blank and any\n * `{firstName}`-style label placeholder leaked its literal token to the\n * recipient — `interpolateLabelParams` returns the raw `{token}` verbatim when\n * the param is absent.\n *\n * Names are now read from the user's profile and degrade to `email` when a\n * user has no profile yet (SSO-JIT / anonymous edge cases, or a not-yet-seeded\n * profile). This mirrors the SCIM formatter's `displayName || fullName ||\n * email` degradation so every surface renders *something* human — never a\n * blank, never a raw placeholder token. `name` carries the same greeting label\n * as `displayName`; `firstName` is the informal variant with the same email\n * floor.\n */\n private async fetchUserContext(userId: string): Promise<any | undefined> {\n try {\n const userRepository = this.repositoriesRegistry.getRepository(CoreResourceType.USERS);\n if (!userRepository) {\n this.logDebug('No user repository available for fetchUserContext', { userId });\n return undefined;\n }\n const user = await userRepository.read(\n { operation: { resourceIdentifier: CoreResourceType.USERS, operationIdentifier: 'read' } } as any,\n userId,\n { excludeContextualFilter: true },\n );\n if (!user) return undefined;\n\n const email = (user as any).email as string | undefined;\n\n // Profile (name fields) and preferences (locale) are independent lookups\n // keyed only by `userId`, so resolve them concurrently — adding the profile\n // read must not serialize an extra round-trip per recipient on batch sends.\n // Both helpers are best-effort (own try/catch → undefined), so `Promise.all`\n // never rejects here.\n const [profile, preferences] = await Promise.all([\n this.fetchUserProfile(userId),\n this.fetchUserPreferences(userId),\n ]);\n\n // Names come from USER_PROFILES (1:1 with USERS). Fall back to `email` so a\n // profile-less recipient still gets a sensible greeting and never a blank\n // or a leaked `{firstName}` token. `filter(Boolean)` drops a missing half of\n // the name; `|| undefined` collapses the empty-string join so the `??`\n // chain reaches the email floor.\n const fullName = [profile?.firstName, profile?.lastName].filter(Boolean).join(' ') || undefined;\n const displayName = profile?.displayName ?? fullName ?? email;\n const firstName = profile?.firstName ?? email;\n\n const preferredLanguage = this.normalizeAvailableLanguage(preferences?.languagePreferences?.primaryLanguage)\n ?? this.normalizeAvailableLanguage(preferences?.regional?.locale);\n return {\n email,\n displayName,\n name: displayName,\n firstName,\n preferredLanguage,\n userId,\n };\n } catch {\n this.logDebug('Failed to fetch user context', { userId });\n return undefined;\n }\n }\n\n private async getOrganizationRecipientUserIds(\n executionContext: ExecutionContext<any>,\n organizationId: string | undefined,\n allowedRoles?: string[],\n ): Promise<string[]> {\n if (!organizationId) {\n return [];\n }\n\n const organizationMembersRepository = this.repositoriesRegistry.getRepository(CoreResourceType.ORGANIZATION_MEMBERS);\n if (!organizationMembersRepository) {\n this.logDebug('No organization members repository available for notification targeting', {\n organizationId,\n });\n return [];\n }\n\n // Read the roster on a SUB-CALL context, not the caller's. This runs during dispatch for a\n // notification attached to ANY resource operation, so the caller's context is keyed to that\n // resource — a nested route contributes its own FK (`todoId`, …), and the repository's contextual\n // filter is fail-closed on a field ORGANIZATION_MEMBERS does not model: it THROWS rather than\n // ignoring it. Narrowing keeps `organizationId`/`userId` (both real columns) and drops the rest.\n // Falls back to the caller's context only when the creator is unavailable (minimal containers).\n const rosterReadContext = this.executionContextCreator\n ? await this.executionContextCreator.createForSubCall(\n executionContext as any,\n CoreResourceType.ORGANIZATION_MEMBERS,\n CoreResourceOperation.LIST,\n )\n : executionContext;\n\n const membershipSummaries = await organizationMembersRepository.list<OrganizationMember>(\n rosterReadContext as any,\n {\n organizationId,\n status: OrganizationMemberStatus.ACTIVE,\n },\n );\n const memberships = await Promise.all(\n membershipSummaries.map(async (membership) => {\n if (membership?.userId && Array.isArray(membership.roles)) {\n return membership;\n }\n if (membership?._id) {\n try {\n return await organizationMembersRepository.read(\n executionContext as any,\n membership._id,\n ) as OrganizationMember | null;\n } catch {\n return membership;\n }\n }\n return membership;\n }),\n );\n\n const allowedRoleSet = allowedRoles && allowedRoles.length > 0\n ? new Set(allowedRoles)\n : null;\n const initiatorUserId = executionContext.initiatorIds?.userId;\n const userIds = memberships\n .filter((membership): membership is OrganizationMember => Boolean(membership))\n .filter((membership) => membership.status === OrganizationMemberStatus.ACTIVE)\n .filter((membership) => typeof membership.userId === 'string' && membership.userId.length > 0)\n .filter((membership) => membership.userId !== initiatorUserId)\n .filter((membership) => {\n if (!allowedRoleSet) {\n return true;\n }\n return membership.roles.some((role) => allowedRoleSet.has(role));\n })\n .map((membership) => membership.userId);\n\n return Array.from(new Set(userIds));\n }\n\n /**\n * Build the public token-consume URL for a token-bearing notification email.\n *\n * When the operation generated a consumable token — its `tokenValue` was injected\n * into `functionParameters.additionalContext` by the services-registry-handler\n * before dispatch — AND the operation declares `tokenGeneration.emailLinkPath`,\n * this returns `<frontendBaseUrl><emailLinkPath>?token=<tokenValue>` (e.g. the\n * `/invitation?token=…` acceptance link). Returns undefined otherwise, so the\n * email template falls back to its generic CTA. Generic across token types — the\n * consume path comes from the operation's declarative config, not hard-coded here.\n */\n private resolveTokenAcceptUrl(\n operation: ResourceConfiguration_Operation<any, any, any>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n frontendBaseUrl: string | undefined,\n ): string | undefined {\n const emailLinkPath = 'tokenGeneration' in operation ? operation.tokenGeneration?.emailLinkPath : undefined;\n // `additionalContext` is injected dynamically by the services-registry-handler\n // (it carries the freshly-minted `tokenValue`); it is not on the static\n // FunctionParameters type, so read it through a narrow cast.\n const tokenValue = (functionParameters as { additionalContext?: Record<string, unknown> })\n .additionalContext?.tokenValue;\n if (!emailLinkPath || typeof tokenValue !== 'string' || tokenValue.length === 0 || !frontendBaseUrl) {\n return undefined;\n }\n const base = frontendBaseUrl.endsWith('/') ? frontendBaseUrl.slice(0, -1) : frontendBaseUrl;\n const path = emailLinkPath.startsWith('/') ? emailLinkPath : `/${emailLinkPath}`;\n return `${base}${path}?token=${encodeURIComponent(tokenValue)}`;\n }\n\n /**\n * Resolve the correct frontend app URL based on notification target.\n * Uses the config-driven reverse lookup: notification target → user type (via defaultAppRoles) → app type.\n * Admin-targeted notifications route to the app type that serves admin user types.\n * All other notifications route to the default frontend app type.\n */\n private resolveDashboardUrlForNotification(\n _operation: ResourceConfiguration_Operation<any, any, any>,\n notification: UserNotificationDefinition\n ): string | undefined {\n const target = notification.target;\n const config = this.appConfigService.config;\n\n const isAdminTarget =\n target === CoreUserNotificationTarget.APPLICATION_ADMINISTRATOR ||\n target === CoreUserNotificationTarget.APPLICATION_BILLING ||\n target === CoreUserNotificationTarget.APPLICATION_USER_MANAGEMENT ||\n target === CoreUserNotificationTarget.APPLICATION_SECURITY ||\n target === CoreUserNotificationTarget.APPLICATION_SUPPORT ||\n target === CoreUserNotificationTarget.APPLICATION_OTHER ||\n target === CoreUserNotificationTarget.APPLICATION_ADMIN_VIEWER;\n\n let appType: string | null = null;\n\n if (isAdminTarget) {\n const adminUserType = Object.entries(config.userTypes)\n .find(([, def]) => def.defaultAppRoles?.includes(CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN))?.[0];\n appType = adminUserType\n ? this.appConfigService.resolveFrontendServiceNameFromUserType(adminUserType)\n : null;\n }\n\n if (!appType) {\n appType = this.appConfigService.resolveDefaultFrontendServiceName();\n }\n\n if (!appType) return undefined;\n return AuthControllerUtils.lookupFrontendPublicUrl(config, appType) ?? undefined;\n }\n\n /**\n * Resolve organization name for email context.\n * Only fetches for org-scoped resources (ORGANIZATIONS scope) using the org ID\n * from executionContext. Returns undefined for USER_SELF, APPLICATION scopes.\n */\n private async resolveOrganizationName(\n operation: ResourceConfiguration_Operation<any, any, any>,\n executionContext: ExecutionContext<any>\n ): Promise<string | undefined> {\n if (operation.resourcePrimaryScope !== ResourcePrimaryScope.ORGANIZATIONS) {\n return undefined;\n }\n\n const organizationId = executionContext.initiatorIds?.organizationId;\n if (!organizationId) {\n return undefined;\n }\n\n try {\n const orgRepository = this.repositoriesRegistry.getRepository(CoreResourceType.ORGANIZATIONS);\n if (!orgRepository) {\n return undefined;\n }\n const org = await orgRepository.read(\n { operation: { resourceIdentifier: CoreResourceType.ORGANIZATIONS, operationIdentifier: 'read' } } as any,\n organizationId,\n { excludeContextualFilter: true },\n );\n if (!org) return undefined;\n return (org as any).displayName ?? (org as any).name ?? undefined;\n } catch {\n this.logDebug('Failed to resolve organization name', { organizationId });\n return undefined;\n }\n }\n\n /**\n * Resolve a direct resource URL for the entity that triggered the notification.\n * Builds the READ operation's frontend route and replaces `:param` placeholders\n * with actual IDs from the currentObject and executionContext.\n * Returns undefined for destructive operations (DELETE) or when resolution fails.\n */\n private resolveResourceUrl(\n operation: ResourceConfiguration_Operation<any, any, any>,\n currentObject: Record<string, unknown> | undefined,\n executionContext: ExecutionContext<any>,\n dashboardUrl: string | undefined\n ): string | undefined {\n if (!dashboardUrl || !currentObject) return undefined;\n\n const effectiveOperation = this.resolveEffectiveCoreOperation(\n operation.operationIdentifier,\n operation.resourceOperationLike,\n );\n if (shouldOmitResourceUrlForOperation(effectiveOperation)) {\n return undefined;\n }\n\n try {\n const resourceType = String(operation.resourceIdentifier);\n const routePaths = this.getReadRoutePaths(resourceType);\n if (!routePaths) return undefined;\n\n const resourceConfig = this.resourcesRegistry.tryGetResourceConfiguration(resourceType as any);\n\n const idSources: Record<string, unknown> = {\n ...(executionContext.initiatorIds ?? {}),\n ...(currentObject as Record<string, unknown>),\n };\n\n const entityId = (currentObject as any).id ?? (currentObject as any)._id;\n const selfFieldId = resourceConfig?.resourceFieldIdentifier;\n if (selfFieldId && entityId) {\n idSources[selfFieldId] = entityId;\n }\n\n const base = dashboardUrl.endsWith('/') ? dashboardUrl.slice(0, -1) : dashboardUrl;\n\n for (const { url: routeTemplate, parameters } of routePaths) {\n let resolved = routeTemplate;\n let allResolved = true;\n for (const param of parameters) {\n const value = idSources[param.fieldIdentifier];\n if (!value) { allResolved = false; break; }\n resolved = resolved.replace(`:${param.fieldIdentifier}`, String(value));\n }\n if (allResolved && !resolved.includes(':')) {\n return `${base}${resolved}`;\n }\n }\n\n return undefined;\n } catch {\n this.logDebug('Failed to resolve resource URL', {\n resourceIdentifier: String(operation.resourceIdentifier),\n });\n return undefined;\n }\n }\n\n /**\n * Get cached READ operation route paths for a resource type.\n * Computed once per resource type since configs are immutable after initialization.\n * Returns null (cached miss) when the resource has no routable READ operation.\n */\n private getReadRoutePaths(resourceType: string): CachedRoutePaths | null {\n if (this.readRoutePathsCache.has(resourceType)) {\n return this.readRoutePathsCache.get(resourceType)!;\n }\n\n const resourceConfig = this.resourcesRegistry.tryGetResourceConfiguration(resourceType as any);\n if (!resourceConfig) {\n this.readRoutePathsCache.set(resourceType, null);\n return null;\n }\n\n const readCandidates = resourceConfig.operations.filter(\n (op: ResourceConfiguration_Operation<any, any, any>) =>\n op.operationIdentifier === CoreResourceOperation.READ\n && op.isOperationDefault === true\n && !('isBulkOperation' in op && op.isBulkOperation === true)\n && (\n op.variantType === ResourceOperationVariantType.API_CALL\n || op.variantType === ResourceOperationVariantType.API_CALL_WITH_CALLBACK\n )\n );\n if (readCandidates.length > 1) {\n const candidateVariants = readCandidates.map((op) => ({\n variantType: op.variantType,\n variantKey: op.variantKey,\n }));\n this.logDebug('Ambiguous notification READ route candidates', {\n resourceType,\n candidateVariants,\n });\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n customMessageReference: ErrorCustomMessageReference.SERVICE_RESOURCE_OPERATION_FAILED,\n context: {\n message: 'Notification deep-link routing requires exactly one default non-bulk URL-bearing READ operation',\n resourceType,\n candidateVariants,\n },\n },\n );\n }\n const readOp = readCandidates[0];\n if (!readOp) {\n this.readRoutePathsCache.set(resourceType, null);\n return null;\n }\n\n const allFieldIds = this.resourcesRegistry.getAllResourceFieldIdentifiers();\n const paths = ResourcesConfigOperationsUrlsBuilderUtils.buildOperationFrontendRoutePaths(\n resourceConfig, readOp as any, allFieldIds\n );\n\n const result = paths.length > 0 ? paths : null;\n this.readRoutePathsCache.set(resourceType, result);\n return result;\n }\n\n /**\n * Dispatch WebSocket-based user notification\n * Routes to appropriate rooms based on target\n */\n private async dispatchWebSocketUserNotification<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition\n ): Promise<void> {\n const operation = executionContext.operation;\n const target = notification.target;\n const operationPathKey = (() => {\n try {\n return ResourcesConfig_OperationPathUtils.createOperationPathKeyFromOperation(operation);\n } catch (error) {\n this.logDebug('Unable to serialize resource notification operation path key', {\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n variantType: operation.variantType,\n variantKey: operation.variantKey,\n error: describeCaughtError(error),\n });\n return undefined;\n }\n })();\n\n // Build the notification payload\n const payload: WS_ResourceNotificationPayload = {\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n operationPathKey,\n variantType: operation.variantType,\n isOperationDefault: operation.isOperationDefault,\n isBulkOperation: 'isBulkOperation' in operation && operation.isBulkOperation === true,\n variantKey: operation.variantKey,\n action: this.mapOperationToAction(\n operation.operationIdentifier,\n operation.resourceOperationLike,\n ),\n // Pass configured notification level (if provided) - frontend will use this over action-based default\n // UserNotificationLevel and NotificationLevel are identical enums - cast through unknown\n notificationLevel: notification.level as unknown as NotificationLevel | undefined,\n affectedIds: this.extractAffectedIds(functionParameters.currentObject),\n contextResourceIdentifiers: this.convertContextResourceIdsToRecord(executionContext),\n notificationIdentifier: notification.identifier,\n initiatorUserId: executionContext.initiatorIds?.userId,\n timestamp: new Date(),\n };\n\n // Copy FRONT_END_SUCCESS-specific display hints into the WS payload.\n // The backend does NOT interpret these — it passes them through for the frontend.\n if (notification.channel === CoreUserNotificationChannel.FRONT_END_SUCCESS) {\n const feNotification = notification as z.infer<typeof UserNotificationDefinition_FrontEndSuccessSchema>;\n if (feNotification.celebration || feNotification.nextStep) {\n payload.frontendDisplayHints = {\n celebration: feNotification.celebration,\n nextStep: feNotification.nextStep,\n };\n }\n }\n\n const message: WebSocketMessage = {\n type: CoreWebSocketEvent.RESOURCE_NOTIFICATION,\n payload,\n timestamp: new Date(),\n userId: executionContext.initiatorIds?.userId,\n organizationId: executionContext.initiatorIds?.organizationId,\n };\n\n // Route based on target\n switch (target) {\n case CoreUserNotificationTarget.USER_SELF:\n if (executionContext.initiatorIds?.userId) {\n await this.webSocketService.sendToUser(executionContext.initiatorIds.userId, message);\n }\n break;\n\n case CoreUserNotificationTarget.ORGANIZATION:\n case CoreUserNotificationTarget.ORGANIZATION_USERS:\n if (executionContext.initiatorIds?.organizationId) {\n await this.webSocketService.sendToOrganization(\n executionContext.initiatorIds.organizationId,\n message,\n // Optionally exclude the initiator\n executionContext.initiatorIds?.userId ? [executionContext.initiatorIds.userId] : undefined\n );\n }\n break;\n\n case CoreUserNotificationTarget.ORGANIZATION_BILLING:\n case CoreUserNotificationTarget.ORGANIZATION_USER_MANAGEMENT:\n case CoreUserNotificationTarget.ORGANIZATION_ADMINISTRATIVE:\n case CoreUserNotificationTarget.ORGANIZATION_SECURITY:\n // Send to specific role rooms within the organization\n if (executionContext.initiatorIds?.organizationId && notification.userRoles) {\n for (const role of notification.userRoles) {\n await this.webSocketService.sendToRole(\n executionContext.initiatorIds.organizationId,\n role,\n message\n );\n }\n }\n break;\n\n case CoreUserNotificationTarget.APPLICATION_ADMINISTRATOR:\n case CoreUserNotificationTarget.APPLICATION_BILLING:\n case CoreUserNotificationTarget.APPLICATION_USER_MANAGEMENT:\n case CoreUserNotificationTarget.APPLICATION_SECURITY:\n case CoreUserNotificationTarget.APPLICATION_SUPPORT:\n case CoreUserNotificationTarget.APPLICATION_OTHER:\n case CoreUserNotificationTarget.APPLICATION_ADMIN_VIEWER:\n // Application-level notifications go to admin dashboard users\n // Map target to app-level role name for WebSocket room targeting\n const appRoles = this.mapApplicationTargetToRoles(target, notification);\n for (const appRole of appRoles) {\n await this.webSocketService.sendToAppRole(appRole, message);\n }\n this.logDebug('Application-level notification sent', {\n target,\n identifier: notification.identifier,\n roles: appRoles,\n });\n break;\n\n case CoreUserNotificationTarget.USERS_CUSTOM:\n // Custom user targeting via userIdsSelector\n if (notification.userIdsSelector) {\n // Ensure objectContext has the expected structure (parents/children)\n const objectContext = functionParameters.objectContext || {};\n const normalizedObjectContext = {\n parents: (objectContext as any)?.parents || {},\n children: (objectContext as any)?.children || {}\n };\n\n const userIds = notification.userIdsSelector({\n currentObject: functionParameters.currentObject,\n inputDto: functionParameters.inputDto,\n objectContext: normalizedObjectContext,\n initiatorIds: functionParameters.initiatorIds\n });\n\n // For WebSocket, we only need userIds (no need to fetch userContext)\n for (const userId of userIds) {\n await this.webSocketService.sendToUser(userId, message);\n }\n }\n break;\n\n case CoreUserNotificationTarget.INBOUND_CONTACT:\n // Inbound contact notifications (e.g., contact form submissions)\n // Route to support and admin roles by default\n const inboundContactRoles = notification.userRoles?.length\n ? notification.userRoles\n : [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n for (const role of inboundContactRoles) {\n await this.webSocketService.sendToAppRole(role, message);\n }\n this.logDebug('Inbound contact notification sent', {\n identifier: notification.identifier,\n roles: inboundContactRoles,\n });\n break;\n\n default:\n this.logDebug('Unknown notification target', {\n target,\n identifier: notification.identifier,\n });\n }\n }\n\n /**\n * Dispatch M2M notifications (webhooks)\n *\n * @param executionContext - The execution context\n * @param functionParameters - Function parameters with data context\n * @private\n */\n private async dispatchM2MNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters\n ): Promise<void> {\n const operation = executionContext.operation;\n const m2mNotifications = operation.m2mNotifications || [];\n\n if (m2mNotifications.length === 0) {\n return;\n }\n\n for (const m2mNotification of m2mNotifications) {\n const channel = m2mNotification.channel as CoreM2MNotificationChannel | string;\n\n if (\n channel === CoreM2MNotificationChannel.WEBHOOK_ORGANIZATION\n || channel === CoreM2MNotificationChannel.WEBHOOK_APPLICATION\n ) {\n // Delegate to the dispatcher; it owns scope resolution, feature\n // gating, config loading, payload serialization, log creation\n // and queue enqueue. Failures inside `enqueueDelivery` are logged\n // here and never bubble back to the caller — webhook delivery\n // is best-effort and must not block the primary operation.\n try {\n await this.m2mWebhookDispatcher.enqueueDelivery(\n operation as ResourceConfiguration_Operation<any, any, any>,\n m2mNotification as M2MNotificationDefinition,\n executionContext as ExecutionContext<ResourceConfiguration_Operation<any, any, any>>,\n functionParameters,\n );\n } catch (error) {\n this.logger.error('Failed to dispatch M2M webhook delivery', {\n channel,\n resourceIdentifier: String(operation.resourceIdentifier),\n operationIdentifier: String(operation.operationIdentifier),\n ...projectCaughtErrorLogFields(error),\n });\n }\n continue;\n }\n\n throw new Error(`M2M notification channel '${channel}' is not implemented.`);\n }\n }\n\n /**\n * Dispatch resource-room notifications (path-independent collaboration).\n *\n * This stays separately callable because some post-write orchestration paths\n * only have authoritative object truth and initiator ids, not the full\n * computation context required for authored notification delivery.\n */\n async dispatchResourceRoomNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters\n ): Promise<void> {\n const operation = executionContext.operation;\n const resourceType = operation.resourceIdentifier;\n const currentObject = functionParameters.currentObject;\n\n // Only dispatch for write operations\n const operationIdentifier = operation.operationIdentifier;\n if (!this.isWriteOperation(operationIdentifier, operation.resourceOperationLike)) {\n return;\n }\n\n const affectedIds = this.extractAffectedIds(currentObject);\n if (affectedIds.length === 0) {\n return;\n }\n\n const action = this.mapOperationToAction(\n operationIdentifier,\n operation.resourceOperationLike,\n );\n const contextResourceIdentifiers = this.convertContextResourceIdsToRecord(executionContext);\n const initiatorUserId = executionContext.initiatorIds?.userId;\n\n const timestamp = new Date();\n const operationIdentifierString = String(operationIdentifier);\n const operationPathKey = (() => {\n try {\n return ResourcesConfig_OperationPathUtils.createOperationPathKeyFromOperation(operation);\n } catch (error) {\n this.logDebug('Unable to serialize resource-room operation path key', {\n resourceType,\n operationIdentifier: operationIdentifierString,\n variantType: operation.variantType,\n variantKey: operation.variantKey,\n error: describeCaughtError(error),\n });\n return undefined;\n }\n })();\n const isBulkOperation = 'isBulkOperation' in operation && operation.isBulkOperation === true;\n const scopePayload = buildScopeRoomNotificationPayload({\n resourceType,\n resourceId: affectedIds[0],\n contextResourceIdentifiers,\n action,\n affectedIds,\n operationIdentifier: operationIdentifierString,\n operationPathKey,\n variantType: operation.variantType,\n isOperationDefault: operation.isOperationDefault,\n isBulkOperation,\n variantKey: operation.variantKey,\n initiatorUserId,\n currentObject,\n timestamp,\n });\n\n // Emit to individual resource rooms\n for (const resourceId of affectedIds) {\n const resourcePayload = buildResourceRoomSyncPayload({\n resourceType,\n resourceId,\n contextResourceIdentifiers,\n action,\n affectedIds,\n operationIdentifier: operationIdentifierString,\n operationPathKey,\n variantType: operation.variantType,\n isOperationDefault: operation.isOperationDefault,\n isBulkOperation,\n variantKey: operation.variantKey,\n initiatorUserId,\n currentObject,\n timestamp,\n });\n\n const resourceNotificationFallback = buildResourceRoomStaleHintPayload({\n resourceType,\n resourceId,\n contextResourceIdentifiers,\n action,\n affectedIds,\n operationIdentifier: operationIdentifierString,\n operationPathKey,\n variantType: operation.variantType,\n isOperationDefault: operation.isOperationDefault,\n isBulkOperation,\n variantKey: operation.variantKey,\n initiatorUserId,\n timestamp,\n });\n\n // Resource rooms get the strongest contract first: try authoritative sync\n // replay for that exact id, and degrade to a notification-grade stale hint\n // only when the backend cannot prove replay truth or the websocket layer\n // rejects the replay payload during canonical validation.\n if (!resourcePayload) {\n this.logDebug('Skipped resource-room sync payload due to missing authoritative replay data', {\n resourceType,\n resourceId,\n action,\n affectedCount: affectedIds.length,\n });\n this.webSocketService.emitToResourceRoom(\n resourceType,\n resourceId,\n CoreWebSocketEvent.RESOURCE_UPDATED,\n resourceNotificationFallback,\n );\n continue;\n }\n\n const event = action === ResourceAction.DELETED\n ? CoreWebSocketEvent.RESOURCE_DELETED\n : CoreWebSocketEvent.RESOURCE_UPDATED;\n\n const emitted = this.webSocketService.emitToResourceRoom(resourceType, resourceId, event, resourcePayload);\n if (!emitted) {\n this.logDebug('Skipped resource-room sync emit after canonical replay validation failure', {\n resourceType,\n resourceId,\n action,\n affectedCount: affectedIds.length,\n });\n this.webSocketService.emitToResourceRoom(\n resourceType,\n resourceId,\n CoreWebSocketEvent.RESOURCE_UPDATED,\n resourceNotificationFallback,\n );\n }\n }\n\n // Scope rooms are emitted separately from per-resource rooms because they\n // serve list/cache refresh semantics rather than authoritative per-resource\n // replay semantics.\n const scopes = this.extractScopesFromContext(contextResourceIdentifiers, operation.resourcePrimaryScope);\n if (scopes.length > 0) {\n this.webSocketService.emitToScopeRooms(\n resourceType,\n scopes,\n CoreWebSocketEvent.RESOURCE_UPDATED,\n scopePayload,\n );\n }\n\n this.logDebug('Resource room notifications dispatched', {\n resourceType,\n action,\n affectedCount: affectedIds.length,\n scopeCount: scopes.length,\n });\n }\n\n // ================================\n // Helper Methods\n // ================================\n\n /**\n * Map APPLICATION_* notification targets to app-level role names for WebSocket targeting.\n *\n * These roles correspond to the `app:role:${role}` rooms that users join when they have\n * application-level permissions (e.g., super admins, support staff).\n *\n * @param target - The CoreUserNotificationTarget\n * @param notification - The notification definition (may contain userRoles override)\n * @returns Array of role names to target\n */\n private mapApplicationTargetToRoles(\n target: CoreUserNotificationTarget,\n notification: UserNotificationDefinition\n ): string[] {\n // If userRoles is explicitly provided, use those\n if (notification.userRoles && notification.userRoles.length > 0) {\n return notification.userRoles;\n }\n\n // Map target to default app-level roles using CORE_APP_ROLES enum\n // These should match the roles that users with app-level permissions have\n switch (target) {\n case CoreUserNotificationTarget.APPLICATION_ADMINISTRATOR:\n return [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_BILLING:\n return [CORE_APP_ROLES.APP_ADMIN_BILLING_MANAGER, CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_USER_MANAGEMENT:\n return [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_SECURITY:\n return [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_SUPPORT:\n return [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_ADMIN_VIEWER:\n return [CORE_APP_ROLES.APP_ADMIN_VIEWER, CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_OTHER:\n default:\n // Default to admin roles for generic application notifications\n return [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n }\n }\n\n private mapOrganizationTargetToRoles(\n target: CoreUserNotificationTarget,\n notification: UserNotificationDefinition,\n ): string[] {\n if (notification.userRoles && notification.userRoles.length > 0) {\n return notification.userRoles;\n }\n\n switch (target) {\n case CoreUserNotificationTarget.ORGANIZATION_BILLING:\n case CoreUserNotificationTarget.ORGANIZATION_USER_MANAGEMENT:\n case CoreUserNotificationTarget.ORGANIZATION_ADMINISTRATIVE:\n case CoreUserNotificationTarget.ORGANIZATION_SECURITY:\n return [CORE_ORG_ROLES.ORG_OWNER, CORE_ORG_ROLES.ORG_ADMIN];\n case CoreUserNotificationTarget.ORGANIZATION:\n case CoreUserNotificationTarget.ORGANIZATION_USERS:\n default:\n return [];\n }\n }\n\n /**\n * Map operation identifier to action type\n */\n private mapOperationToAction(\n operationIdentifier: any,\n resourceOperationLike?: CoreResourceOperation,\n ): ResourceAction {\n const effectiveOperation = this.resolveEffectiveCoreOperation(operationIdentifier, resourceOperationLike);\n\n switch (effectiveOperation) {\n case CoreResourceOperation.CREATE:\n case CoreResourceOperation.CREATE_MANY:\n return ResourceAction.CREATED;\n case CoreResourceOperation.DELETE:\n case CoreResourceOperation.DELETE_MANY:\n return ResourceAction.DELETED;\n case CoreResourceOperation.UPDATE:\n case CoreResourceOperation.UPDATE_MANY:\n default:\n return ResourceAction.UPDATED;\n }\n }\n\n /**\n * Check if operation is a write operation (CREATE, UPDATE, DELETE)\n */\n private isWriteOperation(\n operationIdentifier: any,\n resourceOperationLike?: CoreResourceOperation,\n ): boolean {\n const effectiveOperation = this.resolveEffectiveCoreOperation(operationIdentifier, resourceOperationLike);\n return (\n effectiveOperation === CoreResourceOperation.CREATE ||\n effectiveOperation === CoreResourceOperation.CREATE_MANY ||\n effectiveOperation === CoreResourceOperation.UPDATE ||\n effectiveOperation === CoreResourceOperation.UPDATE_MANY ||\n effectiveOperation === CoreResourceOperation.DELETE ||\n effectiveOperation === CoreResourceOperation.DELETE_MANY\n );\n }\n\n private resolveEffectiveCoreOperation(\n operationIdentifier: any,\n resourceOperationLike?: CoreResourceOperation,\n ): CoreResourceOperation | undefined {\n if (resourceOperationLike) {\n return resourceOperationLike;\n }\n\n const candidate = String(operationIdentifier) as CoreResourceOperation;\n return Object.values(CoreResourceOperation).includes(candidate)\n ? candidate\n : undefined;\n }\n\n /**\n * Extract affected IDs from the current object (result)\n */\n private extractAffectedIds(currentObject: any): string[] {\n if (!currentObject) {\n return [];\n }\n\n // Handle a BARE ID STRING (single DELETE). A single `delete` returns the deleted `_id` as a plain\n // string (services-registry-handler `delete(): Promise<string | string[]>`), so `currentObject` is\n // that string — NOT `{ _id }`. Without this branch the id fell through to `return []` and the whole\n // resource-room broadcast early-returned, so a single delete emitted NEITHER `resource:deleted`\n // (resource room) NOR `resource:updated` action=deleted (scope room). DELETE_MANY already worked via\n // the array branch below (bare-string items). The not-found case returns `''`, excluded by the\n // `!currentObject`/length guard. Placed FIRST because a string has no `_id`/`id` for the object branch.\n if (typeof currentObject === 'string') {\n return currentObject.length > 0 ? [currentObject] : [];\n }\n\n // Handle array of objects (bulk operations)\n if (Array.isArray(currentObject)) {\n return currentObject\n .flatMap((item) => {\n if (typeof item === 'string' && item.length > 0) {\n return [item];\n }\n\n if (item && (item._id || item.id)) {\n return [String(item._id || item.id)];\n }\n\n return [];\n });\n }\n\n // Handle single object\n if (currentObject._id || currentObject.id) {\n return [String(currentObject._id || currentObject.id)];\n }\n\n // Handle delete responses\n if (currentObject.deletedIds) {\n return currentObject.deletedIds.map((id: any) => String(id));\n }\n if (currentObject.deletedId) {\n return [String(currentObject.deletedId)];\n }\n\n // Handle update responses\n if (currentObject.updatedIds) {\n return currentObject.updatedIds.map((id: any) => String(id));\n }\n\n return [];\n }\n\n /**\n * Convert ExecutionContext context resource IDs Map to Record<string, string>\n * Handles string, string[], and undefined values appropriately\n */\n private convertContextResourceIdsToRecord<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>\n ): Record<string, string> {\n const contextResourceIds = executionContext.getContextResourceIds();\n const result: Record<string, string> = {};\n\n for (const [key, value] of contextResourceIds.entries()) {\n if (value === undefined) {\n continue;\n }\n\n // Handle string or string[] - for arrays, take first element (same as getContextResourceId)\n const stringValue = Array.isArray(value) ? value[0] : value;\n if (stringValue !== undefined) {\n result[key] = stringValue;\n }\n }\n\n return result;\n }\n\n /**\n * Extract scopes from context resource identifiers for scope room notifications\n */\n private extractScopesFromContext(\n contextResourceIdentifiers: Record<string, string>,\n primaryScope: ResourcePrimaryScope\n ): Array<{ scopeKey: string; scopeId: string }> {\n const scopes: Array<{ scopeKey: string; scopeId: string }> = [];\n const seenScopes = new Set<string>();\n const pushScope = (scopeKey: string, scopeId: string | undefined): void => {\n if (!scopeId) {\n return;\n }\n const dedupeKey = `${scopeKey}:${scopeId}`;\n if (seenScopes.has(dedupeKey)) {\n return;\n }\n seenScopes.add(dedupeKey);\n scopes.push({ scopeKey, scopeId });\n };\n\n if (primaryScope === ResourcePrimaryScope.APPLICATION && contextResourceIdentifiers.applicationId) {\n pushScope('app', contextResourceIdentifiers.applicationId);\n }\n\n if (primaryScope === ResourcePrimaryScope.USER_SELF && contextResourceIdentifiers.userId) {\n pushScope('user', contextResourceIdentifiers.userId);\n }\n\n // Add organization scope if present\n if (contextResourceIdentifiers.organizationId) {\n pushScope('org', contextResourceIdentifiers.organizationId);\n }\n\n // Add other parent resource scopes\n for (const [key, value] of Object.entries(contextResourceIdentifiers)) {\n // Skip organizationId (already handled) and the resource's own ID\n if (key === 'organizationId' || key.endsWith('Id') && !key.includes('Parent')) {\n // Add parent resource scopes (e.g., todoListId -> todolist scope)\n const scopeKey = key.replace(/Id$/, '').toLowerCase();\n if (scopeKey !== 'organization' && value) {\n pushScope(scopeKey, value);\n }\n }\n }\n\n return scopes;\n }\n}\n"]}
1
+ {"version":3,"file":"notifications-dispatcher.backend.service.js","sourceRoot":"","sources":["../../../../../src/notifications/services/notifications-dispatcher.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { inject, injectable, optional } from 'inversify';\nimport type { ExecutionContextCreatorBackendService } from '~wildo-backend-lib/runtime/services/execution-context-creator.backend.service';\nimport { createHash, randomUUID } from 'node:crypto';\nimport { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport {\n ResourceConfiguration_Operation,\n ResourcePrimaryScope,\n deriveResourceScopeRoomQualifiers,\n CoreM2MNotificationChannel,\n CoreUserNotificationChannel,\n CoreUserNotificationTarget,\n UserNotificationDefinition,\n UserNotificationDefinition_EmailSchema,\n UserNotificationDefinition_FrontEndSuccessSchema,\n M2MNotificationDefinition,\n NotificationBadgeOperation,\n NotificationBadgeSourceKind,\n CoreResourceOperation,\n CoreWebSocketEvent,\n WS_ResourceNotificationPayload,\n WS_ResourceUpdatedPayload,\n WS_ResourceDeletedPayload,\n WS_ResourceSyncUpdatedPayload,\n WS_ResourceUpdateNotificationPayload,\n ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n EmailTemplateType,\n ResourceAction,\n NotificationLevel,\n CORE_APP_ROLES,\n CORE_ORG_ROLES,\n CoreResourceType,\n OrganizationMemberStatus,\n ResourcesConfigOperationsUrlsBuilderUtils,\n ResourcesConfig_OperationPathUtils,\n ResourceOperationVariantType,\n WebSocketResourceDeliveryTarget,\n ErrorType,\n ErrorCustomMessageReference,\n} from '@wildo-ai/saas-models';\nimport { BrandAssetComposition, BrandAssetPurpose } from '@wildo-ai/saas-models';\nimport type { FieldMetaEntry, OrganizationMember, UserPreferences, UserProfile } from '@wildo-ai/saas-models';\nimport type { z } from 'zod';\nimport { AvailableLanguage } from '@wildo-ai/presets-components-models';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport { describeCaughtError, projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { WebSocketService, WebSocketMessage } from '~wildo-backend-lib/requests/service/websocket.service';\nimport { NotificationBadgeBackendService } from './notification-badge.backend.service';\nimport {\n type EmailBackendService,\n type EmailSendResult,\n} from '~wildo-backend-lib/notifications/email/services/email.backend.service';\n// Internal callers go through the path alias (`@wildo-ai/saas-backend-lib/custom-batch-manifests`\n// is the public spec-layer subpath; self-imports through the public package name are not\n// wired in this workspace's tsconfig path map).\nimport { EMAIL_BATCH_SEND_BATCH_REF } from '~wildo-backend-lib/base-classes/services/batches/engine-custom-batch-manifests';\nimport type { QueueBackendService } from '~wildo-backend-lib/queue/queue.backend.service';\nimport { AppConfigurationService } from '~wildo-backend-lib/config/services/app-configuration.backend.service';\nimport { getConfiguredPrimaryLanguage } from '~wildo-backend-lib/config/services/app-configuration.backend.utils';\nimport { AuthControllerUtils } from '~wildo-backend-lib/security/authentications/services/utils/auth-controller.utils';\nimport { RepositoriesRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/repositories/repositories-registry-handler.backend.service';\nimport { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport { M2MWebhookDispatcherBackendService } from '~wildo-backend-lib/notifications/webhooks/outbound/services/m2m-webhook-dispatcher.backend.service';\n\n/**\n * Notification Dispatcher Service\n *\n * Handles dispatching of all notification types based on resource operation configurations:\n * - Notification badge operations (incrementing/decrementing/resetting badge counts)\n * - User notifications (email, SMS, push, WebSocket, frontend success)\n * - M2M (Machine-to-Machine) notifications (webhooks)\n * - Resource room notifications (path-independent collaboration)\n */\n/** Batch threshold for email sending - above this, use queue */\nconst EMAIL_BATCH_THRESHOLD = 10;\n\n/**\n * Canonical template identity for operation-authored email notifications.\n *\n * Startup validation and runtime dispatch must use the same derivation;\n * otherwise an application can boot against one template reference and fail\n * only after a mutation commits because delivery derived another.\n */\nexport function buildUserNotificationEmailTemplateRef(\n operation: {\n resourceIdentifier: string;\n operationIdentifier: string;\n variantKey?: string;\n },\n notification: {\n identifier: string;\n target?: string;\n customNotificationRef?: string;\n },\n): string {\n const targetKebab =\n (notification.target || notification.identifier)\n .toLowerCase()\n .replace(/_/g, '-');\n const refParts = [\n 'email',\n operation.resourceIdentifier,\n operation.operationIdentifier,\n ];\n if (operation.variantKey) {\n refParts.push(operation.variantKey);\n }\n refParts.push(targetKebab);\n const baseRef = refParts.join('.');\n return notification.customNotificationRef\n ? `${baseRef}_${notification.customNotificationRef}`\n : baseRef;\n}\n\n/**\n * Optional identity source for post-commit email submissions.\n *\n * Token-backed operation dispatch passes the committed token ID. The\n * dispatcher derives one deterministic provider identity per concrete\n * notification and recipient, so a fan-out cannot accidentally deduplicate\n * distinct emails while a repeated logical send remains provider-idempotent\n * where the selected adapter supports it.\n */\nexport interface NotificationDispatchOptions {\n emailSubmissionSourceId?: string;\n}\n\n/**\n * Derive a fixed-size provider submission identity without exposing recipient\n * data in transport headers. A new token ID produces a new identity, so an\n * explicit RESEND is intentionally a new logical email.\n */\nexport function deriveEmailNotificationSubmissionId(\n sourceId: string,\n notificationIdentifier: string,\n templateRef: string,\n recipientIdentity: { email?: string; userId?: string },\n): string {\n return createHash('sha256')\n .update(JSON.stringify({\n sourceId,\n notificationIdentifier,\n templateRef,\n recipientIdentity,\n }))\n .digest('hex');\n}\n\ntype CachedRoutePaths = { url: string; parameters: { fieldIdentifier: string; resourceType: string }[] }[];\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Normalise a mutated-object slot (`currentObject` / `previousObject`) to the list of plain rows a\n * derived-badge recompute must read its `scopeField` from.\n *\n * A single write yields one object; a bulk write yields an array; `undefined` (CREATE has no\n * pre-image; a slot may be absent) yields nothing. Non-record array entries and bulk-result blobs\n * (`{ updatedIds: [...] }`) are dropped — they carry no per-row field truth.\n */\nfunction toDerivedBadgeRowArray(value: unknown): Record<string, unknown>[] {\n if (Array.isArray(value)) {\n return value.filter(isPlainRecord);\n }\n return isPlainRecord(value) ? [value] : [];\n}\n\nfunction normalizeResourceId(value: unknown): string | undefined {\n if (typeof value === 'string' && value.length > 0) {\n return value;\n }\n\n if (\n typeof value === 'object'\n && value !== null\n && typeof (value as { toString?: () => string }).toString === 'function'\n ) {\n const normalized = value.toString();\n if (normalized.length > 0 && normalized !== '[object Object]') {\n return normalized;\n }\n }\n\n return undefined;\n}\n\nfunction resolveResourceObjectForSync(\n currentObject: unknown,\n resourceId: string,\n affectedIds: string[],\n): Record<string, unknown> | undefined {\n if (Array.isArray(currentObject)) {\n return currentObject.find((candidate): candidate is Record<string, unknown> => (\n // `_id` ONLY — `id` is Mongoose's built-in virtual (surrogate-PK resources only) and does not\n // exist on PostgreSQL. The arm was dead, since `_id` is always present and evaluated first.\n isPlainRecord(candidate) && normalizeResourceId(candidate._id) === resourceId\n ));\n }\n\n if (!isPlainRecord(currentObject)) {\n return undefined;\n }\n\n if (typeof currentObject._id === 'string' && currentObject._id !== resourceId) {\n return undefined;\n }\n\n // A shared bulk result blob (e.g. { updatedIds: [...] }) is not authoritative\n // per-resource replay truth for sync-grade room payloads.\n if (affectedIds.length > 1 && typeof currentObject._id !== 'string') {\n return undefined;\n }\n\n return currentObject;\n}\n\nfunction splitResourceObjectForWebSocket(resourceObject: Record<string, unknown>): {\n cleanedResourceData: Record<string, unknown>;\n fieldMeta?: Record<string, FieldMetaEntry>;\n version?: number;\n} {\n const { _field_meta, ...rest } = resourceObject;\n return {\n cleanedResourceData: rest,\n fieldMeta: _field_meta as Record<string, FieldMetaEntry> | undefined,\n version: resourceObject._version as number | undefined,\n };\n}\n\nexport function shouldOmitResourceUrlForOperation(\n effectiveOperation: CoreResourceOperation | undefined,\n): boolean {\n return effectiveOperation === CoreResourceOperation.DELETE\n || effectiveOperation === CoreResourceOperation.DELETE_MANY;\n}\n\nexport function buildResourceRoomSyncPayload(params: {\n resourceType: string;\n resourceId: string;\n contextResourceIdentifiers: Record<string, string>;\n action: ResourceAction;\n affectedIds: string[];\n operationIdentifier: string;\n operationPathKey?: string;\n variantType?: ResourceOperationVariantType;\n isOperationDefault?: boolean;\n isBulkOperation?: boolean;\n variantKey?: string;\n initiatorUserId?: string;\n currentObject: unknown;\n timestamp?: Date;\n}): WS_ResourceSyncUpdatedPayload | WS_ResourceDeletedPayload | null {\n const timestamp = params.timestamp ?? new Date();\n\n if (params.action === ResourceAction.DELETED) {\n return {\n deliveryTarget: WebSocketResourceDeliveryTarget.RESOURCE_ROOM_SYNC,\n resourceType: params.resourceType,\n resourceId: params.resourceId,\n contextResourceIdentifiers: params.contextResourceIdentifiers,\n action: ResourceAction.DELETED,\n affectedIds: params.affectedIds,\n operationIdentifier: params.operationIdentifier,\n operationPathKey: params.operationPathKey,\n variantType: params.variantType,\n isOperationDefault: params.isOperationDefault,\n isBulkOperation: params.isBulkOperation,\n variantKey: params.variantKey,\n initiatorUserId: params.initiatorUserId,\n timestamp,\n };\n }\n\n const resourceObject = resolveResourceObjectForSync(\n params.currentObject,\n params.resourceId,\n params.affectedIds,\n );\n if (!resourceObject) {\n return null;\n }\n\n const {\n cleanedResourceData,\n fieldMeta,\n version,\n } = splitResourceObjectForWebSocket(resourceObject);\n\n if (version == null) {\n return null;\n }\n\n // Sync-grade resource-room events are the only websocket payloads allowed to\n // carry authoritative replay data for a specific resource. If we cannot prove\n // both the per-resource object body and its authoritative version, callers\n // must fall back to a notification-grade stale hint instead.\n return {\n deliveryTarget: WebSocketResourceDeliveryTarget.RESOURCE_ROOM_SYNC,\n resourceType: params.resourceType,\n resourceId: params.resourceId,\n contextResourceIdentifiers: params.contextResourceIdentifiers,\n action: params.action,\n affectedIds: params.affectedIds,\n operationIdentifier: params.operationIdentifier,\n operationPathKey: params.operationPathKey,\n variantType: params.variantType,\n isOperationDefault: params.isOperationDefault,\n isBulkOperation: params.isBulkOperation,\n variantKey: params.variantKey,\n initiatorUserId: params.initiatorUserId,\n timestamp,\n version,\n resourceData: cleanedResourceData,\n fieldMeta,\n };\n}\n\nexport function buildScopeRoomNotificationPayload(params: {\n resourceType: string;\n resourceId: string;\n contextResourceIdentifiers: Record<string, string>;\n action: ResourceAction;\n affectedIds: string[];\n operationIdentifier: string;\n operationPathKey?: string;\n variantType?: ResourceOperationVariantType;\n isOperationDefault?: boolean;\n isBulkOperation?: boolean;\n variantKey?: string;\n initiatorUserId?: string;\n currentObject: unknown;\n timestamp?: Date;\n}): WS_ResourceUpdateNotificationPayload {\n const timestamp = params.timestamp ?? new Date();\n // Scope rooms are collection/list invalidation surfaces. For multi-id writes\n // they must not overstate single-resource replay truth, so replay-like fields\n // are only included when the payload still represents one authoritative row.\n const shouldIncludeReplayLikeFields = params.affectedIds.length <= 1;\n const resourceObject = resolveResourceObjectForSync(\n params.currentObject,\n params.resourceId,\n params.affectedIds,\n );\n const splitResourceObject = shouldIncludeReplayLikeFields && resourceObject\n ? splitResourceObjectForWebSocket(resourceObject)\n : null;\n\n return {\n deliveryTarget: WebSocketResourceDeliveryTarget.SCOPE_ROOM_NOTIFICATION,\n resourceType: params.resourceType,\n resourceId: params.resourceId,\n contextResourceIdentifiers: params.contextResourceIdentifiers,\n action: params.action,\n affectedIds: params.affectedIds,\n operationIdentifier: params.operationIdentifier,\n operationPathKey: params.operationPathKey,\n variantType: params.variantType,\n isOperationDefault: params.isOperationDefault,\n isBulkOperation: params.isBulkOperation,\n variantKey: params.variantKey,\n initiatorUserId: params.initiatorUserId,\n timestamp,\n version: splitResourceObject?.version,\n resourceData: splitResourceObject?.cleanedResourceData,\n fieldMeta: splitResourceObject?.fieldMeta,\n };\n}\n\nexport function buildResourceRoomStaleHintPayload(params: {\n resourceType: string;\n resourceId: string;\n contextResourceIdentifiers: Record<string, string>;\n action: ResourceAction;\n affectedIds: string[];\n operationIdentifier: string;\n operationPathKey?: string;\n variantType?: ResourceOperationVariantType;\n isOperationDefault?: boolean;\n isBulkOperation?: boolean;\n variantKey?: string;\n initiatorUserId?: string;\n timestamp?: Date;\n}): WS_ResourceUpdateNotificationPayload {\n const timestamp = params.timestamp ?? new Date();\n return {\n deliveryTarget: WebSocketResourceDeliveryTarget.RESOURCE_ROOM_NOTIFICATION,\n resourceType: params.resourceType,\n resourceId: params.resourceId,\n contextResourceIdentifiers: params.contextResourceIdentifiers,\n action: params.action,\n affectedIds: params.affectedIds,\n operationIdentifier: params.operationIdentifier,\n operationPathKey: params.operationPathKey,\n variantType: params.variantType,\n isOperationDefault: params.isOperationDefault,\n isBulkOperation: params.isBulkOperation,\n variantKey: params.variantKey,\n initiatorUserId: params.initiatorUserId,\n timestamp,\n };\n}\n\n@injectable()\nexport class NotificationDispatcherService {\n\n protected logDebug: (message: string, context?: Record<string, unknown>) => void;\n\n private readRoutePathsCache = new Map<string, CachedRoutePaths | null>();\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) private logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.WebSocketService) private webSocketService: WebSocketService,\n @inject(SAAS_SERVICE_TYPES.NotificationBadgeService) private badgeService: NotificationBadgeBackendService,\n @inject(SAAS_SERVICE_TYPES.EmailService) private emailService: EmailBackendService,\n @inject(SAAS_SERVICE_TYPES.QueueBackendService) private queueService: QueueBackendService,\n @inject(SAAS_SERVICE_TYPES.AppConfigService) private appConfigService: AppConfigurationService,\n @inject(SAAS_SERVICE_TYPES.RepositoriesRegistryHandlerService) private repositoriesRegistry: RepositoriesRegistryHandlerBackendService,\n @inject(SAAS_SERVICE_TYPES.ResourceRegistryService) private resourcesRegistry: ResourcesRegistryBackendService,\n @inject(SAAS_SERVICE_TYPES.M2MWebhookDispatcherService)\n private m2mWebhookDispatcher: M2MWebhookDispatcherBackendService,\n // Appended LAST so positional construction in tests keeps working, and `@optional()` so a\n // minimal container still builds: the only consumer degrades to the caller's context, which is\n // the pre-existing behaviour.\n @inject(SAAS_SERVICE_TYPES.ExecutionContextCreatorBackendService) @optional()\n private readonly executionContextCreator?: ExecutionContextCreatorBackendService,\n ) {\n this.logDebug = this.logger.debugByType('NotificationDispatcherService');\n this.logger.setDebugTypeLogging('NotificationDispatcherService', false);\n }\n\n /**\n * Dispatch notifications based on operation configuration\n *\n * @param executionContext - The execution context containing operation details and user information\n * @param functionParameters - Parameters containing input data, current object, and context\n */\n async dispatchNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n options?: NotificationDispatchOptions,\n ): Promise<void> {\n const operation = executionContext.operation;\n\n try {\n const results = await Promise.allSettled([\n this.dispatchConfiguredNotifications(\n executionContext,\n functionParameters,\n options,\n ),\n this.dispatchResourceRoomNotifications(executionContext, functionParameters),\n ]);\n\n for (const result of results) {\n if (result.status === 'rejected') {\n this.logger.error('Error dispatching notifications', {\n ...projectCaughtErrorLogFields(result.reason),\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n });\n }\n }\n } catch (error) {\n this.logger.error('Failed to dispatch notifications', {\n ...projectCaughtErrorLogFields(error),\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n });\n }\n }\n\n async dispatchConfiguredNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n options?: NotificationDispatchOptions,\n ): Promise<void> {\n const operation = executionContext.operation;\n\n try {\n // Dispatch authored notification types in parallel. Resource-room\n // synchronization can be invoked independently from this path when the\n // caller only has post-write object truth and not a full computation context.\n const results = await Promise.allSettled([\n // 1. Notification badge operations (EVENT_COUNTER: authored per-op increments)\n this.dispatchNotificationBadgeOperations(executionContext, functionParameters),\n\n // 2. User notifications (email, SMS, push, WebSocket, frontend success)\n this.dispatchUserNotifications(\n executionContext,\n functionParameters,\n options?.emailSubmissionSourceId,\n ),\n\n // 3. M2M notifications (webhooks)\n this.dispatchM2MNotifications(executionContext, functionParameters),\n\n // 4. DERIVED_QUERY badge recomputes: any badge whose source resource was\n // just mutated is re-counted from the source collection (never drifts).\n this.dispatchDerivedBadgeRecomputes(executionContext, functionParameters),\n ]);\n\n for (const result of results) {\n if (result.status === 'rejected') {\n this.logger.error('Error dispatching notifications', {\n ...projectCaughtErrorLogFields(result.reason),\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n });\n }\n }\n\n this.logDebug('All notifications dispatched successfully', {\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n userNotificationCount: (operation.userNotifications || []).length,\n badgeOperationsCount: (operation.notificationBadgeOperations || []).length,\n m2mNotificationsCount: (operation.m2mNotifications || []).length,\n });\n\n } catch (error) {\n // Log but don't throw - notifications should not break the main operation\n this.logger.error('Error dispatching notifications', {\n ...projectCaughtErrorLogFields(error),\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n });\n }\n }\n\n /**\n * Dispatch notification badge operations\n *\n * @param executionContext - The execution context\n * @param functionParameters - Function parameters with data context\n * @private\n */\n private async dispatchNotificationBadgeOperations<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters\n ): Promise<void> {\n const operation = executionContext.operation;\n const badgeOperations = operation.notificationBadgeOperations || [];\n\n if (badgeOperations.length === 0) {\n return;\n }\n\n // Determine the scope and scopeId based on operation's primary scope\n const { scope, scopeId } = this.determineBadgeScope(executionContext);\n if (!scope || !scopeId) {\n this.logDebug('Cannot determine badge scope, skipping badge operations', {\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n });\n return;\n }\n\n // Execute each badge operation\n for (const badgeOp of badgeOperations) {\n try {\n await this.badgeService.executeBadgeOperation(\n executionContext,\n scope,\n scopeId,\n badgeOp.identifier,\n badgeOp.operation as NotificationBadgeOperation,\n 1 // Default value (can be extended to support custom values)\n );\n\n this.logDebug('Badge operation executed', {\n identifier: badgeOp.identifier,\n operation: badgeOp.operation,\n scope,\n scopeId,\n });\n } catch (error) {\n this.logger.warn('Failed to execute badge operation', {\n identifier: badgeOp.identifier,\n operation: badgeOp.operation,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n }\n\n /**\n * Recompute every DERIVED_QUERY badge whose source resource is the one just\n * mutated (R5). Reads the registered `notificationBadgeDefinitions`, filters to\n * derived badges pointing at `operation.resourceIdentifier`, resolves the badge's\n * scopeId from the initiator, and asks the badge service to re-count + emit.\n *\n * Runs on the same write-time dispatch as event badges. Read operations don't\n * reach here (notifications dispatch is post-write), and the recompute is\n * idempotent regardless. Per-badge failures are logged and never abort siblings.\n */\n private async dispatchDerivedBadgeRecomputes<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n ): Promise<void> {\n const operation = executionContext.operation;\n const definitions = this.resourcesRegistry.getResourcesRegistry().notificationBadgeDefinitions ?? [];\n\n const derivedForThisResource = definitions.filter(\n (definition) =>\n definition.source.kind === NotificationBadgeSourceKind.DERIVED_QUERY &&\n definition.source.resourceType === operation.resourceIdentifier,\n );\n if (derivedForThisResource.length === 0) {\n return;\n }\n\n // The scopeId of a derived badge is the VALUE of its `scopeField` on the MUTATED ROW — never\n // the actor. A derived \"incomplete todos assigned to me\" badge is scoped by the todo's\n // `assignedToUserId`; when an admin assigns/reassigns/completes a todo on a member's behalf,\n // it is the MEMBER's badge that changed, and the admin never had a stake in it. Resolving the\n // scope from `executionContext.initiatorIds` (the previous behaviour) silently skipped EVERY\n // cross-user mutation — the affected user's count stayed stale until a reconnect reseeded it.\n //\n // Both the post-write row (`currentObject`) and, when the framework captured one, the pre-image\n // (`previousObject`) are consulted: a reassignment moves TWO scopes — the row leaves the prior\n // holder's set (pre-image) and joins the new holder's (post-image). A completion or a same-scope\n // edit moves ONE, which the post-image alone covers. `recomputeDerivedBadge` SETs the\n // authoritative count for each scope from the source collection, so recomputing a scope that did\n // not actually change is harmless (it re-derives the same number) — the correctness requirement\n // is only that no affected scope is MISSED.\n const affectedRows = [\n ...toDerivedBadgeRowArray(functionParameters.currentObject),\n ...toDerivedBadgeRowArray(functionParameters.previousObject),\n ];\n\n for (const definition of derivedForThisResource) {\n const source = definition.source;\n if (source.kind !== NotificationBadgeSourceKind.DERIVED_QUERY) {\n continue; // narrowed by the filter above; re-checked for the type guard on `scopeField`.\n }\n\n const scopeIds = new Set<string>();\n for (const row of affectedRows) {\n const value = row[source.scopeField];\n if (typeof value === 'string' && value.length > 0) {\n scopeIds.add(value);\n }\n }\n\n if (scopeIds.size === 0) {\n // No affected scope carries the badge's scopeField (e.g. a todo with no assignee) — nothing\n // to recompute. This is normal, not an error: no user's count could have changed.\n this.logDebug('No affected scopeId for derived badge, skipping', {\n identifier: definition.identifier,\n scopeField: source.scopeField,\n });\n continue;\n }\n\n for (const scopeId of scopeIds) {\n try {\n await this.badgeService.recomputeDerivedBadge(executionContext, definition, scopeId);\n } catch (error) {\n this.logger.warn('Failed to recompute derived badge', {\n identifier: definition.identifier,\n resourceType: operation.resourceIdentifier,\n scopeId,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n }\n }\n\n /**\n * Determine the badge scope and scopeId from execution context.\n *\n * Only USER_SELF and ORGANIZATIONS are supported badge scopes after the\n * polymorphism refactor (`.cursor/plans/notification-badges-polymorphism-refactor.md`):\n * the APPLICATION variant was dropped (no canonical badges declared at app\n * scope and no resource type backs it anymore). An operation whose\n * `resourcePrimaryScope` is APPLICATION (or any other unsupported value)\n * yields `{ scope: null, scopeId: null }` so the caller logs and skips\n * cleanly — never silently dispatches into the badge service where\n * `resolveRepository(APPLICATION)` would throw.\n *\n * The fallback (org-then-user from `initiatorIds`) is retained for the\n * `undefined` / unscoped operation case so badge effects on operations that\n * happen to share an org/user context still fire.\n */\n private determineBadgeScope<TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>>(\n executionContext: ExecutionContext<TResourceConfigOperation>\n ): { scope: ResourcePrimaryScope | null; scopeId: string | null } {\n const operation = executionContext.operation;\n const primaryScope = operation.resourcePrimaryScope;\n const initiatorIds = executionContext.initiatorIds;\n\n switch (primaryScope) {\n case ResourcePrimaryScope.USER_SELF:\n return { scope: ResourcePrimaryScope.USER_SELF, scopeId: initiatorIds?.userId || null };\n\n case ResourcePrimaryScope.ORGANIZATIONS:\n return { scope: ResourcePrimaryScope.ORGANIZATIONS, scopeId: initiatorIds?.organizationId || null };\n\n // APPLICATION (and ANONYMOUS) intentionally fall through to the\n // unscoped-fallback branch below: see JSDoc above.\n\n default:\n // Fallback to organization if available, otherwise user.\n // Note: APPLICATION-scoped operations land here too — they take the\n // org/user path if those identifiers are available, otherwise the\n // dispatcher logs \"Cannot determine badge scope, skipping\".\n if (initiatorIds?.organizationId) {\n return { scope: ResourcePrimaryScope.ORGANIZATIONS, scopeId: initiatorIds.organizationId };\n }\n if (initiatorIds?.userId) {\n return { scope: ResourcePrimaryScope.USER_SELF, scopeId: initiatorIds.userId };\n }\n return { scope: null, scopeId: null };\n }\n }\n\n /**\n * Dispatch user notifications\n *\n * @param executionContext - The execution context\n * @param functionParameters - Function parameters with data context\n * @private\n */\n private async dispatchUserNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n emailSubmissionSourceId?: string,\n ): Promise<EmailSendResult[]> {\n const operation = executionContext.operation;\n const userNotifications = operation.userNotifications || [];\n\n if (userNotifications.length === 0) {\n return [];\n }\n\n const emailResults: EmailSendResult[] = [];\n for (const notification of userNotifications) {\n // Config-declared side-effect gate: skip a notification whose `condition` evaluates falsy\n // against the post-operation context. Evaluated here — before channel resolution and the\n // email-by-address path — so it gates every channel uniformly. Canonical use: the org-member\n // invite email fires only for INVITED rows, never for an ACTIVE direct-add (founder / SSO-JIT /\n // SCIM), whose denormalized `userEmail` is the member's OWN address. Absent = always dispatch.\n if (notification.condition && !notification.condition(functionParameters)) {\n this.logDebug('Skipping user notification: condition not met', {\n identifier: notification.identifier,\n channel: notification.channel,\n target: notification.target,\n });\n continue;\n }\n try {\n const notificationEmailResults = await this.dispatchSingleUserNotification(\n executionContext,\n functionParameters,\n notification,\n emailSubmissionSourceId,\n );\n emailResults.push(...notificationEmailResults);\n } catch (error) {\n this.logger.warn('Failed to dispatch user notification', {\n identifier: notification.identifier,\n channel: notification.channel,\n target: notification.target,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n return emailResults;\n }\n\n /**\n * Dispatch a single user notification based on its channel\n */\n private async dispatchSingleUserNotification<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n emailSubmissionSourceId?: string,\n ): Promise<EmailSendResult[]> {\n const channel = notification.channel;\n\n switch (channel) {\n case CoreUserNotificationChannel.WEBSOCKET:\n await this.dispatchWebSocketUserNotification(executionContext, functionParameters, notification);\n return [];\n\n case CoreUserNotificationChannel.EMAIL:\n case CoreUserNotificationChannel.SMS:\n case CoreUserNotificationChannel.PUSH:\n // Email/SMS/Push notifications require recipient userContext fetching\n return this.dispatchEmailSmsPushUserNotification(\n executionContext,\n functionParameters,\n notification,\n emailSubmissionSourceId,\n );\n\n case CoreUserNotificationChannel.FRONT_END_SUCCESS:\n // Frontend success notifications are handled client-side\n // We can optionally send them via WebSocket for SPAs\n await this.dispatchWebSocketUserNotification(executionContext, functionParameters, notification);\n return [];\n\n default:\n this.logDebug('Unknown notification channel', {\n channel,\n identifier: notification.identifier,\n });\n return [];\n }\n }\n\n /**\n * Dispatch Email/SMS/Push user notifications\n * These channels require recipient userContext fetching for template rendering\n */\n private async dispatchEmailSmsPushUserNotification<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n emailSubmissionSourceId?: string,\n ): Promise<EmailSendResult[]> {\n const target = notification.target;\n const channel = notification.channel;\n\n // Email-by-address: when an EMAIL notification declares `recipientEmailField`, the\n // recipient is a raw address read from the current object — a party who is NOT a\n // platform user (an organization-invitation invitee, an inbound lead). There is no\n // `userId` to resolve, so this bypasses `getUserIdsForTarget` entirely.\n const recipientEmailField = channel === CoreUserNotificationChannel.EMAIL\n ? (notification as z.infer<typeof UserNotificationDefinition_EmailSchema>).recipientEmailField\n : undefined;\n if (recipientEmailField) {\n return this.dispatchEmailToRecipientAddress(\n executionContext,\n functionParameters,\n notification,\n recipientEmailField,\n emailSubmissionSourceId,\n );\n }\n\n // Get user IDs based on target\n const userIds = await this.getUserIdsForTarget(\n executionContext,\n functionParameters,\n notification,\n target,\n );\n\n if (userIds.length === 0) {\n this.logDebug('No user IDs found for notification', {\n identifier: notification.identifier,\n target,\n channel,\n });\n return [];\n }\n\n // Handle by channel type\n switch (channel) {\n case CoreUserNotificationChannel.EMAIL:\n return this.dispatchEmailNotifications(\n executionContext,\n functionParameters,\n notification,\n userIds,\n emailSubmissionSourceId,\n );\n\n case CoreUserNotificationChannel.SMS:\n case CoreUserNotificationChannel.PUSH:\n // SMS and Push not yet implemented\n this.logDebug('SMS/Push notifications not yet implemented', {\n identifier: notification.identifier,\n channel,\n userCount: userIds.length,\n });\n return [];\n }\n }\n\n /**\n * Build the shared email-dispatch context for a user notification: the resolved\n * `templateRef`, the app default `locale`, and the `baseContext` (object + additional\n * context, including the token `acceptUrl` enricher). These are computed ONCE per\n * notification (recipient-independent), so both the user-id recipient path\n * (`dispatchEmailNotifications`) and the email-by-address path\n * (`dispatchEmailToRecipientAddress`) render from identical context.\n */\n private async buildEmailNotificationContext<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n ) {\n const operation = executionContext.operation;\n\n // Build template reference from executionContext.operation (guaranteed correct after doOperation corrections)\n const templateRef = buildUserNotificationEmailTemplateRef(\n {\n resourceIdentifier: String(operation.resourceIdentifier),\n operationIdentifier: String(operation.operationIdentifier),\n ...(operation.variantKey && {\n variantKey: String(operation.variantKey),\n }),\n },\n notification,\n );\n\n // Determine the app primary locale from backend configuration.\n const locale = this.getDefaultLocale();\n\n // Get app identity and ID from config.\n // Slice 3.7 (F-53) terminology pin: `appIdentity.appName` is the\n // canonical id (from `WildoSaasConfig.name`), `appIdentity.displayName`\n // is the UI label. Notifications want the UI label, so we resolve a\n // local `appDisplayLabel` from `displayName ?? appName ?? 'Application'`\n // and pass it under the template prop name `appName` (existing\n // template contract — renaming the prop would ripple to every email\n // template, tracked separately).\n const appConfig = this.appConfigService.config as Record<string, unknown>;\n const appIdentity = appConfig.appIdentity as { appName?: string; displayName?: string } | undefined;\n const applicationId = this.appConfigService.applicationId || 'unknown';\n const appDisplayLabel = appIdentity?.displayName || appIdentity?.appName || 'Application';\n\n // Resolve dashboard URL — scope/target-aware (admin targets → APP_ADMIN, else MAIN_APP)\n const dashboardUrl = this.resolveDashboardUrlForNotification(\n operation as unknown as ResourceConfiguration_Operation<any, any, any>, notification\n );\n\n // Fetch initiator name when user-initiated (for \"X added you\" style personalization)\n const initiatorUserId = executionContext.initiatorIds?.userId;\n const initiatorContext = initiatorUserId ? await this.fetchUserContext(initiatorUserId) : undefined;\n const initiatorName = initiatorContext?.firstName ?? initiatorContext?.name ?? undefined;\n\n // Resolve organization name from executionContext (org-scoped resources only)\n const organizationName = await this.resolveOrganizationName(\n operation as unknown as ResourceConfiguration_Operation<any, any, any>, executionContext\n );\n\n // Resolve direct resource URL (e.g. /organizations/:orgId/todos/:todoId → full link)\n const resourceUrl = this.resolveResourceUrl(\n operation as unknown as ResourceConfiguration_Operation<any, any, any>,\n functionParameters.currentObject as Record<string, unknown> | undefined,\n executionContext,\n dashboardUrl\n );\n\n // Build base context from function parameters\n const baseContext = {\n currentObject: functionParameters.currentObject,\n objectContext: {\n primaryScopeContext: {\n appName: appDisplayLabel,\n applicationId,\n organizationName: organizationName ?? undefined,\n // App brand logo for the email header. Resolve the email-optimised\n // lockup from config brandAssets; `resolveBrandAsset` falls back\n // (EMAIL → DEFAULT theme → PRIMARY), and the resolver returns\n // undefined when no brand asset was generated yet. ABSOLUTE variant:\n // email clients can't fetch a same-origin `/brand/<ref>.png`, so a\n // relative brand-asset path is prefixed with the app public base URL.\n logoUrl: this.appConfigService.resolveBrandLogoAbsoluteUrl({\n composition: BrandAssetComposition.LOCKUP,\n purpose: BrandAssetPurpose.EMAIL,\n }) ?? undefined,\n },\n },\n additionalContext: {\n operationType: String(operation.operationIdentifier),\n resourceType: String(operation.resourceIdentifier),\n dashboardUrl: dashboardUrl ?? undefined,\n initiatorName: initiatorName ?? undefined,\n resourceUrl: resourceUrl ?? undefined,\n // Token-consume link for token-bearing emails (e.g. invitation accept):\n // <frontendBase><emailLinkPath>?token=<tokenValue> when the op generated a\n // token and declares `tokenGeneration.emailLinkPath`. Undefined otherwise.\n acceptUrl: this.resolveTokenAcceptUrl(\n operation as unknown as ResourceConfiguration_Operation<any, any, any>,\n functionParameters,\n dashboardUrl,\n ) ?? undefined,\n },\n };\n\n return { templateRef, locale, baseContext };\n }\n\n /**\n * Dispatch email notifications to a list of users.\n * Uses direct sending for small lists, batch queue for larger lists.\n */\n private async dispatchEmailNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n userIds: string[],\n emailSubmissionSourceId?: string,\n ): Promise<EmailSendResult[]> {\n const { templateRef, locale, baseContext } = await this.buildEmailNotificationContext(\n executionContext,\n functionParameters,\n notification,\n );\n\n if (userIds.length > EMAIL_BATCH_THRESHOLD) {\n await this.enqueueEmailBatch(\n templateRef,\n locale,\n userIds,\n baseContext,\n notification,\n emailSubmissionSourceId,\n );\n return [];\n }\n\n // Direct sending for smaller lists\n const results: EmailSendResult[] = [];\n for (const userId of userIds) {\n try {\n const recipientUserContext = await this.fetchUserContext(userId);\n\n if (!recipientUserContext?.email) {\n this.logger.warn('No email address for user, skipping notification', {\n userId,\n identifier: notification.identifier,\n });\n continue;\n }\n\n const recipientLocale = this.resolveRecipientLocale(recipientUserContext, locale);\n const result = await this.emailService.send({\n ...(emailSubmissionSourceId && {\n submissionId: deriveEmailNotificationSubmissionId(\n emailSubmissionSourceId,\n notification.identifier,\n templateRef,\n { userId },\n ),\n }),\n templateRef,\n locale: recipientLocale,\n type: EmailTemplateType.TRANSACTIONAL,\n to: recipientUserContext.email,\n context: {\n ...baseContext,\n userContext: {\n userId,\n email: recipientUserContext.email,\n name: recipientUserContext.name,\n firstName: recipientUserContext.firstName,\n },\n },\n });\n results.push(result);\n\n this.logDebug('Email notification sent', {\n identifier: notification.identifier,\n userId,\n success: result.success,\n submissionId: result.submissionId,\n outcome: result.outcome,\n providerMessageIds: result.providerMessageIds,\n });\n } catch (error) {\n this.logger.warn('Failed to send email notification', {\n userId,\n identifier: notification.identifier,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n return results;\n }\n\n /**\n * Deliver a single email to a raw address read from the current object — the\n * email-by-address path selected when an EMAIL notification declares\n * `recipientEmailField` (see `dispatchEmailSmsPushUserNotification`).\n *\n * The recipient is `currentObject[recipientEmailField]` (a top-level string field,\n * e.g. `email`) — a party who is NOT a platform user (an invitation invitee, an\n * inbound lead), so there is no `userId` and no user preferences. The app default\n * locale is used, and the shared notification context is reused verbatim, so\n * token-bearing emails still carry their `acceptUrl`. Best-effort: a missing address\n * or a send failure is logged and swallowed, never thrown into the operation pipeline.\n */\n private async dispatchEmailToRecipientAddress<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n recipientEmailField: string,\n emailSubmissionSourceId?: string,\n ): Promise<EmailSendResult[]> {\n const operation = executionContext.operation;\n const currentObject = functionParameters.currentObject as Record<string, unknown> | undefined;\n const rawAddress = currentObject?.[recipientEmailField];\n const recipientEmail = typeof rawAddress === 'string' ? rawAddress.trim() : '';\n\n if (!recipientEmail) {\n this.logger.warn('Email-by-address notification has no recipient address on the current object; skipping', {\n identifier: notification.identifier,\n recipientEmailField,\n resourceType: String(operation.resourceIdentifier),\n operationIdentifier: String(operation.operationIdentifier),\n });\n return [];\n }\n\n const { templateRef, locale, baseContext } = await this.buildEmailNotificationContext(\n executionContext,\n functionParameters,\n notification,\n );\n\n try {\n const result = await this.emailService.send({\n ...(emailSubmissionSourceId && {\n submissionId: deriveEmailNotificationSubmissionId(\n emailSubmissionSourceId,\n notification.identifier,\n templateRef,\n { email: recipientEmail },\n ),\n }),\n templateRef,\n locale,\n type: EmailTemplateType.TRANSACTIONAL,\n to: recipientEmail,\n context: {\n ...baseContext,\n // Non-user recipient: only the address is known. `userId: ''` is the explicit\n // \"no platform user\" sentinel for the required `EmailUserContext.userId` field.\n userContext: {\n userId: '',\n email: recipientEmail,\n },\n },\n });\n\n this.logDebug('Email-by-address notification sent', {\n identifier: notification.identifier,\n recipientEmailField,\n success: result.success,\n submissionId: result.submissionId,\n outcome: result.outcome,\n providerMessageIds: result.providerMessageIds,\n });\n return [result];\n } catch (error) {\n this.logger.warn('Failed to send email-by-address notification', {\n identifier: notification.identifier,\n recipientEmailField,\n ...projectCaughtErrorLogFields(error),\n });\n return [];\n }\n }\n\n /**\n * Enqueue a batch of emails for asynchronous sending.\n * Used for large recipient lists (above EMAIL_BATCH_THRESHOLD).\n */\n private async enqueueEmailBatch(\n templateRef: string,\n locale: AvailableLanguage,\n userIds: string[],\n baseContext: Record<string, unknown>,\n notification: UserNotificationDefinition,\n emailSubmissionSourceId?: string,\n ): Promise<void> {\n // Fetch all user contexts first\n const emailItems: Array<{\n submissionId: string;\n templateRef: string;\n locale: string;\n type: string;\n to: string;\n context: Record<string, unknown>;\n }> = [];\n\n for (const userId of userIds) {\n try {\n const recipientUserContext = await this.fetchUserContext(userId);\n\n if (!recipientUserContext?.email) {\n continue;\n }\n\n emailItems.push({\n submissionId: emailSubmissionSourceId\n ? deriveEmailNotificationSubmissionId(\n emailSubmissionSourceId,\n notification.identifier,\n templateRef,\n { userId },\n )\n : randomUUID(),\n templateRef,\n locale: this.resolveRecipientLocale(recipientUserContext, locale),\n type: EmailTemplateType.TRANSACTIONAL,\n to: recipientUserContext.email,\n context: {\n ...baseContext,\n userContext: {\n userId,\n email: recipientUserContext.email,\n name: recipientUserContext.name,\n firstName: recipientUserContext.firstName,\n },\n },\n });\n } catch (error) {\n this.logger.warn('Failed to fetch user context for batch', {\n userId,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n\n if (emailItems.length === 0) {\n this.logDebug('No valid email recipients for batch', {\n identifier: notification.identifier,\n });\n return;\n }\n\n // Enqueue the batch\n const { jobId } = await this.queueService.enqueueCustomBatch(\n EMAIL_BATCH_SEND_BATCH_REF,\n {\n batchId: `${notification.identifier}-${randomUUID()}`,\n emails: emailItems,\n retryOnFailure: true,\n maxRetries: 3,\n }\n );\n\n this.logDebug('Email batch enqueued', {\n identifier: notification.identifier,\n jobId,\n emailCount: emailItems.length,\n });\n }\n\n /**\n * Get default locale from app config\n */\n private getDefaultLocale(): AvailableLanguage {\n return getConfiguredPrimaryLanguage(this.appConfigService.config);\n }\n\n private resolveRecipientLocale(\n recipientUserContext: { preferredLanguage?: AvailableLanguage } | undefined,\n fallbackLocale: AvailableLanguage,\n ): AvailableLanguage {\n return recipientUserContext?.preferredLanguage || fallbackLocale;\n }\n\n private normalizeAvailableLanguage(value: unknown): AvailableLanguage | undefined {\n return Object.values(AvailableLanguage).includes(value as AvailableLanguage)\n ? value as AvailableLanguage\n : undefined;\n }\n\n private async fetchUserPreferences(userId: string): Promise<UserPreferences | undefined> {\n try {\n const userPreferencesRepository = this.repositoriesRegistry.getRepository(CoreResourceType.USER_PREFERENCES);\n if (!userPreferencesRepository) {\n this.logDebug('No user preferences repository available for recipient locale resolution', { userId });\n return undefined;\n }\n\n return await userPreferencesRepository.read<UserPreferences>(\n { operation: { resourceIdentifier: CoreResourceType.USER_PREFERENCES, operationIdentifier: 'read' } } as any,\n { userId },\n { excludeContextualFilter: true },\n ) ?? undefined;\n } catch {\n this.logDebug('Failed to fetch user preferences for recipient locale resolution', { userId });\n return undefined;\n }\n }\n\n /**\n * Resolve the recipient's profile (`USER_PROFILES`, 1:1 with `USERS` via a\n * unique `userId` FK — read context-addressed by `{ userId }`, exactly like\n * {@link fetchUserPreferences}). This is where the human name fields live\n * (`firstName` / `lastName` / `displayName`); the `USERS` row carries none of\n * them. Best-effort: a missing repository or read failure degrades to\n * `undefined` so the caller can fall back to the email address.\n */\n private async fetchUserProfile(userId: string): Promise<UserProfile | undefined> {\n try {\n const userProfilesRepository = this.repositoriesRegistry.getRepository(CoreResourceType.USER_PROFILES);\n if (!userProfilesRepository) {\n this.logDebug('No user profiles repository available for recipient name resolution', { userId });\n return undefined;\n }\n\n return await userProfilesRepository.read<UserProfile>(\n { operation: { resourceIdentifier: CoreResourceType.USER_PROFILES, operationIdentifier: 'read' } } as any,\n { userId },\n { excludeContextualFilter: true },\n ) ?? undefined;\n } catch {\n this.logDebug('Failed to fetch user profile for recipient name resolution', { userId });\n return undefined;\n }\n }\n\n /**\n * Get user IDs for a notification target\n * Handles both fixed targets and custom userIdsSelector\n */\n private async getUserIdsForTarget<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition,\n target: string\n ): Promise<string[]> {\n // Custom user targeting via userIdsSelector\n if (target === CoreUserNotificationTarget.USERS_CUSTOM && notification.userIdsSelector) {\n // Ensure objectContext has the expected structure (parents/children)\n const objectContext = functionParameters.objectContext || {};\n const normalizedObjectContext = {\n parents: (objectContext as any)?.parents || {},\n children: (objectContext as any)?.children || {}\n };\n\n return Array.from(new Set(notification.userIdsSelector({\n currentObject: functionParameters.currentObject,\n inputDto: functionParameters.inputDto,\n objectContext: normalizedObjectContext,\n initiatorIds: functionParameters.initiatorIds\n })));\n }\n\n // Fixed targets - extract from executionContext.initiatorIds\n const initiatorIds = executionContext.initiatorIds;\n\n switch (target) {\n case CoreUserNotificationTarget.USER_SELF:\n return initiatorIds?.userId ? [initiatorIds.userId] : [];\n\n case CoreUserNotificationTarget.ORGANIZATION:\n case CoreUserNotificationTarget.ORGANIZATION_USERS:\n return this.getOrganizationRecipientUserIds(executionContext, initiatorIds?.organizationId);\n\n case CoreUserNotificationTarget.ORGANIZATION_BILLING:\n case CoreUserNotificationTarget.ORGANIZATION_USER_MANAGEMENT:\n case CoreUserNotificationTarget.ORGANIZATION_ADMINISTRATIVE:\n case CoreUserNotificationTarget.ORGANIZATION_SECURITY:\n return this.getOrganizationRecipientUserIds(\n executionContext,\n initiatorIds?.organizationId,\n this.mapOrganizationTargetToRoles(target as CoreUserNotificationTarget, notification),\n );\n\n default:\n // Other targets (role-based, application-level) would also need user ID lookup\n this.logDebug('Target requires user ID lookup', { target });\n return [];\n }\n }\n\n /**\n * Resolve the per-recipient context consumed by every greeting surface (email\n * subject/body, the `initiatorName` personalization, batch/direct sends).\n *\n * The human name fields (`firstName` / `lastName` / `displayName`) live on\n * `USER_PROFILES`, NOT on the `USERS` row — `UserSchema` carries only the email\n * identity anchor, status, roles and timestamps. Reading `firstName`/`name`\n * off the `USERS` row (as this method historically did) therefore resolved to\n * `undefined` for EVERY user, so greetings rendered blank and any\n * `{firstName}`-style label placeholder leaked its literal token to the\n * recipient — `interpolateLabelParams` returns the raw `{token}` verbatim when\n * the param is absent.\n *\n * Names are now read from the user's profile and degrade to `email` when a\n * user has no profile yet (SSO-JIT / anonymous edge cases, or a not-yet-seeded\n * profile). This mirrors the SCIM formatter's `displayName || fullName ||\n * email` degradation so every surface renders *something* human — never a\n * blank, never a raw placeholder token. `name` carries the same greeting label\n * as `displayName`; `firstName` is the informal variant with the same email\n * floor.\n */\n private async fetchUserContext(userId: string): Promise<any | undefined> {\n try {\n const userRepository = this.repositoriesRegistry.getRepository(CoreResourceType.USERS);\n if (!userRepository) {\n this.logDebug('No user repository available for fetchUserContext', { userId });\n return undefined;\n }\n const user = await userRepository.read(\n { operation: { resourceIdentifier: CoreResourceType.USERS, operationIdentifier: 'read' } } as any,\n userId,\n { excludeContextualFilter: true },\n );\n if (!user) return undefined;\n\n const email = (user as any).email as string | undefined;\n\n // Profile (name fields) and preferences (locale) are independent lookups\n // keyed only by `userId`, so resolve them concurrently — adding the profile\n // read must not serialize an extra round-trip per recipient on batch sends.\n // Both helpers are best-effort (own try/catch → undefined), so `Promise.all`\n // never rejects here.\n const [profile, preferences] = await Promise.all([\n this.fetchUserProfile(userId),\n this.fetchUserPreferences(userId),\n ]);\n\n // Names come from USER_PROFILES (1:1 with USERS). Fall back to `email` so a\n // profile-less recipient still gets a sensible greeting and never a blank\n // or a leaked `{firstName}` token. `filter(Boolean)` drops a missing half of\n // the name; `|| undefined` collapses the empty-string join so the `??`\n // chain reaches the email floor.\n const fullName = [profile?.firstName, profile?.lastName].filter(Boolean).join(' ') || undefined;\n const displayName = profile?.displayName ?? fullName ?? email;\n const firstName = profile?.firstName ?? email;\n\n const preferredLanguage = this.normalizeAvailableLanguage(preferences?.languagePreferences?.primaryLanguage)\n ?? this.normalizeAvailableLanguage(preferences?.regional?.locale);\n return {\n email,\n displayName,\n name: displayName,\n firstName,\n preferredLanguage,\n userId,\n };\n } catch {\n this.logDebug('Failed to fetch user context', { userId });\n return undefined;\n }\n }\n\n private async getOrganizationRecipientUserIds(\n executionContext: ExecutionContext<any>,\n organizationId: string | undefined,\n allowedRoles?: string[],\n ): Promise<string[]> {\n if (!organizationId) {\n return [];\n }\n\n const organizationMembersRepository = this.repositoriesRegistry.getRepository(CoreResourceType.ORGANIZATION_MEMBERS);\n if (!organizationMembersRepository) {\n this.logDebug('No organization members repository available for notification targeting', {\n organizationId,\n });\n return [];\n }\n\n // Read the roster on a SUB-CALL context, not the caller's. This runs during dispatch for a\n // notification attached to ANY resource operation, so the caller's context is keyed to that\n // resource — a nested route contributes its own FK (`todoId`, …), and the repository's contextual\n // filter is fail-closed on a field ORGANIZATION_MEMBERS does not model: it THROWS rather than\n // ignoring it. Narrowing keeps `organizationId`/`userId` (both real columns) and drops the rest.\n // Falls back to the caller's context only when the creator is unavailable (minimal containers).\n const rosterReadContext = this.executionContextCreator\n ? await this.executionContextCreator.createForSubCall(\n executionContext as any,\n CoreResourceType.ORGANIZATION_MEMBERS,\n CoreResourceOperation.LIST,\n )\n : executionContext;\n\n const membershipSummaries = await organizationMembersRepository.list<OrganizationMember>(\n rosterReadContext as any,\n {\n organizationId,\n status: OrganizationMemberStatus.ACTIVE,\n },\n );\n const memberships = await Promise.all(\n membershipSummaries.map(async (membership) => {\n if (membership?.userId && Array.isArray(membership.roles)) {\n return membership;\n }\n if (membership?._id) {\n try {\n return await organizationMembersRepository.read(\n executionContext as any,\n membership._id,\n ) as OrganizationMember | null;\n } catch {\n return membership;\n }\n }\n return membership;\n }),\n );\n\n const allowedRoleSet = allowedRoles && allowedRoles.length > 0\n ? new Set(allowedRoles)\n : null;\n const initiatorUserId = executionContext.initiatorIds?.userId;\n const userIds = memberships\n .filter((membership): membership is OrganizationMember => Boolean(membership))\n .filter((membership) => membership.status === OrganizationMemberStatus.ACTIVE)\n .filter((membership) => typeof membership.userId === 'string' && membership.userId.length > 0)\n .filter((membership) => membership.userId !== initiatorUserId)\n .filter((membership) => {\n if (!allowedRoleSet) {\n return true;\n }\n return membership.roles.some((role) => allowedRoleSet.has(role));\n })\n .map((membership) => membership.userId);\n\n return Array.from(new Set(userIds));\n }\n\n /**\n * Build the public token-consume URL for a token-bearing notification email.\n *\n * When the operation generated a consumable token — its `tokenValue` was injected\n * into `functionParameters.additionalContext` by the services-registry-handler\n * before dispatch — AND the operation declares `tokenGeneration.emailLinkPath`,\n * this returns `<frontendBaseUrl><emailLinkPath>?token=<tokenValue>` (e.g. the\n * `/invitation?token=…` acceptance link). Returns undefined otherwise, so the\n * email template falls back to its generic CTA. Generic across token types — the\n * consume path comes from the operation's declarative config, not hard-coded here.\n */\n private resolveTokenAcceptUrl(\n operation: ResourceConfiguration_Operation<any, any, any>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n frontendBaseUrl: string | undefined,\n ): string | undefined {\n const emailLinkPath = 'tokenGeneration' in operation ? operation.tokenGeneration?.emailLinkPath : undefined;\n // `additionalContext` is injected dynamically by the services-registry-handler\n // (it carries the freshly-minted `tokenValue`); it is not on the static\n // FunctionParameters type, so read it through a narrow cast.\n const tokenValue = (functionParameters as { additionalContext?: Record<string, unknown> })\n .additionalContext?.tokenValue;\n if (!emailLinkPath || typeof tokenValue !== 'string' || tokenValue.length === 0 || !frontendBaseUrl) {\n return undefined;\n }\n const base = frontendBaseUrl.endsWith('/') ? frontendBaseUrl.slice(0, -1) : frontendBaseUrl;\n const path = emailLinkPath.startsWith('/') ? emailLinkPath : `/${emailLinkPath}`;\n return `${base}${path}?token=${encodeURIComponent(tokenValue)}`;\n }\n\n /**\n * Resolve the correct frontend app URL based on notification target.\n * Uses the config-driven reverse lookup: notification target → user type (via defaultAppRoles) → app type.\n * Admin-targeted notifications route to the app type that serves admin user types.\n * All other notifications route to the default frontend app type.\n */\n private resolveDashboardUrlForNotification(\n _operation: ResourceConfiguration_Operation<any, any, any>,\n notification: UserNotificationDefinition\n ): string | undefined {\n const target = notification.target;\n const config = this.appConfigService.config;\n\n const isAdminTarget =\n target === CoreUserNotificationTarget.APPLICATION_ADMINISTRATOR ||\n target === CoreUserNotificationTarget.APPLICATION_BILLING ||\n target === CoreUserNotificationTarget.APPLICATION_USER_MANAGEMENT ||\n target === CoreUserNotificationTarget.APPLICATION_SECURITY ||\n target === CoreUserNotificationTarget.APPLICATION_SUPPORT ||\n target === CoreUserNotificationTarget.APPLICATION_OTHER ||\n target === CoreUserNotificationTarget.APPLICATION_ADMIN_VIEWER;\n\n let appType: string | null = null;\n\n if (isAdminTarget) {\n const adminUserType = Object.entries(config.userTypes)\n .find(([, def]) => def.defaultAppRoles?.includes(CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN))?.[0];\n appType = adminUserType\n ? this.appConfigService.resolveFrontendServiceNameFromUserType(adminUserType)\n : null;\n }\n\n if (!appType) {\n appType = this.appConfigService.resolveDefaultFrontendServiceName();\n }\n\n if (!appType) return undefined;\n return AuthControllerUtils.lookupFrontendPublicUrl(config, appType) ?? undefined;\n }\n\n /**\n * Resolve organization name for email context.\n * Only fetches for org-scoped resources (ORGANIZATIONS scope) using the org ID\n * from executionContext. Returns undefined for USER_SELF, APPLICATION scopes.\n */\n private async resolveOrganizationName(\n operation: ResourceConfiguration_Operation<any, any, any>,\n executionContext: ExecutionContext<any>\n ): Promise<string | undefined> {\n if (operation.resourcePrimaryScope !== ResourcePrimaryScope.ORGANIZATIONS) {\n return undefined;\n }\n\n const organizationId = executionContext.initiatorIds?.organizationId;\n if (!organizationId) {\n return undefined;\n }\n\n try {\n const orgRepository = this.repositoriesRegistry.getRepository(CoreResourceType.ORGANIZATIONS);\n if (!orgRepository) {\n return undefined;\n }\n const org = await orgRepository.read(\n { operation: { resourceIdentifier: CoreResourceType.ORGANIZATIONS, operationIdentifier: 'read' } } as any,\n organizationId,\n { excludeContextualFilter: true },\n );\n if (!org) return undefined;\n return (org as any).displayName ?? (org as any).name ?? undefined;\n } catch {\n this.logDebug('Failed to resolve organization name', { organizationId });\n return undefined;\n }\n }\n\n /**\n * Resolve a direct resource URL for the entity that triggered the notification.\n * Builds the READ operation's frontend route and replaces `:param` placeholders\n * with actual IDs from the currentObject and executionContext.\n * Returns undefined for destructive operations (DELETE) or when resolution fails.\n */\n private resolveResourceUrl(\n operation: ResourceConfiguration_Operation<any, any, any>,\n currentObject: Record<string, unknown> | undefined,\n executionContext: ExecutionContext<any>,\n dashboardUrl: string | undefined\n ): string | undefined {\n if (!dashboardUrl || !currentObject) return undefined;\n\n const effectiveOperation = this.resolveEffectiveCoreOperation(\n operation.operationIdentifier,\n operation.resourceOperationLike,\n );\n if (shouldOmitResourceUrlForOperation(effectiveOperation)) {\n return undefined;\n }\n\n try {\n const resourceType = String(operation.resourceIdentifier);\n const routePaths = this.getReadRoutePaths(resourceType);\n if (!routePaths) return undefined;\n\n const resourceConfig = this.resourcesRegistry.tryGetResourceConfiguration(resourceType as any);\n\n const idSources: Record<string, unknown> = {\n ...(executionContext.initiatorIds ?? {}),\n ...(currentObject as Record<string, unknown>),\n };\n\n const entityId = (currentObject as any).id ?? (currentObject as any)._id;\n const selfFieldId = resourceConfig?.resourceFieldIdentifier;\n if (selfFieldId && entityId) {\n idSources[selfFieldId] = entityId;\n }\n\n const base = dashboardUrl.endsWith('/') ? dashboardUrl.slice(0, -1) : dashboardUrl;\n\n for (const { url: routeTemplate, parameters } of routePaths) {\n let resolved = routeTemplate;\n let allResolved = true;\n for (const param of parameters) {\n const value = idSources[param.fieldIdentifier];\n if (!value) { allResolved = false; break; }\n resolved = resolved.replace(`:${param.fieldIdentifier}`, String(value));\n }\n if (allResolved && !resolved.includes(':')) {\n return `${base}${resolved}`;\n }\n }\n\n return undefined;\n } catch {\n this.logDebug('Failed to resolve resource URL', {\n resourceIdentifier: String(operation.resourceIdentifier),\n });\n return undefined;\n }\n }\n\n /**\n * Get cached READ operation route paths for a resource type.\n * Computed once per resource type since configs are immutable after initialization.\n * Returns null (cached miss) when the resource has no routable READ operation.\n */\n private getReadRoutePaths(resourceType: string): CachedRoutePaths | null {\n if (this.readRoutePathsCache.has(resourceType)) {\n return this.readRoutePathsCache.get(resourceType)!;\n }\n\n const resourceConfig = this.resourcesRegistry.tryGetResourceConfiguration(resourceType as any);\n if (!resourceConfig) {\n this.readRoutePathsCache.set(resourceType, null);\n return null;\n }\n\n const readCandidates = resourceConfig.operations.filter(\n (op: ResourceConfiguration_Operation<any, any, any>) =>\n op.operationIdentifier === CoreResourceOperation.READ\n && op.isOperationDefault === true\n && !('isBulkOperation' in op && op.isBulkOperation === true)\n && (\n op.variantType === ResourceOperationVariantType.API_CALL\n || op.variantType === ResourceOperationVariantType.API_CALL_WITH_CALLBACK\n )\n );\n if (readCandidates.length > 1) {\n const candidateVariants = readCandidates.map((op) => ({\n variantType: op.variantType,\n variantKey: op.variantKey,\n }));\n this.logDebug('Ambiguous notification READ route candidates', {\n resourceType,\n candidateVariants,\n });\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n customMessageReference: ErrorCustomMessageReference.SERVICE_RESOURCE_OPERATION_FAILED,\n context: {\n message: 'Notification deep-link routing requires exactly one default non-bulk URL-bearing READ operation',\n resourceType,\n candidateVariants,\n },\n },\n );\n }\n const readOp = readCandidates[0];\n if (!readOp) {\n this.readRoutePathsCache.set(resourceType, null);\n return null;\n }\n\n const allFieldIds = this.resourcesRegistry.getAllResourceFieldIdentifiers();\n const paths = ResourcesConfigOperationsUrlsBuilderUtils.buildOperationFrontendRoutePaths(\n resourceConfig, readOp as any, allFieldIds\n );\n\n const result = paths.length > 0 ? paths : null;\n this.readRoutePathsCache.set(resourceType, result);\n return result;\n }\n\n /**\n * Dispatch WebSocket-based user notification\n * Routes to appropriate rooms based on target\n */\n private async dispatchWebSocketUserNotification<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters,\n notification: UserNotificationDefinition\n ): Promise<void> {\n const operation = executionContext.operation;\n const target = notification.target;\n const operationPathKey = (() => {\n try {\n return ResourcesConfig_OperationPathUtils.createOperationPathKeyFromOperation(operation);\n } catch (error) {\n this.logDebug('Unable to serialize resource notification operation path key', {\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n variantType: operation.variantType,\n variantKey: operation.variantKey,\n error: describeCaughtError(error),\n });\n return undefined;\n }\n })();\n\n // Build the notification payload\n const payload: WS_ResourceNotificationPayload = {\n resourceType: operation.resourceIdentifier,\n operationIdentifier: String(operation.operationIdentifier),\n operationPathKey,\n variantType: operation.variantType,\n isOperationDefault: operation.isOperationDefault,\n isBulkOperation: 'isBulkOperation' in operation && operation.isBulkOperation === true,\n variantKey: operation.variantKey,\n action: this.mapOperationToAction(\n operation.operationIdentifier,\n operation.resourceOperationLike,\n ),\n // Pass configured notification level (if provided) - frontend will use this over action-based default\n // UserNotificationLevel and NotificationLevel are identical enums - cast through unknown\n notificationLevel: notification.level as unknown as NotificationLevel | undefined,\n affectedIds: this.extractAffectedIds(functionParameters.currentObject),\n contextResourceIdentifiers: this.convertContextResourceIdsToRecord(executionContext),\n notificationIdentifier: notification.identifier,\n initiatorUserId: executionContext.initiatorIds?.userId,\n timestamp: new Date(),\n };\n\n // Copy FRONT_END_SUCCESS-specific display hints into the WS payload.\n // The backend does NOT interpret these — it passes them through for the frontend.\n if (notification.channel === CoreUserNotificationChannel.FRONT_END_SUCCESS) {\n const feNotification = notification as z.infer<typeof UserNotificationDefinition_FrontEndSuccessSchema>;\n if (feNotification.celebration || feNotification.nextStep) {\n payload.frontendDisplayHints = {\n celebration: feNotification.celebration,\n nextStep: feNotification.nextStep,\n };\n }\n }\n\n const message: WebSocketMessage = {\n type: CoreWebSocketEvent.RESOURCE_NOTIFICATION,\n payload,\n timestamp: new Date(),\n userId: executionContext.initiatorIds?.userId,\n organizationId: executionContext.initiatorIds?.organizationId,\n };\n\n // Route based on target\n switch (target) {\n case CoreUserNotificationTarget.USER_SELF:\n if (executionContext.initiatorIds?.userId) {\n await this.webSocketService.sendToUser(executionContext.initiatorIds.userId, message);\n }\n break;\n\n case CoreUserNotificationTarget.ORGANIZATION:\n case CoreUserNotificationTarget.ORGANIZATION_USERS:\n if (executionContext.initiatorIds?.organizationId) {\n await this.webSocketService.sendToOrganization(\n executionContext.initiatorIds.organizationId,\n message,\n // Optionally exclude the initiator\n executionContext.initiatorIds?.userId ? [executionContext.initiatorIds.userId] : undefined\n );\n }\n break;\n\n case CoreUserNotificationTarget.ORGANIZATION_BILLING:\n case CoreUserNotificationTarget.ORGANIZATION_USER_MANAGEMENT:\n case CoreUserNotificationTarget.ORGANIZATION_ADMINISTRATIVE:\n case CoreUserNotificationTarget.ORGANIZATION_SECURITY:\n // Send to specific role rooms within the organization\n if (executionContext.initiatorIds?.organizationId && notification.userRoles) {\n for (const role of notification.userRoles) {\n await this.webSocketService.sendToRole(\n executionContext.initiatorIds.organizationId,\n role,\n message\n );\n }\n }\n break;\n\n case CoreUserNotificationTarget.APPLICATION_ADMINISTRATOR:\n case CoreUserNotificationTarget.APPLICATION_BILLING:\n case CoreUserNotificationTarget.APPLICATION_USER_MANAGEMENT:\n case CoreUserNotificationTarget.APPLICATION_SECURITY:\n case CoreUserNotificationTarget.APPLICATION_SUPPORT:\n case CoreUserNotificationTarget.APPLICATION_OTHER:\n case CoreUserNotificationTarget.APPLICATION_ADMIN_VIEWER:\n // Application-level notifications go to admin dashboard users\n // Map target to app-level role name for WebSocket room targeting\n const appRoles = this.mapApplicationTargetToRoles(target, notification);\n for (const appRole of appRoles) {\n await this.webSocketService.sendToAppRole(appRole, message);\n }\n this.logDebug('Application-level notification sent', {\n target,\n identifier: notification.identifier,\n roles: appRoles,\n });\n break;\n\n case CoreUserNotificationTarget.USERS_CUSTOM:\n // Custom user targeting via userIdsSelector\n if (notification.userIdsSelector) {\n // Ensure objectContext has the expected structure (parents/children)\n const objectContext = functionParameters.objectContext || {};\n const normalizedObjectContext = {\n parents: (objectContext as any)?.parents || {},\n children: (objectContext as any)?.children || {}\n };\n\n const userIds = notification.userIdsSelector({\n currentObject: functionParameters.currentObject,\n inputDto: functionParameters.inputDto,\n objectContext: normalizedObjectContext,\n initiatorIds: functionParameters.initiatorIds\n });\n\n // For WebSocket, we only need userIds (no need to fetch userContext)\n for (const userId of userIds) {\n await this.webSocketService.sendToUser(userId, message);\n }\n }\n break;\n\n case CoreUserNotificationTarget.INBOUND_CONTACT:\n // Inbound contact notifications (e.g., contact form submissions)\n // Route to support and admin roles by default\n const inboundContactRoles = notification.userRoles?.length\n ? notification.userRoles\n : [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n for (const role of inboundContactRoles) {\n await this.webSocketService.sendToAppRole(role, message);\n }\n this.logDebug('Inbound contact notification sent', {\n identifier: notification.identifier,\n roles: inboundContactRoles,\n });\n break;\n\n default:\n this.logDebug('Unknown notification target', {\n target,\n identifier: notification.identifier,\n });\n }\n }\n\n /**\n * Dispatch M2M notifications (webhooks)\n *\n * @param executionContext - The execution context\n * @param functionParameters - Function parameters with data context\n * @private\n */\n private async dispatchM2MNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters\n ): Promise<void> {\n const operation = executionContext.operation;\n const m2mNotifications = operation.m2mNotifications || [];\n\n if (m2mNotifications.length === 0) {\n return;\n }\n\n for (const m2mNotification of m2mNotifications) {\n const channel = m2mNotification.channel as CoreM2MNotificationChannel | string;\n\n if (\n channel === CoreM2MNotificationChannel.WEBHOOK_ORGANIZATION\n || channel === CoreM2MNotificationChannel.WEBHOOK_APPLICATION\n ) {\n // Delegate to the dispatcher; it owns scope resolution, feature\n // gating, config loading, payload serialization, log creation\n // and queue enqueue. Failures inside `enqueueDelivery` are logged\n // here and never bubble back to the caller — webhook delivery\n // is best-effort and must not block the primary operation.\n try {\n await this.m2mWebhookDispatcher.enqueueDelivery(\n operation as ResourceConfiguration_Operation<any, any, any>,\n m2mNotification as M2MNotificationDefinition,\n executionContext as ExecutionContext<ResourceConfiguration_Operation<any, any, any>>,\n functionParameters,\n );\n } catch (error) {\n this.logger.error('Failed to dispatch M2M webhook delivery', {\n channel,\n resourceIdentifier: String(operation.resourceIdentifier),\n operationIdentifier: String(operation.operationIdentifier),\n ...projectCaughtErrorLogFields(error),\n });\n }\n continue;\n }\n\n throw new Error(`M2M notification channel '${channel}' is not implemented.`);\n }\n }\n\n /**\n * Dispatch resource-room notifications (path-independent collaboration).\n *\n * This stays separately callable because some post-write orchestration paths\n * only have authoritative object truth and initiator ids, not the full\n * computation context required for authored notification delivery.\n */\n async dispatchResourceRoomNotifications<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>,\n functionParameters: ResourceConfiguration_OperationVariant_CustomImplementation_FunctionParameters\n ): Promise<void> {\n const operation = executionContext.operation;\n const resourceType = operation.resourceIdentifier;\n const currentObject = functionParameters.currentObject;\n\n // Only dispatch for write operations\n const operationIdentifier = operation.operationIdentifier;\n if (!this.isWriteOperation(operationIdentifier, operation.resourceOperationLike)) {\n return;\n }\n\n const affectedIds = this.extractAffectedIds(currentObject);\n if (affectedIds.length === 0) {\n return;\n }\n\n const action = this.mapOperationToAction(\n operationIdentifier,\n operation.resourceOperationLike,\n );\n const contextResourceIdentifiers = this.convertContextResourceIdsToRecord(executionContext);\n const initiatorUserId = executionContext.initiatorIds?.userId;\n\n const timestamp = new Date();\n const operationIdentifierString = String(operationIdentifier);\n const operationPathKey = (() => {\n try {\n return ResourcesConfig_OperationPathUtils.createOperationPathKeyFromOperation(operation);\n } catch (error) {\n this.logDebug('Unable to serialize resource-room operation path key', {\n resourceType,\n operationIdentifier: operationIdentifierString,\n variantType: operation.variantType,\n variantKey: operation.variantKey,\n error: describeCaughtError(error),\n });\n return undefined;\n }\n })();\n const isBulkOperation = 'isBulkOperation' in operation && operation.isBulkOperation === true;\n const scopePayload = buildScopeRoomNotificationPayload({\n resourceType,\n resourceId: affectedIds[0],\n contextResourceIdentifiers,\n action,\n affectedIds,\n operationIdentifier: operationIdentifierString,\n operationPathKey,\n variantType: operation.variantType,\n isOperationDefault: operation.isOperationDefault,\n isBulkOperation,\n variantKey: operation.variantKey,\n initiatorUserId,\n currentObject,\n timestamp,\n });\n\n // Emit to individual resource rooms\n for (const resourceId of affectedIds) {\n const resourcePayload = buildResourceRoomSyncPayload({\n resourceType,\n resourceId,\n contextResourceIdentifiers,\n action,\n affectedIds,\n operationIdentifier: operationIdentifierString,\n operationPathKey,\n variantType: operation.variantType,\n isOperationDefault: operation.isOperationDefault,\n isBulkOperation,\n variantKey: operation.variantKey,\n initiatorUserId,\n currentObject,\n timestamp,\n });\n\n const resourceNotificationFallback = buildResourceRoomStaleHintPayload({\n resourceType,\n resourceId,\n contextResourceIdentifiers,\n action,\n affectedIds,\n operationIdentifier: operationIdentifierString,\n operationPathKey,\n variantType: operation.variantType,\n isOperationDefault: operation.isOperationDefault,\n isBulkOperation,\n variantKey: operation.variantKey,\n initiatorUserId,\n timestamp,\n });\n\n // Resource rooms get the strongest contract first: try authoritative sync\n // replay for that exact id, and degrade to a notification-grade stale hint\n // only when the backend cannot prove replay truth or the websocket layer\n // rejects the replay payload during canonical validation.\n if (!resourcePayload) {\n this.logDebug('Skipped resource-room sync payload due to missing authoritative replay data', {\n resourceType,\n resourceId,\n action,\n affectedCount: affectedIds.length,\n });\n this.webSocketService.emitToResourceRoom(\n resourceType,\n resourceId,\n CoreWebSocketEvent.RESOURCE_UPDATED,\n resourceNotificationFallback,\n );\n continue;\n }\n\n const event = action === ResourceAction.DELETED\n ? CoreWebSocketEvent.RESOURCE_DELETED\n : CoreWebSocketEvent.RESOURCE_UPDATED;\n\n const emitted = this.webSocketService.emitToResourceRoom(resourceType, resourceId, event, resourcePayload);\n if (!emitted) {\n this.logDebug('Skipped resource-room sync emit after canonical replay validation failure', {\n resourceType,\n resourceId,\n action,\n affectedCount: affectedIds.length,\n });\n this.webSocketService.emitToResourceRoom(\n resourceType,\n resourceId,\n CoreWebSocketEvent.RESOURCE_UPDATED,\n resourceNotificationFallback,\n );\n }\n }\n\n // Scope rooms are emitted separately from per-resource rooms because they\n // serve list/cache refresh semantics rather than authoritative per-resource\n // replay semantics.\n const scopes = this.extractScopesFromContext(contextResourceIdentifiers, operation.resourcePrimaryScope);\n if (scopes.length > 0) {\n this.webSocketService.emitToScopeRooms(\n resourceType,\n scopes,\n CoreWebSocketEvent.RESOURCE_UPDATED,\n scopePayload,\n );\n }\n\n this.logDebug('Resource room notifications dispatched', {\n resourceType,\n action,\n affectedCount: affectedIds.length,\n scopeCount: scopes.length,\n });\n }\n\n // ================================\n // Helper Methods\n // ================================\n\n /**\n * Map APPLICATION_* notification targets to app-level role names for WebSocket targeting.\n *\n * These roles correspond to the `app:role:${role}` rooms that users join when they have\n * application-level permissions (e.g., super admins, support staff).\n *\n * @param target - The CoreUserNotificationTarget\n * @param notification - The notification definition (may contain userRoles override)\n * @returns Array of role names to target\n */\n private mapApplicationTargetToRoles(\n target: CoreUserNotificationTarget,\n notification: UserNotificationDefinition\n ): string[] {\n // If userRoles is explicitly provided, use those\n if (notification.userRoles && notification.userRoles.length > 0) {\n return notification.userRoles;\n }\n\n // Map target to default app-level roles using CORE_APP_ROLES enum\n // These should match the roles that users with app-level permissions have\n switch (target) {\n case CoreUserNotificationTarget.APPLICATION_ADMINISTRATOR:\n return [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_BILLING:\n return [CORE_APP_ROLES.APP_ADMIN_BILLING_MANAGER, CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_USER_MANAGEMENT:\n return [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_SECURITY:\n return [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_SUPPORT:\n return [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_ADMIN_VIEWER:\n return [CORE_APP_ROLES.APP_ADMIN_VIEWER, CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n\n case CoreUserNotificationTarget.APPLICATION_OTHER:\n default:\n // Default to admin roles for generic application notifications\n return [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN];\n }\n }\n\n private mapOrganizationTargetToRoles(\n target: CoreUserNotificationTarget,\n notification: UserNotificationDefinition,\n ): string[] {\n if (notification.userRoles && notification.userRoles.length > 0) {\n return notification.userRoles;\n }\n\n switch (target) {\n case CoreUserNotificationTarget.ORGANIZATION_BILLING:\n case CoreUserNotificationTarget.ORGANIZATION_USER_MANAGEMENT:\n case CoreUserNotificationTarget.ORGANIZATION_ADMINISTRATIVE:\n case CoreUserNotificationTarget.ORGANIZATION_SECURITY:\n return [CORE_ORG_ROLES.ORG_OWNER, CORE_ORG_ROLES.ORG_ADMIN];\n case CoreUserNotificationTarget.ORGANIZATION:\n case CoreUserNotificationTarget.ORGANIZATION_USERS:\n default:\n return [];\n }\n }\n\n /**\n * Map operation identifier to action type\n */\n private mapOperationToAction(\n operationIdentifier: any,\n resourceOperationLike?: CoreResourceOperation,\n ): ResourceAction {\n const effectiveOperation = this.resolveEffectiveCoreOperation(operationIdentifier, resourceOperationLike);\n\n switch (effectiveOperation) {\n case CoreResourceOperation.CREATE:\n case CoreResourceOperation.CREATE_MANY:\n return ResourceAction.CREATED;\n case CoreResourceOperation.DELETE:\n case CoreResourceOperation.DELETE_MANY:\n return ResourceAction.DELETED;\n case CoreResourceOperation.UPDATE:\n case CoreResourceOperation.UPDATE_MANY:\n default:\n return ResourceAction.UPDATED;\n }\n }\n\n /**\n * Check if operation is a write operation (CREATE, UPDATE, DELETE)\n */\n private isWriteOperation(\n operationIdentifier: any,\n resourceOperationLike?: CoreResourceOperation,\n ): boolean {\n const effectiveOperation = this.resolveEffectiveCoreOperation(operationIdentifier, resourceOperationLike);\n return (\n effectiveOperation === CoreResourceOperation.CREATE ||\n effectiveOperation === CoreResourceOperation.CREATE_MANY ||\n effectiveOperation === CoreResourceOperation.UPDATE ||\n effectiveOperation === CoreResourceOperation.UPDATE_MANY ||\n effectiveOperation === CoreResourceOperation.DELETE ||\n effectiveOperation === CoreResourceOperation.DELETE_MANY\n );\n }\n\n private resolveEffectiveCoreOperation(\n operationIdentifier: any,\n resourceOperationLike?: CoreResourceOperation,\n ): CoreResourceOperation | undefined {\n if (resourceOperationLike) {\n return resourceOperationLike;\n }\n\n const candidate = String(operationIdentifier) as CoreResourceOperation;\n return Object.values(CoreResourceOperation).includes(candidate)\n ? candidate\n : undefined;\n }\n\n /**\n * Extract affected IDs from the current object (result)\n */\n private extractAffectedIds(currentObject: any): string[] {\n if (!currentObject) {\n return [];\n }\n\n // Handle a BARE ID STRING (single DELETE). A single `delete` returns the deleted `_id` as a plain\n // string (services-registry-handler `delete(): Promise<string | string[]>`), so `currentObject` is\n // that string — NOT `{ _id }`. Without this branch the id fell through to `return []` and the whole\n // resource-room broadcast early-returned, so a single delete emitted NEITHER `resource:deleted`\n // (resource room) NOR `resource:updated` action=deleted (scope room). DELETE_MANY already worked via\n // the array branch below (bare-string items). The not-found case returns `''`, excluded by the\n // `!currentObject`/length guard. Placed FIRST because a string has no `_id`/`id` for the object branch.\n if (typeof currentObject === 'string') {\n return currentObject.length > 0 ? [currentObject] : [];\n }\n\n // Handle array of objects (bulk operations)\n if (Array.isArray(currentObject)) {\n return currentObject\n .flatMap((item) => {\n if (typeof item === 'string' && item.length > 0) {\n return [item];\n }\n\n if (item && (item._id || item.id)) {\n return [String(item._id || item.id)];\n }\n\n return [];\n });\n }\n\n // Handle single object\n if (currentObject._id || currentObject.id) {\n return [String(currentObject._id || currentObject.id)];\n }\n\n // Handle delete responses\n if (currentObject.deletedIds) {\n return currentObject.deletedIds.map((id: any) => String(id));\n }\n if (currentObject.deletedId) {\n return [String(currentObject.deletedId)];\n }\n\n // Handle update responses\n if (currentObject.updatedIds) {\n return currentObject.updatedIds.map((id: any) => String(id));\n }\n\n return [];\n }\n\n /**\n * Convert ExecutionContext context resource IDs Map to Record<string, string>\n * Handles string, string[], and undefined values appropriately\n */\n private convertContextResourceIdsToRecord<\n TResourceConfigOperation extends ResourceConfiguration_Operation<any, any, any>\n >(\n executionContext: ExecutionContext<TResourceConfigOperation>\n ): Record<string, string> {\n const contextResourceIds = executionContext.getContextResourceIds();\n const result: Record<string, string> = {};\n\n for (const [key, value] of contextResourceIds.entries()) {\n if (value === undefined) {\n continue;\n }\n\n // Handle string or string[] - for arrays, take first element (same as getContextResourceId)\n const stringValue = Array.isArray(value) ? value[0] : value;\n if (stringValue !== undefined) {\n result[key] = stringValue;\n }\n }\n\n return result;\n }\n\n /**\n * Extract scopes from context resource identifiers for scope room notifications\n */\n /**\n * Which scope rooms this mutation's rows belong to.\n *\n * Delegates to `deriveResourceScopeRoomQualifiers` in `@wildo-ai/saas-models`, which is where the\n * rule now lives so that a CLIENT caching a read can subscribe to exactly the rooms this emits\n * into. Two copies of this rule would agree only until one side gained a case, and the failure\n * would be silent — a client subscribed to the wrong room does not error, it simply never hears\n * that its cache is stale.\n */\n private extractScopesFromContext(\n contextResourceIdentifiers: Record<string, string>,\n primaryScope: ResourcePrimaryScope\n ): Array<{ scopeKey: string; scopeId: string }> {\n return deriveResourceScopeRoomQualifiers(contextResourceIdentifiers, primaryScope) as Array<{\n scopeKey: string;\n scopeId: string;\n }>;\n }\n}\n"]}