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

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 (853) hide show
  1. package/dist/esm/applications/services/worker-remote-client-factory.backend.service.d.ts.map +1 -1
  2. package/dist/esm/applications/services/worker-remote-client-factory.backend.service.js +19 -1
  3. package/dist/esm/applications/services/worker-remote-client-factory.backend.service.js.map +1 -1
  4. package/dist/esm/base-classes/models/manual-controllers.backend.definition.d.ts.map +1 -1
  5. package/dist/esm/base-classes/models/manual-controllers.backend.definition.js +4 -0
  6. package/dist/esm/base-classes/models/manual-controllers.backend.definition.js.map +1 -1
  7. package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.d.ts +35 -0
  8. package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.d.ts.map +1 -0
  9. package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.js +111 -0
  10. package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.js.map +1 -0
  11. package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.d.ts +50 -0
  12. package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.d.ts.map +1 -0
  13. package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.js +199 -0
  14. package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.js.map +1 -0
  15. package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.d.ts +111 -0
  16. package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.d.ts.map +1 -1
  17. package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.js +140 -0
  18. package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.js.map +1 -1
  19. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts.map +1 -1
  20. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js +27 -6
  21. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js.map +1 -1
  22. package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.d.ts +124 -13
  23. package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.d.ts.map +1 -1
  24. package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.js +207 -21
  25. package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.js.map +1 -1
  26. package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.d.ts +60 -8
  27. package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.d.ts.map +1 -1
  28. package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.js +174 -26
  29. package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.js.map +1 -1
  30. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts +47 -4
  31. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts.map +1 -1
  32. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js +96 -29
  33. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js.map +1 -1
  34. package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.d.ts +55 -0
  35. package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.d.ts.map +1 -0
  36. package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.js +114 -0
  37. package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.js.map +1 -0
  38. package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.d.ts +89 -14
  39. package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.d.ts.map +1 -1
  40. package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.js +84 -11
  41. package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.js.map +1 -1
  42. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts.map +1 -1
  43. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js +9 -1
  44. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js.map +1 -1
  45. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts +49 -0
  46. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts.map +1 -1
  47. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js +171 -18
  48. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js.map +1 -1
  49. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts.map +1 -1
  50. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js +23 -3
  51. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js.map +1 -1
  52. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts.map +1 -1
  53. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js +20 -0
  54. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js.map +1 -1
  55. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.d.ts +22 -0
  56. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.d.ts.map +1 -1
  57. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.js.map +1 -1
  58. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts.map +1 -1
  59. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js +4 -1
  60. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js.map +1 -1
  61. package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.d.ts +11 -0
  62. package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.d.ts.map +1 -1
  63. package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.js +39 -5
  64. package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.js.map +1 -1
  65. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts +181 -2
  66. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
  67. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +529 -41
  68. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
  69. package/dist/esm/base-classes/services/services/system-access.backend.service.d.ts +36 -3
  70. package/dist/esm/base-classes/services/services/system-access.backend.service.d.ts.map +1 -1
  71. package/dist/esm/base-classes/services/services/system-access.backend.service.js +70 -8
  72. package/dist/esm/base-classes/services/services/system-access.backend.service.js.map +1 -1
  73. package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.d.ts +28 -0
  74. package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.d.ts.map +1 -0
  75. package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.js +90 -0
  76. package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.js.map +1 -0
  77. package/dist/esm/billing/batches/usage-flush.batch.backend.service.d.ts +44 -0
  78. package/dist/esm/billing/batches/usage-flush.batch.backend.service.d.ts.map +1 -0
  79. package/dist/esm/billing/batches/usage-flush.batch.backend.service.js +99 -0
  80. package/dist/esm/billing/batches/usage-flush.batch.backend.service.js.map +1 -0
  81. package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.d.ts +91 -0
  82. package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.d.ts.map +1 -0
  83. package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.js +152 -0
  84. package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.js.map +1 -0
  85. package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.d.ts +186 -0
  86. package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.d.ts.map +1 -0
  87. package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.js +474 -0
  88. package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.js.map +1 -0
  89. package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.d.ts +100 -0
  90. package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.d.ts.map +1 -1
  91. package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.js +209 -6
  92. package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.js.map +1 -1
  93. package/dist/esm/billing/services/back-office/usage-metering.backend.service.d.ts +200 -4
  94. package/dist/esm/billing/services/back-office/usage-metering.backend.service.d.ts.map +1 -1
  95. package/dist/esm/billing/services/back-office/usage-metering.backend.service.js +593 -64
  96. package/dist/esm/billing/services/back-office/usage-metering.backend.service.js.map +1 -1
  97. package/dist/esm/billing/services/billing-adapter-registry.backend.d.ts +36 -0
  98. package/dist/esm/billing/services/billing-adapter-registry.backend.d.ts.map +1 -0
  99. package/dist/esm/billing/services/billing-adapter-registry.backend.js +83 -0
  100. package/dist/esm/billing/services/billing-adapter-registry.backend.js.map +1 -0
  101. package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.d.ts +9 -0
  102. package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.d.ts.map +1 -1
  103. package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.js +11 -1
  104. package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.js.map +1 -1
  105. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.d.ts.map +1 -1
  106. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js +48 -7
  107. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js.map +1 -1
  108. package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.d.ts +38 -1
  109. package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.d.ts.map +1 -1
  110. package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.js +67 -2
  111. package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.js.map +1 -1
  112. package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.d.ts +30 -1
  113. package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.d.ts.map +1 -1
  114. package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.js +43 -1
  115. package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.js.map +1 -1
  116. package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.d.ts +11 -3
  117. package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.d.ts.map +1 -1
  118. package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.js +30 -16
  119. package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.js.map +1 -1
  120. package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.d.ts.map +1 -1
  121. package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.js +104 -25
  122. package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.js.map +1 -1
  123. package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.d.ts +18 -1
  124. package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.d.ts.map +1 -1
  125. package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.js +106 -2
  126. package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.js.map +1 -1
  127. package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.d.ts +52 -0
  128. package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.d.ts.map +1 -0
  129. package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.js +74 -0
  130. package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.js.map +1 -0
  131. package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.d.ts +104 -11
  132. package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.d.ts.map +1 -1
  133. package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.js +260 -26
  134. package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.js.map +1 -1
  135. package/dist/esm/billing/testing/mock-billing-provider.d.ts +30 -1
  136. package/dist/esm/billing/testing/mock-billing-provider.d.ts.map +1 -1
  137. package/dist/esm/billing/testing/mock-billing-provider.js +25 -0
  138. package/dist/esm/billing/testing/mock-billing-provider.js.map +1 -1
  139. package/dist/esm/compliance/audit-trails/batches/audit-logs-archive.batch.backend.service.js +11 -4
  140. package/dist/esm/compliance/audit-trails/batches/audit-logs-archive.batch.backend.service.js.map +1 -1
  141. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts +225 -13
  142. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts.map +1 -1
  143. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js +340 -62
  144. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js.map +1 -1
  145. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts +244 -7
  146. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts.map +1 -1
  147. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js +386 -5
  148. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js.map +1 -1
  149. package/dist/esm/compliance/audit-trails/services/composite-audit-log-sink.backend.d.ts.map +1 -1
  150. package/dist/esm/compliance/audit-trails/services/composite-audit-log-sink.backend.js +7 -1
  151. package/dist/esm/compliance/audit-trails/services/composite-audit-log-sink.backend.js.map +1 -1
  152. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts +6 -2
  153. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -1
  154. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js +31 -9
  155. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js.map +1 -1
  156. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts +42 -0
  157. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts.map +1 -1
  158. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js +57 -1
  159. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js.map +1 -1
  160. package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.d.ts +110 -0
  161. package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.d.ts.map +1 -0
  162. package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.js +192 -0
  163. package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.js.map +1 -0
  164. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.d.ts.map +1 -1
  165. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js +31 -0
  166. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js.map +1 -1
  167. package/dist/esm/config/bootstrap/application-runtime-profile.backend.d.ts +5 -0
  168. package/dist/esm/config/bootstrap/application-runtime-profile.backend.d.ts.map +1 -1
  169. package/dist/esm/config/bootstrap/application-runtime-profile.backend.js +6 -0
  170. package/dist/esm/config/bootstrap/application-runtime-profile.backend.js.map +1 -1
  171. package/dist/esm/config/models/app-config.backend.schemas.d.ts +142 -46
  172. package/dist/esm/config/models/app-config.backend.schemas.d.ts.map +1 -1
  173. package/dist/esm/config/models/app-config.backend.schemas.js +121 -12
  174. package/dist/esm/config/models/app-config.backend.schemas.js.map +1 -1
  175. package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.d.ts +38 -15
  176. package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.d.ts.map +1 -1
  177. package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.js +17 -2
  178. package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.js.map +1 -1
  179. package/dist/esm/config/services/app-configuration-loader.backend.service.d.ts +0 -1
  180. package/dist/esm/config/services/app-configuration-loader.backend.service.d.ts.map +1 -1
  181. package/dist/esm/config/services/app-configuration-loader.backend.service.js +68 -76
  182. package/dist/esm/config/services/app-configuration-loader.backend.service.js.map +1 -1
  183. package/dist/esm/config/services/app-configuration.backend.service.d.ts.map +1 -1
  184. package/dist/esm/config/services/app-configuration.backend.service.js +23 -1
  185. package/dist/esm/config/services/app-configuration.backend.service.js.map +1 -1
  186. package/dist/esm/config/services/app-configuration.backend.utils.d.ts +33 -0
  187. package/dist/esm/config/services/app-configuration.backend.utils.d.ts.map +1 -1
  188. package/dist/esm/config/services/app-configuration.backend.utils.js +39 -1
  189. package/dist/esm/config/services/app-configuration.backend.utils.js.map +1 -1
  190. package/dist/esm/config/services/application-startup-config-validator.backend.service.d.ts +25 -0
  191. package/dist/esm/config/services/application-startup-config-validator.backend.service.d.ts.map +1 -1
  192. package/dist/esm/config/services/application-startup-config-validator.backend.service.js +41 -1
  193. package/dist/esm/config/services/application-startup-config-validator.backend.service.js.map +1 -1
  194. package/dist/esm/databases/services/postgresql-schema-plan-diff.backend.d.ts.map +1 -1
  195. package/dist/esm/databases/services/postgresql-schema-plan-diff.backend.js +48 -0
  196. package/dist/esm/databases/services/postgresql-schema-plan-diff.backend.js.map +1 -1
  197. package/dist/esm/errors/services/error-builder.backend.service.d.ts +13 -1
  198. package/dist/esm/errors/services/error-builder.backend.service.d.ts.map +1 -1
  199. package/dist/esm/errors/services/error-builder.backend.service.js +13 -1
  200. package/dist/esm/errors/services/error-builder.backend.service.js.map +1 -1
  201. package/dist/esm/errors/services/error-handler.backend.service.d.ts +70 -7
  202. package/dist/esm/errors/services/error-handler.backend.service.d.ts.map +1 -1
  203. package/dist/esm/errors/services/error-handler.backend.service.js +129 -8
  204. package/dist/esm/errors/services/error-handler.backend.service.js.map +1 -1
  205. package/dist/esm/errors/services/rate-limit.backend.service.d.ts +66 -0
  206. package/dist/esm/errors/services/rate-limit.backend.service.d.ts.map +1 -1
  207. package/dist/esm/errors/services/rate-limit.backend.service.js +102 -25
  208. package/dist/esm/errors/services/rate-limit.backend.service.js.map +1 -1
  209. package/dist/esm/errors/utils/error-log-level-classification.backend.utils.d.ts +5 -0
  210. package/dist/esm/errors/utils/error-log-level-classification.backend.utils.d.ts.map +1 -1
  211. package/dist/esm/errors/utils/error-log-level-classification.backend.utils.js +25 -0
  212. package/dist/esm/errors/utils/error-log-level-classification.backend.utils.js.map +1 -1
  213. package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.d.ts +33 -0
  214. package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.d.ts.map +1 -1
  215. package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.js +40 -0
  216. package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.js.map +1 -1
  217. package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts +59 -2
  218. package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts.map +1 -1
  219. package/dist/esm/external-data/external-data-pipeline-run.backend.service.js +52 -17
  220. package/dist/esm/external-data/external-data-pipeline-run.backend.service.js.map +1 -1
  221. package/dist/esm/external-providers/models/provider-selection-resolution-evidence.backend.definitions.d.ts +4 -2
  222. package/dist/esm/external-providers/models/provider-selection-resolution-evidence.backend.definitions.d.ts.map +1 -1
  223. package/dist/esm/external-providers/models/provider-selection-resolution-evidence.backend.definitions.js.map +1 -1
  224. package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.d.ts +256 -0
  225. package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.d.ts.map +1 -0
  226. package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.js +333 -0
  227. package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.js.map +1 -0
  228. package/dist/esm/external-providers/operations/provider-operation-request.backend.d.ts +56 -0
  229. package/dist/esm/external-providers/operations/provider-operation-request.backend.d.ts.map +1 -0
  230. package/dist/esm/external-providers/operations/provider-operation-request.backend.js +211 -0
  231. package/dist/esm/external-providers/operations/provider-operation-request.backend.js.map +1 -0
  232. package/dist/esm/external-providers/operations/provider-request-signing.backend.d.ts +45 -0
  233. package/dist/esm/external-providers/operations/provider-request-signing.backend.d.ts.map +1 -0
  234. package/dist/esm/external-providers/operations/provider-request-signing.backend.js +216 -0
  235. package/dist/esm/external-providers/operations/provider-request-signing.backend.js.map +1 -0
  236. package/dist/esm/external-providers/operations/provider-rest-call-client.backend.d.ts +56 -0
  237. package/dist/esm/external-providers/operations/provider-rest-call-client.backend.d.ts.map +1 -0
  238. package/dist/esm/external-providers/operations/provider-rest-call-client.backend.js +78 -0
  239. package/dist/esm/external-providers/operations/provider-rest-call-client.backend.js.map +1 -0
  240. package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.d.ts +1 -1
  241. package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.d.ts.map +1 -1
  242. package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.js +2 -2
  243. package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.js.map +1 -1
  244. package/dist/esm/external-providers/services/backend-provider-loader.backend.service.d.ts +89 -0
  245. package/dist/esm/external-providers/services/backend-provider-loader.backend.service.d.ts.map +1 -0
  246. package/dist/esm/external-providers/services/backend-provider-loader.backend.service.js +164 -0
  247. package/dist/esm/external-providers/services/backend-provider-loader.backend.service.js.map +1 -0
  248. package/dist/esm/external-providers/services/backend-provider-registry.backend.service.d.ts +26 -27
  249. package/dist/esm/external-providers/services/backend-provider-registry.backend.service.d.ts.map +1 -1
  250. package/dist/esm/external-providers/services/backend-provider-registry.backend.service.js +50 -64
  251. package/dist/esm/external-providers/services/backend-provider-registry.backend.service.js.map +1 -1
  252. package/dist/esm/external-providers/services/document-extraction.backend.service.d.ts.map +1 -1
  253. package/dist/esm/external-providers/services/document-extraction.backend.service.js +3 -3
  254. package/dist/esm/external-providers/services/document-extraction.backend.service.js.map +1 -1
  255. package/dist/esm/external-providers/services/embeddings.backend.service.d.ts.map +1 -1
  256. package/dist/esm/external-providers/services/embeddings.backend.service.js +4 -4
  257. package/dist/esm/external-providers/services/embeddings.backend.service.js.map +1 -1
  258. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +292 -7
  259. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
  260. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +533 -45
  261. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
  262. package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.d.ts.map +1 -1
  263. package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.js +25 -2
  264. package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.js.map +1 -1
  265. package/dist/esm/files/controllers/file.controller.d.ts.map +1 -1
  266. package/dist/esm/files/controllers/file.controller.js +21 -13
  267. package/dist/esm/files/controllers/file.controller.js.map +1 -1
  268. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts.map +1 -1
  269. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js +39 -15
  270. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js.map +1 -1
  271. package/dist/esm/files/services/file-scanning.backend.service.d.ts +94 -9
  272. package/dist/esm/files/services/file-scanning.backend.service.d.ts.map +1 -1
  273. package/dist/esm/files/services/file-scanning.backend.service.js +197 -17
  274. package/dist/esm/files/services/file-scanning.backend.service.js.map +1 -1
  275. package/dist/esm/files/services/file-text-extraction.backend.service.d.ts +60 -1
  276. package/dist/esm/files/services/file-text-extraction.backend.service.d.ts.map +1 -1
  277. package/dist/esm/files/services/file-text-extraction.backend.service.js +167 -8
  278. package/dist/esm/files/services/file-text-extraction.backend.service.js.map +1 -1
  279. package/dist/esm/files/services/file-upload-grant.backend.service.d.ts +53 -2
  280. package/dist/esm/files/services/file-upload-grant.backend.service.d.ts.map +1 -1
  281. package/dist/esm/files/services/file-upload-grant.backend.service.js +127 -3
  282. package/dist/esm/files/services/file-upload-grant.backend.service.js.map +1 -1
  283. package/dist/esm/files/services/files.backend.service.d.ts +68 -0
  284. package/dist/esm/files/services/files.backend.service.d.ts.map +1 -1
  285. package/dist/esm/files/services/files.backend.service.js +175 -5
  286. package/dist/esm/files/services/files.backend.service.js.map +1 -1
  287. package/dist/esm/files/storage/application-storage-key.backend.utils.d.ts +109 -0
  288. package/dist/esm/files/storage/application-storage-key.backend.utils.d.ts.map +1 -0
  289. package/dist/esm/files/storage/application-storage-key.backend.utils.js +123 -0
  290. package/dist/esm/files/storage/application-storage-key.backend.utils.js.map +1 -0
  291. package/dist/esm/files/storage/file-storage-provider.types.d.ts +16 -10
  292. package/dist/esm/files/storage/file-storage-provider.types.d.ts.map +1 -1
  293. package/dist/esm/files/storage/file-storage-provider.types.js.map +1 -1
  294. package/dist/esm/files/storage/local-directory-storage-provider.backend.service.d.ts +67 -8
  295. package/dist/esm/files/storage/local-directory-storage-provider.backend.service.d.ts.map +1 -1
  296. package/dist/esm/files/storage/local-directory-storage-provider.backend.service.js +101 -28
  297. package/dist/esm/files/storage/local-directory-storage-provider.backend.service.js.map +1 -1
  298. package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.d.ts.map +1 -1
  299. package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.js +8 -55
  300. package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.js.map +1 -1
  301. package/dist/esm/files/utils/file-field-schema-path.backend.utils.d.ts.map +1 -1
  302. package/dist/esm/files/utils/file-field-schema-path.backend.utils.js +20 -0
  303. package/dist/esm/files/utils/file-field-schema-path.backend.utils.js.map +1 -1
  304. package/dist/esm/files/utils/office-document-text-extraction.backend.utils.d.ts +86 -0
  305. package/dist/esm/files/utils/office-document-text-extraction.backend.utils.d.ts.map +1 -0
  306. package/dist/esm/files/utils/office-document-text-extraction.backend.utils.js +288 -0
  307. package/dist/esm/files/utils/office-document-text-extraction.backend.utils.js.map +1 -0
  308. package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.d.ts +15 -0
  309. package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.d.ts.map +1 -1
  310. package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.js +76 -5
  311. package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.js.map +1 -1
  312. package/dist/esm/flows-actors/a2a/controllers/a2a.controller.d.ts.map +1 -1
  313. package/dist/esm/flows-actors/a2a/controllers/a2a.controller.js +6 -1
  314. package/dist/esm/flows-actors/a2a/controllers/a2a.controller.js.map +1 -1
  315. package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.d.ts +60 -0
  316. package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.d.ts.map +1 -1
  317. package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.js +63 -0
  318. package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.js.map +1 -1
  319. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.d.ts +74 -0
  320. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.d.ts.map +1 -1
  321. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js +196 -40
  322. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js.map +1 -1
  323. package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.d.ts +7 -1
  324. package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.d.ts.map +1 -1
  325. package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.js +53 -1
  326. package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.js.map +1 -1
  327. package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.d.ts +18 -0
  328. package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.d.ts.map +1 -1
  329. package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.js +18 -0
  330. package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.js.map +1 -1
  331. package/dist/esm/flows-actors/a2a/services/a2a.backend.service.d.ts +12 -7
  332. package/dist/esm/flows-actors/a2a/services/a2a.backend.service.d.ts.map +1 -1
  333. package/dist/esm/flows-actors/a2a/services/a2a.backend.service.js.map +1 -1
  334. package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.d.ts +0 -13
  335. package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.d.ts.map +1 -1
  336. package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.js +14 -22
  337. package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.js.map +1 -1
  338. package/dist/esm/flows-actors/models/core-facets.backend.definitions.d.ts +8 -3
  339. package/dist/esm/flows-actors/models/core-facets.backend.definitions.d.ts.map +1 -1
  340. package/dist/esm/flows-actors/models/core-facets.backend.definitions.js +25 -15
  341. package/dist/esm/flows-actors/models/core-facets.backend.definitions.js.map +1 -1
  342. package/dist/esm/flows-actors/models/flows-actors.backend.schemas.d.ts +13 -1
  343. package/dist/esm/flows-actors/models/flows-actors.backend.schemas.d.ts.map +1 -1
  344. package/dist/esm/flows-actors/models/flows-actors.backend.schemas.js.map +1 -1
  345. package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts +88 -8
  346. package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts.map +1 -1
  347. package/dist/esm/flows-actors/models/function-tools.backend.definitions.js +333 -31
  348. package/dist/esm/flows-actors/models/function-tools.backend.definitions.js.map +1 -1
  349. package/dist/esm/flows-actors/models/market-generation.actors-system.backend.definitions.d.ts.map +1 -1
  350. package/dist/esm/flows-actors/models/market-generation.actors-system.backend.definitions.js +4 -2
  351. package/dist/esm/flows-actors/models/market-generation.actors-system.backend.definitions.js.map +1 -1
  352. package/dist/esm/flows-actors/models/mcp-client.backend.definitions.d.ts +113 -0
  353. package/dist/esm/flows-actors/models/mcp-client.backend.definitions.d.ts.map +1 -0
  354. package/dist/esm/flows-actors/models/mcp-client.backend.definitions.js +62 -0
  355. package/dist/esm/flows-actors/models/mcp-client.backend.definitions.js.map +1 -0
  356. package/dist/esm/flows-actors/services/actors-system.backend.service.d.ts.map +1 -1
  357. package/dist/esm/flows-actors/services/actors-system.backend.service.js +0 -2
  358. package/dist/esm/flows-actors/services/actors-system.backend.service.js.map +1 -1
  359. package/dist/esm/flows-actors/services/agents.backend.service.d.ts +28 -1
  360. package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
  361. package/dist/esm/flows-actors/services/agents.backend.service.js +204 -18
  362. package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
  363. package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts +5 -1
  364. package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts.map +1 -1
  365. package/dist/esm/flows-actors/services/conversational-execution.backend.service.js +79 -16
  366. package/dist/esm/flows-actors/services/conversational-execution.backend.service.js.map +1 -1
  367. package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts +34 -5
  368. package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts.map +1 -1
  369. package/dist/esm/flows-actors/services/flows-actors-registry.service.js +154 -20
  370. package/dist/esm/flows-actors/services/flows-actors-registry.service.js.map +1 -1
  371. package/dist/esm/flows-actors/services/flows.backend.services.d.ts.map +1 -1
  372. package/dist/esm/flows-actors/services/flows.backend.services.js +27 -23
  373. package/dist/esm/flows-actors/services/flows.backend.services.js.map +1 -1
  374. package/dist/esm/flows-actors/services/llm-observability-agent-call-trace-sink.backend.d.ts.map +1 -1
  375. package/dist/esm/flows-actors/services/llm-observability-agent-call-trace-sink.backend.js +7 -1
  376. package/dist/esm/flows-actors/services/llm-observability-agent-call-trace-sink.backend.js.map +1 -1
  377. package/dist/esm/flows-actors/services/mcp-client.backend.service.d.ts +90 -0
  378. package/dist/esm/flows-actors/services/mcp-client.backend.service.d.ts.map +1 -0
  379. package/dist/esm/flows-actors/services/mcp-client.backend.service.js +368 -0
  380. package/dist/esm/flows-actors/services/mcp-client.backend.service.js.map +1 -0
  381. package/dist/esm/flows-actors/services/prompt-compiler.backend.service.d.ts +9 -5
  382. package/dist/esm/flows-actors/services/prompt-compiler.backend.service.d.ts.map +1 -1
  383. package/dist/esm/flows-actors/services/prompt-compiler.backend.service.js +12 -17
  384. package/dist/esm/flows-actors/services/prompt-compiler.backend.service.js.map +1 -1
  385. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
  386. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +8 -4
  387. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
  388. package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.d.ts +0 -207
  389. package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.d.ts.map +1 -1
  390. package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.js +8 -243
  391. package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.js.map +1 -1
  392. package/dist/esm/flows-actors/utils/meta-workflow-structured-generation-plan.backend.utils.d.ts.map +1 -1
  393. package/dist/esm/flows-actors/utils/meta-workflow-structured-generation-plan.backend.utils.js.map +1 -1
  394. package/dist/esm/guidance/services/milestone-evaluator.backend.service.d.ts +9 -14
  395. package/dist/esm/guidance/services/milestone-evaluator.backend.service.d.ts.map +1 -1
  396. package/dist/esm/guidance/services/milestone-evaluator.backend.service.js +18 -89
  397. package/dist/esm/guidance/services/milestone-evaluator.backend.service.js.map +1 -1
  398. package/dist/esm/guidance/services/progression-state-store.backend.service.d.ts +86 -0
  399. package/dist/esm/guidance/services/progression-state-store.backend.service.d.ts.map +1 -0
  400. package/dist/esm/guidance/services/progression-state-store.backend.service.js +155 -0
  401. package/dist/esm/guidance/services/progression-state-store.backend.service.js.map +1 -0
  402. package/dist/esm/i18n/controllers/i18n-controller.backend.service.d.ts +10 -0
  403. package/dist/esm/i18n/controllers/i18n-controller.backend.service.d.ts.map +1 -1
  404. package/dist/esm/i18n/controllers/i18n-controller.backend.service.js +55 -5
  405. package/dist/esm/i18n/controllers/i18n-controller.backend.service.js.map +1 -1
  406. package/dist/esm/index.d.ts +11 -4
  407. package/dist/esm/index.d.ts.map +1 -1
  408. package/dist/esm/index.js +31 -4
  409. package/dist/esm/index.js.map +1 -1
  410. package/dist/esm/inject/models/container.d.ts.map +1 -1
  411. package/dist/esm/inject/models/container.js +78 -10
  412. package/dist/esm/inject/models/container.js.map +1 -1
  413. package/dist/esm/inject/models/service-types.d.ts +17 -3
  414. package/dist/esm/inject/models/service-types.d.ts.map +1 -1
  415. package/dist/esm/inject/models/service-types.js +19 -3
  416. package/dist/esm/inject/models/service-types.js.map +1 -1
  417. package/dist/esm/mcp/controllers/mcp.controller.d.ts.map +1 -1
  418. package/dist/esm/mcp/controllers/mcp.controller.js +20 -0
  419. package/dist/esm/mcp/controllers/mcp.controller.js.map +1 -1
  420. package/dist/esm/mcp/services/mcp-server.backend.service.d.ts +56 -1
  421. package/dist/esm/mcp/services/mcp-server.backend.service.d.ts.map +1 -1
  422. package/dist/esm/mcp/services/mcp-server.backend.service.js +107 -11
  423. package/dist/esm/mcp/services/mcp-server.backend.service.js.map +1 -1
  424. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts.map +1 -1
  425. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js +22 -0
  426. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js.map +1 -1
  427. package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.d.ts.map +1 -1
  428. package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.js +49 -4
  429. package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.js.map +1 -1
  430. package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.d.ts +66 -0
  431. package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.d.ts.map +1 -0
  432. package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.js +199 -0
  433. package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.js.map +1 -0
  434. package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.d.ts +149 -13
  435. package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.d.ts.map +1 -1
  436. package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.js +411 -19
  437. package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.js.map +1 -1
  438. package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.d.ts +11 -2
  439. package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.d.ts.map +1 -1
  440. package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.js.map +1 -1
  441. package/dist/esm/monitoring/logger/models/logger.backend.schemas.d.ts +28 -9
  442. package/dist/esm/monitoring/logger/models/logger.backend.schemas.d.ts.map +1 -1
  443. package/dist/esm/monitoring/logger/models/logger.backend.schemas.js +30 -10
  444. package/dist/esm/monitoring/logger/models/logger.backend.schemas.js.map +1 -1
  445. package/dist/esm/monitoring/logger/services/logger.service.d.ts +12 -0
  446. package/dist/esm/monitoring/logger/services/logger.service.d.ts.map +1 -1
  447. package/dist/esm/monitoring/logger/services/logger.service.js +52 -11
  448. package/dist/esm/monitoring/logger/services/logger.service.js.map +1 -1
  449. package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.d.ts +62 -0
  450. package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.d.ts.map +1 -0
  451. package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.js +78 -0
  452. package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.js.map +1 -0
  453. package/dist/esm/monitoring/observability/audit-observation-emission.backend.d.ts +309 -0
  454. package/dist/esm/monitoring/observability/audit-observation-emission.backend.d.ts.map +1 -0
  455. package/dist/esm/monitoring/observability/audit-observation-emission.backend.js +385 -0
  456. package/dist/esm/monitoring/observability/audit-observation-emission.backend.js.map +1 -0
  457. package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts +1 -0
  458. package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts.map +1 -1
  459. package/dist/esm/monitoring/observability/models/observability.backend.schemas.js.map +1 -1
  460. package/dist/esm/monitoring/observability/services/metrics.service.d.ts +21 -0
  461. package/dist/esm/monitoring/observability/services/metrics.service.d.ts.map +1 -1
  462. package/dist/esm/monitoring/observability/services/metrics.service.js +38 -0
  463. package/dist/esm/monitoring/observability/services/metrics.service.js.map +1 -1
  464. package/dist/esm/notifications/email/models/email-context-provider.interface.d.ts +0 -80
  465. package/dist/esm/notifications/email/models/email-context-provider.interface.d.ts.map +0 -1
  466. package/dist/esm/notifications/email/models/email-context-provider.interface.js +0 -25
  467. package/dist/esm/notifications/email/models/email-context-provider.interface.js.map +0 -1
  468. package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.d.ts +0 -49
  469. package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.d.ts.map +0 -1
  470. package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.js +0 -141
  471. package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.js.map +0 -1
  472. package/dist/esm/notifications/email/services/email-template-compiler.backend.service.d.ts +0 -37
  473. package/dist/esm/notifications/email/services/email-template-compiler.backend.service.d.ts.map +0 -1
  474. package/dist/esm/notifications/email/services/email-template-compiler.backend.service.js +0 -121
  475. package/dist/esm/notifications/email/services/email-template-compiler.backend.service.js.map +0 -1
  476. package/dist/esm/notifications/email/services/email-template-registry.backend.service.d.ts +66 -1
  477. package/dist/esm/notifications/email/services/email-template-registry.backend.service.d.ts.map +1 -1
  478. package/dist/esm/notifications/email/services/email-template-registry.backend.service.js +105 -10
  479. package/dist/esm/notifications/email/services/email-template-registry.backend.service.js.map +1 -1
  480. package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.d.ts +0 -58
  481. package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.d.ts.map +0 -1
  482. package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.js +0 -223
  483. package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.js.map +0 -1
  484. package/dist/esm/notifications/email/services/email-template-validator.backend.service.d.ts.map +1 -1
  485. package/dist/esm/notifications/email/services/email-template-validator.backend.service.js +10 -1
  486. package/dist/esm/notifications/email/services/email-template-validator.backend.service.js.map +1 -1
  487. package/dist/esm/notifications/email/services/email.backend.service.d.ts +60 -4
  488. package/dist/esm/notifications/email/services/email.backend.service.d.ts.map +1 -1
  489. package/dist/esm/notifications/email/services/email.backend.service.js +145 -43
  490. package/dist/esm/notifications/email/services/email.backend.service.js.map +1 -1
  491. package/dist/esm/notifications/email/utils/color-conversion.utils.d.ts +0 -1
  492. package/dist/esm/notifications/email/utils/color-conversion.utils.d.ts.map +1 -1
  493. package/dist/esm/notifications/email/utils/color-conversion.utils.js.map +1 -1
  494. package/dist/esm/notifications/services/notification-badge.backend.service.d.ts +142 -21
  495. package/dist/esm/notifications/services/notification-badge.backend.service.d.ts.map +1 -1
  496. package/dist/esm/notifications/services/notification-badge.backend.service.js +283 -58
  497. package/dist/esm/notifications/services/notification-badge.backend.service.js.map +1 -1
  498. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts +99 -13
  499. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts.map +1 -1
  500. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js +422 -66
  501. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js.map +1 -1
  502. package/dist/esm/notifications/sms/services/sms.backend.service.d.ts +2 -2
  503. package/dist/esm/notifications/sms/services/sms.backend.service.d.ts.map +1 -1
  504. package/dist/esm/notifications/sms/services/sms.backend.service.js +5 -5
  505. package/dist/esm/notifications/sms/services/sms.backend.service.js.map +1 -1
  506. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts +117 -5
  507. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts.map +1 -1
  508. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js +164 -6
  509. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js.map +1 -1
  510. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.d.ts +0 -6
  511. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.d.ts.map +1 -1
  512. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js +46 -1
  513. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js.map +1 -1
  514. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts.map +1 -1
  515. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js +16 -6
  516. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js.map +1 -1
  517. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.d.ts.map +1 -1
  518. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js +12 -12
  519. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js.map +1 -1
  520. package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.d.ts +16 -0
  521. package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.d.ts.map +1 -1
  522. package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.js +18 -0
  523. package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.js.map +1 -1
  524. package/dist/esm/organizations/batches/organization-purge.batch.backend.service.d.ts +2 -2
  525. package/dist/esm/organizations/batches/organization-purge.batch.backend.service.js +2 -2
  526. package/dist/esm/organizations/batches/organization-purge.batch.backend.service.js.map +1 -1
  527. package/dist/esm/organizations/services/organization-custom-implementation.backend.service.d.ts.map +1 -1
  528. package/dist/esm/organizations/services/organization-custom-implementation.backend.service.js +63 -2
  529. package/dist/esm/organizations/services/organization-custom-implementation.backend.service.js.map +1 -1
  530. package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.d.ts +66 -0
  531. package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.d.ts.map +1 -0
  532. package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.js +257 -0
  533. package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.js.map +1 -0
  534. package/dist/esm/queue/adapters/queue-adapter.backend.binding.d.ts +12 -0
  535. package/dist/esm/queue/adapters/queue-adapter.backend.binding.d.ts.map +1 -0
  536. package/dist/esm/queue/adapters/queue-adapter.backend.binding.js +47 -0
  537. package/dist/esm/queue/adapters/queue-adapter.backend.binding.js.map +1 -0
  538. package/dist/esm/queue/adapters/queue-adapter.backend.interface.d.ts +87 -0
  539. package/dist/esm/queue/adapters/queue-adapter.backend.interface.d.ts.map +1 -0
  540. package/dist/esm/queue/adapters/queue-adapter.backend.interface.js +1 -0
  541. package/dist/esm/queue/adapters/queue-adapter.backend.interface.js.map +1 -0
  542. package/dist/esm/queue/adapters/queue-adapter.backend.options.d.ts +31 -0
  543. package/dist/esm/queue/adapters/queue-adapter.backend.options.d.ts.map +1 -0
  544. package/dist/esm/queue/adapters/queue-adapter.backend.options.js +13 -0
  545. package/dist/esm/queue/adapters/queue-adapter.backend.options.js.map +1 -0
  546. package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.d.ts +19 -25
  547. package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.d.ts.map +1 -1
  548. package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.js +33 -0
  549. package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.js.map +1 -1
  550. package/dist/esm/queue/domain-queue-consumer.backend.service.d.ts +2 -2
  551. package/dist/esm/queue/domain-queue-consumer.backend.service.d.ts.map +1 -1
  552. package/dist/esm/queue/domain-queue-consumer.backend.service.js +1 -4
  553. package/dist/esm/queue/domain-queue-consumer.backend.service.js.map +1 -1
  554. package/dist/esm/queue/job-consumer.backend.service.d.ts +2 -2
  555. package/dist/esm/queue/job-consumer.backend.service.d.ts.map +1 -1
  556. package/dist/esm/queue/job-consumer.backend.service.js +1 -4
  557. package/dist/esm/queue/job-consumer.backend.service.js.map +1 -1
  558. package/dist/esm/queue/job-executor.backend.service.d.ts +2 -2
  559. package/dist/esm/queue/job-executor.backend.service.d.ts.map +1 -1
  560. package/dist/esm/queue/job-executor.backend.service.js +1 -4
  561. package/dist/esm/queue/job-executor.backend.service.js.map +1 -1
  562. package/dist/esm/queue/queue-monitoring.backend.service.d.ts +8 -4
  563. package/dist/esm/queue/queue-monitoring.backend.service.d.ts.map +1 -1
  564. package/dist/esm/queue/queue-monitoring.backend.service.js +25 -17
  565. package/dist/esm/queue/queue-monitoring.backend.service.js.map +1 -1
  566. package/dist/esm/queue/queue-worker-initializer.backend.service.d.ts +16 -1
  567. package/dist/esm/queue/queue-worker-initializer.backend.service.d.ts.map +1 -1
  568. package/dist/esm/queue/queue-worker-initializer.backend.service.js +16 -1
  569. package/dist/esm/queue/queue-worker-initializer.backend.service.js.map +1 -1
  570. package/dist/esm/queue/queue.backend.service.d.ts +3 -3
  571. package/dist/esm/queue/queue.backend.service.d.ts.map +1 -1
  572. package/dist/esm/queue/queue.backend.service.js +26 -4
  573. package/dist/esm/queue/queue.backend.service.js.map +1 -1
  574. package/dist/esm/queue/worker-shutdown-manager.backend.service.d.ts +2 -2
  575. package/dist/esm/queue/worker-shutdown-manager.backend.service.d.ts.map +1 -1
  576. package/dist/esm/queue/worker-shutdown-manager.backend.service.js +18 -3
  577. package/dist/esm/queue/worker-shutdown-manager.backend.service.js.map +1 -1
  578. package/dist/esm/rag/utils/rag-chunking.backend.utils.d.ts +50 -25
  579. package/dist/esm/rag/utils/rag-chunking.backend.utils.d.ts.map +1 -1
  580. package/dist/esm/rag/utils/rag-chunking.backend.utils.js +147 -39
  581. package/dist/esm/rag/utils/rag-chunking.backend.utils.js.map +1 -1
  582. package/dist/esm/rag/utils/rag-context-assembly.backend.utils.d.ts +12 -3
  583. package/dist/esm/rag/utils/rag-context-assembly.backend.utils.d.ts.map +1 -1
  584. package/dist/esm/rag/utils/rag-context-assembly.backend.utils.js +12 -3
  585. package/dist/esm/rag/utils/rag-context-assembly.backend.utils.js.map +1 -1
  586. package/dist/esm/requests/service/websocket.service.d.ts +9 -0
  587. package/dist/esm/requests/service/websocket.service.d.ts.map +1 -1
  588. package/dist/esm/requests/service/websocket.service.js +32 -8
  589. package/dist/esm/requests/service/websocket.service.js.map +1 -1
  590. package/dist/esm/resources/models/custom-service-implementations.backend.definition.d.ts.map +1 -1
  591. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js +14 -2
  592. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js.map +1 -1
  593. package/dist/esm/resources/models/resources-operations.backend.definitions.d.ts.map +1 -1
  594. package/dist/esm/resources/models/resources-operations.backend.definitions.js +2 -0
  595. package/dist/esm/resources/models/resources-operations.backend.definitions.js.map +1 -1
  596. package/dist/esm/resources/models/resources-relationships.backend.definitions.d.ts.map +1 -1
  597. package/dist/esm/resources/models/resources-relationships.backend.definitions.js +14 -0
  598. package/dist/esm/resources/models/resources-relationships.backend.definitions.js.map +1 -1
  599. package/dist/esm/resources/models/resources-types.backend.schemas.d.ts +2 -1
  600. package/dist/esm/resources/models/resources-types.backend.schemas.d.ts.map +1 -1
  601. package/dist/esm/resources/models/resources-types.backend.schemas.js +8 -0
  602. package/dist/esm/resources/models/resources-types.backend.schemas.js.map +1 -1
  603. package/dist/esm/resources/services/resources-registry.backend.service.d.ts +60 -5
  604. package/dist/esm/resources/services/resources-registry.backend.service.d.ts.map +1 -1
  605. package/dist/esm/resources/services/resources-registry.backend.service.js +90 -6
  606. package/dist/esm/resources/services/resources-registry.backend.service.js.map +1 -1
  607. package/dist/esm/runtime/controllers/health-controller.backend.service.d.ts +36 -3
  608. package/dist/esm/runtime/controllers/health-controller.backend.service.d.ts.map +1 -1
  609. package/dist/esm/runtime/controllers/health-controller.backend.service.js +32 -10
  610. package/dist/esm/runtime/controllers/health-controller.backend.service.js.map +1 -1
  611. package/dist/esm/runtime/domain-module.backend.definitions.d.ts +24 -0
  612. package/dist/esm/runtime/domain-module.backend.definitions.d.ts.map +1 -1
  613. package/dist/esm/runtime/domain-module.backend.definitions.js +24 -0
  614. package/dist/esm/runtime/domain-module.backend.definitions.js.map +1 -1
  615. package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.d.ts +51 -0
  616. package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.d.ts.map +1 -1
  617. package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.js.map +1 -1
  618. package/dist/esm/runtime/services/http-server.backend.service.d.ts +26 -0
  619. package/dist/esm/runtime/services/http-server.backend.service.d.ts.map +1 -1
  620. package/dist/esm/runtime/services/http-server.backend.service.js +181 -1
  621. package/dist/esm/runtime/services/http-server.backend.service.js.map +1 -1
  622. package/dist/esm/runtime/services/start-application.backend.service.d.ts +19 -1
  623. package/dist/esm/runtime/services/start-application.backend.service.d.ts.map +1 -1
  624. package/dist/esm/runtime/services/start-application.backend.service.js +261 -77
  625. package/dist/esm/runtime/services/start-application.backend.service.js.map +1 -1
  626. package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.d.ts +15 -0
  627. package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.d.ts.map +1 -1
  628. package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.js +28 -0
  629. package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.js.map +1 -1
  630. package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.d.ts +5 -1
  631. package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.d.ts.map +1 -1
  632. package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.js +24 -4
  633. package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.js.map +1 -1
  634. package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.d.ts.map +1 -1
  635. package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.js +29 -4
  636. package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.js.map +1 -1
  637. package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.d.ts +114 -0
  638. package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.d.ts.map +1 -1
  639. package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.js +354 -3
  640. package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.js.map +1 -1
  641. package/dist/esm/security/authentications/models/cimd.backend.schemas.d.ts +1 -0
  642. package/dist/esm/security/authentications/models/cimd.backend.schemas.d.ts.map +1 -1
  643. package/dist/esm/security/authentications/models/cimd.backend.schemas.js +22 -0
  644. package/dist/esm/security/authentications/models/cimd.backend.schemas.js.map +1 -1
  645. package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.d.ts +15 -0
  646. package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.d.ts.map +1 -1
  647. package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.js.map +1 -1
  648. package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.d.ts +0 -2
  649. package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.d.ts.map +1 -1
  650. package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.js +23 -14
  651. package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.js.map +1 -1
  652. package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.d.ts +0 -1
  653. package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.d.ts.map +1 -1
  654. package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.js +15 -12
  655. package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.js.map +1 -1
  656. package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.d.ts +113 -3
  657. package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.d.ts.map +1 -1
  658. package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.js +207 -30
  659. package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.js.map +1 -1
  660. package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.d.ts +95 -2
  661. package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.d.ts.map +1 -1
  662. package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.js +153 -9
  663. package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.js.map +1 -1
  664. package/dist/esm/security/authentications/services/anonymous-session.backend.service.d.ts +190 -0
  665. package/dist/esm/security/authentications/services/anonymous-session.backend.service.d.ts.map +1 -1
  666. package/dist/esm/security/authentications/services/anonymous-session.backend.service.js +377 -53
  667. package/dist/esm/security/authentications/services/anonymous-session.backend.service.js.map +1 -1
  668. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts.map +1 -1
  669. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js +68 -1
  670. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js.map +1 -1
  671. package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.d.ts +41 -0
  672. package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.d.ts.map +1 -1
  673. package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.js +202 -23
  674. package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.js.map +1 -1
  675. package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.d.ts.map +1 -1
  676. package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.js +42 -1
  677. package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.js.map +1 -1
  678. package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.d.ts.map +1 -1
  679. package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.js +34 -4
  680. package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.js.map +1 -1
  681. package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.d.ts +29 -5
  682. package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.d.ts.map +1 -1
  683. package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.js +77 -5
  684. package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.js.map +1 -1
  685. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts +17 -1
  686. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts.map +1 -1
  687. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js +49 -17
  688. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js.map +1 -1
  689. package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.d.ts +43 -1
  690. package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.d.ts.map +1 -1
  691. package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.js +277 -97
  692. package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.js.map +1 -1
  693. package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.d.ts +28 -5
  694. package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.d.ts.map +1 -1
  695. package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.js +72 -12
  696. package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.js.map +1 -1
  697. package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.d.ts.map +1 -1
  698. package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.js +3 -0
  699. package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.js.map +1 -1
  700. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.d.ts +28 -0
  701. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.d.ts.map +1 -0
  702. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js +283 -0
  703. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js.map +1 -0
  704. package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.d.ts +4 -3
  705. package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.d.ts.map +1 -1
  706. package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.js +4 -3
  707. package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.js.map +1 -1
  708. package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.d.ts +35 -0
  709. package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.d.ts.map +1 -1
  710. package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.js +111 -21
  711. package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.js.map +1 -1
  712. package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.d.ts +14 -1
  713. package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.d.ts.map +1 -1
  714. package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.js +49 -8
  715. package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.js.map +1 -1
  716. package/dist/esm/security/authentications/services/utils/auth-policy-resolution.backend.utils.d.ts.map +1 -1
  717. package/dist/esm/security/authentications/services/utils/auth-policy-resolution.backend.utils.js +4 -0
  718. package/dist/esm/security/authentications/services/utils/auth-policy-resolution.backend.utils.js.map +1 -1
  719. package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.d.ts.map +1 -1
  720. package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.js +6 -0
  721. package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.js.map +1 -1
  722. package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.d.ts +37 -1
  723. package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.d.ts.map +1 -1
  724. package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.js +51 -0
  725. package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.js.map +1 -1
  726. package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.d.ts +41 -0
  727. package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.d.ts.map +1 -1
  728. package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.js +45 -0
  729. package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.js.map +1 -1
  730. package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.d.ts +116 -0
  731. package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.d.ts.map +1 -0
  732. package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.js +162 -0
  733. package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.js.map +1 -0
  734. package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.d.ts +20 -20
  735. package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.d.ts.map +1 -1
  736. package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.js +27 -28
  737. package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.js.map +1 -1
  738. package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.d.ts.map +1 -1
  739. package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.js +77 -3
  740. package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.js.map +1 -1
  741. package/dist/esm/security/authorizations/role-ceiling.backend.utils.d.ts +4 -0
  742. package/dist/esm/security/authorizations/role-ceiling.backend.utils.d.ts.map +1 -1
  743. package/dist/esm/security/authorizations/role-ceiling.backend.utils.js +4 -0
  744. package/dist/esm/security/authorizations/role-ceiling.backend.utils.js.map +1 -1
  745. package/dist/esm/security/authorizations/role-conferral.backend.utils.d.ts +93 -0
  746. package/dist/esm/security/authorizations/role-conferral.backend.utils.d.ts.map +1 -0
  747. package/dist/esm/security/authorizations/role-conferral.backend.utils.js +95 -0
  748. package/dist/esm/security/authorizations/role-conferral.backend.utils.js.map +1 -0
  749. package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.d.ts +124 -1
  750. package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.d.ts.map +1 -1
  751. package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.js +142 -5
  752. package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.js.map +1 -1
  753. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts +74 -8
  754. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts.map +1 -1
  755. package/dist/esm/security/authorizations/services/authorizations.backend.service.js +175 -19
  756. package/dist/esm/security/authorizations/services/authorizations.backend.service.js.map +1 -1
  757. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts +6 -14
  758. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts.map +1 -1
  759. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js +13 -22
  760. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js.map +1 -1
  761. package/dist/esm/security/connected-accounts/connection-target-authorization.backend.d.ts +60 -0
  762. package/dist/esm/security/connected-accounts/connection-target-authorization.backend.d.ts.map +1 -0
  763. package/dist/esm/security/connected-accounts/connection-target-authorization.backend.js +79 -0
  764. package/dist/esm/security/connected-accounts/connection-target-authorization.backend.js.map +1 -0
  765. package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.d.ts +161 -0
  766. package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.d.ts.map +1 -0
  767. package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.js +512 -0
  768. package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.js.map +1 -0
  769. package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.d.ts +59 -0
  770. package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.d.ts.map +1 -0
  771. package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.js +22 -0
  772. package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.js.map +1 -0
  773. package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.d.ts +44 -0
  774. package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.d.ts.map +1 -0
  775. package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.js +20 -0
  776. package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.js.map +1 -0
  777. package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.d.ts +191 -0
  778. package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.d.ts.map +1 -0
  779. package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.js +385 -0
  780. package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.js.map +1 -0
  781. package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.d.ts +41 -0
  782. package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.d.ts.map +1 -0
  783. package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.js +358 -0
  784. package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.js.map +1 -0
  785. package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.d.ts +160 -0
  786. package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.d.ts.map +1 -0
  787. package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.js +266 -0
  788. package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.js.map +1 -0
  789. package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.d.ts +111 -0
  790. package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.d.ts.map +1 -0
  791. package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.js +107 -0
  792. package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.js.map +1 -0
  793. package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.d.ts +54 -0
  794. package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.d.ts.map +1 -0
  795. package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.js +153 -0
  796. package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.js.map +1 -0
  797. package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.d.ts +195 -0
  798. package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.d.ts.map +1 -0
  799. package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.js +387 -0
  800. package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.js.map +1 -0
  801. package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.d.ts +45 -0
  802. package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.d.ts.map +1 -0
  803. package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.js +291 -0
  804. package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.js.map +1 -0
  805. package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.d.ts +62 -0
  806. package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.d.ts.map +1 -0
  807. package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.js +29 -0
  808. package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.js.map +1 -0
  809. package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.d.ts +127 -0
  810. package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.d.ts.map +1 -0
  811. package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.js +277 -0
  812. package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.js.map +1 -0
  813. package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.d.ts +66 -0
  814. package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.d.ts.map +1 -0
  815. package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.js +75 -0
  816. package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.js.map +1 -0
  817. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts +21 -3
  818. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts.map +1 -1
  819. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js +26 -16
  820. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js.map +1 -1
  821. package/dist/esm/security/credential-rotation-grace.backend.utils.d.ts +9 -4
  822. package/dist/esm/security/credential-rotation-grace.backend.utils.d.ts.map +1 -1
  823. package/dist/esm/security/credential-rotation-grace.backend.utils.js +9 -4
  824. package/dist/esm/security/credential-rotation-grace.backend.utils.js.map +1 -1
  825. package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.d.ts +26 -0
  826. package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.d.ts.map +1 -1
  827. package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.js +43 -0
  828. package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.js.map +1 -1
  829. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts +8 -1
  830. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts.map +1 -1
  831. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js +49 -0
  832. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js.map +1 -1
  833. package/dist/esm/security/scim/controllers/scim.backend.controller.d.ts.map +1 -1
  834. package/dist/esm/security/scim/controllers/scim.backend.controller.js +17 -5
  835. package/dist/esm/security/scim/controllers/scim.backend.controller.js.map +1 -1
  836. package/dist/esm/security/scim/models/scim-protocol.backend.schemas.d.ts +67 -29
  837. package/dist/esm/security/scim/models/scim-protocol.backend.schemas.d.ts.map +1 -1
  838. package/dist/esm/security/scim/models/scim-protocol.backend.schemas.js +47 -25
  839. package/dist/esm/security/scim/models/scim-protocol.backend.schemas.js.map +1 -1
  840. package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.d.ts +10 -2
  841. package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.d.ts.map +1 -1
  842. package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.js +10 -2
  843. package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.js.map +1 -1
  844. package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.d.ts +143 -0
  845. package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.d.ts.map +1 -0
  846. package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.js +258 -0
  847. package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.js.map +1 -0
  848. package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.d.ts +39 -0
  849. package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.d.ts.map +1 -0
  850. package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.js +159 -0
  851. package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.js.map +1 -0
  852. package/dist/tsconfig.build.tsbuildinfo +1 -1
  853. package/package.json +11 -9
