@openlup/platform 0.25.0 → 0.27.0

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 (524) hide show
  1. package/CHANGELOG.md +156 -440
  2. package/README.md +230 -11
  3. package/dist/commerce/adapters/managed/commerceOmsControlPlane.d.ts +3 -0
  4. package/dist/commerce/adapters/managed/commerceOmsControlPlane.js +71 -0
  5. package/dist/commerce/adapters/managed/commerceOmsMutations.d.ts +10 -0
  6. package/dist/commerce/adapters/managed/commerceOmsMutations.js +119 -0
  7. package/dist/commerce/adapters/managed/commerceOmsPort.d.ts +28 -0
  8. package/dist/commerce/adapters/managed/commerceOmsPort.js +101 -0
  9. package/dist/commerce/adapters/managed/oms/accounting.d.ts +3 -0
  10. package/dist/commerce/adapters/managed/oms/accounting.js +13 -0
  11. package/dist/commerce/adapters/managed/oms/fulfillmentReads.d.ts +17 -0
  12. package/dist/commerce/adapters/managed/oms/fulfillmentReads.js +81 -0
  13. package/dist/commerce/adapters/managed/oms/inboundEvents.d.ts +9 -0
  14. package/dist/commerce/adapters/managed/oms/inboundEvents.js +40 -0
  15. package/dist/commerce/adapters/managed/oms/outboxEvents.d.ts +2 -0
  16. package/dist/commerce/adapters/managed/oms/outboxEvents.js +23 -0
  17. package/dist/commerce/adapters/managed/oms/paymentAttempts.d.ts +3 -0
  18. package/dist/commerce/adapters/managed/oms/paymentAttempts.js +15 -0
  19. package/dist/commerce/adapters/managed/oms/queueSelection.d.ts +12 -0
  20. package/dist/commerce/adapters/managed/oms/queueSelection.js +109 -0
  21. package/dist/commerce/adapters/managed/oms/readProjections.d.ts +18 -0
  22. package/dist/commerce/adapters/managed/oms/readProjections.js +13 -0
  23. package/dist/commerce/adapters/managed/oms/readQueries.d.ts +16 -0
  24. package/dist/commerce/adapters/managed/oms/readQueries.js +276 -0
  25. package/dist/commerce/adapters/managed/oms/types.d.ts +2 -0
  26. package/dist/commerce/adapters/managed/oms/types.js +7 -0
  27. package/dist/commerce/checkoutCommandSchemas.d.ts +89 -0
  28. package/dist/commerce/checkoutCommandSchemas.js +70 -0
  29. package/dist/commerce/checkoutHelpers.d.ts +21 -0
  30. package/dist/commerce/checkoutHelpers.js +29 -0
  31. package/dist/commerce/checkoutResumeSchemas.d.ts +158 -0
  32. package/dist/commerce/checkoutResumeSchemas.js +145 -0
  33. package/dist/commerce/checkoutSchemas.d.ts +158 -0
  34. package/dist/commerce/checkoutSchemas.js +161 -0
  35. package/dist/commerce/commerceReturnsPort.d.ts +97 -0
  36. package/dist/commerce/commerceReturnsPort.js +39 -0
  37. package/dist/commerce/configuratorIntentPersistenceSchemas.d.ts +20 -0
  38. package/dist/commerce/configuratorIntentPersistenceSchemas.js +21 -0
  39. package/dist/commerce/configuratorIntentSchemas.d.ts +63 -0
  40. package/dist/commerce/configuratorIntentSchemas.js +43 -0
  41. package/dist/commerce/contractPrimitives.d.ts +50 -0
  42. package/dist/commerce/contractPrimitives.js +25 -0
  43. package/dist/commerce/contracts/availability.d.ts +23 -0
  44. package/dist/commerce/contracts/availability.js +1 -0
  45. package/dist/commerce/contracts/fulfillmentRecovery.d.ts +25 -0
  46. package/dist/commerce/contracts/fulfillmentRecovery.js +1 -0
  47. package/dist/commerce/contracts/index.d.ts +13 -0
  48. package/dist/commerce/contracts/index.js +1 -0
  49. package/dist/commerce/contracts/intent.d.ts +86 -0
  50. package/dist/commerce/contracts/intent.js +1 -0
  51. package/dist/commerce/contracts/omsTypes.d.ts +1216 -0
  52. package/dist/commerce/contracts/omsTypes.js +1 -0
  53. package/dist/commerce/contracts/order.d.ts +39 -0
  54. package/dist/commerce/contracts/order.js +1 -0
  55. package/dist/commerce/contracts/orderMoney.d.ts +52 -0
  56. package/dist/commerce/contracts/orderMoney.js +1 -0
  57. package/dist/commerce/contracts/ports.d.ts +113 -0
  58. package/dist/commerce/contracts/ports.js +1 -0
  59. package/dist/commerce/contracts/recovery.d.ts +11 -0
  60. package/dist/commerce/contracts/recovery.js +1 -0
  61. package/dist/commerce/contracts/runtimePorts.d.ts +196 -0
  62. package/dist/commerce/contracts/runtimePorts.js +1 -0
  63. package/dist/commerce/contracts/state.d.ts +26 -0
  64. package/dist/commerce/contracts/state.js +43 -0
  65. package/dist/commerce/customerDefaultsSnapshotSchemas.d.ts +51 -0
  66. package/dist/commerce/customerDefaultsSnapshotSchemas.js +106 -0
  67. package/dist/commerce/errors.d.ts +18 -0
  68. package/dist/commerce/errors.js +36 -0
  69. package/dist/commerce/fulfillmentEligibility.d.ts +6 -0
  70. package/dist/commerce/fulfillmentEligibility.js +31 -0
  71. package/dist/commerce/index.d.ts +72 -0
  72. package/dist/commerce/index.js +67 -0
  73. package/dist/commerce/model/customerFulfillmentRecovery.d.ts +40 -0
  74. package/dist/commerce/model/customerFulfillmentRecovery.js +144 -0
  75. package/dist/commerce/model/fulfillmentCancellationEligibility.d.ts +7 -0
  76. package/dist/commerce/model/fulfillmentCancellationEligibility.js +9 -0
  77. package/dist/commerce/model/omsAccountingVisibility.d.ts +12 -0
  78. package/dist/commerce/model/omsAccountingVisibility.js +118 -0
  79. package/dist/commerce/model/omsBillingInvoiceBuyer.d.ts +2 -0
  80. package/dist/commerce/model/omsBillingInvoiceBuyer.js +15 -0
  81. package/dist/commerce/model/omsCurrency.d.ts +4 -0
  82. package/dist/commerce/model/omsCurrency.js +5 -0
  83. package/dist/commerce/model/omsFulfillmentDebug.d.ts +20 -0
  84. package/dist/commerce/model/omsFulfillmentDebug.js +122 -0
  85. package/dist/commerce/model/omsFulfillmentSummary.d.ts +16 -0
  86. package/dist/commerce/model/omsFulfillmentSummary.js +189 -0
  87. package/dist/commerce/model/omsListTotals.d.ts +13 -0
  88. package/dist/commerce/model/omsListTotals.js +32 -0
  89. package/dist/commerce/model/omsOperationalLadder.d.ts +51 -0
  90. package/dist/commerce/model/omsOperationalLadder.js +158 -0
  91. package/dist/commerce/model/omsOrderLineMoney.d.ts +4 -0
  92. package/dist/commerce/model/omsOrderLineMoney.js +25 -0
  93. package/dist/commerce/model/omsPaymentMethodSummary.d.ts +5 -0
  94. package/dist/commerce/model/omsPaymentMethodSummary.js +11 -0
  95. package/dist/commerce/model/omsReadModel.d.ts +43 -0
  96. package/dist/commerce/model/omsReadModel.js +211 -0
  97. package/dist/commerce/model/omsReadModelCommunication.d.ts +3 -0
  98. package/dist/commerce/model/omsReadModelCommunication.js +29 -0
  99. package/dist/commerce/model/omsReadModelHelpers.d.ts +125 -0
  100. package/dist/commerce/model/omsReadModelHelpers.js +212 -0
  101. package/dist/commerce/model/omsReadModelList.d.ts +33 -0
  102. package/dist/commerce/model/omsReadModelList.js +50 -0
  103. package/dist/commerce/model/omsReadModelListSummary.d.ts +3 -0
  104. package/dist/commerce/model/omsReadModelListSummary.js +13 -0
  105. package/dist/commerce/model/omsReadModelPricing.d.ts +5 -0
  106. package/dist/commerce/model/omsReadModelPricing.js +36 -0
  107. package/dist/commerce/model/omsReadModelProjections.d.ts +1 -0
  108. package/dist/commerce/model/omsReadModelProjections.js +1 -0
  109. package/dist/commerce/model/omsReadModelRowCore.d.ts +79 -0
  110. package/dist/commerce/model/omsReadModelRowCore.js +149 -0
  111. package/dist/commerce/model/omsReadModelRows.d.ts +1 -0
  112. package/dist/commerce/model/omsReadModelRows.js +6 -0
  113. package/dist/commerce/offerAvailability.d.ts +18 -0
  114. package/dist/commerce/offerAvailability.js +53 -0
  115. package/dist/commerce/offerAvailabilitySchemas.d.ts +43 -0
  116. package/dist/commerce/offerAvailabilitySchemas.js +42 -0
  117. package/dist/commerce/offerEvidenceSchemas.d.ts +7 -0
  118. package/dist/commerce/offerEvidenceSchemas.js +13 -0
  119. package/dist/commerce/oms/omsContractBase.d.ts +130 -0
  120. package/dist/commerce/oms/omsContractBase.js +86 -0
  121. package/dist/commerce/oms/omsContractReadAuxSchemas.d.ts +222 -0
  122. package/dist/commerce/oms/omsContractReadAuxSchemas.js +123 -0
  123. package/dist/commerce/oms/omsContractReadSchemas.d.ts +2266 -0
  124. package/dist/commerce/oms/omsContractReadSchemas.js +277 -0
  125. package/dist/commerce/oms/omsContractRequests.d.ts +196 -0
  126. package/dist/commerce/oms/omsContractRequests.js +118 -0
  127. package/dist/commerce/oms/omsContracts.d.ts +5 -0
  128. package/dist/commerce/oms/omsContracts.js +4 -0
  129. package/dist/commerce/oms/omsControlPlane.d.ts +275 -0
  130. package/dist/commerce/oms/omsControlPlane.js +72 -0
  131. package/dist/commerce/oms/omsFulfillmentContractSchemas.d.ts +203 -0
  132. package/dist/commerce/oms/omsFulfillmentContractSchemas.js +94 -0
  133. package/dist/commerce/oms/omsFulfillmentDebugSchemas.d.ts +69 -0
  134. package/dist/commerce/oms/omsFulfillmentDebugSchemas.js +33 -0
  135. package/dist/commerce/oms/omsFulfillmentHealthSchemas.d.ts +67 -0
  136. package/dist/commerce/oms/omsFulfillmentHealthSchemas.js +44 -0
  137. package/dist/commerce/oms/omsPorts.d.ts +84 -0
  138. package/dist/commerce/oms/omsPorts.js +148 -0
  139. package/dist/commerce/oms/omsPrimitives.d.ts +5 -0
  140. package/dist/commerce/oms/omsPrimitives.js +3 -0
  141. package/dist/commerce/oms/omsProviderEvidenceSchemas.d.ts +15 -0
  142. package/dist/commerce/oms/omsProviderEvidenceSchemas.js +12 -0
  143. package/dist/commerce/orderDraftErrors.d.ts +13 -0
  144. package/dist/commerce/orderDraftErrors.js +20 -0
  145. package/dist/commerce/orderEmailEligibility.d.ts +54 -0
  146. package/dist/commerce/orderEmailEligibility.js +123 -0
  147. package/dist/commerce/orderEmailLines.d.ts +12 -0
  148. package/dist/commerce/orderEmailLines.js +8 -0
  149. package/dist/commerce/orderFeedbackContracts.d.ts +41 -0
  150. package/dist/commerce/orderFeedbackContracts.js +33 -0
  151. package/dist/commerce/orderMoney.d.ts +6 -0
  152. package/dist/commerce/orderMoney.js +168 -0
  153. package/dist/commerce/orderReviewContracts.d.ts +475 -0
  154. package/dist/commerce/orderReviewContracts.js +94 -0
  155. package/dist/commerce/orderReviewPorts.d.ts +140 -0
  156. package/dist/commerce/orderReviewPorts.js +1 -0
  157. package/dist/commerce/outboxDispatchContracts.d.ts +30 -0
  158. package/dist/commerce/outboxDispatchContracts.js +1 -0
  159. package/dist/commerce/outboxEventSchemas.d.ts +162 -0
  160. package/dist/commerce/outboxEventSchemas.js +164 -0
  161. package/dist/commerce/outboxOrderDraftEmailPorts.d.ts +207 -0
  162. package/dist/commerce/outboxOrderDraftEmailPorts.js +12 -0
  163. package/dist/commerce/paymentContinuation.d.ts +4 -0
  164. package/dist/commerce/paymentContinuation.js +4 -0
  165. package/dist/commerce/ports.d.ts +8 -0
  166. package/dist/commerce/ports.js +1 -0
  167. package/dist/commerce/recoveryDestination.d.ts +3 -0
  168. package/dist/commerce/recoveryDestination.js +17 -0
  169. package/dist/commerce/runtimeErrors.d.ts +8 -0
  170. package/dist/commerce/runtimeErrors.js +16 -0
  171. package/dist/commerce/salesChannelEnvelope.d.ts +20 -0
  172. package/dist/commerce/salesChannelEnvelope.js +7 -0
  173. package/dist/commerce/schemas.d.ts +174 -0
  174. package/dist/commerce/schemas.js +84 -0
  175. package/dist/commerce/server/checkoutCompensation.d.ts +21 -0
  176. package/dist/commerce/server/checkoutCompensation.js +32 -0
  177. package/dist/commerce/server/checkoutConflictClassifiers.d.ts +17 -0
  178. package/dist/commerce/server/checkoutConflictClassifiers.js +38 -0
  179. package/dist/commerce/server/checkoutExpiredRecoveryPolicy.d.ts +38 -0
  180. package/dist/commerce/server/checkoutExpiredRecoveryPolicy.js +85 -0
  181. package/dist/commerce/server/checkoutInvoiceBuyerSnapshot.d.ts +22 -0
  182. package/dist/commerce/server/checkoutInvoiceBuyerSnapshot.js +30 -0
  183. package/dist/commerce/server/checkoutOfferPolicyPort.d.ts +33 -0
  184. package/dist/commerce/server/checkoutOfferPolicyPort.js +49 -0
  185. package/dist/commerce/server/checkoutPaymentContinuationCredential.d.ts +58 -0
  186. package/dist/commerce/server/checkoutPaymentContinuationCredential.js +154 -0
  187. package/dist/commerce/server/checkoutQuoteTypes.d.ts +19 -0
  188. package/dist/commerce/server/checkoutQuoteTypes.js +1 -0
  189. package/dist/commerce/server/checkoutRecoveryOrderPort.d.ts +42 -0
  190. package/dist/commerce/server/checkoutRecoveryOrderPort.js +1 -0
  191. package/dist/commerce/server/checkoutRecoveryToken.d.ts +40 -0
  192. package/dist/commerce/server/checkoutRecoveryToken.js +26 -0
  193. package/dist/commerce/server/checkoutRefusalContinuation.d.ts +24 -0
  194. package/dist/commerce/server/checkoutRefusalContinuation.js +18 -0
  195. package/dist/commerce/server/checkoutRuntimeTypes.d.ts +81 -0
  196. package/dist/commerce/server/checkoutRuntimeTypes.js +1 -0
  197. package/dist/commerce/server/commerceCheckoutCommandExecution.d.ts +60 -0
  198. package/dist/commerce/server/commerceCheckoutCommandExecution.js +136 -0
  199. package/dist/commerce/server/commerceCheckoutCompensation.d.ts +26 -0
  200. package/dist/commerce/server/commerceCheckoutCompensation.js +46 -0
  201. package/dist/commerce/server/commerceCheckoutContinuationTerms.d.ts +50 -0
  202. package/dist/commerce/server/commerceCheckoutContinuationTerms.js +66 -0
  203. package/dist/commerce/server/commerceCheckoutCustomerDefaults.d.ts +18 -0
  204. package/dist/commerce/server/commerceCheckoutCustomerDefaults.js +17 -0
  205. package/dist/commerce/server/commerceCheckoutFailureHandler.d.ts +51 -0
  206. package/dist/commerce/server/commerceCheckoutFailureHandler.js +90 -0
  207. package/dist/commerce/server/commerceCheckoutHandler.d.ts +213 -0
  208. package/dist/commerce/server/commerceCheckoutHandler.js +196 -0
  209. package/dist/commerce/server/commerceCheckoutHandlerAdmission.d.ts +58 -0
  210. package/dist/commerce/server/commerceCheckoutHandlerAdmission.js +94 -0
  211. package/dist/commerce/server/commerceCheckoutHandlerHelpers.d.ts +67 -0
  212. package/dist/commerce/server/commerceCheckoutHandlerHelpers.js +155 -0
  213. package/dist/commerce/server/commerceCheckoutOrchestrationError.d.ts +9 -0
  214. package/dist/commerce/server/commerceCheckoutOrchestrationError.js +14 -0
  215. package/dist/commerce/server/commerceCheckoutPromotionPriceChange.d.ts +47 -0
  216. package/dist/commerce/server/commerceCheckoutPromotionPriceChange.js +43 -0
  217. package/dist/commerce/server/commerceCheckoutProviderPayment.d.ts +34 -0
  218. package/dist/commerce/server/commerceCheckoutProviderPayment.js +37 -0
  219. package/dist/commerce/server/commerceCheckoutQuoteGuard.d.ts +62 -0
  220. package/dist/commerce/server/commerceCheckoutQuoteGuard.js +106 -0
  221. package/dist/commerce/server/commerceCheckoutResume.d.ts +29 -0
  222. package/dist/commerce/server/commerceCheckoutResume.js +81 -0
  223. package/dist/commerce/server/commerceCheckoutResumeGuard.d.ts +54 -0
  224. package/dist/commerce/server/commerceCheckoutResumeGuard.js +138 -0
  225. package/dist/commerce/server/commerceCheckoutSavedPaymentMethod.d.ts +39 -0
  226. package/dist/commerce/server/commerceCheckoutSavedPaymentMethod.js +44 -0
  227. package/dist/commerce/server/commerceCheckoutStartRuntimeFailure.d.ts +7 -0
  228. package/dist/commerce/server/commerceCheckoutStartRuntimeFailure.js +39 -0
  229. package/dist/commerce/server/commerceCheckoutTiming.d.ts +8 -0
  230. package/dist/commerce/server/commerceCheckoutTiming.js +31 -0
  231. package/dist/commerce/server/commerceDiagnostics.d.ts +6 -0
  232. package/dist/commerce/server/commerceDiagnostics.js +31 -0
  233. package/dist/commerce/server/commerceOmsCancelOrderHandler.d.ts +7 -0
  234. package/dist/commerce/server/commerceOmsCancelOrderHandler.js +22 -0
  235. package/dist/commerce/server/commerceOmsControlPlaneHandlers.d.ts +18 -0
  236. package/dist/commerce/server/commerceOmsControlPlaneHandlers.js +60 -0
  237. package/dist/commerce/server/commerceOmsHandlers.d.ts +47 -0
  238. package/dist/commerce/server/commerceOmsHandlers.js +176 -0
  239. package/dist/commerce/server/commerceOmsMarkRefundedHandler.d.ts +7 -0
  240. package/dist/commerce/server/commerceOmsMarkRefundedHandler.js +19 -0
  241. package/dist/commerce/server/commerceOrderDraft.d.ts +24 -0
  242. package/dist/commerce/server/commerceOrderDraft.js +92 -0
  243. package/dist/commerce/server/commercePaidOrderOrchestration.d.ts +131 -0
  244. package/dist/commerce/server/commercePaidOrderOrchestration.js +140 -0
  245. package/dist/commerce/server/commerceProviderAttemptFailure.d.ts +133 -0
  246. package/dist/commerce/server/commerceProviderAttemptFailure.js +175 -0
  247. package/dist/commerce/server/commerceReturnsHandlers.d.ts +41 -0
  248. package/dist/commerce/server/commerceReturnsHandlers.js +100 -0
  249. package/dist/commerce/server/commerceRuntimePort.d.ts +16 -0
  250. package/dist/commerce/server/commerceRuntimePort.js +57 -0
  251. package/dist/commerce/server/commerceRuntimeService.d.ts +98 -0
  252. package/dist/commerce/server/commerceRuntimeService.js +186 -0
  253. package/dist/commerce/server/commerceRuntimeStartResponse.d.ts +37 -0
  254. package/dist/commerce/server/commerceRuntimeStartResponse.js +56 -0
  255. package/dist/commerce/server/commerceStarterOfferGuard.d.ts +55 -0
  256. package/dist/commerce/server/commerceStarterOfferGuard.js +128 -0
  257. package/dist/commerce/server/configuratorIntentPersistence.d.ts +47 -0
  258. package/dist/commerce/server/configuratorIntentPersistence.js +85 -0
  259. package/dist/commerce/server/configuratorIntentPersistenceHandler.d.ts +14 -0
  260. package/dist/commerce/server/configuratorIntentPersistenceHandler.js +42 -0
  261. package/dist/commerce/server/emailRuntime.d.ts +47 -0
  262. package/dist/commerce/server/emailRuntime.js +1 -0
  263. package/dist/commerce/server/handlerSupport.d.ts +68 -0
  264. package/dist/commerce/server/handlerSupport.js +1 -0
  265. package/dist/commerce/server/index.d.ts +178 -0
  266. package/dist/commerce/server/index.js +127 -0
  267. package/dist/commerce/server/offerAvailability.d.ts +21 -0
  268. package/dist/commerce/server/offerAvailability.js +163 -0
  269. package/dist/commerce/server/orderDraftRpcPayload.d.ts +20 -0
  270. package/dist/commerce/server/orderDraftRpcPayload.js +21 -0
  271. package/dist/commerce/server/orderFeedbackSubmit.d.ts +20 -0
  272. package/dist/commerce/server/orderFeedbackSubmit.js +16 -0
  273. package/dist/commerce/server/orderFeedbackTokenCheck.d.ts +17 -0
  274. package/dist/commerce/server/orderFeedbackTokenCheck.js +14 -0
  275. package/dist/commerce/server/orderReviewAdminHandlers.d.ts +47 -0
  276. package/dist/commerce/server/orderReviewAdminHandlers.js +41 -0
  277. package/dist/commerce/server/orderReviewHandlers.d.ts +114 -0
  278. package/dist/commerce/server/orderReviewHandlers.js +42 -0
  279. package/dist/commerce/server/orderReviewLifecycle.d.ts +10 -0
  280. package/dist/commerce/server/orderReviewLifecycle.js +121 -0
  281. package/dist/commerce/server/orderReviewMedia.d.ts +11 -0
  282. package/dist/commerce/server/orderReviewMedia.js +172 -0
  283. package/dist/commerce/server/orderReviewRawUploadHandler.d.ts +40 -0
  284. package/dist/commerce/server/orderReviewRawUploadHandler.js +316 -0
  285. package/dist/commerce/server/outboxCheckoutExpiredEmailHandler.d.ts +14 -0
  286. package/dist/commerce/server/outboxCheckoutExpiredEmailHandler.js +57 -0
  287. package/dist/commerce/server/outboxCheckoutRecoveryEmailHandler.d.ts +13 -0
  288. package/dist/commerce/server/outboxCheckoutRecoveryEmailHandler.js +150 -0
  289. package/dist/commerce/server/outboxDispatchRegistry.d.ts +46 -0
  290. package/dist/commerce/server/outboxDispatchRegistry.js +184 -0
  291. package/dist/commerce/server/outboxDispatchRegistryComposition.d.ts +6 -0
  292. package/dist/commerce/server/outboxDispatchRegistryComposition.js +23 -0
  293. package/dist/commerce/server/outboxOrderDraftEmailHandler.d.ts +14 -0
  294. package/dist/commerce/server/outboxOrderDraftEmailHandler.js +130 -0
  295. package/dist/commerce/server/outboxOrderPaidEmailHandler.d.ts +21 -0
  296. package/dist/commerce/server/outboxOrderPaidEmailHandler.js +93 -0
  297. package/dist/commerce/server/outboxOrderPaidFulfillmentHandler.d.ts +3 -0
  298. package/dist/commerce/server/outboxOrderPaidFulfillmentHandler.js +1 -0
  299. package/dist/commerce/server/outboxOrderPaidFulfillmentPorts.d.ts +3 -0
  300. package/dist/commerce/server/outboxOrderPaidFulfillmentPorts.js +1 -0
  301. package/dist/commerce/server/outboxOrderRefundedEmailHandler.d.ts +13 -0
  302. package/dist/commerce/server/outboxOrderRefundedEmailHandler.js +42 -0
  303. package/dist/commerce/server/outboxPaymentFailedEmailHandler.d.ts +14 -0
  304. package/dist/commerce/server/outboxPaymentFailedEmailHandler.js +65 -0
  305. package/dist/commerce/server/outboxReturnEmailHandlers.d.ts +26 -0
  306. package/dist/commerce/server/outboxReturnEmailHandlers.js +53 -0
  307. package/dist/commerce/server/outboxShipmentDeliveredEmailHandler.d.ts +17 -0
  308. package/dist/commerce/server/outboxShipmentDeliveredEmailHandler.js +52 -0
  309. package/dist/commerce/server/outboxShipmentDispatchedEmailHandler.d.ts +13 -0
  310. package/dist/commerce/server/outboxShipmentDispatchedEmailHandler.js +87 -0
  311. package/dist/commerce/server/outboxShipmentExceptionEmailHandler.d.ts +13 -0
  312. package/dist/commerce/server/outboxShipmentExceptionEmailHandler.js +46 -0
  313. package/dist/commerce/server/referenceCheckoutHandler.d.ts +48 -0
  314. package/dist/commerce/server/referenceCheckoutHandler.js +68 -0
  315. package/dist/commerce/server/reservationSweepPort.d.ts +31 -0
  316. package/dist/commerce/server/reservationSweepPort.js +45 -0
  317. package/dist/commerce/server/starterTermsPort.d.ts +22 -0
  318. package/dist/commerce/server/starterTermsPort.js +1 -0
  319. package/dist/commerce/server/supabaseCommerceReturnsPort.d.ts +13 -0
  320. package/dist/commerce/server/supabaseCommerceReturnsPort.js +56 -0
  321. package/dist/communications/consentPurposeRegistry.d.ts +1 -1
  322. package/dist/communications/newsletterIntegrationContracts.d.ts +5 -5
  323. package/dist/composition/commerceContribution.d.ts +21 -0
  324. package/dist/composition/commerceContribution.js +27 -0
  325. package/dist/composition/index.d.ts +1 -0
  326. package/dist/composition/index.js +1 -0
  327. package/dist/fulfillment/handlerSchemas.d.ts +41 -41
  328. package/dist/fulfillment/index.d.ts +1 -1
  329. package/dist/fulfillment/index.js +1 -1
  330. package/dist/fulfillment/paidHandoff.d.ts +12 -1
  331. package/dist/fulfillment/paidHandoff.js +2 -2
  332. package/dist/fulfillment/providerDispatchWorker.d.ts +4 -4
  333. package/dist/identity/customerContracts.d.ts +2 -2
  334. package/dist/inventory/bindings.d.ts +3 -0
  335. package/dist/inventory/bindings.js +10 -4
  336. package/dist/inventory/index.d.ts +1 -0
  337. package/dist/inventory/index.js +1 -0
  338. package/dist/inventory/managedStockAvailability.d.ts +15 -0
  339. package/dist/inventory/managedStockAvailability.js +16 -0
  340. package/dist/inventory/postgresStockAvailability.js +2 -25
  341. package/dist/inventory/schemas.d.ts +1 -1
  342. package/dist/inventory/stockReadResponse.d.ts +4 -0
  343. package/dist/inventory/stockReadResponse.js +27 -0
  344. package/dist/pricing/browser/index.d.ts +6 -0
  345. package/dist/pricing/browser/index.js +6 -0
  346. package/dist/promotions/adminPromotionsContracts.d.ts +2 -2
  347. package/dist/subscriptions/contracts/renewal.d.ts +2 -0
  348. package/dist/subscriptions/index.d.ts +3 -2
  349. package/dist/subscriptions/index.js +3 -2
  350. package/dist/subscriptions/renewalCycleFailureMechanism.js +3 -2
  351. package/package.json +22 -2
  352. package/release-gates.json +63 -8
  353. package/src/commerce/adapters/managed/commerceOmsControlPlane.ts +80 -0
  354. package/src/commerce/adapters/managed/commerceOmsMutations.ts +145 -0
  355. package/src/commerce/adapters/managed/commerceOmsPort.ts +158 -0
  356. package/src/commerce/adapters/managed/oms/accounting.ts +18 -0
  357. package/src/commerce/adapters/managed/oms/fulfillmentReads.ts +82 -0
  358. package/src/commerce/adapters/managed/oms/inboundEvents.ts +45 -0
  359. package/src/commerce/adapters/managed/oms/outboxEvents.ts +30 -0
  360. package/src/commerce/adapters/managed/oms/paymentAttempts.ts +19 -0
  361. package/src/commerce/adapters/managed/oms/queueSelection.ts +132 -0
  362. package/src/commerce/adapters/managed/oms/readProjections.ts +22 -0
  363. package/src/commerce/adapters/managed/oms/readQueries.ts +292 -0
  364. package/src/commerce/adapters/managed/oms/types.ts +9 -0
  365. package/src/commerce/checkoutCommandSchemas.ts +93 -0
  366. package/src/commerce/checkoutHelpers.ts +47 -0
  367. package/src/commerce/checkoutResumeSchemas.ts +164 -0
  368. package/src/commerce/checkoutSchemas.ts +182 -0
  369. package/src/commerce/commerceReturnsPort.ts +67 -0
  370. package/src/commerce/configuratorIntentPersistenceSchemas.ts +26 -0
  371. package/src/commerce/configuratorIntentSchemas.ts +47 -0
  372. package/src/commerce/contractPrimitives.ts +30 -0
  373. package/src/commerce/contracts/availability.ts +21 -0
  374. package/src/commerce/contracts/fulfillmentRecovery.ts +26 -0
  375. package/src/commerce/contracts/index.ts +17 -0
  376. package/src/commerce/contracts/intent.ts +58 -0
  377. package/src/commerce/contracts/omsTypes.ts +1217 -0
  378. package/src/commerce/contracts/order.ts +44 -0
  379. package/src/commerce/contracts/orderMoney.ts +75 -0
  380. package/src/commerce/contracts/ports.ts +124 -0
  381. package/src/commerce/contracts/recovery.ts +24 -0
  382. package/src/commerce/contracts/runtimePorts.ts +201 -0
  383. package/src/commerce/contracts/state.ts +64 -0
  384. package/src/commerce/customerDefaultsSnapshotSchemas.ts +117 -0
  385. package/src/commerce/errors.ts +53 -0
  386. package/src/commerce/fulfillmentEligibility.ts +32 -0
  387. package/src/commerce/index.ts +82 -0
  388. package/src/commerce/model/customerFulfillmentRecovery.ts +185 -0
  389. package/src/commerce/model/fulfillmentCancellationEligibility.ts +18 -0
  390. package/src/commerce/model/omsAccountingVisibility.ts +135 -0
  391. package/src/commerce/model/omsBillingInvoiceBuyer.ts +20 -0
  392. package/src/commerce/model/omsCurrency.ts +8 -0
  393. package/src/commerce/model/omsFulfillmentDebug.ts +157 -0
  394. package/src/commerce/model/omsFulfillmentSummary.ts +225 -0
  395. package/src/commerce/model/omsListTotals.ts +38 -0
  396. package/src/commerce/model/omsOperationalLadder.ts +181 -0
  397. package/src/commerce/model/omsOrderLineMoney.ts +34 -0
  398. package/src/commerce/model/omsPaymentMethodSummary.ts +19 -0
  399. package/src/commerce/model/omsReadModel.ts +302 -0
  400. package/src/commerce/model/omsReadModelCommunication.ts +32 -0
  401. package/src/commerce/model/omsReadModelHelpers.ts +279 -0
  402. package/src/commerce/model/omsReadModelList.ts +90 -0
  403. package/src/commerce/model/omsReadModelListSummary.ts +19 -0
  404. package/src/commerce/model/omsReadModelPricing.ts +57 -0
  405. package/src/commerce/model/omsReadModelProjections.ts +1 -0
  406. package/src/commerce/model/omsReadModelRowCore.ts +193 -0
  407. package/src/commerce/model/omsReadModelRows.ts +7 -0
  408. package/src/commerce/offerAvailability.ts +75 -0
  409. package/src/commerce/offerAvailabilitySchemas.ts +56 -0
  410. package/src/commerce/offerEvidenceSchemas.ts +17 -0
  411. package/src/commerce/oms/omsContractBase.ts +92 -0
  412. package/src/commerce/oms/omsContractReadAuxSchemas.ts +130 -0
  413. package/src/commerce/oms/omsContractReadSchemas.ts +303 -0
  414. package/src/commerce/oms/omsContractRequests.ts +143 -0
  415. package/src/commerce/oms/omsContracts.ts +6 -0
  416. package/src/commerce/oms/omsControlPlane.ts +85 -0
  417. package/src/commerce/oms/omsFulfillmentContractSchemas.ts +113 -0
  418. package/src/commerce/oms/omsFulfillmentDebugSchemas.ts +38 -0
  419. package/src/commerce/oms/omsFulfillmentHealthSchemas.ts +46 -0
  420. package/src/commerce/oms/omsPorts.ts +165 -0
  421. package/src/commerce/oms/omsPrimitives.ts +3 -0
  422. package/src/commerce/oms/omsProviderEvidenceSchemas.ts +13 -0
  423. package/src/commerce/orderDraftErrors.ts +28 -0
  424. package/src/commerce/orderEmailEligibility.ts +131 -0
  425. package/src/commerce/orderEmailLines.ts +22 -0
  426. package/src/commerce/orderFeedbackContracts.ts +47 -0
  427. package/src/commerce/orderMoney.ts +207 -0
  428. package/src/commerce/orderReviewContracts.ts +124 -0
  429. package/src/commerce/orderReviewPorts.ts +94 -0
  430. package/src/commerce/outboxDispatchContracts.ts +30 -0
  431. package/src/commerce/outboxEventSchemas.ts +230 -0
  432. package/src/commerce/outboxOrderDraftEmailPorts.ts +241 -0
  433. package/src/commerce/paymentContinuation.ts +5 -0
  434. package/src/commerce/ports.ts +7 -0
  435. package/src/commerce/recoveryDestination.ts +23 -0
  436. package/src/commerce/runtimeErrors.ts +19 -0
  437. package/src/commerce/salesChannelEnvelope.ts +28 -0
  438. package/src/commerce/schemas.ts +104 -0
  439. package/src/commerce/server/checkoutCompensation.ts +49 -0
  440. package/src/commerce/server/checkoutConflictClassifiers.ts +53 -0
  441. package/src/commerce/server/checkoutExpiredRecoveryPolicy.ts +107 -0
  442. package/src/commerce/server/checkoutInvoiceBuyerSnapshot.ts +36 -0
  443. package/src/commerce/server/checkoutOfferPolicyPort.ts +60 -0
  444. package/src/commerce/server/checkoutPaymentContinuationCredential.ts +222 -0
  445. package/src/commerce/server/checkoutQuoteTypes.ts +9 -0
  446. package/src/commerce/server/checkoutRecoveryOrderPort.ts +40 -0
  447. package/src/commerce/server/checkoutRecoveryToken.ts +63 -0
  448. package/src/commerce/server/checkoutRefusalContinuation.ts +29 -0
  449. package/src/commerce/server/checkoutRuntimeTypes.ts +26 -0
  450. package/src/commerce/server/commerceCheckoutCommandExecution.ts +188 -0
  451. package/src/commerce/server/commerceCheckoutCompensation.ts +66 -0
  452. package/src/commerce/server/commerceCheckoutContinuationTerms.ts +87 -0
  453. package/src/commerce/server/commerceCheckoutCustomerDefaults.ts +24 -0
  454. package/src/commerce/server/commerceCheckoutFailureHandler.ts +144 -0
  455. package/src/commerce/server/commerceCheckoutHandler.ts +269 -0
  456. package/src/commerce/server/commerceCheckoutHandlerAdmission.ts +157 -0
  457. package/src/commerce/server/commerceCheckoutHandlerHelpers.ts +223 -0
  458. package/src/commerce/server/commerceCheckoutOrchestrationError.ts +15 -0
  459. package/src/commerce/server/commerceCheckoutPromotionPriceChange.ts +83 -0
  460. package/src/commerce/server/commerceCheckoutProviderPayment.ts +45 -0
  461. package/src/commerce/server/commerceCheckoutQuoteGuard.ts +172 -0
  462. package/src/commerce/server/commerceCheckoutResume.ts +132 -0
  463. package/src/commerce/server/commerceCheckoutResumeGuard.ts +195 -0
  464. package/src/commerce/server/commerceCheckoutSavedPaymentMethod.ts +85 -0
  465. package/src/commerce/server/commerceCheckoutStartRuntimeFailure.ts +59 -0
  466. package/src/commerce/server/commerceCheckoutTiming.ts +53 -0
  467. package/src/commerce/server/commerceDiagnostics.ts +37 -0
  468. package/src/commerce/server/commerceOmsCancelOrderHandler.ts +43 -0
  469. package/src/commerce/server/commerceOmsControlPlaneHandlers.ts +71 -0
  470. package/src/commerce/server/commerceOmsHandlers.ts +275 -0
  471. package/src/commerce/server/commerceOmsMarkRefundedHandler.ts +39 -0
  472. package/src/commerce/server/commerceOrderDraft.ts +131 -0
  473. package/src/commerce/server/commercePaidOrderOrchestration.ts +275 -0
  474. package/src/commerce/server/commerceProviderAttemptFailure.ts +257 -0
  475. package/src/commerce/server/commerceReturnsHandlers.ts +143 -0
  476. package/src/commerce/server/commerceRuntimePort.ts +75 -0
  477. package/src/commerce/server/commerceRuntimeService.ts +229 -0
  478. package/src/commerce/server/commerceRuntimeStartResponse.ts +76 -0
  479. package/src/commerce/server/commerceStarterOfferGuard.ts +200 -0
  480. package/src/commerce/server/configuratorIntentPersistence.ts +161 -0
  481. package/src/commerce/server/configuratorIntentPersistenceHandler.ts +54 -0
  482. package/src/commerce/server/emailRuntime.ts +30 -0
  483. package/src/commerce/server/handlerSupport.ts +22 -0
  484. package/src/commerce/server/index.ts +181 -0
  485. package/src/commerce/server/offerAvailability.ts +275 -0
  486. package/src/commerce/server/orderDraftRpcPayload.ts +39 -0
  487. package/src/commerce/server/orderFeedbackSubmit.ts +40 -0
  488. package/src/commerce/server/orderFeedbackTokenCheck.ts +28 -0
  489. package/src/commerce/server/orderReviewAdminHandlers.ts +43 -0
  490. package/src/commerce/server/orderReviewHandlers.ts +57 -0
  491. package/src/commerce/server/orderReviewLifecycle.ts +129 -0
  492. package/src/commerce/server/orderReviewMedia.ts +170 -0
  493. package/src/commerce/server/orderReviewRawUploadHandler.ts +300 -0
  494. package/src/commerce/server/outboxCheckoutExpiredEmailHandler.ts +86 -0
  495. package/src/commerce/server/outboxCheckoutRecoveryEmailHandler.ts +188 -0
  496. package/src/commerce/server/outboxDispatchRegistry.ts +269 -0
  497. package/src/commerce/server/outboxDispatchRegistryComposition.ts +31 -0
  498. package/src/commerce/server/outboxOrderDraftEmailHandler.ts +162 -0
  499. package/src/commerce/server/outboxOrderPaidEmailHandler.ts +147 -0
  500. package/src/commerce/server/outboxOrderPaidFulfillmentHandler.ts +4 -0
  501. package/src/commerce/server/outboxOrderPaidFulfillmentPorts.ts +3 -0
  502. package/src/commerce/server/outboxOrderRefundedEmailHandler.ts +58 -0
  503. package/src/commerce/server/outboxPaymentFailedEmailHandler.ts +99 -0
  504. package/src/commerce/server/outboxReturnEmailHandlers.ts +92 -0
  505. package/src/commerce/server/outboxShipmentDeliveredEmailHandler.ts +94 -0
  506. package/src/commerce/server/outboxShipmentDispatchedEmailHandler.ts +112 -0
  507. package/src/commerce/server/outboxShipmentExceptionEmailHandler.ts +73 -0
  508. package/src/commerce/server/referenceCheckoutHandler.ts +87 -0
  509. package/src/commerce/server/reservationSweepPort.ts +67 -0
  510. package/src/commerce/server/starterTermsPort.ts +22 -0
  511. package/src/commerce/server/supabaseCommerceReturnsPort.ts +81 -0
  512. package/src/composition/commerceContribution.ts +35 -0
  513. package/src/composition/index.ts +1 -0
  514. package/src/fulfillment/index.ts +1 -1
  515. package/src/fulfillment/paidHandoff.ts +2 -2
  516. package/src/inventory/bindings.ts +12 -4
  517. package/src/inventory/index.ts +1 -0
  518. package/src/inventory/managedStockAvailability.ts +23 -0
  519. package/src/inventory/postgresStockAvailability.ts +2 -21
  520. package/src/inventory/stockReadResponse.ts +25 -0
  521. package/src/pricing/browser/index.ts +6 -0
  522. package/src/subscriptions/contracts/renewal.ts +2 -1
  523. package/src/subscriptions/index.ts +3 -2
  524. package/src/subscriptions/renewalCycleFailureMechanism.ts +3 -1