@@ -28,6 +28,20 @@ export interface ProductCatalogSyncResult {
28
28
  created: number;
29
29
  updated: number;
30
30
  featuresDirty: string[];
31
+ /**
32
+ * Keys that exist in the DATABASE and no longer in the code catalogue, and were soft-retired by
33
+ * this run (`isActive: false` on the product and every one of its prices).
34
+ */
35
+ retired: string[];
36
+ /**
37
+ * Retired keys that STILL HAVE LIVE SUBSCRIBERS. Reported, never acted on — see
38
+ * {@link ProductCatalogSyncBackendService.reconcileRetiredProducts} for why the framework refuses
39
+ * to decide what happens to those customers.
40
+ */
41
+ retiredWithLiveSubscribers: Array<{
42
+ productKey: string;
43
+ liveSubscriptions: number;
44
+ }>;
31
45
  errors: string[];
32
46
  }
33
47
  export declare class ProductCatalogSyncBackendService extends AbstractBillingBackendService {
@@ -62,6 +76,77 @@ export declare class ProductCatalogSyncBackendService extends AbstractBillingBac
62
76
  * Idempotent and safe to run multiple times.
63
77
  */
64
78
  syncProductCatalog(): Promise<ProductCatalogSyncResult>;
79
+ /**
80
+ * Soft-retire every local product whose key has left the code catalogue.
81
+ *
82
+ * ## What was wrong
83
+ *
84
+ * `syncProductCatalog` iterated `this.productCatalog` and nothing else, so it could only ever ADD
85
+ * and UPDATE. A key deleted from the code catalogue left its `Product` row `isActive: true`, its
86
+ * `Price` rows active, and its provider product and prices live — and because the purchase path
87
+ * reads the DATABASE rather than the code catalogue, a product that no longer existed in code
88
+ * could still be bought, granting whatever `grantedFeatures` the last sync happened to write.
89
+ *
90
+ * ## The policy, stated because it changes what a paying customer experiences
91
+ *
92
+ * **Retire LOCALLY, always. Report the provider. Never migrate a subscriber. Never delete.**
93
+ *
94
+ * - **`isActive: false` on the product and on every one of its prices, unconditionally** — even
95
+ * when subscribers are on it. It is entitlement-SAFE, which is the fact that makes the policy
96
+ * possible: `BillingFeatureSyncBackendService.getProduct` resolves a subscription item's product
97
+ * by `_id` with no `isActive` filter, and renewal happens entirely at the provider against the
98
+ * provider price, which this does not touch. So an existing subscriber keeps their features and
99
+ * keeps renewing; what stops is NEW acquisition, through the gate in
100
+ * `readProductByKey(..., BillingCatalogReadIntent.ACQUIRE, ...)`.
101
+ *
102
+ * - **The PROVIDER catalogue is left completely alone.** REJECTED ALTERNATIVE: archive the
103
+ * provider product and prices in the same pass. The provider is the party that actually charges,
104
+ * and archiving a price a live subscription renews against is a customer-visible failed renewal
105
+ * — the exact outcome this whole policy is arranged to avoid. It would also mean adding a
106
+ * destructive provider write (`StandardBilling_Interface` has no archive verb today) in the same
107
+ * change as the sweep that calls it. An operator archives provider rows deliberately, after
108
+ * deciding what happens to the subscribers, and the report below is what tells them to.
109
+ *
110
+ * - **A retired key WITH LIVE SUBSCRIBERS is reported and otherwise untouched.** REJECTED
111
+ * ALTERNATIVE: migrate them to the nearest surviving plan tier, or cancel them. Which plan a
112
+ * customer should move to — and whether they should be moved at all rather than grandfathered —
113
+ * is a commercial decision with a price attached, and a framework that guesses it either
114
+ * overcharges someone or cancels a paying customer because a key was deleted in a refactor.
115
+ * The count is reported at error level so the decision is put in front of a human.
116
+ *
117
+ * - **Nothing is ever deleted.** The `Product` and `Price` rows are the only local record of what
118
+ * a RETAINED subscription and its retained invoices refer to, and billing rows deliberately
119
+ * survive the deletion of their scope for a tax/audit obligation. Deleting a retired product
120
+ * would strand exactly the trail that retention exists to preserve.
121
+ */
122
+ private reconcileRetiredProducts;
123
+ /**
124
+ * How many LIVE subscriptions reference each product, across every billing scope.
125
+ *
126
+ * Built by paging live subscriptions and reading their items, rather than by filtering on
127
+ * `items.productId` per product. Two reasons: a nested-path filter over an array is a document-store
128
+ * idiom that does not translate to the PostgreSQL adapter's JSON column, and one pass over the live
129
+ * set answers the question for every retired product at once instead of one query each.
130
+ */
131
+ private collectProductIdsWithLiveSubscriptions;
132
+ /**
133
+ * `isActive: false` on the product and on every price beneath it.
134
+ *
135
+ * The prices matter as much as the product: an application that lists prices directly, or a caller
136
+ * that names a price id, would otherwise still transact against a retired product's price — and
137
+ * `readPriceForProduct` refuses on the PRICE's own flag, so leaving them active would leave a
138
+ * second door open on the surface the gate was built for.
139
+ */
140
+ private deactivateProductAndPrices;
141
+ /** One page of the live-subscription scan. */
142
+ private static readonly SUBSCRIPTION_SCAN_PAGE_SIZE;
143
+ /**
144
+ * Page ceiling for the live-subscription scan. Reaching it UNDER-counts, which is the safe
145
+ * direction here for exactly one reason: the count only ever decides whether a WARNING is emitted
146
+ * — the retirement itself is unconditional — so a missed page costs a quieter log line, never a
147
+ * different write.
148
+ */
149
+ private static readonly MAX_SUBSCRIPTION_SCAN_PAGES;
65
150
  private findProductByKey;
66
151
  private upsertProduct;
67
152
  private upsertPrices;
@@ -83,6 +168,21 @@ export declare class ProductCatalogSyncBackendService extends AbstractBillingBac
83
168
  * provider catalog stale.
84
169
  */
85
170
  private syncUnsyncedPricesToProvider;
171
+ /**
172
+ * One amount, converted from its authored scale to the currency's smallest unit — or a throw naming
173
+ * exactly why it cannot be (#515).
174
+ *
175
+ * Throws rather than returning a result, because every caller is inside the per-price `try` and the
176
+ * only correct response to any of the three failures is the same: do not sync this price. Returning
177
+ * a union here would give each of the three call sites its own chance to forget one.
178
+ *
179
+ * **The currency is passed in rather than read off the value**, and that is the second half of the
180
+ * defect. A tier's `unitPrice`/`flatPrice` carry an OPTIONAL currency — they inherit the price's —
181
+ * so reading each amount's own currency would resolve a scale per amount and let one price be
182
+ * converted at up to three different ones. One price is denominated in one currency; the amounts
183
+ * are its parts.
184
+ */
185
+ private toProviderAmountOrThrow;
86
186
  /**
87
187
  * Check if a product's features/limits have changed relative to the catalog definition.
88
188
  * If so, all subscriptions using this product need feature recomputation.
@@ -1 +1 @@
1
- {"version":3,"file":"product-catalog-sync.backend.service.d.ts","sourceRoot":"","sources":["../../../../../../src/billing/services/back-office/product-catalog-sync.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,OAAO,EAOb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAEtF,OAAO,EAAE,6BAA6B,EAAE,MAAM,kFAAkF,CAAC;AAEjI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAC;AAClG,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,6FAA6F,CAAC;AACzJ,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,+EAA+E,CAAC;AAC3I,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,0EAA0E,CAAC;AAChI,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kEAAkE,CAAC;AAMnH,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAMD,qBACa,gCAAiC,SAAQ,6BAA6B;IAEjF,4DAA4D;IAC5D,OAAO,CAAC,cAAc,CAA2B;gBAGZ,MAAM,EAAE,aAAa,EACG,gBAAgB,EAAE,qCAAqC,EAChD,uBAAuB,EAAE,qCAAqC,EAC5E,iBAAiB,EAAE,+BAA+B,EACtD,YAAY,EAAE,0BAA0B;IAS1F;;OAEG;IACU,UAAU,CACrB,cAAc,EAAE,iBAAiB,EAAE,EACnC,QAAQ,EAAE,yBAAyB,GAClC,OAAO,CAAC,IAAI,CAAC;IAWhB;;;OAGG;IACI,qBAAqB,IAAI,iBAAiB,EAAE;IAQnD;;;;;;;;;OASG;IACU,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAoCtE;;;;;;OAMG;IACU,kBAAkB,IAAI,OAAO,CAAC,wBAAwB,CAAC;YAiEtD,gBAAgB;YAehB,aAAa;YAkCb,YAAY;IA4C1B;;;;;;;OAOG;IACH,OAAO,CAAC,+BAA+B;YAWzB,qBAAqB;IAsCnC;;;;;;OAMG;YACW,4BAA4B;IAoD1C;;;OAGG;IACH,OAAO,CAAC,eAAe;CAuBxB"}
1
+ {"version":3,"file":"product-catalog-sync.backend.service.d.ts","sourceRoot":"","sources":["../../../../../../src/billing/services/back-office/product-catalog-sync.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,OAAO,EAQb,MAAM,uBAAuB,CAAC;AAK/B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAEtF,OAAO,EAAE,6BAA6B,EAAE,MAAM,kFAAkF,CAAC;AAOjI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAC;AAClG,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,6FAA6F,CAAC;AACzJ,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,+EAA+E,CAAC;AAC3I,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,0EAA0E,CAAC;AAChI,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kEAAkE,CAAC;AAMnH,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB;;;OAGG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;OAIG;IACH,0BAA0B,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrF,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAMD,qBACa,gCAAiC,SAAQ,6BAA6B;IAEjF,4DAA4D;IAC5D,OAAO,CAAC,cAAc,CAA2B;gBAGZ,MAAM,EAAE,aAAa,EACG,gBAAgB,EAAE,qCAAqC,EAChD,uBAAuB,EAAE,qCAAqC,EAC5E,iBAAiB,EAAE,+BAA+B,EACtD,YAAY,EAAE,0BAA0B;IAS1F;;OAEG;IACU,UAAU,CACrB,cAAc,EAAE,iBAAiB,EAAE,EACnC,QAAQ,EAAE,yBAAyB,GAClC,OAAO,CAAC,IAAI,CAAC;IAWhB;;;OAGG;IACI,qBAAqB,IAAI,iBAAiB,EAAE;IAQnD;;;;;;;;;OASG;IACU,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAoCtE;;;;;;OAMG;IACU,kBAAkB,IAAI,OAAO,CAAC,wBAAwB,CAAC;IAiFpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA0CG;YACW,wBAAwB;IAuCtC;;;;;;;OAOG;YACW,sCAAsC;IAiCpD;;;;;;;OAOG;YACW,0BAA0B;IAgBxC,8CAA8C;IAC9C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,2BAA2B,CAAO;IAE1D;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,2BAA2B,CAAM;YAM3C,gBAAgB;YAehB,aAAa;YAkCb,YAAY;IA4C1B;;;;;;;OAOG;IACH,OAAO,CAAC,+BAA+B;YAWzB,qBAAqB;IAsCnC;;;;;;OAMG;YACW,4BAA4B;IAwE1C;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,uBAAuB;IAY/B;;;OAGG;IACH,OAAO,CAAC,eAAe;CAuBxB"}
@@ -27,14 +27,22 @@ var __metadata = (this && this.__metadata) || function (k, v) {
27
27
  var __param = (this && this.__param) || function (paramIndex, decorator) {
28
28
  return function (target, key) { decorator(target, key, paramIndex); }
29
29
  };
30
+ var ProductCatalogSyncBackendService_1;
30
31
  import { injectable, inject } from 'inversify';
31
32
  import { CoreResourceType, CoreResourceOperation, ErrorType, ErrorCustomMessageReference, deriveTrustedSystemWritePreservedFields, } from '@wildo-ai/saas-models';
33
+ // MoneyValue fields use bigint at an AUTHORED scale; the provider interface uses a number in the
34
+ // CURRENCY's smallest unit. `Number()` alone crosses only the first of those two gaps, which is why
35
+ // it was wrong here for as long as it stood — see `toProviderAmountOrThrow` (#515).
36
+ import { MoneyMinorUnitConversionError, toCurrencyMinorUnitAmountOrThrow } from '@wildo-ai/zod-decorators';
32
37
  import { AbstractBillingBackendService } from '../../../billing/services/back-office/abstract-billing.backend.service.js';
38
+ import { TERMINAL_SUBSCRIPTION_STATUSES } from '../../../billing/services/back-office/billing-subject-erasure-effect.backend.js';
39
+ import { BILLING_SCOPE_TO_VARIANTS, } from '../../../billing/services/custom-impl/billing-custom-impl-utils.backend.js';
33
40
  import { SAAS_SERVICE_TYPES } from '../../../inject/models/service-types.js';
34
41
  // =====================================================
35
42
  // Service
36
43
  // =====================================================
37
44
  let ProductCatalogSyncBackendService = class ProductCatalogSyncBackendService extends AbstractBillingBackendService {
45
+ static { ProductCatalogSyncBackendService_1 = this; }
38
46
  /** The product catalog from code (set at initialization) */
39
47
  productCatalog = [];
40
48
  constructor(logger, servicesRegistry, executionContextCreator, resourcesRegistry, errorBuilder) {
@@ -121,6 +129,8 @@ let ProductCatalogSyncBackendService = class ProductCatalogSyncBackendService ex
121
129
  created: 0,
122
130
  updated: 0,
123
131
  featuresDirty: [],
132
+ retired: [],
133
+ retiredWithLiveSubscribers: [],
124
134
  errors: [],
125
135
  };
126
136
  for (const definition of this.productCatalog) {
@@ -163,10 +173,162 @@ let ProductCatalogSyncBackendService = class ProductCatalogSyncBackendService ex
163
173
  });
164
174
  }
165
175
  }
176
+ /*
177
+ * The other direction, and it runs LAST so that a key present in both is upserted before it is
178
+ * examined for retirement — otherwise a first-ever sync would race itself.
179
+ *
180
+ * A failure here does not fail the sync: pushing the code catalogue is the primary job, and
181
+ * refusing to do it because the retirement pass could not read subscriptions would make an
182
+ * unrelated read fault block every deploy.
183
+ */
184
+ try {
185
+ await this.reconcileRetiredProducts(result);
186
+ }
187
+ catch (error) {
188
+ result.errors.push(`Retired-product reconciliation failed: ${error.message}`);
189
+ }
166
190
  this.logDebug('Bulk product catalog sync complete', { ...result });
167
191
  return result;
168
192
  }
169
193
  // ════════════════════════════════════════════════════════════
194
+ // Retirement — the catalogue's OTHER direction
195
+ // ════════════════════════════════════════════════════════════
196
+ /**
197
+ * Soft-retire every local product whose key has left the code catalogue.
198
+ *
199
+ * ## What was wrong
200
+ *
201
+ * `syncProductCatalog` iterated `this.productCatalog` and nothing else, so it could only ever ADD
202
+ * and UPDATE. A key deleted from the code catalogue left its `Product` row `isActive: true`, its
203
+ * `Price` rows active, and its provider product and prices live — and because the purchase path
204
+ * reads the DATABASE rather than the code catalogue, a product that no longer existed in code
205
+ * could still be bought, granting whatever `grantedFeatures` the last sync happened to write.
206
+ *
207
+ * ## The policy, stated because it changes what a paying customer experiences
208
+ *
209
+ * **Retire LOCALLY, always. Report the provider. Never migrate a subscriber. Never delete.**
210
+ *
211
+ * - **`isActive: false` on the product and on every one of its prices, unconditionally** — even
212
+ * when subscribers are on it. It is entitlement-SAFE, which is the fact that makes the policy
213
+ * possible: `BillingFeatureSyncBackendService.getProduct` resolves a subscription item's product
214
+ * by `_id` with no `isActive` filter, and renewal happens entirely at the provider against the
215
+ * provider price, which this does not touch. So an existing subscriber keeps their features and
216
+ * keeps renewing; what stops is NEW acquisition, through the gate in
217
+ * `readProductByKey(..., BillingCatalogReadIntent.ACQUIRE, ...)`.
218
+ *
219
+ * - **The PROVIDER catalogue is left completely alone.** REJECTED ALTERNATIVE: archive the
220
+ * provider product and prices in the same pass. The provider is the party that actually charges,
221
+ * and archiving a price a live subscription renews against is a customer-visible failed renewal
222
+ * — the exact outcome this whole policy is arranged to avoid. It would also mean adding a
223
+ * destructive provider write (`StandardBilling_Interface` has no archive verb today) in the same
224
+ * change as the sweep that calls it. An operator archives provider rows deliberately, after
225
+ * deciding what happens to the subscribers, and the report below is what tells them to.
226
+ *
227
+ * - **A retired key WITH LIVE SUBSCRIBERS is reported and otherwise untouched.** REJECTED
228
+ * ALTERNATIVE: migrate them to the nearest surviving plan tier, or cancel them. Which plan a
229
+ * customer should move to — and whether they should be moved at all rather than grandfathered —
230
+ * is a commercial decision with a price attached, and a framework that guesses it either
231
+ * overcharges someone or cancels a paying customer because a key was deleted in a refactor.
232
+ * The count is reported at error level so the decision is put in front of a human.
233
+ *
234
+ * - **Nothing is ever deleted.** The `Product` and `Price` rows are the only local record of what
235
+ * a RETAINED subscription and its retained invoices refer to, and billing rows deliberately
236
+ * survive the deletion of their scope for a tax/audit obligation. Deleting a retired product
237
+ * would strand exactly the trail that retention exists to preserve.
238
+ */
239
+ async reconcileRetiredProducts(result) {
240
+ const catalogKeys = new Set(this.productCatalog.map(definition => definition.key));
241
+ const listCtx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.LIST);
242
+ const localProducts = await this.servicesRegistry.list(CoreResourceType.PRODUCTS, listCtx, { isActive: true });
243
+ const retiredProducts = localProducts.filter(product => !catalogKeys.has(product.key));
244
+ if (retiredProducts.length === 0)
245
+ return;
246
+ const liveProductIds = await this.collectProductIdsWithLiveSubscriptions();
247
+ for (const product of retiredProducts) {
248
+ const liveSubscriptions = liveProductIds.get(product._id) ?? 0;
249
+ try {
250
+ await this.deactivateProductAndPrices(product);
251
+ result.retired.push(product.key);
252
+ }
253
+ catch (error) {
254
+ result.errors.push(`Failed to retire product ${product.key}: ${error.message}`);
255
+ continue;
256
+ }
257
+ if (liveSubscriptions > 0) {
258
+ result.retiredWithLiveSubscribers.push({ productKey: product.key, liveSubscriptions });
259
+ this.logger.error('Retired product still has live subscribers', {
260
+ productKey: product.key,
261
+ productId: product._id,
262
+ liveSubscriptions,
263
+ message: 'This product left the code catalogue and is no longer purchasable, but subscriptions still ' +
264
+ 'renew against it at the provider and still grant its last-synced features. Decide whether to ' +
265
+ 'migrate, grandfather or cancel these subscribers — the framework deliberately does not choose. ' +
266
+ 'Its provider product and prices were NOT archived, so renewals keep working until you act.',
267
+ });
268
+ }
269
+ }
270
+ }
271
+ /**
272
+ * How many LIVE subscriptions reference each product, across every billing scope.
273
+ *
274
+ * Built by paging live subscriptions and reading their items, rather than by filtering on
275
+ * `items.productId` per product. Two reasons: a nested-path filter over an array is a document-store
276
+ * idiom that does not translate to the PostgreSQL adapter's JSON column, and one pass over the live
277
+ * set answers the question for every retired product at once instead of one query each.
278
+ */
279
+ async collectProductIdsWithLiveSubscriptions() {
280
+ const counts = new Map();
281
+ for (const [scopeKey, scopeData] of Object.entries(BILLING_SCOPE_TO_VARIANTS)) {
282
+ const variants = { scopeKey, ...scopeData };
283
+ const ctx = await this.internalCtx(variants.subscription, CoreResourceOperation.LIST);
284
+ for (let page = 1; page <= ProductCatalogSyncBackendService_1.MAX_SUBSCRIPTION_SCAN_PAGES; page += 1) {
285
+ const subscriptions = await this.servicesRegistry.list(variants.subscription, ctx, { status: { $nin: TERMINAL_SUBSCRIPTION_STATUSES } }, { page, limit: ProductCatalogSyncBackendService_1.SUBSCRIPTION_SCAN_PAGE_SIZE });
286
+ for (const subscription of subscriptions) {
287
+ const seen = new Set();
288
+ for (const item of subscription.items ?? []) {
289
+ // One subscription counts ONCE per product however many items name it — the number is
290
+ // "how many customers am I about to strand", not "how many line items exist".
291
+ if (!item?.productId || seen.has(item.productId))
292
+ continue;
293
+ seen.add(item.productId);
294
+ counts.set(item.productId, (counts.get(item.productId) ?? 0) + 1);
295
+ }
296
+ }
297
+ if (subscriptions.length < ProductCatalogSyncBackendService_1.SUBSCRIPTION_SCAN_PAGE_SIZE)
298
+ break;
299
+ }
300
+ }
301
+ return counts;
302
+ }
303
+ /**
304
+ * `isActive: false` on the product and on every price beneath it.
305
+ *
306
+ * The prices matter as much as the product: an application that lists prices directly, or a caller
307
+ * that names a price id, would otherwise still transact against a retired product's price — and
308
+ * `readPriceForProduct` refuses on the PRICE's own flag, so leaving them active would leave a
309
+ * second door open on the surface the gate was built for.
310
+ */
311
+ async deactivateProductAndPrices(product) {
312
+ const productUpdate = { isActive: false };
313
+ const productCtx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.UPDATE);
314
+ await this.servicesRegistry.update(CoreResourceType.PRODUCTS, productCtx, product._id, productUpdate);
315
+ const pricesCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.LIST);
316
+ const prices = await this.servicesRegistry.list(CoreResourceType.PRICES, pricesCtx, { productId: product._id, isActive: true });
317
+ for (const price of prices) {
318
+ const priceCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.UPDATE);
319
+ await this.servicesRegistry.update(CoreResourceType.PRICES, priceCtx, price._id, { isActive: false });
320
+ }
321
+ }
322
+ /** One page of the live-subscription scan. */
323
+ static SUBSCRIPTION_SCAN_PAGE_SIZE = 200;
324
+ /**
325
+ * Page ceiling for the live-subscription scan. Reaching it UNDER-counts, which is the safe
326
+ * direction here for exactly one reason: the count only ever decides whether a WARNING is emitted
327
+ * — the retirement itself is unconditional — so a missed page costs a quieter log line, never a
328
+ * different write.
329
+ */
330
+ static MAX_SUBSCRIPTION_SCAN_PAGES = 50;
331
+ // ════════════════════════════════════════════════════════════
170
332
  // Private — Product Operations