@@ -0,0 +1,186 @@
1
+ import { CommerceRuntimeConflictError } from "../runtimeErrors.js";
2
+ export function createCommerceRuntimeService(bindings) {
3
+ function createService({ orderPort, inventoryPort, paymentPort, readinessPort, executionPort = bindings.defaultExecutionPort, resolveExecutionPort, }) {
4
+ const pickExecutionPort = (providerKind) => resolveExecutionPort ? resolveExecutionPort(providerKind) : executionPort;
5
+ const startRuntime = async (request, resolvedExecutionPort) => {
6
+ const paymentProvider = request.paymentProvider ?? bindings.defaultPaymentProvider;
7
+ const providerFlow = request.providerFlow ?? bindings.defaultProviderFlow;
8
+ const executionPortForRequest = resolvedExecutionPort ?? pickExecutionPort(paymentProvider);
9
+ const order = await orderPort.finalizeOrderForCheckout(request);
10
+ const reservations = await inventoryPort.reserveOrderItems({
11
+ idempotencyKey: `${request.idempotencyKey}:inventory`,
12
+ order,
13
+ paymentStatus: "created",
14
+ metadata: request.metadata,
15
+ });
16
+ const targetKind = order.mode === "subscription_cycle" ? "subscription_cycle" : "one_time_order";
17
+ const intent = await paymentPort.createIntent({
18
+ idempotencyKey: `${request.idempotencyKey}:payment-intent`,
19
+ targetKind,
20
+ orderId: order.orderId,
21
+ subscriptionId: order.subscriptionId,
22
+ subscriptionCycleId: order.subscriptionCycleId,
23
+ amountMinor: order.total.amountMinor,
24
+ currency: order.total.currency,
25
+ metadata: {
26
+ ...request.metadata,
27
+ source: "commerce.runtime.hidden.v0",
28
+ runtimeIdempotencyKey: request.idempotencyKey,
29
+ ...bindings.paymentMetadataExtension(order),
30
+ },
31
+ });
32
+ // Attempt-scoped, not journey-scoped: a retry after a terminal decline —
33
+ // and above all a switch to another provider — needs a fresh provider
34
+ // attempt identity on the SAME order. Sequence 0 keeps the historic key
35
+ // byte-identical.
36
+ const attemptSequence = request.paymentAttemptSequence ?? 0;
37
+ const paymentExecutionIdempotencyKey = attemptSequence > 0
38
+ ? `${request.idempotencyKey}:payment-execution:attempt:${attemptSequence}`
39
+ : `${request.idempotencyKey}:payment-execution`;
40
+ const providerAttemptIdentity = bindings.buildProviderAttemptIdentity({
41
+ provider: paymentProvider,
42
+ localExecutionIdempotencyKey: paymentExecutionIdempotencyKey,
43
+ paymentIntentId: intent.paymentIntentId,
44
+ amountMinor: order.total.amountMinor,
45
+ currency: order.total.currency,
46
+ mode: order.mode,
47
+ orderRef: order.orderRef,
48
+ });
49
+ const executionInput = {
50
+ idempotencyKey: paymentExecutionIdempotencyKey,
51
+ providerIdempotencyKey: providerAttemptIdentity.providerIdempotencyKey,
52
+ providerRequestFingerprint: providerAttemptIdentity.providerRequestFingerprint,
53
+ paymentIntentId: intent.paymentIntentId,
54
+ amountMinor: order.total.amountMinor,
55
+ currency: order.total.currency,
56
+ mode: order.mode,
57
+ orderRef: order.orderRef,
58
+ providerFlow,
59
+ clientId: order.clientId,
60
+ ...bindings.executionSubject(order),
61
+ orderId: order.orderId,
62
+ paymentMethodRef: request.paymentMethodRef,
63
+ paymentMethodAliasType: request.paymentMethodAliasType,
64
+ paymentMethodRecurringModel: request.paymentMethodRecurringModel,
65
+ payer: request.providerPayer,
66
+ // The host execution adapter owns reusable-method policy.
67
+ saveForFutureUse: request.saveForFutureUse,
68
+ returnContext: request.returnContext,
69
+ transientProviderInput: bindings.transientProviderInput(request.paymentExecution),
70
+ };
71
+ if (bindings.requiresPreparedProviderAttempt(paymentProvider)) {
72
+ const preparedPaymentPort = bindings.preparedProviderAttemptPort(paymentPort, paymentProvider);
73
+ const preparedExecution = await bindings.executePreparedProviderAttempt({
74
+ paymentPort: preparedPaymentPort,
75
+ executionPort: executionPortForRequest,
76
+ provider: paymentProvider,
77
+ paymentIntentId: intent.paymentIntentId,
78
+ executionInput,
79
+ prepareIdempotencyKey: `${paymentExecutionIdempotencyKey}:prepare-attempt`,
80
+ finalizeIdempotencyKey: `${paymentExecutionIdempotencyKey}:finalize-attempt`,
81
+ providerIdempotencyKey: providerAttemptIdentity.providerIdempotencyKey,
82
+ providerRequestFingerprint: providerAttemptIdentity.providerRequestFingerprint,
83
+ providerFlow,
84
+ paymentMethodRef: request.paymentMethodRef ?? null,
85
+ prepareRequestPayload: {
86
+ source: "commerce.runtime.provider-attempt.prepare.v0",
87
+ providerIdempotencyKey: providerAttemptIdentity.providerIdempotencyKey,
88
+ providerRequestFingerprint: providerAttemptIdentity.providerRequestFingerprint,
89
+ providerFlow,
90
+ paymentMethodRef: request.paymentMethodRef ?? null,
91
+ recurringModel: bindings.preparedRecurringModel(request),
92
+ // Audit only: recorded so a refusal can be attributed to an issuer
93
+ // later. It is not part of the execution object, so it cannot reach
94
+ // the provider request built below.
95
+ declaredBankId: request.declaredBankId ?? null,
96
+ amountMinor: order.total.amountMinor,
97
+ currency: order.total.currency,
98
+ orderRef: order.orderRef,
99
+ runtimeIdempotencyKey: request.idempotencyKey,
100
+ },
101
+ }).catch((error) => {
102
+ if (!(bindings.isPreDispatch(error)))
103
+ throw error;
104
+ return bindings.reopenExhaustedPreDispatchAttempt({
105
+ error, paymentPort, paymentExecutionIdempotencyKey,
106
+ order, reservations, intent, provider: paymentProvider,
107
+ });
108
+ });
109
+ if ("runtime" in preparedExecution)
110
+ return preparedExecution;
111
+ return bindings.preserveProviderDispatchUncertainty(() => bindings.buildStartedRuntimeResponse({
112
+ paymentExecutionIdempotencyKey,
113
+ order,
114
+ reservations,
115
+ intent,
116
+ execution: preparedExecution.execution,
117
+ attempt: preparedExecution.attempt,
118
+ continuationActionOrigin: "fresh_execution",
119
+ paymentPort,
120
+ readinessPort,
121
+ }), preparedExecution.attempt.paymentAttemptId);
122
+ }
123
+ const execution = await executionPortForRequest.execute(executionInput);
124
+ const attempt = await bindings.recordPaymentAttempt(paymentPort, {
125
+ idempotencyKey: `${request.idempotencyKey}:payment-attempt`,
126
+ paymentIntentId: intent.paymentIntentId,
127
+ execution,
128
+ });
129
+ return bindings.buildStartedRuntimeResponse({
130
+ paymentExecutionIdempotencyKey,
131
+ order,
132
+ reservations,
133
+ intent,
134
+ execution,
135
+ attempt,
136
+ continuationActionOrigin: null,
137
+ paymentPort,
138
+ readinessPort,
139
+ });
140
+ };
141
+ const applyPaymentResult = async (request) => {
142
+ const paymentResult = await paymentPort.applyResult(request);
143
+ if (paymentResult.orderId !== request.orderId) {
144
+ throw new CommerceRuntimeConflictError("Payment result order mismatch", {
145
+ requestOrderId: request.orderId,
146
+ paymentResultOrderId: paymentResult.orderId,
147
+ paymentIntentId: request.paymentIntentId,
148
+ });
149
+ }
150
+ // Interactive PSP declines remain payable on the same order/payment
151
+ // intent. Releasing their stock here creates a paid-without-reservation
152
+ // path on the next recovery attempt. Expiry and genuinely terminal
153
+ // failures still release through this single boundary.
154
+ const shouldRelease = request.resultStatus === "expired" ||
155
+ (request.resultStatus === "failed" && paymentResult.kind !== "recoverable_decline");
156
+ const reservationRelease = shouldRelease
157
+ ? {
158
+ attempted: true,
159
+ ...(await inventoryPort.releaseOrderReservations({
160
+ idempotencyKey: `${request.idempotencyKey}:inventory-release`,
161
+ orderId: request.orderId,
162
+ reason: `payment_${request.resultStatus}`,
163
+ })),
164
+ }
165
+ : { attempted: false, releasedCount: 0 };
166
+ const readiness = shouldRelease
167
+ ? null
168
+ : await readinessPort.evaluateOrderReadiness({
169
+ orderId: request.orderId,
170
+ fallbackOrderItemCount: null,
171
+ allOrderItemsHaveSku: true,
172
+ });
173
+ return bindings.resultResponseSchema.parse({
174
+ contractVersion: bindings.contractVersion,
175
+ paymentResult,
176
+ reservationRelease,
177
+ readiness,
178
+ });
179
+ };
180
+ return {
181
+ startRuntime,
182
+ applyPaymentResult,
183
+ };
184
+ }
185
+ return createService;
186
+ }
@@ -0,0 +1,37 @@
1
+ import type { z } from "zod";
2
+ import type { FinalizedCheckoutOrder, CommerceRuntimeReadinessPort } from "../contracts/index.js";
3
+ import type { CheckoutRuntimeExecutionResult } from "./checkoutRuntimeTypes.js";
4
+ export declare function createRuntimeStartResponse<Order extends FinalizedCheckoutOrder<string>, Reservation, PaymentPort, Execution extends CheckoutRuntimeExecutionResult, Readiness, Response>(bindings: {
5
+ contractVersion: string;
6
+ responseSchema: z.ZodType<Response>;
7
+ runtimeResponseExtension(order: Order): object;
8
+ finalizeDeclinedAttempt(port: PaymentPort, input: {
9
+ idempotencyKey: string;
10
+ orderId: string;
11
+ paymentIntentId: string;
12
+ fallbackAttemptId: string;
13
+ decline: NonNullable<Execution["providerDecline"]>;
14
+ }): Promise<{
15
+ paymentAttemptId: string;
16
+ status: string;
17
+ }>;
18
+ }): {
19
+ buildStartedRuntimeResponse: (input: {
20
+ paymentExecutionIdempotencyKey: string;
21
+ order: Order;
22
+ reservations: Reservation[];
23
+ intent: {
24
+ paymentIntentId: string;
25
+ paymentId: string;
26
+ status: string;
27
+ };
28
+ execution: Execution;
29
+ attempt: {
30
+ paymentAttemptId: string;
31
+ status: string;
32
+ };
33
+ continuationActionOrigin: "fresh_execution" | null;
34
+ paymentPort: PaymentPort;
35
+ readinessPort: CommerceRuntimeReadinessPort<Readiness>;
36
+ }) => Promise<Response>;
37
+ };
@@ -0,0 +1,56 @@
1
+ export function createRuntimeStartResponse(bindings) {
2
+ async function buildStartedRuntimeResponse(input) {
3
+ let attempt = input.attempt;
4
+ if (input.execution.providerDecline) {
5
+ attempt = await bindings.finalizeDeclinedAttempt(input.paymentPort, {
6
+ idempotencyKey: `${input.paymentExecutionIdempotencyKey}:payment-declined`,
7
+ orderId: input.order.orderId,
8
+ paymentIntentId: input.intent.paymentIntentId,
9
+ fallbackAttemptId: attempt.paymentAttemptId,
10
+ decline: input.execution.providerDecline,
11
+ });
12
+ }
13
+ const readiness = await input.readinessPort.evaluateOrderReadiness({
14
+ orderId: input.order.orderId,
15
+ fallbackOrderItemCount: input.order.items.length,
16
+ allOrderItemsHaveSku: true,
17
+ });
18
+ return bindings.responseSchema.parse({
19
+ contractVersion: bindings.contractVersion,
20
+ runtime: {
21
+ orderId: input.order.orderId,
22
+ orderRef: input.order.orderRef,
23
+ mode: input.order.mode,
24
+ clientId: input.order.clientId,
25
+ ...bindings.runtimeResponseExtension(input.order),
26
+ shippingAddressId: input.order.shippingAddressId,
27
+ total: input.order.total,
28
+ finalizedReplayed: input.order.replayed,
29
+ reservations: input.reservations,
30
+ payment: {
31
+ paymentIntentId: input.intent.paymentIntentId,
32
+ paymentId: input.intent.paymentId,
33
+ paymentAttemptId: attempt.paymentAttemptId,
34
+ // finalizeDeclinedAttempt above already applied the canonical failed
35
+ // result to the durable intent/payment/attempt. Reflect that result
36
+ // instead of returning the stale pre-execution "created" snapshot.
37
+ status: input.execution.providerDecline ? "failed" : input.intent.status,
38
+ ...(input.execution.providerDecline?.mandateUnsupported ? { declineMandateUnsupported: true } : {}),
39
+ attemptStatus: attempt.status,
40
+ provider: input.execution.provider,
41
+ providerAttemptId: input.execution.providerAttemptId,
42
+ providerClientSecret: input.execution.clientSecret ?? null,
43
+ providerRedirectUrl: input.execution.redirectUrl ?? null,
44
+ providerNextActionKind: input.execution.nextActionKind ?? null,
45
+ continuationActionOrigin: input.continuationActionOrigin,
46
+ },
47
+ readiness,
48
+ nextAction: {
49
+ kind: "await_hidden_payment_result",
50
+ provider: input.execution.provider,
51
+ },
52
+ },
53
+ });
54
+ }
55
+ return { buildStartedRuntimeResponse };
56
+ }
@@ -0,0 +1,55 @@
1
+ import type { z } from "zod";
2
+ import type { ConfiguratorIntent } from "../contracts/index.js";
3
+ import type { CommerceQuotePort } from "../ports.js";
4
+ import type { StarterTermsPort } from "./starterTermsPort.js";
5
+ import type { CheckoutQuoteSnapshot } from "./checkoutQuoteTypes.js";
6
+ export interface StarterDeclaration {
7
+ intervalDays: number;
8
+ delivery2DiscountBps: number;
9
+ acquisitionTerms?: {
10
+ revision: string;
11
+ delivery2DiscountBps: number;
12
+ };
13
+ steady: {
14
+ cadenceDays: number;
15
+ units: number;
16
+ };
17
+ }
18
+ export type StarterOfferGuardResult<Plan> = {
19
+ kind: "absent";
20
+ } | {
21
+ kind: "rejected";
22
+ reason: string;
23
+ } | {
24
+ kind: "minted";
25
+ plan: Plan;
26
+ };
27
+ export declare function withStarterPackContext<Snapshot extends CheckoutQuoteSnapshot, Plan>(snapshot: Snapshot, plan: Plan | null): Snapshot;
28
+ export declare function createStarterOfferGuard<Intent extends ConfiguratorIntent, Provisioned extends {
29
+ clientId: string | null;
30
+ }, Request, Snapshot extends CheckoutQuoteSnapshot, Plan>(bindings: {
31
+ declaration(intent: Intent): StarterDeclaration | undefined;
32
+ defaultTermsPort: StarterTermsPort<Intent, Snapshot>;
33
+ defaultDiscountBps: number;
34
+ discountMinor(input: {
35
+ bandSubtotalMinor: number;
36
+ listAnchorTotalMinor: number;
37
+ discountBps: number;
38
+ }): number | null;
39
+ planSchema: z.ZodType<Plan>;
40
+ aggregateBySku(entries: Intent["selectedVariants"]): Intent["selectedVariants"];
41
+ rescaleBasket(entries: Intent["selectedVariants"], units: number): Intent["selectedVariants"];
42
+ steadyIntent(intent: Intent, cadenceDays: number, units: number, variants: Intent["selectedVariants"]): Intent;
43
+ buildQuoteRequest(intent: Intent, provisioned: Provisioned): Request;
44
+ }): {
45
+ resolveStarterOfferGuard: (input: {
46
+ flagEnabled: boolean;
47
+ intent: Intent;
48
+ provisioned: Provisioned;
49
+ authoritativeQuote: Snapshot;
50
+ quotePort: CommerceQuotePort<Request, Snapshot, import("../../pricing/index.js").CreateQuoteOptions>;
51
+ isFirstOrderEligible?: () => Promise<boolean>;
52
+ termsPort?: StarterTermsPort<Intent, Snapshot>;
53
+ offerVersion?: string;
54
+ }) => Promise<StarterOfferGuardResult<Plan>>;
55
+ };
@@ -0,0 +1,128 @@
1
+ export function withStarterPackContext(snapshot, plan) {
2
+ if (!plan || !snapshot.quote.context)
3
+ return snapshot;
4
+ return { ...snapshot, quote: { ...snapshot.quote, context: { ...snapshot.quote.context, starterPack: plan } } };
5
+ }
6
+ export function createStarterOfferGuard(bindings) {
7
+ const TERMS_REFUSALS = {
8
+ basket_too_small: "starter_offer_basket_too_small",
9
+ basket_not_admitted: "starter_offer_basket_not_admitted",
10
+ demand_unknown: "starter_offer_demand_unknown",
11
+ };
12
+ const ACQUISITION_TEMPLATE_VERSION = 1;
13
+ async function resolveStarterOfferGuard(input) {
14
+ const declared = bindings.declaration(input.intent);
15
+ // Flag OFF and nothing declared is the overwhelmingly common case and must do
16
+ // exactly zero work — no quote, no read, no allocation.
17
+ if (!declared)
18
+ return { kind: "absent" };
19
+ if (!input.flagEnabled)
20
+ return { kind: "rejected", reason: "starter_offer_disabled" };
21
+ if (input.intent.mode !== "subscription") {
22
+ return { kind: "rejected", reason: "starter_offer_wrong_mode" };
23
+ }
24
+ // The terms of the effective basket, from the server's own quote. The default
25
+ // port is the arithmetic the client asks with (see `defaultStarterTermsPort`),
26
+ // so any disagreement below is a drifted ask, never a rounding difference.
27
+ const resolution = await (input.termsPort ?? bindings.defaultTermsPort).resolve({
28
+ intent: input.intent,
29
+ authoritativeQuote: input.authoritativeQuote,
30
+ ...(input.offerVersion ? { offerVersion: input.offerVersion } : {}),
31
+ });
32
+ if (resolution.kind === "refused") {
33
+ return { kind: "rejected", reason: TERMS_REFUSALS[resolution.reason] };
34
+ }
35
+ const { intervalDays, steadyCadenceDays: cadenceDays, steadyUnits: steadyUnits, graduationSizeConstraint, } = resolution.terms;
36
+ const acquisition = input.authoritativeQuote.quote.context?.acquisitionTerms;
37
+ const delivery2DiscountBps = acquisition?.delivery2DiscountBps ?? bindings.defaultDiscountBps;
38
+ if ((acquisition !== undefined && (declared.acquisitionTerms?.revision !== acquisition.revision ||
39
+ declared.acquisitionTerms.delivery2DiscountBps !== delivery2DiscountBps)) ||
40
+ declared.intervalDays !== intervalDays ||
41
+ declared.delivery2DiscountBps !== delivery2DiscountBps ||
42
+ declared.steady.cadenceDays !== cadenceDays ||
43
+ declared.steady.units !== steadyUnits) {
44
+ return { kind: "rejected", reason: "starter_offer_terms_drifted" };
45
+ }
46
+ if (!(await input.isFirstOrderEligible?.())) {
47
+ return { kind: "rejected", reason: "starter_offer_not_first_order" };
48
+ }
49
+ const bandSubtotalMinor = input.authoritativeQuote.quote.subtotalGross.amountMinor;
50
+ const discountMinor = bindings.discountMinor({
51
+ bandSubtotalMinor,
52
+ listAnchorTotalMinor: listAnchorTotalMinor(input.authoritativeQuote),
53
+ discountBps: delivery2DiscountBps,
54
+ });
55
+ if (discountMinor === null) {
56
+ return { kind: "rejected", reason: "starter_offer_uncollectable_delivery_2" };
57
+ }
58
+ const steadyQuote = await quoteSteadyPackage(input, steadyUnits, cadenceDays);
59
+ if (steadyQuote === null) {
60
+ return { kind: "rejected", reason: "starter_offer_steady_quote_failed" };
61
+ }
62
+ const parsed = bindings.planSchema.safeParse({
63
+ schemaVersion: "1",
64
+ starterIntervalDays: intervalDays,
65
+ basisTemplateVersion: ACQUISITION_TEMPLATE_VERSION,
66
+ delivery2: {
67
+ discountBps: delivery2DiscountBps,
68
+ discountMinor,
69
+ basisSubtotalMinor: bandSubtotalMinor,
70
+ },
71
+ graduation: {
72
+ cadenceDays,
73
+ sizeConstraint: graduationSizeConstraint ?? { kind: "unit_count", value: steadyUnits },
74
+ lines: steadyQuote.quote.lines.map((line, index) => ({
75
+ sku: line.sku,
76
+ qty: line.quantity,
77
+ sortOrder: index,
78
+ // Addons are never part of a graduation basket; the RPC deletes only
79
+ // non-addon template lines, so an existing addon survives untouched.
80
+ isAddon: false,
81
+ quoteLine: frozenQuoteLine(line),
82
+ })),
83
+ },
84
+ });
85
+ if (!parsed.success)
86
+ return { kind: "rejected", reason: "starter_offer_plan_invalid" };
87
+ return { kind: "minted", plan: parsed.data };
88
+ }
89
+ function listAnchorTotalMinor(snapshot) {
90
+ const orderScoped = sumBaseUnit(snapshot.quote.pricingComponents);
91
+ if (orderScoped > 0)
92
+ return orderScoped;
93
+ return snapshot.quote.lines.reduce((total, line) => total + sumBaseUnit(line.pricingComponents), 0);
94
+ }
95
+ function sumBaseUnit(components) {
96
+ if (!components)
97
+ return 0;
98
+ return components
99
+ .filter((component) => component.componentType === "base_unit")
100
+ .reduce((total, component) => total + component.amountMinor, 0);
101
+ }
102
+ function frozenQuoteLine(line) {
103
+ const { pricingComponents: _dropped, ...rest } = line;
104
+ return { ...rest };
105
+ }
106
+ async function quoteSteadyPackage(input, steadyUnits, cadenceDays) {
107
+ const steadyVariants = bindings.rescaleBasket(bindings.aggregateBySku(input.intent.selectedVariants), steadyUnits);
108
+ // Fail closed on an unrepresentable basket (more distinct variants than units).
109
+ // Quoting it would mint a marker whose lines contradict the size it promises.
110
+ if (steadyVariants.reduce((total, v) => total + v.qty, 0) !== steadyUnits)
111
+ return null;
112
+ const steadyIntent = bindings.steadyIntent(input.intent, cadenceDays, steadyUnits, steadyVariants);
113
+ try {
114
+ // A bound offer prices its steady basket from its own list, like the checkout quote.
115
+ const quoted = await input.quotePort.createQuote(bindings.buildQuoteRequest(steadyIntent, input.provisioned), {
116
+ ...(input.provisioned.clientId ? { clientId: input.provisioned.clientId } : {}),
117
+ ...(input.offerVersion ? { offerVersion: input.offerVersion } : {}),
118
+ ...(input.authoritativeQuote.quote.context?.pricingPolicy
119
+ ? { pricingPolicy: input.authoritativeQuote.quote.context.pricingPolicy } : {}),
120
+ });
121
+ return quoted.quote.lines.length > 0 ? quoted : null;
122
+ }
123
+ catch {
124
+ return null;
125
+ }
126
+ }
127
+ return { resolveStarterOfferGuard };
128
+ }
@@ -0,0 +1,47 @@
1
+ import type { z } from "zod";
2
+ import type { ConfiguratorIntentPersistencePort } from "../contracts/ports.js";
3
+ import type { CheckoutCommandPersistencePort } from "../contracts/runtimePorts.js";
4
+ import type { RpcError } from "../contracts/omsTypes.js";
5
+ interface ConfiguratorIntentIdentityQueryResult {
6
+ data: Array<{
7
+ response_payload?: unknown;
8
+ }> | null;
9
+ error: RpcError | null;
10
+ }
11
+ interface ConfiguratorIntentIdentityQuery {
12
+ eq(column: string, value: unknown): ConfiguratorIntentIdentityQuery;
13
+ limit(count: number): PromiseLike<ConfiguratorIntentIdentityQueryResult>;
14
+ }
15
+ interface ConfiguratorIntentIdentityTable {
16
+ select(columns: string): ConfiguratorIntentIdentityQuery;
17
+ }
18
+ /**
19
+ * The identity the ROUTE proved for this request, and the only identity the RPC
20
+ * is allowed to believe.
21
+ *
22
+ * ⛔ It is not read from the request body and never can be: `withVerifiedSubject`
23
+ * writes it last and unconditionally, so a payload that carries the key has it
24
+ * overwritten rather than honoured. A guest is `null`, which is a positive claim
25
+ * that nobody proved anything - not an absence the RPC may fill in.
26
+ */
27
+ export interface ConfiguratorIntentPersistenceIdentity {
28
+ authenticatedUserId: string | null;
29
+ }
30
+ type PersistIntentPayload<Request, Command> = (Request | Command) & {
31
+ authenticatedUserId: string | null;
32
+ };
33
+ export interface ConfiguratorIntentRpcQueryClient<Request, Command> {
34
+ rpc(functionName: "commerce_configurator_persist_intent", args: {
35
+ p_intent: PersistIntentPayload<Request, Command>;
36
+ }): PromiseLike<{
37
+ data: unknown;
38
+ error: RpcError | null;
39
+ }>;
40
+ from(tableName: "commerce_idempotency_keys"): ConfiguratorIntentIdentityTable;
41
+ }
42
+ export declare function createConfiguratorIntentPersistenceRpcPort<Request extends object, Response, Command extends object, Persistence>(client: ConfiguratorIntentRpcQueryClient<Request, Command>, bindings: {
43
+ responseSchema: z.ZodType<Response>;
44
+ decodeCommandResponse(data: unknown): Persistence;
45
+ normalizePhoneToE164(phone: string, country: unknown): string | null;
46
+ }, identity?: ConfiguratorIntentPersistenceIdentity): ConfiguratorIntentPersistencePort<Request, Response> & CheckoutCommandPersistencePort<Command, Persistence>;
47
+ export {};
@@ -0,0 +1,85 @@
1
+ import { ConfiguratorIntentPersistenceConflictError } from "./configuratorIntentPersistenceHandler.js";
2
+ /** Scope used by the persist-intent RPC for its idempotency-key rows. */
3
+ const CONFIGURATOR_INTENT_SCOPE = "commerce_configurator_intent";
4
+ export function createConfiguratorIntentPersistenceRpcPort(client, bindings, identity = { authenticatedUserId: null }) {
5
+ return {
6
+ async persistIntent(request) {
7
+ const { data, error } = await client.rpc("commerce_configurator_persist_intent", {
8
+ p_intent: withVerifiedSubject(withCanonicalIntentPhone(request), identity),
9
+ });
10
+ if (error)
11
+ throw mapRpcError(error);
12
+ return bindings.responseSchema.parse(data);
13
+ },
14
+ async persistCheckoutCommand(command) {
15
+ const { data, error } = await client.rpc("commerce_configurator_persist_intent", {
16
+ p_intent: withVerifiedSubject(withCanonicalCommandPhone(command), identity),
17
+ });
18
+ if (error)
19
+ throw mapRpcError(error);
20
+ return bindings.decodeCommandResponse(data);
21
+ },
22
+ async findCompletedIdentity(idempotencyKey) {
23
+ // Read back the identity the RPC stored on the COMPLETED key. The RPC writes
24
+ // the full response object into `response_payload`, so it validates against
25
+ // the same schema persistIntent returns. A different/missing row -> null,
26
+ // which the caller treats as "cannot resume -> 409".
27
+ const { data, error } = await client
28
+ .from("commerce_idempotency_keys")
29
+ .select("response_payload")
30
+ .eq("scope", CONFIGURATOR_INTENT_SCOPE)
31
+ .eq("idempotency_key", idempotencyKey)
32
+ .eq("status", "completed")
33
+ .limit(1);
34
+ if (error) {
35
+ throw new Error(`Configurator intent identity lookup failed: ${error.message ?? "query failed"}`);
36
+ }
37
+ const payload = data?.[0]?.response_payload;
38
+ if (!payload)
39
+ return null;
40
+ const parsed = bindings.responseSchema.safeParse(payload);
41
+ return parsed.success ? parsed.data : null;
42
+ },
43
+ };
44
+ // Canonicalization is fail-open: an unparseable non-empty phone is preserved verbatim.
45
+ function canonicalPhoneRewrite(contact, address) {
46
+ const phone = contact?.phone;
47
+ if (typeof phone !== "string" || phone.trim() === "")
48
+ return null;
49
+ const country = address?.country;
50
+ const canonical = bindings.normalizePhoneToE164(phone, country) ?? phone;
51
+ return canonical === phone ? null : canonical;
52
+ }
53
+ /**
54
+ * Stamp the route-verified subject onto the payload, LAST.
55
+ *
56
+ * The RPC resolves its client row by e-mail, and an e-mail typed into an
57
+ * anonymous request is a client-supplied object identifier - knowing one is not
58
+ * authorization to edit the record it names. This is the single line that decides
59
+ * whose identity the database is allowed to write, so it overwrites rather than
60
+ * defaults: a caller who puts `authenticatedUserId` in the body gets it replaced.
61
+ */
62
+ function withVerifiedSubject(payload, identity) {
63
+ return { ...payload, authenticatedUserId: identity.authenticatedUserId };
64
+ }
65
+ function withCanonicalIntentPhone(request) {
66
+ const phone = canonicalPhoneRewrite(request.contact, request.address);
67
+ if (phone === null)
68
+ return request;
69
+ return { ...request, contact: { ...request.contact, phone } };
70
+ }
71
+ function withCanonicalCommandPhone(command) {
72
+ const phone = canonicalPhoneRewrite(command.customer, command.shippingAddress);
73
+ if (phone === null)
74
+ return command;
75
+ return { ...command, customer: { ...command.customer, phone } };
76
+ }
77
+ }
78
+ function mapRpcError(error) {
79
+ const text = [error.message, error.details, error.hint].filter(Boolean).join(" ");
80
+ if (error.code === "23505" ||
81
+ /configurator_intent_.*(?:conflict|invalid|missing)/.test(text)) {
82
+ return new ConfiguratorIntentPersistenceConflictError("Configurator intent persistence conflict", { code: error.code });
83
+ }
84
+ return new Error(`Configurator intent persistence RPC failed: ${text}`);
85
+ }
@@ -0,0 +1,14 @@
1
+ import type { z } from "zod";
2
+ import type { HttpRequest, HttpResponse } from "../../http/index.js";
3
+ import type { BffResponder } from "../../bff/index.js";
4
+ import type { ConfiguratorIntentPersistencePort } from "../contracts/index.js";
5
+ export declare class ConfiguratorIntentPersistenceConflictError extends Error {
6
+ readonly details: Record<string, unknown>;
7
+ constructor(message?: string, details?: Record<string, unknown>);
8
+ }
9
+ export declare function createConfiguratorIntentPersistenceHandler<Request, Response>({ persistencePort, responder, requestSchema, responseSchema, }: {
10
+ persistencePort: ConfiguratorIntentPersistencePort<Request, Response>;
11
+ responder: BffResponder;
12
+ requestSchema: z.ZodType<Request>;
13
+ responseSchema: z.ZodType<Response>;
14
+ }): (req: HttpRequest, res: HttpResponse) => Promise<void>;
@@ -0,0 +1,42 @@
1
+ export class ConfiguratorIntentPersistenceConflictError extends Error {
2
+ details;
3
+ constructor(message = "Configurator intent idempotency conflict", details = {}) {
4
+ super(message);
5
+ this.name = "ConfiguratorIntentPersistenceConflictError";
6
+ this.details = details;
7
+ }
8
+ }
9
+ export function createConfiguratorIntentPersistenceHandler({ persistencePort, responder, requestSchema, responseSchema, }) {
10
+ const { sendBffError, sendBffSuccess, sendMethodNotAllowed } = responder;
11
+ return async function handler(req, res) {
12
+ if (req.method !== "POST") {
13
+ sendMethodNotAllowed(res, ["POST"]);
14
+ return;
15
+ }
16
+ const request = requestSchema.safeParse(req.body);
17
+ if (!request.success) {
18
+ sendBffError(res, "BAD_REQUEST", "Invalid configurator intent", {
19
+ details: request.error.flatten(),
20
+ });
21
+ return;
22
+ }
23
+ try {
24
+ const persisted = await persistencePort.persistIntent(request.data);
25
+ const response = responseSchema.safeParse(persisted);
26
+ if (!response.success) {
27
+ sendBffError(res, "INVALID_RESPONSE", "Configurator intent persistence returned invalid response");
28
+ return;
29
+ }
30
+ sendBffSuccess(res, response.data, {
31
+ contractVersion: "commerce.configurator_intent_persistence.v1",
32
+ });
33
+ }
34
+ catch (error) {
35
+ if (error instanceof ConfiguratorIntentPersistenceConflictError) {
36
+ sendBffError(res, "CONFLICT", error.message, { details: error.details });
37
+ return;
38
+ }
39
+ sendBffError(res, "UPSTREAM_UNAVAILABLE", "Configurator intent persistence failed");
40
+ }
41
+ };
42
+ }