171
333
  // ════════════════════════════════════════════════════════════
172
334
  async findProductByKey(productKey) {
@@ -318,17 +480,32 @@ let ProductCatalogSyncBackendService = class ProductCatalogSyncBackendService ex
318
480
  if (price.providerPriceId)
319
481
  continue;
320
482
  try {
321
- // Convert MoneyValue (bigint) → provider format (number in cents)
483
+ /*
484
+ * Convert every amount from its AUTHORED scale to the CURRENCY's smallest unit (#515).
485
+ *
486
+ * This was `Number(price.unitPrice.amount)` and two more like it — the stored amount handed
487
+ * over verbatim, with `MoneyValue.decimals` discarded. A price authored at any scale other
488
+ * than the currency's was therefore synced at the wrong magnitude, by a factor of 10 per
489
+ * decimal place of disagreement, and the three amounts in one price could each carry a
490
+ * different scale and still be combined as if they shared one.
491
+ *
492
+ * A conversion that cannot be made exactly REFUSES the price rather than rounding it. The
493
+ * throw is caught by the loop below, which logs and moves to the next price — so one
494
+ * unrepresentable price does not stop a catalogue sync, and it does not reach the provider
495
+ * either.
496
+ */
497
+ const priceCurrency = price.unitPrice.currency;
498
+ const amount = this.toProviderAmountOrThrow(price.unitPrice, priceCurrency, `price ${price._id}`);
322
499
  const { providerPriceId } = await this.billingProvider.syncPrice({
323
500
  providerProductId,
324
- amount: Number(price.unitPrice.amount),
501
+ amount,
325
502
  currency: price.unitPrice.currency,
326
503
  interval: price.interval,
327
504
  model: price.model,
328
- tiers: price.tiers?.map(t => ({
505
+ tiers: price.tiers?.map((t, index) => ({
329
506
  upTo: t.upTo ?? null,
330
- unitAmount: Number(t.unitPrice.amount),
331
- flatAmount: Number(t.flatPrice.amount),
507
+ unitAmount: this.toProviderAmountOrThrow(t.unitPrice, priceCurrency, `price ${price._id} tier ${index} unit amount`),
508
+ flatAmount: this.toProviderAmountOrThrow(t.flatPrice, priceCurrency, `price ${price._id} tier ${index} flat amount`),
332
509
  })),
333
510
  packageSize: price.packageSize,
334
511
  taxBehavior: price.taxBehavior,
@@ -344,11 +521,37 @@ let ProductCatalogSyncBackendService = class ProductCatalogSyncBackendService ex
344
521
  this.logger.error('Failed to sync price to provider', {
345
522
  priceId: price._id,
346
523
  productKey: product.key,
524
+ /*
525
+ * The CLASSIFIED reason when the failure is a scale one (#515), because the three have
526
+ * different remedies and an operator should not have to read prose to tell them apart:
527
+ * `unknown_minor_unit` is a catalogue problem, `precision_loss` is an authoring problem,
528
+ * `unsafe_magnitude` is a limit of the provider's number type. This `instanceof` is why the
529
+ * conversion throws a TYPED error rather than returning a result union — the engine compiles
530
+ * with `strict: false`, where a discriminated union does not narrow.
531
+ */
532
+ ...(error instanceof MoneyMinorUnitConversionError ? { moneyScaleFailure: error.reason } : {}),
347
533
  error: error.message,
348
534
  });
349
535
  }
350
536
  }
351
537
  }
538
+ /**
539
+ * One amount, converted from its authored scale to the currency's smallest unit — or a throw naming
540
+ * exactly why it cannot be (#515).
541
+ *
542
+ * Throws rather than returning a result, because every caller is inside the per-price `try` and the
543
+ * only correct response to any of the three failures is the same: do not sync this price. Returning
544
+ * a union here would give each of the three call sites its own chance to forget one.
545
+ *
546
+ * **The currency is passed in rather than read off the value**, and that is the second half of the
547
+ * defect. A tier's `unitPrice`/`flatPrice` carry an OPTIONAL currency — they inherit the price's —
548
+ * so reading each amount's own currency would resolve a scale per amount and let one price be
549
+ * converted at up to three different ones. One price is denominated in one currency; the amounts
550
+ * are its parts.
551
+ */
552
+ toProviderAmountOrThrow(value, currency, subject) {
553
+ return toCurrencyMinorUnitAmountOrThrow({ ...value, currency }, subject);
554
+ }
352
555
  // ════════════════════════════════════════════════════════════
353
556
  // Private — Dirty Detection
354
557
  // ════════════════════════════════════════════════════════════
@@ -384,7 +587,7 @@ let ProductCatalogSyncBackendService = class ProductCatalogSyncBackendService ex
384
587
  return false;
385
588
  }
386
589
  };
387
- ProductCatalogSyncBackendService = __decorate([
590
+ ProductCatalogSyncBackendService = ProductCatalogSyncBackendService_1 = __decorate([
388
591
  injectable(),
389
592
  __param(0, inject(SAAS_SERVICE_TYPES.Logger)),
390
593
  __param(1, inject(SAAS_SERVICE_TYPES.ServicesRegistryHandlerService)),
@@ -1 +1 @@
1
- {"version":3,"file":"product-catalog-sync.backend.service.js","sourceRoot":"","sources":["../../../../../../src/billing/services/back-office/product-catalog-sync.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Product Catalog Sync Backend Service\n *\n * Synchronizes the code-defined ProductDefinition catalog with the database\n * and the billing provider. Two modes:\n *\n * 1. LAZY: `ensureProductSynced(key)` — On-demand, single product (first checkout or admin view)\n * 2. BULK: `syncProductCatalog()` — Admin action, all products (post-deploy hook)\n *\n * Design:\n * - Config (code) is the source of truth → DB always reflects code\n * - Provider sync is separate from DB sync (happens on first use or bulk sync)\n * - \"features-dirty\" detection: when grantedFeatures/grantedLimits change, trigger\n * feature recomputation for all affected subscriptions\n *\n * @see billing-and-features-system.md §8.6 (Product Catalog Versioning Strategy)\n */\n\nimport { injectable, inject } from 'inversify';\nimport {\n type ProductDefinition,\n type Product,\n type Price,\n CoreResourceType,\n CoreResourceOperation,\n ErrorType,\n ErrorCustomMessageReference,\n deriveTrustedSystemWritePreservedFields,\n} from '@wildo-ai/saas-models';\n// MoneyValue fields use bigint; provider interface uses number — convert at the boundary with Number()\nimport type { StandardBilling_Interface } from '@wildo-ai/external-connectors-models';\nimport type { ServiceOptions } from '~wildo-backend-lib/base-classes/models/repositories.backend.schemas';\nimport { AbstractBillingBackendService } from '~wildo-backend-lib/billing/services/back-office/abstract-billing.backend.service';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { ServicesRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/services/services-registry-handler.backend.service';\nimport type { ExecutionContextCreatorBackendService } from '~wildo-backend-lib/runtime/services/execution-context-creator.backend.service';\nimport type { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\n\n// =====================================================\n// Types\n// =====================================================\n\nexport interface ProductCatalogSyncResult {\n synced: number;\n created: number;\n updated: number;\n featuresDirty: string[];\n errors: string[];\n}\n\n// =====================================================\n// Service\n// =====================================================\n\n@injectable()\nexport class ProductCatalogSyncBackendService extends AbstractBillingBackendService {\n\n /** The product catalog from code (set at initialization) */\n private productCatalog: ProductDefinition[] = [];\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ServicesRegistryHandlerService) servicesRegistry: ServicesRegistryHandlerBackendService,\n @inject(SAAS_SERVICE_TYPES.ExecutionContextCreatorBackendService) executionContextCreator: ExecutionContextCreatorBackendService,\n @inject(SAAS_SERVICE_TYPES.ResourceRegistryService) resourcesRegistry: ResourcesRegistryBackendService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) errorBuilder: ErrorBuilderBackendService,\n ) {\n super(logger, servicesRegistry, executionContextCreator, resourcesRegistry, errorBuilder);\n }\n\n // ════════════════════════════════════════════════════════════\n // Initialization\n // ════════════════════════════════════════════════════════════\n\n /**\n * Initialize with the code-defined product catalog and billing provider.\n */\n public async initialize(\n productCatalog: ProductDefinition[],\n provider: StandardBilling_Interface,\n ): Promise<void> {\n if (this.isInitialized) return;\n\n this.productCatalog = productCatalog;\n this.initializeProvider(provider);\n\n this.logDebug('Product catalog sync initialized', {\n productsInCatalog: productCatalog.length,\n });\n }\n\n /**\n * Returns the in-memory product catalog (set at initialization).\n * Used by the companion labelling service to discover billing keys for i18n.\n */\n public getProductDefinitions(): ProductDefinition[] {\n return this.productCatalog;\n }\n\n // ════════════════════════════════════════════════════════════\n // Lazy Sync (on-demand, single product)\n // ════════════════════════════════════════════════════════════\n\n /**\n * Ensure a single product and its prices exist in DB and provider.\n * Idempotent: safe to call multiple times.\n *\n * Flow:\n * 1. Look up ProductDefinition by key in code catalog\n * 2. Upsert Product DB record (key → _id mapping)\n * 3. Upsert Price DB records for each inline price\n * 4. If providerProductId is missing: sync to billing provider\n */\n public async ensureProductSynced(productKey: string): Promise<Product> {\n this.ensureInitialized();\n this.logDebug('Ensuring product synced', { productKey });\n\n // 1. Find in code catalog\n const definition = this.productCatalog.find(p => p.key === productKey);\n if (!definition) {\n throw this.errorBuilder.buildError(ErrorType.NOT_FOUND, undefined, {\n customMessageReference: ErrorCustomMessageReference.BILLING_PRODUCT_NOT_FOUND,\n context: { productKey },\n });\n }\n\n // 2. Upsert product in DB\n const product = await this.upsertProduct(definition);\n\n // 3. Upsert prices\n await this.upsertPrices(product._id, definition);\n\n // 4. Sync to provider when available.\n // Existing provider-linked products must still push any newly added local\n // prices, otherwise the DB/provider catalogs silently drift.\n if (this.billingProvider) {\n if (!product.providerProductId) {\n return await this.syncProductToProvider(product);\n }\n await this.syncUnsyncedPricesToProvider(product, product.providerProductId);\n }\n\n return product;\n }\n\n // ════════════════════════════════════════════════════════════\n // Bulk Sync (admin action)\n // ════════════════════════════════════════════════════════════\n\n /**\n * Sync ALL products from code catalog to DB + provider.\n * Detects \"features-dirty\" products and returns their keys for\n * downstream feature recomputation.\n *\n * Idempotent and safe to run multiple times.\n */\n public async syncProductCatalog(): Promise<ProductCatalogSyncResult> {\n this.ensureInitialized();\n this.logDebug('Starting bulk product catalog sync', {\n productsInCatalog: this.productCatalog.length,\n });\n\n const result: ProductCatalogSyncResult = {\n synced: 0,\n created: 0,\n updated: 0,\n featuresDirty: [],\n errors: [],\n };\n\n for (const definition of this.productCatalog) {\n try {\n // Check if existing product has different features/limits\n const existingProduct = await this.findProductByKey(definition.key);\n const isFeaturesDirty = existingProduct\n ? this.isFeaturesDirty(existingProduct, definition)\n : false;\n\n // Upsert product (pass existing to avoid a second DB lookup)\n const product = await this.upsertProduct(definition, existingProduct);\n result.synced++;\n\n if (!existingProduct) {\n result.created++;\n } else {\n result.updated++;\n }\n\n // Upsert prices\n await this.upsertPrices(product._id, definition);\n\n // Sync to provider when available.\n if (this.billingProvider) {\n if (!product.providerProductId) {\n await this.syncProductToProvider(product);\n } else {\n await this.syncUnsyncedPricesToProvider(product, product.providerProductId);\n }\n }\n\n // Track features-dirty products\n if (isFeaturesDirty) {\n result.featuresDirty.push(definition.key);\n }\n } catch (error) {\n result.errors.push(`${definition.key}: ${(error as Error).message}`);\n this.logger.error('Failed to sync product', {\n productKey: definition.key,\n error: (error as Error).message,\n });\n }\n }\n\n this.logDebug('Bulk product catalog sync complete', { ...result });\n return result;\n }\n\n // ════════════════════════════════════════════════════════════\n // Private — Product Operations\n // ════════════════════════════════════════════════════════════\n\n private async findProductByKey(productKey: string): Promise<Product | null> {\n // Context construction stays OUTSIDE the try: failing to resolve the\n // INTERNAL_CALL operation path is a wiring fault, never \"product absent\".\n // A masked failure is worse here than a missing read — callers treat null as\n // \"not yet in the catalog\" and CREATE, so a swallowed fault duplicates products.\n const ctx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.LIST);\n try {\n const items = await this.servicesRegistry.list<Product>(CoreResourceType.PRODUCTS, ctx, { key: productKey }) as Product[];\n return items.length > 0 ? items[0] : null;\n } catch (error) {\n this.degradeOrRethrow(error, 'Failed to find product by key', { productKey });\n return null;\n }\n }\n\n private async upsertProduct(definition: ProductDefinition, existingProductHint?: Product | null): Promise<Product> {\n // Use the pre-fetched product if available (avoids double DB lookup in bulk sync)\n const existingProduct = existingProductHint !== undefined\n ? existingProductHint\n : await this.findProductByKey(definition.key);\n\n const productData: Partial<Product> = {\n type: definition.type,\n key: definition.key,\n targetScopes: definition.targetScopes,\n grantedFeatures: definition.grantedFeatures,\n grantedLimits: definition.grantedLimits,\n planTier: definition.planTier,\n planTierOrder: definition.planTierOrder,\n requiredPlanTiers: definition.requiredPlanTiers,\n taxDisplayMode: definition.taxDisplayMode,\n purchaseConfig: definition.purchaseConfig,\n behaviorPolicy: definition.behaviorPolicy,\n sortOrder: definition.sortOrder,\n isPublic: definition.isPublic,\n isActive: true,\n };\n\n if (existingProduct) {\n // Update\n const ctx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.UPDATE);\n return await this.servicesRegistry.update<Product>(CoreResourceType.PRODUCTS, ctx, existingProduct._id, productData) as Product;\n } else {\n // Create\n const ctx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.CREATE);\n return await this.servicesRegistry.create<Product>(CoreResourceType.PRODUCTS, ctx, productData);\n }\n }\n\n private async upsertPrices(productId: string, definition: ProductDefinition): Promise<void> {\n for (const priceDef of definition.prices) {\n const priceData: Partial<Price> = {\n productId,\n model: priceDef.model,\n unitPrice: priceDef.unitPrice,\n interval: priceDef.interval,\n intervalCount: priceDef.intervalCount,\n tiers: priceDef.tiers,\n packageSize: priceDef.packageSize,\n usageAggregation: priceDef.usageAggregation,\n taxBehavior: priceDef.taxBehavior,\n isDefault: priceDef.isDefault,\n isActive: true,\n };\n\n // Try to find existing price for this product with same model+interval+currency\n try {\n const listCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.LIST);\n const items = await this.servicesRegistry.list<Price>(CoreResourceType.PRICES, listCtx, {\n productId,\n model: priceDef.model,\n 'unitPrice.currency': priceDef.unitPrice.currency,\n ...(priceDef.interval && { interval: priceDef.interval }),\n }) as Price[];\n\n if (items.length > 0) {\n const updateCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.UPDATE);\n await this.servicesRegistry.update<Price>(CoreResourceType.PRICES, updateCtx, items[0]._id, priceData);\n } else {\n const createCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.CREATE);\n await this.servicesRegistry.create<Price>(CoreResourceType.PRICES, createCtx, priceData);\n }\n } catch (error) {\n this.logger.error('Failed to upsert price', {\n productId,\n model: priceDef.model,\n currency: priceDef.unitPrice.currency,\n error: (error as Error).message,\n });\n }\n }\n }\n\n /**\n * `ServiceOptions` that re-attach the backend-only provider-link field(s) a plain update request\n * DTO would strip. The billing catalog sync is a trusted in-process write of provider identifiers\n * (`providerProductId` / `providerPriceId`, both `.isBackendOnly()`); without this the strict\n * request-DTO parse drops them and the update persists nothing. Mirrors the billing webhook\n * event router's trusted-system write (`deriveTrustedSystemWritePreservedFields` — schema-aware,\n * so it only preserves fields that are genuinely backend-only AND present in the payload).\n */\n private trustedProviderLinkWriteOptions(resourceType: CoreResourceType, payload: Record<string, unknown>): ServiceOptions {\n const { mainSchema } = this.resourcesRegistry.getResourceConfiguration(resourceType);\n return {\n preserveServerInjectedFields: deriveTrustedSystemWritePreservedFields(\n mainSchema,\n Object.keys(payload),\n CoreResourceOperation.UPDATE,\n ),\n };\n }\n\n private async syncProductToProvider(product: Product): Promise<Product> {\n if (!this.billingProvider) return product;\n\n try {\n // Sync product\n const { providerProductId } = await this.billingProvider.syncProduct({\n productKey: product.key,\n name: product.key,\n metadata: { key: product.key, type: product.type },\n });\n\n // Persist the provider link locally. `providerProductId` is `.isBackendOnly()`, so a plain\n // update request DTO STRIPS it: the write \"succeeds\" but the field never lands, leaving the\n // local link null forever — which is what made every catalog sync re-create the provider\n // product (accumulating duplicates). Re-attach it through the trusted-system-write allowlist,\n // the same seam the billing webhook path uses for the same class of backend-only field.\n const providerLink = { providerProductId };\n const updateCtx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.UPDATE);\n const updated = await this.servicesRegistry.update<Product>(\n CoreResourceType.PRODUCTS,\n updateCtx,\n product._id,\n providerLink,\n this.trustedProviderLinkWriteOptions(CoreResourceType.PRODUCTS, providerLink),\n ) as Product;\n\n await this.syncUnsyncedPricesToProvider(updated, providerProductId);\n\n return updated;\n } catch (error) {\n this.logger.error('Failed to sync product to provider', {\n productKey: product.key,\n error: (error as Error).message,\n });\n return product;\n }\n }\n\n /**\n * Sync any locally defined prices that do not yet have a provider identifier.\n *\n * This must run for both first-time product syncs and already-synced products,\n * otherwise adding a new local price after the initial product sync leaves the\n * provider catalog stale.\n */\n private async syncUnsyncedPricesToProvider(product: Product, providerProductId: string): Promise<void> {\n if (!this.billingProvider) return;\n\n const listCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.LIST);\n const prices = await this.servicesRegistry.list<Price>(CoreResourceType.PRICES, listCtx, { productId: product._id }) as Price[];\n\n for (const price of prices) {\n if (price.providerPriceId) continue;\n\n try {\n // Convert MoneyValue (bigint) → provider format (number in cents)\n const { providerPriceId } = await this.billingProvider.syncPrice({\n providerProductId,\n amount: Number(price.unitPrice.amount),\n currency: price.unitPrice.currency,\n interval: price.interval,\n model: price.model,\n tiers: price.tiers?.map(t => ({\n upTo: t.upTo ?? null,\n unitAmount: Number(t.unitPrice.amount),\n flatAmount: Number(t.flatPrice.amount),\n })),\n packageSize: price.packageSize,\n taxBehavior: price.taxBehavior,\n metadata: { productKey: product.key },\n });\n\n // `providerPriceId` is `.isBackendOnly()` too — same trusted-system-write preservation as\n // the product link above, or the price link would silently never persist.\n const priceLink = { providerPriceId };\n const priceUpdateCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.UPDATE);\n await this.servicesRegistry.update<Price>(\n CoreResourceType.PRICES,\n priceUpdateCtx,\n price._id,\n priceLink,\n this.trustedProviderLinkWriteOptions(CoreResourceType.PRICES, priceLink),\n );\n } catch (error) {\n this.logger.error('Failed to sync price to provider', {\n priceId: price._id,\n productKey: product.key,\n error: (error as Error).message,\n });\n }\n }\n }\n\n // ════════════════════════════════════════════════════════════\n // Private — Dirty Detection\n // ════════════════════════════════════════════════════════════\n\n /**\n * Check if a product's features/limits have changed relative to the catalog definition.\n * If so, all subscriptions using this product need feature recomputation.\n */\n private isFeaturesDirty(existing: Product, definition: ProductDefinition): boolean {\n // Check grantedFeatures\n const existingFeatures = new Set(existing.grantedFeatures ?? []);\n const newFeatures = new Set(definition.grantedFeatures ?? []);\n if (existingFeatures.size !== newFeatures.size) return true;\n for (const f of existingFeatures) {\n if (!newFeatures.has(f)) return true;\n }\n\n // Check grantedLimits\n const existingLimits = existing.grantedLimits ?? {};\n const newLimits = definition.grantedLimits ?? {};\n const existingKeys = Object.keys(existingLimits);\n const newKeys = Object.keys(newLimits);\n if (existingKeys.length !== newKeys.length) return true;\n for (const key of existingKeys) {\n if (!newLimits[key]) return true;\n if (existingLimits[key].value !== newLimits[key].value) return true;\n if (existingLimits[key].mode !== newLimits[key].mode) return true;\n }\n\n return false;\n }\n}\n"]}
1
+ {"version":3,"file":"product-catalog-sync.backend.service.js","sourceRoot":"","sources":["../../../../../../src/billing/services/back-office/product-catalog-sync.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Product Catalog Sync Backend Service\n *\n * Synchronizes the code-defined ProductDefinition catalog with the database\n * and the billing provider. Two modes:\n *\n * 1. LAZY: `ensureProductSynced(key)` — On-demand, single product (first checkout or admin view)\n * 2. BULK: `syncProductCatalog()` — Admin action, all products (post-deploy hook)\n *\n * Design:\n * - Config (code) is the source of truth → DB always reflects code\n * - Provider sync is separate from DB sync (happens on first use or bulk sync)\n * - \"features-dirty\" detection: when grantedFeatures/grantedLimits change, trigger\n * feature recomputation for all affected subscriptions\n *\n * @see billing-and-features-system.md §8.6 (Product Catalog Versioning Strategy)\n */\n\nimport { injectable, inject } from 'inversify';\nimport {\n type ProductDefinition,\n type Product,\n type Price,\n type BillingSubscriptionBase,\n CoreResourceType,\n CoreResourceOperation,\n ErrorType,\n ErrorCustomMessageReference,\n deriveTrustedSystemWritePreservedFields,\n} from '@wildo-ai/saas-models';\n// MoneyValue fields use bigint at an AUTHORED scale; the provider interface uses a number in the\n// CURRENCY's smallest unit. `Number()` alone crosses only the first of those two gaps, which is why\n// it was wrong here for as long as it stood — see `toProviderAmountOrThrow` (#515).\nimport { MoneyMinorUnitConversionError, toCurrencyMinorUnitAmountOrThrow } from '@wildo-ai/zod-decorators';\nimport type { StandardBilling_Interface } from '@wildo-ai/external-connectors-models';\nimport type { ServiceOptions } from '~wildo-backend-lib/base-classes/models/repositories.backend.schemas';\nimport { AbstractBillingBackendService } from '~wildo-backend-lib/billing/services/back-office/abstract-billing.backend.service';\nimport { TERMINAL_SUBSCRIPTION_STATUSES } from '~wildo-backend-lib/billing/services/back-office/billing-subject-erasure-effect.backend';\nimport {\n BILLING_SCOPE_TO_VARIANTS,\n type BillingResolvedVariants,\n} from '~wildo-backend-lib/billing/services/custom-impl/billing-custom-impl-utils.backend';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { ServicesRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/services/services-registry-handler.backend.service';\nimport type { ExecutionContextCreatorBackendService } from '~wildo-backend-lib/runtime/services/execution-context-creator.backend.service';\nimport type { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\n\n// =====================================================\n// Types\n// =====================================================\n\nexport interface ProductCatalogSyncResult {\n synced: number;\n created: number;\n updated: number;\n featuresDirty: string[];\n /**\n * Keys that exist in the DATABASE and no longer in the code catalogue, and were soft-retired by\n * this run (`isActive: false` on the product and every one of its prices).\n */\n retired: string[];\n /**\n * Retired keys that STILL HAVE LIVE SUBSCRIBERS. Reported, never acted on — see\n * {@link ProductCatalogSyncBackendService.reconcileRetiredProducts} for why the framework refuses\n * to decide what happens to those customers.\n */\n retiredWithLiveSubscribers: Array<{ productKey: string; liveSubscriptions: number }>;\n errors: string[];\n}\n\n// =====================================================\n// Service\n// =====================================================\n\n@injectable()\nexport class ProductCatalogSyncBackendService extends AbstractBillingBackendService {\n\n /** The product catalog from code (set at initialization) */\n private productCatalog: ProductDefinition[] = [];\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ServicesRegistryHandlerService) servicesRegistry: ServicesRegistryHandlerBackendService,\n @inject(SAAS_SERVICE_TYPES.ExecutionContextCreatorBackendService) executionContextCreator: ExecutionContextCreatorBackendService,\n @inject(SAAS_SERVICE_TYPES.ResourceRegistryService) resourcesRegistry: ResourcesRegistryBackendService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) errorBuilder: ErrorBuilderBackendService,\n ) {\n super(logger, servicesRegistry, executionContextCreator, resourcesRegistry, errorBuilder);\n }\n\n // ════════════════════════════════════════════════════════════\n // Initialization\n // ════════════════════════════════════════════════════════════\n\n /**\n * Initialize with the code-defined product catalog and billing provider.\n */\n public async initialize(\n productCatalog: ProductDefinition[],\n provider: StandardBilling_Interface,\n ): Promise<void> {\n if (this.isInitialized) return;\n\n this.productCatalog = productCatalog;\n this.initializeProvider(provider);\n\n this.logDebug('Product catalog sync initialized', {\n productsInCatalog: productCatalog.length,\n });\n }\n\n /**\n * Returns the in-memory product catalog (set at initialization).\n * Used by the companion labelling service to discover billing keys for i18n.\n */\n public getProductDefinitions(): ProductDefinition[] {\n return this.productCatalog;\n }\n\n // ════════════════════════════════════════════════════════════\n // Lazy Sync (on-demand, single product)\n // ════════════════════════════════════════════════════════════\n\n /**\n * Ensure a single product and its prices exist in DB and provider.\n * Idempotent: safe to call multiple times.\n *\n * Flow:\n * 1. Look up ProductDefinition by key in code catalog\n * 2. Upsert Product DB record (key → _id mapping)\n * 3. Upsert Price DB records for each inline price\n * 4. If providerProductId is missing: sync to billing provider\n */\n public async ensureProductSynced(productKey: string): Promise<Product> {\n this.ensureInitialized();\n this.logDebug('Ensuring product synced', { productKey });\n\n // 1. Find in code catalog\n const definition = this.productCatalog.find(p => p.key === productKey);\n if (!definition) {\n throw this.errorBuilder.buildError(ErrorType.NOT_FOUND, undefined, {\n customMessageReference: ErrorCustomMessageReference.BILLING_PRODUCT_NOT_FOUND,\n context: { productKey },\n });\n }\n\n // 2. Upsert product in DB\n const product = await this.upsertProduct(definition);\n\n // 3. Upsert prices\n await this.upsertPrices(product._id, definition);\n\n // 4. Sync to provider when available.\n // Existing provider-linked products must still push any newly added local\n // prices, otherwise the DB/provider catalogs silently drift.\n if (this.billingProvider) {\n if (!product.providerProductId) {\n return await this.syncProductToProvider(product);\n }\n await this.syncUnsyncedPricesToProvider(product, product.providerProductId);\n }\n\n return product;\n }\n\n // ════════════════════════════════════════════════════════════\n // Bulk Sync (admin action)\n // ════════════════════════════════════════════════════════════\n\n /**\n * Sync ALL products from code catalog to DB + provider.\n * Detects \"features-dirty\" products and returns their keys for\n * downstream feature recomputation.\n *\n * Idempotent and safe to run multiple times.\n */\n public async syncProductCatalog(): Promise<ProductCatalogSyncResult> {\n this.ensureInitialized();\n this.logDebug('Starting bulk product catalog sync', {\n productsInCatalog: this.productCatalog.length,\n });\n\n const result: ProductCatalogSyncResult = {\n synced: 0,\n created: 0,\n updated: 0,\n featuresDirty: [],\n retired: [],\n retiredWithLiveSubscribers: [],\n errors: [],\n };\n\n for (const definition of this.productCatalog) {\n try {\n // Check if existing product has different features/limits\n const existingProduct = await this.findProductByKey(definition.key);\n const isFeaturesDirty = existingProduct\n ? this.isFeaturesDirty(existingProduct, definition)\n : false;\n\n // Upsert product (pass existing to avoid a second DB lookup)\n const product = await this.upsertProduct(definition, existingProduct);\n result.synced++;\n\n if (!existingProduct) {\n result.created++;\n } else {\n result.updated++;\n }\n\n // Upsert prices\n await this.upsertPrices(product._id, definition);\n\n // Sync to provider when available.\n if (this.billingProvider) {\n if (!product.providerProductId) {\n await this.syncProductToProvider(product);\n } else {\n await this.syncUnsyncedPricesToProvider(product, product.providerProductId);\n }\n }\n\n // Track features-dirty products\n if (isFeaturesDirty) {\n result.featuresDirty.push(definition.key);\n }\n } catch (error) {\n result.errors.push(`${definition.key}: ${(error as Error).message}`);\n this.logger.error('Failed to sync product', {\n productKey: definition.key,\n error: (error as Error).message,\n });\n }\n }\n\n /*\n * The other direction, and it runs LAST so that a key present in both is upserted before it is\n * examined for retirement — otherwise a first-ever sync would race itself.\n *\n * A failure here does not fail the sync: pushing the code catalogue is the primary job, and\n * refusing to do it because the retirement pass could not read subscriptions would make an\n * unrelated read fault block every deploy.\n */\n try {\n await this.reconcileRetiredProducts(result);\n } catch (error) {\n result.errors.push(`Retired-product reconciliation failed: ${(error as Error).message}`);\n }\n\n this.logDebug('Bulk product catalog sync complete', { ...result });\n return result;\n }\n\n // ════════════════════════════════════════════════════════════\n // Retirement — the catalogue's OTHER direction\n // ════════════════════════════════════════════════════════════\n\n /**\n * Soft-retire every local product whose key has left the code catalogue.\n *\n * ## What was wrong\n *\n * `syncProductCatalog` iterated `this.productCatalog` and nothing else, so it could only ever ADD\n * and UPDATE. A key deleted from the code catalogue left its `Product` row `isActive: true`, its\n * `Price` rows active, and its provider product and prices live — and because the purchase path\n * reads the DATABASE rather than the code catalogue, a product that no longer existed in code\n * could still be bought, granting whatever `grantedFeatures` the last sync happened to write.\n *\n * ## The policy, stated because it changes what a paying customer experiences\n *\n * **Retire LOCALLY, always. Report the provider. Never migrate a subscriber. Never delete.**\n *\n * - **`isActive: false` on the product and on every one of its prices, unconditionally** — even\n * when subscribers are on it. It is entitlement-SAFE, which is the fact that makes the policy\n * possible: `BillingFeatureSyncBackendService.getProduct` resolves a subscription item's product\n * by `_id` with no `isActive` filter, and renewal happens entirely at the provider against the\n * provider price, which this does not touch. So an existing subscriber keeps their features and\n * keeps renewing; what stops is NEW acquisition, through the gate in\n * `readProductByKey(..., BillingCatalogReadIntent.ACQUIRE, ...)`.\n *\n * - **The PROVIDER catalogue is left completely alone.** REJECTED ALTERNATIVE: archive the\n * provider product and prices in the same pass. The provider is the party that actually charges,\n * and archiving a price a live subscription renews against is a customer-visible failed renewal\n * — the exact outcome this whole policy is arranged to avoid. It would also mean adding a\n * destructive provider write (`StandardBilling_Interface` has no archive verb today) in the same\n * change as the sweep that calls it. An operator archives provider rows deliberately, after\n * deciding what happens to the subscribers, and the report below is what tells them to.\n *\n * - **A retired key WITH LIVE SUBSCRIBERS is reported and otherwise untouched.** REJECTED\n * ALTERNATIVE: migrate them to the nearest surviving plan tier, or cancel them. Which plan a\n * customer should move to — and whether they should be moved at all rather than grandfathered —\n * is a commercial decision with a price attached, and a framework that guesses it either\n * overcharges someone or cancels a paying customer because a key was deleted in a refactor.\n * The count is reported at error level so the decision is put in front of a human.\n *\n * - **Nothing is ever deleted.** The `Product` and `Price` rows are the only local record of what\n * a RETAINED subscription and its retained invoices refer to, and billing rows deliberately\n * survive the deletion of their scope for a tax/audit obligation. Deleting a retired product\n * would strand exactly the trail that retention exists to preserve.\n */\n private async reconcileRetiredProducts(result: ProductCatalogSyncResult): Promise<void> {\n const catalogKeys = new Set(this.productCatalog.map(definition => definition.key));\n\n const listCtx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.LIST);\n const localProducts = await this.servicesRegistry.list<Product>(\n CoreResourceType.PRODUCTS, listCtx, { isActive: true },\n ) as Product[];\n\n const retiredProducts = localProducts.filter(product => !catalogKeys.has(product.key));\n if (retiredProducts.length === 0) return;\n\n const liveProductIds = await this.collectProductIdsWithLiveSubscriptions();\n\n for (const product of retiredProducts) {\n const liveSubscriptions = liveProductIds.get(product._id) ?? 0;\n try {\n await this.deactivateProductAndPrices(product);\n result.retired.push(product.key);\n } catch (error) {\n result.errors.push(`Failed to retire product ${product.key}: ${(error as Error).message}`);\n continue;\n }\n\n if (liveSubscriptions > 0) {\n result.retiredWithLiveSubscribers.push({ productKey: product.key, liveSubscriptions });\n this.logger.error('Retired product still has live subscribers', {\n productKey: product.key,\n productId: product._id,\n liveSubscriptions,\n message:\n 'This product left the code catalogue and is no longer purchasable, but subscriptions still ' +\n 'renew against it at the provider and still grant its last-synced features. Decide whether to ' +\n 'migrate, grandfather or cancel these subscribers — the framework deliberately does not choose. ' +\n 'Its provider product and prices were NOT archived, so renewals keep working until you act.',\n });\n }\n }\n }\n\n /**\n * How many LIVE subscriptions reference each product, across every billing scope.\n *\n * Built by paging live subscriptions and reading their items, rather than by filtering on\n * `items.productId` per product. Two reasons: a nested-path filter over an array is a document-store\n * idiom that does not translate to the PostgreSQL adapter's JSON column, and one pass over the live\n * set answers the question for every retired product at once instead of one query each.\n */\n private async collectProductIdsWithLiveSubscriptions(): Promise<Map<string, number>> {\n const counts = new Map<string, number>();\n\n for (const [scopeKey, scopeData] of Object.entries(BILLING_SCOPE_TO_VARIANTS)) {\n const variants: BillingResolvedVariants = { scopeKey, ...scopeData };\n const ctx = await this.internalCtx(variants.subscription as CoreResourceType, CoreResourceOperation.LIST);\n\n for (let page = 1; page <= ProductCatalogSyncBackendService.MAX_SUBSCRIPTION_SCAN_PAGES; page += 1) {\n const subscriptions = await this.servicesRegistry.list<BillingSubscriptionBase>(\n variants.subscription as CoreResourceType,\n ctx,\n { status: { $nin: TERMINAL_SUBSCRIPTION_STATUSES } },\n { page, limit: ProductCatalogSyncBackendService.SUBSCRIPTION_SCAN_PAGE_SIZE },\n ) as BillingSubscriptionBase[];\n\n for (const subscription of subscriptions) {\n const seen = new Set<string>();\n for (const item of subscription.items ?? []) {\n // One subscription counts ONCE per product however many items name it — the number is\n // \"how many customers am I about to strand\", not \"how many line items exist\".\n if (!item?.productId || seen.has(item.productId)) continue;\n seen.add(item.productId);\n counts.set(item.productId, (counts.get(item.productId) ?? 0) + 1);\n }\n }\n\n if (subscriptions.length < ProductCatalogSyncBackendService.SUBSCRIPTION_SCAN_PAGE_SIZE) break;\n }\n }\n\n return counts;\n }\n\n /**\n * `isActive: false` on the product and on every price beneath it.\n *\n * The prices matter as much as the product: an application that lists prices directly, or a caller\n * that names a price id, would otherwise still transact against a retired product's price — and\n * `readPriceForProduct` refuses on the PRICE's own flag, so leaving them active would leave a\n * second door open on the surface the gate was built for.\n */\n private async deactivateProductAndPrices(product: Product): Promise<void> {\n const productUpdate = { isActive: false };\n const productCtx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.UPDATE);\n await this.servicesRegistry.update<Product>(CoreResourceType.PRODUCTS, productCtx, product._id, productUpdate);\n\n const pricesCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.LIST);\n const prices = await this.servicesRegistry.list<Price>(\n CoreResourceType.PRICES, pricesCtx, { productId: product._id, isActive: true },\n ) as Price[];\n\n for (const price of prices) {\n const priceCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.UPDATE);\n await this.servicesRegistry.update<Price>(CoreResourceType.PRICES, priceCtx, price._id, { isActive: false });\n }\n }\n\n /** One page of the live-subscription scan. */\n private static readonly SUBSCRIPTION_SCAN_PAGE_SIZE = 200;\n\n /**\n * Page ceiling for the live-subscription scan. Reaching it UNDER-counts, which is the safe\n * direction here for exactly one reason: the count only ever decides whether a WARNING is emitted\n * — the retirement itself is unconditional — so a missed page costs a quieter log line, never a\n * different write.\n */\n private static readonly MAX_SUBSCRIPTION_SCAN_PAGES = 50;\n\n // ════════════════════════════════════════════════════════════\n // Private — Product Operations\n // ════════════════════════════════════════════════════════════\n\n private async findProductByKey(productKey: string): Promise<Product | null> {\n // Context construction stays OUTSIDE the try: failing to resolve the\n // INTERNAL_CALL operation path is a wiring fault, never \"product absent\".\n // A masked failure is worse here than a missing read — callers treat null as\n // \"not yet in the catalog\" and CREATE, so a swallowed fault duplicates products.\n const ctx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.LIST);\n try {\n const items = await this.servicesRegistry.list<Product>(CoreResourceType.PRODUCTS, ctx, { key: productKey }) as Product[];\n return items.length > 0 ? items[0] : null;\n } catch (error) {\n this.degradeOrRethrow(error, 'Failed to find product by key', { productKey });\n return null;\n }\n }\n\n private async upsertProduct(definition: ProductDefinition, existingProductHint?: Product | null): Promise<Product> {\n // Use the pre-fetched product if available (avoids double DB lookup in bulk sync)\n const existingProduct = existingProductHint !== undefined\n ? existingProductHint\n : await this.findProductByKey(definition.key);\n\n const productData: Partial<Product> = {\n type: definition.type,\n key: definition.key,\n targetScopes: definition.targetScopes,\n grantedFeatures: definition.grantedFeatures,\n grantedLimits: definition.grantedLimits,\n planTier: definition.planTier,\n planTierOrder: definition.planTierOrder,\n requiredPlanTiers: definition.requiredPlanTiers,\n taxDisplayMode: definition.taxDisplayMode,\n purchaseConfig: definition.purchaseConfig,\n behaviorPolicy: definition.behaviorPolicy,\n sortOrder: definition.sortOrder,\n isPublic: definition.isPublic,\n isActive: true,\n };\n\n if (existingProduct) {\n // Update\n const ctx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.UPDATE);\n return await this.servicesRegistry.update<Product>(CoreResourceType.PRODUCTS, ctx, existingProduct._id, productData) as Product;\n } else {\n // Create\n const ctx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.CREATE);\n return await this.servicesRegistry.create<Product>(CoreResourceType.PRODUCTS, ctx, productData);\n }\n }\n\n private async upsertPrices(productId: string, definition: ProductDefinition): Promise<void> {\n for (const priceDef of definition.prices) {\n const priceData: Partial<Price> = {\n productId,\n model: priceDef.model,\n unitPrice: priceDef.unitPrice,\n interval: priceDef.interval,\n intervalCount: priceDef.intervalCount,\n tiers: priceDef.tiers,\n packageSize: priceDef.packageSize,\n usageAggregation: priceDef.usageAggregation,\n taxBehavior: priceDef.taxBehavior,\n isDefault: priceDef.isDefault,\n isActive: true,\n };\n\n // Try to find existing price for this product with same model+interval+currency\n try {\n const listCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.LIST);\n const items = await this.servicesRegistry.list<Price>(CoreResourceType.PRICES, listCtx, {\n productId,\n model: priceDef.model,\n 'unitPrice.currency': priceDef.unitPrice.currency,\n ...(priceDef.interval && { interval: priceDef.interval }),\n }) as Price[];\n\n if (items.length > 0) {\n const updateCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.UPDATE);\n await this.servicesRegistry.update<Price>(CoreResourceType.PRICES, updateCtx, items[0]._id, priceData);\n } else {\n const createCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.CREATE);\n await this.servicesRegistry.create<Price>(CoreResourceType.PRICES, createCtx, priceData);\n }\n } catch (error) {\n this.logger.error('Failed to upsert price', {\n productId,\n model: priceDef.model,\n currency: priceDef.unitPrice.currency,\n error: (error as Error).message,\n });\n }\n }\n }\n\n /**\n * `ServiceOptions` that re-attach the backend-only provider-link field(s) a plain update request\n * DTO would strip. The billing catalog sync is a trusted in-process write of provider identifiers\n * (`providerProductId` / `providerPriceId`, both `.isBackendOnly()`); without this the strict\n * request-DTO parse drops them and the update persists nothing. Mirrors the billing webhook\n * event router's trusted-system write (`deriveTrustedSystemWritePreservedFields` — schema-aware,\n * so it only preserves fields that are genuinely backend-only AND present in the payload).\n */\n private trustedProviderLinkWriteOptions(resourceType: CoreResourceType, payload: Record<string, unknown>): ServiceOptions {\n const { mainSchema } = this.resourcesRegistry.getResourceConfiguration(resourceType);\n return {\n preserveServerInjectedFields: deriveTrustedSystemWritePreservedFields(\n mainSchema,\n Object.keys(payload),\n CoreResourceOperation.UPDATE,\n ),\n };\n }\n\n private async syncProductToProvider(product: Product): Promise<Product> {\n if (!this.billingProvider) return product;\n\n try {\n // Sync product\n const { providerProductId } = await this.billingProvider.syncProduct({\n productKey: product.key,\n name: product.key,\n metadata: { key: product.key, type: product.type },\n });\n\n // Persist the provider link locally. `providerProductId` is `.isBackendOnly()`, so a plain\n // update request DTO STRIPS it: the write \"succeeds\" but the field never lands, leaving the\n // local link null forever — which is what made every catalog sync re-create the provider\n // product (accumulating duplicates). Re-attach it through the trusted-system-write allowlist,\n // the same seam the billing webhook path uses for the same class of backend-only field.\n const providerLink = { providerProductId };\n const updateCtx = await this.internalCtx(CoreResourceType.PRODUCTS, CoreResourceOperation.UPDATE);\n const updated = await this.servicesRegistry.update<Product>(\n CoreResourceType.PRODUCTS,\n updateCtx,\n product._id,\n providerLink,\n this.trustedProviderLinkWriteOptions(CoreResourceType.PRODUCTS, providerLink),\n ) as Product;\n\n await this.syncUnsyncedPricesToProvider(updated, providerProductId);\n\n return updated;\n } catch (error) {\n this.logger.error('Failed to sync product to provider', {\n productKey: product.key,\n error: (error as Error).message,\n });\n return product;\n }\n }\n\n /**\n * Sync any locally defined prices that do not yet have a provider identifier.\n *\n * This must run for both first-time product syncs and already-synced products,\n * otherwise adding a new local price after the initial product sync leaves the\n * provider catalog stale.\n */\n private async syncUnsyncedPricesToProvider(product: Product, providerProductId: string): Promise<void> {\n if (!this.billingProvider) return;\n\n const listCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.LIST);\n const prices = await this.servicesRegistry.list<Price>(CoreResourceType.PRICES, listCtx, { productId: product._id }) as Price[];\n\n for (const price of prices) {\n if (price.providerPriceId) continue;\n\n try {\n /*\n * Convert every amount from its AUTHORED scale to the CURRENCY's smallest unit (#515).\n *\n * This was `Number(price.unitPrice.amount)` and two more like it — the stored amount handed\n * over verbatim, with `MoneyValue.decimals` discarded. A price authored at any scale other\n * than the currency's was therefore synced at the wrong magnitude, by a factor of 10 per\n * decimal place of disagreement, and the three amounts in one price could each carry a\n * different scale and still be combined as if they shared one.\n *\n * A conversion that cannot be made exactly REFUSES the price rather than rounding it. The\n * throw is caught by the loop below, which logs and moves to the next price — so one\n * unrepresentable price does not stop a catalogue sync, and it does not reach the provider\n * either.\n */\n const priceCurrency = price.unitPrice.currency;\n const amount = this.toProviderAmountOrThrow(price.unitPrice, priceCurrency, `price ${price._id}`);\n const { providerPriceId } = await this.billingProvider.syncPrice({\n providerProductId,\n amount,\n currency: price.unitPrice.currency,\n interval: price.interval,\n model: price.model,\n tiers: price.tiers?.map((t, index) => ({\n upTo: t.upTo ?? null,\n unitAmount: this.toProviderAmountOrThrow(t.unitPrice, priceCurrency, `price ${price._id} tier ${index} unit amount`),\n flatAmount: this.toProviderAmountOrThrow(t.flatPrice, priceCurrency, `price ${price._id} tier ${index} flat amount`),\n })),\n packageSize: price.packageSize,\n taxBehavior: price.taxBehavior,\n metadata: { productKey: product.key },\n });\n\n // `providerPriceId` is `.isBackendOnly()` too — same trusted-system-write preservation as\n // the product link above, or the price link would silently never persist.\n const priceLink = { providerPriceId };\n const priceUpdateCtx = await this.internalCtx(CoreResourceType.PRICES, CoreResourceOperation.UPDATE);\n await this.servicesRegistry.update<Price>(\n CoreResourceType.PRICES,\n priceUpdateCtx,\n price._id,\n priceLink,\n this.trustedProviderLinkWriteOptions(CoreResourceType.PRICES, priceLink),\n );\n } catch (error) {\n this.logger.error('Failed to sync price to provider', {\n priceId: price._id,\n productKey: product.key,\n /*\n * The CLASSIFIED reason when the failure is a scale one (#515), because the three have\n * different remedies and an operator should not have to read prose to tell them apart:\n * `unknown_minor_unit` is a catalogue problem, `precision_loss` is an authoring problem,\n * `unsafe_magnitude` is a limit of the provider's number type. This `instanceof` is why the\n * conversion throws a TYPED error rather than returning a result union — the engine compiles\n * with `strict: false`, where a discriminated union does not narrow.\n */\n ...(error instanceof MoneyMinorUnitConversionError ? { moneyScaleFailure: error.reason } : {}),\n error: (error as Error).message,\n });\n }\n }\n }\n\n /**\n * One amount, converted from its authored scale to the currency's smallest unit — or a throw naming\n * exactly why it cannot be (#515).\n *\n * Throws rather than returning a result, because every caller is inside the per-price `try` and the\n * only correct response to any of the three failures is the same: do not sync this price. Returning\n * a union here would give each of the three call sites its own chance to forget one.\n *\n * **The currency is passed in rather than read off the value**, and that is the second half of the\n * defect. A tier's `unitPrice`/`flatPrice` carry an OPTIONAL currency — they inherit the price's —\n * so reading each amount's own currency would resolve a scale per amount and let one price be\n * converted at up to three different ones. One price is denominated in one currency; the amounts\n * are its parts.\n */\n private toProviderAmountOrThrow(\n value: { amount: bigint; decimals: number },\n currency: string,\n subject: string,\n ): number {\n return toCurrencyMinorUnitAmountOrThrow({ ...value, currency }, subject);\n }\n\n // ════════════════════════════════════════════════════════════\n // Private — Dirty Detection\n // ════════════════════════════════════════════════════════════\n\n /**\n * Check if a product's features/limits have changed relative to the catalog definition.\n * If so, all subscriptions using this product need feature recomputation.\n */\n private isFeaturesDirty(existing: Product, definition: ProductDefinition): boolean {\n // Check grantedFeatures\n const existingFeatures = new Set(existing.grantedFeatures ?? []);\n const newFeatures = new Set(definition.grantedFeatures ?? []);\n if (existingFeatures.size !== newFeatures.size) return true;\n for (const f of existingFeatures) {\n if (!newFeatures.has(f)) return true;\n }\n\n // Check grantedLimits\n const existingLimits = existing.grantedLimits ?? {};\n const newLimits = definition.grantedLimits ?? {};\n const existingKeys = Object.keys(existingLimits);\n const newKeys = Object.keys(newLimits);\n if (existingKeys.length !== newKeys.length) return true;\n for (const key of existingKeys) {\n if (!newLimits[key]) return true;\n if (existingLimits[key].value !== newLimits[key].value) return true;\n if (existingLimits[key].mode !== newLimits[key].mode) return true;\n }\n\n return false;\n }\n}\n"]}