@openlup/platform 0.20.0 → 0.22.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 (458) hide show
  1. package/CHANGELOG.md +272 -278
  2. package/README.md +195 -6
  3. package/dist/composition/composeBundle.d.ts +13 -0
  4. package/dist/composition/composeBundle.js +4 -0
  5. package/dist/composition/fulfillmentContribution.d.ts +21 -0
  6. package/dist/composition/fulfillmentContribution.js +19 -0
  7. package/dist/composition/index.d.ts +1 -0
  8. package/dist/composition/index.js +2 -0
  9. package/dist/fulfillment/adapterConformance.d.ts +3 -0
  10. package/dist/fulfillment/adapterConformance.js +223 -0
  11. package/dist/fulfillment/bindings.d.ts +3 -0
  12. package/dist/fulfillment/bindings.js +29 -0
  13. package/dist/fulfillment/commerceFulfillmentHandlers.d.ts +29 -0
  14. package/dist/fulfillment/commerceFulfillmentHandlers.js +184 -0
  15. package/dist/fulfillment/commerceFulfillmentReadModel.d.ts +86 -0
  16. package/dist/fulfillment/commerceFulfillmentReadModel.js +131 -0
  17. package/dist/fulfillment/contracts/alignment.d.ts +25 -0
  18. package/dist/fulfillment/contracts/alignment.js +1 -0
  19. package/dist/fulfillment/contracts/bindings.d.ts +51 -0
  20. package/dist/fulfillment/contracts/bindings.js +1 -0
  21. package/dist/fulfillment/contracts/capabilities.d.ts +29 -0
  22. package/dist/fulfillment/contracts/capabilities.js +1 -0
  23. package/dist/fulfillment/contracts/conformance.d.ts +93 -0
  24. package/dist/fulfillment/contracts/conformance.js +1 -0
  25. package/dist/fulfillment/contracts/customerAlignment.d.ts +6 -0
  26. package/dist/fulfillment/contracts/customerAlignment.js +1 -0
  27. package/dist/fulfillment/contracts/dispatch.d.ts +105 -0
  28. package/dist/fulfillment/contracts/dispatch.js +1 -0
  29. package/dist/fulfillment/contracts/index.d.ts +18 -0
  30. package/dist/fulfillment/contracts/index.js +1 -0
  31. package/dist/fulfillment/contracts/label.d.ts +35 -0
  32. package/dist/fulfillment/contracts/label.js +1 -0
  33. package/dist/fulfillment/contracts/nativeUnsupported.d.ts +6 -0
  34. package/dist/fulfillment/contracts/nativeUnsupported.js +1 -0
  35. package/dist/fulfillment/contracts/observation.d.ts +52 -0
  36. package/dist/fulfillment/contracts/observation.js +1 -0
  37. package/dist/fulfillment/contracts/operator.d.ts +64 -0
  38. package/dist/fulfillment/contracts/operator.js +1 -0
  39. package/dist/fulfillment/contracts/read.d.ts +110 -0
  40. package/dist/fulfillment/contracts/read.js +1 -0
  41. package/dist/fulfillment/contracts/readback.d.ts +38 -0
  42. package/dist/fulfillment/contracts/readback.js +1 -0
  43. package/dist/fulfillment/contracts/replacement.d.ts +34 -0
  44. package/dist/fulfillment/contracts/replacement.js +1 -0
  45. package/dist/fulfillment/contracts/store.d.ts +86 -0
  46. package/dist/fulfillment/contracts/store.js +1 -0
  47. package/dist/fulfillment/contracts/sync.d.ts +170 -0
  48. package/dist/fulfillment/contracts/sync.js +1 -0
  49. package/dist/fulfillment/currentFulfillmentParcel.d.ts +2 -0
  50. package/dist/fulfillment/currentFulfillmentParcel.js +1 -0
  51. package/dist/fulfillment/delayReadModel.d.ts +11 -0
  52. package/dist/fulfillment/delayReadModel.js +45 -0
  53. package/dist/fulfillment/deliveryAlignmentReadModel.d.ts +4 -0
  54. package/dist/fulfillment/deliveryAlignmentReadModel.js +12 -0
  55. package/dist/fulfillment/dispatchProjection.d.ts +7 -0
  56. package/dist/fulfillment/dispatchProjection.js +18 -0
  57. package/dist/fulfillment/fulfillmentObservationEffects.d.ts +66 -0
  58. package/dist/fulfillment/fulfillmentObservationEffects.js +36 -0
  59. package/dist/fulfillment/handlerSchemas.d.ts +647 -0
  60. package/dist/fulfillment/handlerSchemas.js +213 -0
  61. package/dist/fulfillment/handlerSupport.d.ts +33 -0
  62. package/dist/fulfillment/handlerSupport.js +25 -0
  63. package/dist/fulfillment/index.d.ts +37 -0
  64. package/dist/fulfillment/index.js +37 -0
  65. package/dist/fulfillment/labelLifecycle.d.ts +24 -0
  66. package/dist/fulfillment/labelLifecycle.js +9 -0
  67. package/dist/fulfillment/lowStockEvidenceHandler.d.ts +36 -0
  68. package/dist/fulfillment/lowStockEvidenceHandler.js +46 -0
  69. package/dist/fulfillment/migrations.d.ts +27 -0
  70. package/dist/fulfillment/migrations.js +8 -0
  71. package/dist/fulfillment/nativeUnsupported.d.ts +10 -0
  72. package/dist/fulfillment/nativeUnsupported.js +18 -0
  73. package/dist/fulfillment/normalizedFulfillmentFacts.d.ts +2 -0
  74. package/dist/fulfillment/normalizedFulfillmentFacts.js +1 -0
  75. package/dist/fulfillment/observationProjection.d.ts +11 -0
  76. package/dist/fulfillment/observationProjection.js +37 -0
  77. package/dist/fulfillment/omnipack/capabilities.d.ts +3 -0
  78. package/dist/fulfillment/omnipack/capabilities.js +16 -0
  79. package/dist/fulfillment/omnipack/client.d.ts +37 -0
  80. package/dist/fulfillment/omnipack/client.js +162 -0
  81. package/dist/fulfillment/omnipack/index.d.ts +52 -0
  82. package/dist/fulfillment/omnipack/index.js +349 -0
  83. package/dist/fulfillment/omnipack/mappers.d.ts +73 -0
  84. package/dist/fulfillment/omnipack/mappers.js +177 -0
  85. package/dist/fulfillment/omnipack/observation.d.ts +21 -0
  86. package/dist/fulfillment/omnipack/observation.js +57 -0
  87. package/dist/fulfillment/omnipack/omnipackDispatchPayload.d.ts +36 -0
  88. package/dist/fulfillment/omnipack/omnipackDispatchPayload.js +63 -0
  89. package/dist/fulfillment/omnipack/omnipackOutboundOrderPayload.d.ts +83 -0
  90. package/dist/fulfillment/omnipack/omnipackOutboundOrderPayload.js +113 -0
  91. package/dist/fulfillment/omnipack/omnipackProductPackPayload.d.ts +11 -0
  92. package/dist/fulfillment/omnipack/omnipackProductPackPayload.js +38 -0
  93. package/dist/fulfillment/omnipack/omnipackProductPayload.d.ts +18 -0
  94. package/dist/fulfillment/omnipack/omnipackProductPayload.js +51 -0
  95. package/dist/fulfillment/omnipack/omnipackReconciliationPayload.d.ts +1 -0
  96. package/dist/fulfillment/omnipack/omnipackReconciliationPayload.js +3 -0
  97. package/dist/fulfillment/omnipack/omnipackStatusVocabulary.d.ts +4 -0
  98. package/dist/fulfillment/omnipack/omnipackStatusVocabulary.js +87 -0
  99. package/dist/fulfillment/omnipack/omnipackWebhookPayload.d.ts +9 -0
  100. package/dist/fulfillment/omnipack/omnipackWebhookPayload.js +76 -0
  101. package/dist/fulfillment/omnipack/productSyncMappers.d.ts +18 -0
  102. package/dist/fulfillment/omnipack/productSyncMappers.js +43 -0
  103. package/dist/fulfillment/omnipack/providerError.d.ts +25 -0
  104. package/dist/fulfillment/omnipack/providerError.js +47 -0
  105. package/dist/fulfillment/omnipack/trackingReferences.d.ts +16 -0
  106. package/dist/fulfillment/omnipack/trackingReferences.js +52 -0
  107. package/dist/fulfillment/paidFulfillmentRecovery.d.ts +67 -0
  108. package/dist/fulfillment/paidFulfillmentRecovery.js +154 -0
  109. package/dist/fulfillment/paidHandoff.d.ts +27 -0
  110. package/dist/fulfillment/paidHandoff.js +86 -0
  111. package/dist/fulfillment/paidHandoffPorts.d.ts +24 -0
  112. package/dist/fulfillment/paidHandoffPorts.js +3 -0
  113. package/dist/fulfillment/postgresDeliveryAlignment.d.ts +4 -0
  114. package/dist/fulfillment/postgresDeliveryAlignment.js +12 -0
  115. package/dist/fulfillment/postgresDispatchStore.d.ts +16 -0
  116. package/dist/fulfillment/postgresDispatchStore.js +44 -0
  117. package/dist/fulfillment/postgresEvidenceReadPort.d.ts +25 -0
  118. package/dist/fulfillment/postgresEvidenceReadPort.js +45 -0
  119. package/dist/fulfillment/postgresPaidFulfillmentRecovery.d.ts +25 -0
  120. package/dist/fulfillment/postgresPaidFulfillmentRecovery.js +26 -0
  121. package/dist/fulfillment/postgresPaidHandoffStore.d.ts +4 -0
  122. package/dist/fulfillment/postgresPaidHandoffStore.js +10 -0
  123. package/dist/fulfillment/postgresShipmentSpine.d.ts +63 -0
  124. package/dist/fulfillment/postgresShipmentSpine.js +232 -0
  125. package/dist/fulfillment/postgresStockSyncPort.d.ts +8 -0
  126. package/dist/fulfillment/postgresStockSyncPort.js +63 -0
  127. package/dist/fulfillment/productReconciliationEvidenceHandler.d.ts +36 -0
  128. package/dist/fulfillment/productReconciliationEvidenceHandler.js +50 -0
  129. package/dist/fulfillment/providerCapabilities.d.ts +9 -0
  130. package/dist/fulfillment/providerCapabilities.js +17 -0
  131. package/dist/fulfillment/providerCommandLedger.d.ts +143 -0
  132. package/dist/fulfillment/providerCommandLedger.js +14 -0
  133. package/dist/fulfillment/providerDispatchAcceptance.d.ts +26 -0
  134. package/dist/fulfillment/providerDispatchAcceptance.js +23 -0
  135. package/dist/fulfillment/providerDispatchError.d.ts +6 -0
  136. package/dist/fulfillment/providerDispatchError.js +5 -0
  137. package/dist/fulfillment/providerDispatchWorker.d.ts +31 -0
  138. package/dist/fulfillment/providerDispatchWorker.js +172 -0
  139. package/dist/fulfillment/providerProductSyncWorker.d.ts +28 -0
  140. package/dist/fulfillment/providerProductSyncWorker.js +122 -0
  141. package/dist/fulfillment/providerReconciliationError.d.ts +9 -0
  142. package/dist/fulfillment/providerReconciliationError.js +17 -0
  143. package/dist/fulfillment/providerReconciliationTerminalSkip.d.ts +2 -0
  144. package/dist/fulfillment/providerReconciliationTerminalSkip.js +6 -0
  145. package/dist/fulfillment/providerReconciliationTimestamp.d.ts +1 -0
  146. package/dist/fulfillment/providerReconciliationTimestamp.js +27 -0
  147. package/dist/fulfillment/providerReconciliationWorker.d.ts +82 -0
  148. package/dist/fulfillment/providerReconciliationWorker.js +151 -0
  149. package/dist/fulfillment/providerStockAvailability.d.ts +13 -0
  150. package/dist/fulfillment/providerStockAvailability.js +51 -0
  151. package/dist/fulfillment/providerStockSyncWorker.d.ts +37 -0
  152. package/dist/fulfillment/providerStockSyncWorker.js +186 -0
  153. package/dist/fulfillment/providerTrackingReferences.d.ts +15 -0
  154. package/dist/fulfillment/providerTrackingReferences.js +23 -0
  155. package/dist/fulfillment/replacementRefusals.d.ts +5 -0
  156. package/dist/fulfillment/replacementRefusals.js +38 -0
  157. package/dist/fulfillment/replacementShipmentHandler.d.ts +5 -0
  158. package/dist/fulfillment/replacementShipmentHandler.js +46 -0
  159. package/dist/fulfillment/schemaCapabilities.d.ts +13 -0
  160. package/dist/fulfillment/schemaCapabilities.js +7 -0
  161. package/dist/fulfillment/shipmentsOverviewHandler.d.ts +16 -0
  162. package/dist/fulfillment/shipmentsOverviewHandler.js +54 -0
  163. package/dist/fulfillment/statusMap.d.ts +2 -0
  164. package/dist/fulfillment/statusMap.js +1 -0
  165. package/dist/fulfillment/trackingProgress.d.ts +1 -0
  166. package/dist/fulfillment/trackingProgress.js +1 -0
  167. package/dist/fulfillment/verifiedIngress.d.ts +52 -0
  168. package/dist/fulfillment/verifiedIngress.js +66 -0
  169. package/dist/payments/adapterConformance.d.ts +8 -0
  170. package/dist/payments/adapterConformance.js +109 -0
  171. package/dist/payments/bindings.d.ts +3 -0
  172. package/dist/payments/bindings.js +17 -0
  173. package/dist/payments/checkoutActivePaymentActionResolver.d.ts +7 -0
  174. package/dist/payments/checkoutActivePaymentActionResolver.js +77 -0
  175. package/dist/payments/checkoutRecoveryPaymentResolver.d.ts +8 -0
  176. package/dist/payments/checkoutRecoveryPaymentResolver.js +87 -0
  177. package/dist/payments/contracts/adapter.d.ts +113 -0
  178. package/dist/payments/contracts/adapter.js +1 -0
  179. package/dist/payments/contracts/conformance.d.ts +155 -0
  180. package/dist/payments/contracts/conformance.js +1 -0
  181. package/dist/payments/contracts/evidence.d.ts +157 -0
  182. package/dist/payments/contracts/evidence.js +1 -0
  183. package/dist/payments/contracts/index.d.ts +10 -0
  184. package/dist/payments/contracts/index.js +1 -0
  185. package/dist/payments/contracts/preparedAttempt.d.ts +69 -0
  186. package/dist/payments/contracts/preparedAttempt.js +1 -0
  187. package/dist/payments/contracts/reconciliation.d.ts +303 -0
  188. package/dist/payments/contracts/reconciliation.js +1 -0
  189. package/dist/payments/contracts/repair.d.ts +92 -0
  190. package/dist/payments/contracts/repair.js +1 -0
  191. package/dist/payments/contracts/truth.d.ts +92 -0
  192. package/dist/payments/contracts/truth.js +1 -0
  193. package/dist/payments/eventConformanceRunner.d.ts +12 -0
  194. package/dist/payments/eventConformanceRunner.js +125 -0
  195. package/dist/payments/index.d.ts +16 -0
  196. package/dist/payments/index.js +16 -0
  197. package/dist/payments/paymentAttemptSilenceWindow.d.ts +10 -0
  198. package/dist/payments/paymentAttemptSilenceWindow.js +19 -0
  199. package/dist/payments/paymentMethodLifecycle.d.ts +11 -0
  200. package/dist/payments/paymentMethodLifecycle.js +37 -0
  201. package/dist/payments/paymentProviderReconciliationAbsenceReopen.d.ts +7 -0
  202. package/dist/payments/paymentProviderReconciliationAbsenceReopen.js +100 -0
  203. package/dist/payments/paymentProviderReconciliationEvidence.d.ts +36 -0
  204. package/dist/payments/paymentProviderReconciliationEvidence.js +91 -0
  205. package/dist/payments/paymentProviderReconciliationWorker.d.ts +4 -0
  206. package/dist/payments/paymentProviderReconciliationWorker.js +245 -0
  207. package/dist/payments/paymentTruth.d.ts +8 -0
  208. package/dist/payments/paymentTruth.js +125 -0
  209. package/dist/payments/paymentVerifyNowHandler.d.ts +27 -0
  210. package/dist/payments/paymentVerifyNowHandler.js +70 -0
  211. package/dist/payments/paymentVerifyNowService.d.ts +23 -0
  212. package/dist/payments/paymentVerifyNowService.js +93 -0
  213. package/dist/payments/paymentWebhookPostProcessing.d.ts +22 -0
  214. package/dist/payments/paymentWebhookPostProcessing.js +15 -0
  215. package/dist/payments/postgresPaymentTruth.d.ts +10 -0
  216. package/dist/payments/postgresPaymentTruth.js +126 -0
  217. package/dist/payments/preparedAttempt.d.ts +6 -0
  218. package/dist/payments/preparedAttempt.js +70 -0
  219. package/dist/payments/preparedAttemptFinalization.d.ts +5 -0
  220. package/dist/payments/preparedAttemptFinalization.js +12 -0
  221. package/dist/payments/schemaCapabilities.d.ts +10 -0
  222. package/dist/payments/schemaCapabilities.js +10 -0
  223. package/dist/payments/sql.d.ts +20 -0
  224. package/dist/payments/sql.js +6 -0
  225. package/dist/payments/stripe/classifyDecline.d.ts +46 -0
  226. package/dist/payments/stripe/classifyDecline.js +58 -0
  227. package/dist/payments/stripe/declineFailureHints.d.ts +46 -0
  228. package/dist/payments/stripe/declineFailureHints.js +87 -0
  229. package/dist/payments/stripe/donorContracts.d.ts +120 -0
  230. package/dist/payments/stripe/donorContracts.js +1 -0
  231. package/dist/payments/stripe/executionDecline.d.ts +53 -0
  232. package/dist/payments/stripe/executionDecline.js +107 -0
  233. package/dist/payments/stripe/index.d.ts +41 -0
  234. package/dist/payments/stripe/index.js +264 -0
  235. package/dist/payments/stripe/intentMapper.d.ts +26 -0
  236. package/dist/payments/stripe/intentMapper.js +51 -0
  237. package/dist/payments/stripe/methodFacts.d.ts +10 -0
  238. package/dist/payments/stripe/methodFacts.js +12 -0
  239. package/dist/payments/stripe/paymentFailureEvidence.d.ts +26 -0
  240. package/dist/payments/stripe/paymentFailureEvidence.js +33 -0
  241. package/dist/payments/stripe/stripeFailureEvidence.d.ts +41 -0
  242. package/dist/payments/stripe/stripeFailureEvidence.js +82 -0
  243. package/dist/payments/stripe/stripeIntentConfirmationEvidence.d.ts +28 -0
  244. package/dist/payments/stripe/stripeIntentConfirmationEvidence.js +32 -0
  245. package/dist/payments/stripe/stripePaymentReconciliationProvider.d.ts +35 -0
  246. package/dist/payments/stripe/stripePaymentReconciliationProvider.js +222 -0
  247. package/dist/payments/stripe/stripeRefundEvidence.d.ts +8 -0
  248. package/dist/payments/stripe/stripeRefundEvidence.js +17 -0
  249. package/dist/payments/stripe/stripeSandboxPaymentExecutionAdapter.d.ts +45 -0
  250. package/dist/payments/stripe/stripeSandboxPaymentExecutionAdapter.js +220 -0
  251. package/dist/payments/stripe/stripeWebhookNormalizer.d.ts +14 -0
  252. package/dist/payments/stripe/stripeWebhookNormalizer.js +243 -0
  253. package/dist/payments/stripe/webhookSignature.d.ts +14 -0
  254. package/dist/payments/stripe/webhookSignature.js +43 -0
  255. package/dist/payments/tpay/blikRecurringMapper.d.ts +37 -0
  256. package/dist/payments/tpay/blikRecurringMapper.js +24 -0
  257. package/dist/payments/tpay/capabilities.d.ts +3 -0
  258. package/dist/payments/tpay/capabilities.js +18 -0
  259. package/dist/payments/tpay/classifyDecline.d.ts +46 -0
  260. package/dist/payments/tpay/classifyDecline.js +58 -0
  261. package/dist/payments/tpay/declineFailureHints.d.ts +72 -0
  262. package/dist/payments/tpay/declineFailureHints.js +37 -0
  263. package/dist/payments/tpay/donorContracts.d.ts +140 -0
  264. package/dist/payments/tpay/donorContracts.js +1 -0
  265. package/dist/payments/tpay/index.d.ts +73 -0
  266. package/dist/payments/tpay/index.js +294 -0
  267. package/dist/payments/tpay/paymentFailureEvidence.d.ts +26 -0
  268. package/dist/payments/tpay/paymentFailureEvidence.js +33 -0
  269. package/dist/payments/tpay/preparedProviderAttempt.d.ts +22 -0
  270. package/dist/payments/tpay/preparedProviderAttempt.js +24 -0
  271. package/dist/payments/tpay/providerAttemptFailureDiagnostic.d.ts +3 -0
  272. package/dist/payments/tpay/providerAttemptFailureDiagnostic.js +95 -0
  273. package/dist/payments/tpay/tpayCreateTransactionInput.d.ts +25 -0
  274. package/dist/payments/tpay/tpayCreateTransactionInput.js +128 -0
  275. package/dist/payments/tpay/tpayDeclineEvidence.d.ts +126 -0
  276. package/dist/payments/tpay/tpayDeclineEvidence.js +177 -0
  277. package/dist/payments/tpay/tpayDispatchFailure.d.ts +60 -0
  278. package/dist/payments/tpay/tpayDispatchFailure.js +121 -0
  279. package/dist/payments/tpay/tpayFailureEvidence.d.ts +20 -0
  280. package/dist/payments/tpay/tpayFailureEvidence.js +61 -0
  281. package/dist/payments/tpay/tpayHttpClient.d.ts +52 -0
  282. package/dist/payments/tpay/tpayHttpClient.js +185 -0
  283. package/dist/payments/tpay/tpayHttpFailure.d.ts +57 -0
  284. package/dist/payments/tpay/tpayHttpFailure.js +143 -0
  285. package/dist/payments/tpay/tpayPaymentExecutionAdapter.d.ts +20 -0
  286. package/dist/payments/tpay/tpayPaymentExecutionAdapter.js +249 -0
  287. package/dist/payments/tpay/tpayPaymentReconciliationProvider.d.ts +5 -0
  288. package/dist/payments/tpay/tpayPaymentReconciliationProvider.js +244 -0
  289. package/dist/payments/tpay/tpayTransactionPayload.d.ts +120 -0
  290. package/dist/payments/tpay/tpayTransactionPayload.js +96 -0
  291. package/dist/payments/tpay/wallClockTime.d.ts +31 -0
  292. package/dist/payments/tpay/wallClockTime.js +57 -0
  293. package/dist/payments/tpay/webhookJwsVerifier.d.ts +17 -0
  294. package/dist/payments/tpay/webhookJwsVerifier.js +51 -0
  295. package/dist/payments/tpay/webhookNormalizer.d.ts +54 -0
  296. package/dist/payments/tpay/webhookNormalizer.js +200 -0
  297. package/dist/payments/verifiedEvidenceProjection.d.ts +12 -0
  298. package/dist/payments/verifiedEvidenceProjection.js +166 -0
  299. package/dist/payments/verifiedIngress.d.ts +119 -0
  300. package/dist/payments/verifiedIngress.js +220 -0
  301. package/package.json +37 -2
  302. package/release-gates.json +105 -3
  303. package/sql/20260808210000_fulfillment_shipment_rail.sql +810 -0
  304. package/sql/20260810180000_payment_settlement_rail.sql +574 -0
  305. package/sql/20260815150000_payment_truth_reconciliation.sql +479 -0
  306. package/sql/20260819150000_fulfillment_shipment_sequence.sql +98 -0
  307. package/sql/20260826100000_late_payment_shifts_the_subscription_cycle.sql +215 -0
  308. package/sql/20261022080000_fulfillment_command_ledger.sql +786 -0
  309. package/sql/20261022090000_fulfillment_delivery_alignment.sql +1106 -0
  310. package/src/composition/composeBundle.ts +13 -0
  311. package/src/composition/fulfillmentContribution.ts +28 -0
  312. package/src/composition/index.ts +2 -0
  313. package/src/fulfillment/adapterConformance.ts +195 -0
  314. package/src/fulfillment/bindings.ts +26 -0
  315. package/src/fulfillment/commerceFulfillmentHandlers.ts +263 -0
  316. package/src/fulfillment/commerceFulfillmentReadModel.ts +257 -0
  317. package/src/fulfillment/contracts/alignment.ts +13 -0
  318. package/src/fulfillment/contracts/bindings.ts +30 -0
  319. package/src/fulfillment/contracts/capabilities.ts +15 -0
  320. package/src/fulfillment/contracts/conformance.ts +61 -0
  321. package/src/fulfillment/contracts/customerAlignment.ts +4 -0
  322. package/src/fulfillment/contracts/dispatch.ts +58 -0
  323. package/src/fulfillment/contracts/index.ts +18 -0
  324. package/src/fulfillment/contracts/label.ts +9 -0
  325. package/src/fulfillment/contracts/nativeUnsupported.ts +6 -0
  326. package/src/fulfillment/contracts/observation.ts +18 -0
  327. package/src/fulfillment/contracts/operator.ts +31 -0
  328. package/src/fulfillment/contracts/read.ts +42 -0
  329. package/src/fulfillment/contracts/readback.ts +11 -0
  330. package/src/fulfillment/contracts/replacement.ts +15 -0
  331. package/src/fulfillment/contracts/store.ts +26 -0
  332. package/src/fulfillment/contracts/sync.ts +61 -0
  333. package/src/fulfillment/currentFulfillmentParcel.ts +2 -0
  334. package/src/fulfillment/delayReadModel.ts +60 -0
  335. package/src/fulfillment/deliveryAlignmentReadModel.ts +15 -0
  336. package/src/fulfillment/dispatchProjection.ts +20 -0
  337. package/src/fulfillment/fulfillmentObservationEffects.ts +86 -0
  338. package/src/fulfillment/handlerSchemas.ts +255 -0
  339. package/src/fulfillment/handlerSupport.ts +25 -0
  340. package/src/fulfillment/index.ts +38 -0
  341. package/src/fulfillment/labelLifecycle.ts +11 -0
  342. package/src/fulfillment/lowStockEvidenceHandler.ts +60 -0
  343. package/src/fulfillment/migrations.ts +8 -0
  344. package/src/fulfillment/nativeUnsupported.ts +23 -0
  345. package/src/fulfillment/normalizedFulfillmentFacts.ts +2 -0
  346. package/src/fulfillment/observationProjection.ts +41 -0
  347. package/src/fulfillment/omnipack/capabilities.ts +18 -0
  348. package/src/fulfillment/omnipack/client.ts +258 -0
  349. package/src/fulfillment/omnipack/index.ts +312 -0
  350. package/src/fulfillment/omnipack/mappers.ts +261 -0
  351. package/src/fulfillment/omnipack/observation.ts +61 -0
  352. package/src/fulfillment/omnipack/omnipackDispatchPayload.ts +93 -0
  353. package/src/fulfillment/omnipack/omnipackOutboundOrderPayload.ts +194 -0
  354. package/src/fulfillment/omnipack/omnipackProductPackPayload.ts +47 -0
  355. package/src/fulfillment/omnipack/omnipackProductPayload.ts +67 -0
  356. package/src/fulfillment/omnipack/omnipackReconciliationPayload.ts +7 -0
  357. package/src/fulfillment/omnipack/omnipackStatusVocabulary.ts +103 -0
  358. package/src/fulfillment/omnipack/omnipackWebhookPayload.ts +73 -0
  359. package/src/fulfillment/omnipack/productSyncMappers.ts +74 -0
  360. package/src/fulfillment/omnipack/providerError.ts +64 -0
  361. package/src/fulfillment/omnipack/trackingReferences.ts +77 -0
  362. package/src/fulfillment/paidFulfillmentRecovery.ts +252 -0
  363. package/src/fulfillment/paidHandoff.ts +122 -0
  364. package/src/fulfillment/paidHandoffPorts.ts +21 -0
  365. package/src/fulfillment/postgresDeliveryAlignment.ts +14 -0
  366. package/src/fulfillment/postgresDispatchStore.ts +55 -0
  367. package/src/fulfillment/postgresEvidenceReadPort.ts +59 -0
  368. package/src/fulfillment/postgresPaidFulfillmentRecovery.ts +29 -0
  369. package/src/fulfillment/postgresPaidHandoffStore.ts +11 -0
  370. package/src/fulfillment/postgresShipmentSpine.ts +321 -0
  371. package/src/fulfillment/postgresStockSyncPort.ts +65 -0
  372. package/src/fulfillment/productReconciliationEvidenceHandler.ts +64 -0
  373. package/src/fulfillment/providerCapabilities.ts +18 -0
  374. package/src/fulfillment/providerCommandLedger.ts +53 -0
  375. package/src/fulfillment/providerDispatchAcceptance.ts +31 -0
  376. package/src/fulfillment/providerDispatchError.ts +7 -0
  377. package/src/fulfillment/providerDispatchWorker.ts +131 -0
  378. package/src/fulfillment/providerProductSyncWorker.ts +154 -0
  379. package/src/fulfillment/providerReconciliationError.ts +20 -0
  380. package/src/fulfillment/providerReconciliationTerminalSkip.ts +8 -0
  381. package/src/fulfillment/providerReconciliationTimestamp.ts +34 -0
  382. package/src/fulfillment/providerReconciliationWorker.ts +150 -0
  383. package/src/fulfillment/providerStockAvailability.ts +60 -0
  384. package/src/fulfillment/providerStockSyncWorker.ts +222 -0
  385. package/src/fulfillment/providerTrackingReferences.ts +31 -0
  386. package/src/fulfillment/replacementRefusals.ts +43 -0
  387. package/src/fulfillment/replacementShipmentHandler.ts +47 -0
  388. package/src/fulfillment/schemaCapabilities.ts +7 -0
  389. package/src/fulfillment/shipmentsOverviewHandler.ts +73 -0
  390. package/src/fulfillment/statusMap.ts +2 -0
  391. package/src/fulfillment/trackingProgress.ts +1 -0
  392. package/src/fulfillment/verifiedIngress.ts +80 -0
  393. package/src/payments/adapterConformance.ts +118 -0
  394. package/src/payments/bindings.ts +17 -0
  395. package/src/payments/checkoutActivePaymentActionResolver.ts +97 -0
  396. package/src/payments/checkoutRecoveryPaymentResolver.ts +108 -0
  397. package/src/payments/contracts/adapter.ts +96 -0
  398. package/src/payments/contracts/conformance.ts +171 -0
  399. package/src/payments/contracts/evidence.ts +142 -0
  400. package/src/payments/contracts/index.ts +54 -0
  401. package/src/payments/contracts/preparedAttempt.ts +86 -0
  402. package/src/payments/contracts/reconciliation.ts +296 -0
  403. package/src/payments/contracts/repair.ts +95 -0
  404. package/src/payments/contracts/truth.ts +108 -0
  405. package/src/payments/eventConformanceRunner.ts +149 -0
  406. package/src/payments/index.ts +21 -0
  407. package/src/payments/paymentAttemptSilenceWindow.ts +26 -0
  408. package/src/payments/paymentMethodLifecycle.ts +50 -0
  409. package/src/payments/paymentProviderReconciliationAbsenceReopen.ts +130 -0
  410. package/src/payments/paymentProviderReconciliationEvidence.ts +117 -0
  411. package/src/payments/paymentProviderReconciliationWorker.ts +291 -0
  412. package/src/payments/paymentTruth.ts +131 -0
  413. package/src/payments/paymentVerifyNowHandler.ts +94 -0
  414. package/src/payments/paymentVerifyNowService.ts +125 -0
  415. package/src/payments/paymentWebhookPostProcessing.ts +36 -0
  416. package/src/payments/postgresPaymentTruth.ts +149 -0
  417. package/src/payments/preparedAttempt.ts +90 -0
  418. package/src/payments/preparedAttemptFinalization.ts +13 -0
  419. package/src/payments/schemaCapabilities.ts +10 -0
  420. package/src/payments/sql.ts +6 -0
  421. package/src/payments/stripe/classifyDecline.ts +62 -0
  422. package/src/payments/stripe/declineFailureHints.ts +89 -0
  423. package/src/payments/stripe/donorContracts.ts +87 -0
  424. package/src/payments/stripe/executionDecline.ts +126 -0
  425. package/src/payments/stripe/index.ts +265 -0
  426. package/src/payments/stripe/intentMapper.ts +58 -0
  427. package/src/payments/stripe/methodFacts.ts +21 -0
  428. package/src/payments/stripe/paymentFailureEvidence.ts +58 -0
  429. package/src/payments/stripe/stripeFailureEvidence.ts +115 -0
  430. package/src/payments/stripe/stripeIntentConfirmationEvidence.ts +34 -0
  431. package/src/payments/stripe/stripePaymentReconciliationProvider.ts +263 -0
  432. package/src/payments/stripe/stripeRefundEvidence.ts +19 -0
  433. package/src/payments/stripe/stripeSandboxPaymentExecutionAdapter.ts +283 -0
  434. package/src/payments/stripe/stripeWebhookNormalizer.ts +277 -0
  435. package/src/payments/stripe/webhookSignature.ts +55 -0
  436. package/src/payments/tpay/blikRecurringMapper.ts +42 -0
  437. package/src/payments/tpay/capabilities.ts +21 -0
  438. package/src/payments/tpay/classifyDecline.ts +62 -0
  439. package/src/payments/tpay/declineFailureHints.ts +90 -0
  440. package/src/payments/tpay/donorContracts.ts +104 -0
  441. package/src/payments/tpay/index.ts +293 -0
  442. package/src/payments/tpay/paymentFailureEvidence.ts +58 -0
  443. package/src/payments/tpay/preparedProviderAttempt.ts +38 -0
  444. package/src/payments/tpay/providerAttemptFailureDiagnostic.ts +99 -0
  445. package/src/payments/tpay/tpayCreateTransactionInput.ts +158 -0
  446. package/src/payments/tpay/tpayDeclineEvidence.ts +233 -0
  447. package/src/payments/tpay/tpayDispatchFailure.ts +186 -0
  448. package/src/payments/tpay/tpayFailureEvidence.ts +75 -0
  449. package/src/payments/tpay/tpayHttpClient.ts +290 -0
  450. package/src/payments/tpay/tpayHttpFailure.ts +186 -0
  451. package/src/payments/tpay/tpayPaymentExecutionAdapter.ts +297 -0
  452. package/src/payments/tpay/tpayPaymentReconciliationProvider.ts +285 -0
  453. package/src/payments/tpay/tpayTransactionPayload.ts +207 -0
  454. package/src/payments/tpay/wallClockTime.ts +57 -0
  455. package/src/payments/tpay/webhookJwsVerifier.ts +82 -0
  456. package/src/payments/tpay/webhookNormalizer.ts +279 -0
  457. package/src/payments/verifiedEvidenceProjection.ts +179 -0
  458. package/src/payments/verifiedIngress.ts +317 -0
@@ -0,0 +1,73 @@
1
+ import { type OmnipackTrackingReferenceEvidence } from "./trackingReferences.js";
2
+ export interface OmnipackOrderCreatedEvidence {
3
+ provider: "omnipack";
4
+ providerOrderId: string;
5
+ raw: Record<string, unknown>;
6
+ }
7
+ export interface OmnipackProductCreatedEvidence {
8
+ provider: "omnipack";
9
+ sku: string;
10
+ raw: Record<string, unknown>;
11
+ }
12
+ export interface OmnipackStockEvidence {
13
+ provider: "omnipack";
14
+ sku: string;
15
+ totalQuantity: number;
16
+ forSaleQuantity: number;
17
+ reservedOrUnavailableQuantity: number;
18
+ stockTruth: "external_stock_master_with_local_reservations";
19
+ }
20
+ export interface OmnipackStockMovementEvidence {
21
+ provider: "omnipack";
22
+ sku: string;
23
+ occurredAt: string | null;
24
+ quantity: number;
25
+ operationType: string | null;
26
+ warehouseDocumentNumber: string | null;
27
+ lotNumber: string | null;
28
+ expirationDate: string | null;
29
+ }
30
+ export interface OmnipackFulfilmentEvidence {
31
+ provider: "omnipack";
32
+ providerOrderId: string | null;
33
+ fulfilmentNumber: string;
34
+ externalNumber: string | null;
35
+ orderNumber: string | null;
36
+ createdAt: string | null;
37
+ updatedAt: string | null;
38
+ status: string | null;
39
+ subStatus: string | null;
40
+ trackingNumbers: string[];
41
+ trackingReferences: OmnipackTrackingReferenceEvidence[];
42
+ items: Array<{
43
+ sku: string;
44
+ quantity: number;
45
+ lotNumber: string | null;
46
+ expirationDate: string | null;
47
+ }>;
48
+ }
49
+ export interface OmnipackFulfilmentRequestEvidence {
50
+ provider: "omnipack";
51
+ warehouseDocumentNumber: string;
52
+ warehouseName: string | null;
53
+ state: string | null;
54
+ }
55
+ export interface OmnipackWebhookEvidence {
56
+ provider: "omnipack";
57
+ event: string;
58
+ providerOrderId: string | null;
59
+ orderNumber: string | null;
60
+ fulfilmentNumber: string | null;
61
+ occurredAt: string | null;
62
+ trackingNumbers: string[];
63
+ trackingReferences: OmnipackTrackingReferenceEvidence[];
64
+ shippingMethods: string[];
65
+ }
66
+ export declare function mapOmnipackOrderCreatedResponse(body: unknown): OmnipackOrderCreatedEvidence;
67
+ export declare function mapOmnipackProductCreatedResponse(body: unknown, requestSku: string): OmnipackProductCreatedEvidence;
68
+ export declare function mapOmnipackStockResponse(body: unknown): OmnipackStockEvidence[];
69
+ export declare function mapOmnipackStockMovementsResponse(body: unknown): OmnipackStockMovementEvidence[];
70
+ export declare function mapOmnipackFulfilmentsResponse(body: unknown): OmnipackFulfilmentEvidence[];
71
+ export declare function mapOmnipackFulfilmentRequestsResponse(body: unknown): OmnipackFulfilmentRequestEvidence[];
72
+ export declare function mapOmnipackWebhookPayload(body: unknown, fallbackEvent?: string): OmnipackWebhookEvidence;
73
+ export declare function sanitizeOmnipackPayload(input: Record<string, unknown>): Record<string, unknown>;
@@ -0,0 +1,177 @@
1
+ import { mapOmnipackTrackingReferences, } from "./trackingReferences.js";
2
+ export function mapOmnipackOrderCreatedResponse(body) {
3
+ const response = asRecord(body);
4
+ const providerOrderId = readString(response.orderId);
5
+ if (!providerOrderId)
6
+ throw new Error("omnipack_order_response_invalid");
7
+ return {
8
+ provider: "omnipack",
9
+ providerOrderId,
10
+ raw: sanitizeOmnipackPayload(response),
11
+ };
12
+ }
13
+ // Catalog load (test-readiness). The product/inbound responses are evidence only — we read
14
+ // back authoritative stock via getStock. We tolerate a sparse response body and fall back to
15
+ // the request-side sku/reference so an idempotent re-create still yields usable evidence.
16
+ export function mapOmnipackProductCreatedResponse(body, requestSku) {
17
+ const response = asRecord(body);
18
+ return {
19
+ provider: "omnipack",
20
+ sku: readString(response.sku) || requestSku,
21
+ raw: sanitizeOmnipackPayload(response),
22
+ };
23
+ }
24
+ export function mapOmnipackStockResponse(body) {
25
+ const stockItems = readArray(asRecord(asRecord(body)._embedded).stockItems);
26
+ return stockItems.map((item) => {
27
+ const row = asRecord(item);
28
+ const totalQuantity = readNumber(row.totalQuantity);
29
+ const forSaleQuantity = readNumber(row.forSaleQuantity);
30
+ const unavailable = [
31
+ row.expireSoonQuantity,
32
+ row.faultyQuantity,
33
+ row.complaintsQuantity,
34
+ row.withheldQuantity,
35
+ row.packagingQuantity,
36
+ row.processingQuantity,
37
+ row.unpackingQuantity,
38
+ ].map(readNumber).reduce((sum, value) => sum + value, 0);
39
+ return {
40
+ provider: "omnipack",
41
+ sku: readString(row.sku),
42
+ totalQuantity,
43
+ forSaleQuantity,
44
+ reservedOrUnavailableQuantity: unavailable,
45
+ stockTruth: "external_stock_master_with_local_reservations",
46
+ };
47
+ });
48
+ }
49
+ export function mapOmnipackStockMovementsResponse(body) {
50
+ return readArray(asRecord(body)._embedded).map((item) => {
51
+ const row = asRecord(item);
52
+ return {
53
+ provider: "omnipack",
54
+ sku: readString(row.sku),
55
+ occurredAt: readNullableString(row.occurredAt),
56
+ quantity: readNumber(row.quantity),
57
+ operationType: readNullableString(row.operationType),
58
+ warehouseDocumentNumber: readNullableString(row.warehouseDocumentNumber),
59
+ lotNumber: readNullableString(row.productLotNumber),
60
+ expirationDate: readNullableString(row.expirationDate),
61
+ };
62
+ });
63
+ }
64
+ export function mapOmnipackFulfilmentsResponse(body) {
65
+ const fulfilments = readArray(asRecord(asRecord(body)._embedded).fulfilments);
66
+ return fulfilments.map((item) => {
67
+ const row = asRecord(item);
68
+ const trackingReferences = trackingReferencesFrom(row);
69
+ return {
70
+ provider: "omnipack",
71
+ providerOrderId: readNullableString(row.orderId) ?? readNullableString(row.providerOrderId),
72
+ fulfilmentNumber: readString(row.fulfilmentNumber),
73
+ externalNumber: readNullableString(row.externalNumber),
74
+ orderNumber: readNullableString(row.orderNumber),
75
+ createdAt: readNullableString(row.createdAt),
76
+ updatedAt: readNullableString(row.updatedAt),
77
+ status: readNullableString(row.status),
78
+ subStatus: readNullableString(row.subStatus),
79
+ trackingNumbers: trackingReferences.map((ref) => ref.trackingNumber),
80
+ trackingReferences,
81
+ items: readArray(row.items).map((rawItem) => {
82
+ const fulfilmentItem = asRecord(rawItem);
83
+ return {
84
+ sku: readString(fulfilmentItem.sku),
85
+ quantity: readNumber(fulfilmentItem.quantity),
86
+ lotNumber: readNullableString(fulfilmentItem.productLotNumber),
87
+ expirationDate: readNullableString(fulfilmentItem.expirationDate),
88
+ };
89
+ }),
90
+ };
91
+ });
92
+ }
93
+ export function mapOmnipackFulfilmentRequestsResponse(body) {
94
+ const requests = readArray(asRecord(asRecord(body)._embedded).fulfilmentRequests);
95
+ return requests.map((item) => {
96
+ const row = asRecord(item);
97
+ return {
98
+ provider: "omnipack",
99
+ warehouseDocumentNumber: readString(row.warehouseDocumentNumber),
100
+ warehouseName: readNullableString(row.warehouseName),
101
+ state: readNullableString(row.state),
102
+ };
103
+ });
104
+ }
105
+ export function mapOmnipackWebhookPayload(body, fallbackEvent = "") {
106
+ const payload = asRecord(body);
107
+ const shipments = readArray(payload.shipments).map(asRecord);
108
+ const trackingReferences = trackingReferencesFrom({ shipments });
109
+ return {
110
+ provider: "omnipack",
111
+ event: readString(payload.event) || fallbackEvent,
112
+ providerOrderId: readNullableString(payload.orderId) ?? readNullableString(payload.providerOrderId),
113
+ orderNumber: readNullableString(payload.orderNumber),
114
+ fulfilmentNumber: readNullableString(payload.fulfilmentNumber),
115
+ occurredAt: readNullableString(payload.occurredAt),
116
+ trackingNumbers: trackingReferences.map((ref) => ref.trackingNumber),
117
+ trackingReferences,
118
+ shippingMethods: shipments.map((shipment) => readString(shipment.shippingMethod)).filter(Boolean),
119
+ };
120
+ }
121
+ export function sanitizeOmnipackPayload(input) {
122
+ const blocked = new Set([
123
+ "authorization",
124
+ "Authorization",
125
+ "password",
126
+ "email",
127
+ "phone",
128
+ "firstName",
129
+ "lastName",
130
+ "name",
131
+ "address",
132
+ "street",
133
+ "streetNumber",
134
+ "houseNo",
135
+ "flatNo",
136
+ "city",
137
+ "postalCode",
138
+ ]);
139
+ return sanitizeRecord(input, blocked);
140
+ }
141
+ function sanitizeRecord(input, blocked) {
142
+ return Object.fromEntries(Object.entries(input)
143
+ .filter(([key]) => !blocked.has(key))
144
+ .map(([key, value]) => [key, sanitizeValue(value, blocked)]));
145
+ }
146
+ function sanitizeValue(input, blocked) {
147
+ if (Array.isArray(input))
148
+ return input.map((value) => sanitizeValue(value, blocked));
149
+ if (input && typeof input === "object")
150
+ return sanitizeRecord(input, blocked);
151
+ return input;
152
+ }
153
+ function asRecord(input) {
154
+ return input && typeof input === "object" && !Array.isArray(input) ? input : {};
155
+ }
156
+ function readArray(input) {
157
+ return Array.isArray(input) ? input : [];
158
+ }
159
+ function readString(input) {
160
+ return typeof input === "string" ? input : "";
161
+ }
162
+ function readNullableString(input) {
163
+ const value = readString(input);
164
+ return value || null;
165
+ }
166
+ function readNumber(input) {
167
+ return typeof input === "number" && Number.isFinite(input) ? input : 0;
168
+ }
169
+ function trackingReferencesFrom(row) {
170
+ return mapOmnipackTrackingReferences({
171
+ shipments: readArray(row.shipments),
172
+ trackingNumbers: readArray(row.trackingNumbers),
173
+ readString,
174
+ readNullableString,
175
+ asRecord,
176
+ });
177
+ }
@@ -0,0 +1,21 @@
1
+ import type { CanonicalLocalFulfillmentStatus, FulfillmentObservation, FulfillmentRefusal } from "../contracts/index.js";
2
+ import type { OmnipackWebhookEvidence } from "./mappers.js";
3
+ import { type OmnipackWebhookRouteEvent } from "./omnipackWebhookPayload.js";
4
+ export declare const refusal: (reason: FulfillmentRefusal["reason"], phase: FulfillmentRefusal["phase"], retryable?: boolean) => FulfillmentRefusal;
5
+ export declare const digest: (bytes: string | Uint8Array) => string;
6
+ /** References are opaque identifiers, never arbitrary provider prose or URLs. */
7
+ export declare function reference(value: string | null | undefined): string | null;
8
+ export declare function timestamp(value: string | null): string | null;
9
+ export declare function eventKind(value: string): OmnipackWebhookRouteEvent | null;
10
+ export declare function publicUrl(value: string | null, approve: (url: string) => boolean): string | null;
11
+ export declare function observation(input: {
12
+ evidence: OmnipackWebhookEvidence;
13
+ event: FulfillmentObservation["eventKind"];
14
+ status?: CanonicalLocalFulfillmentStatus;
15
+ receivedAt: string;
16
+ rawDigest: string;
17
+ evidenceRef: `evidence:${string}`;
18
+ source: "provider_webhook" | "provider_reconciliation";
19
+ fulfillmentRef?: string;
20
+ approveTrackingUrl: (url: string) => boolean;
21
+ }): FulfillmentObservation;
@@ -0,0 +1,57 @@
1
+ import { createHash } from "node:crypto";
2
+ import { parseNormalizedFulfillmentFact } from "@openlup/core/fulfillment";
3
+ import { EVENT_TO_STATUS } from "./omnipackWebhookPayload.js";
4
+ import { localStatusFor } from "./omnipackStatusVocabulary.js";
5
+ export const refusal = (reason, phase, retryable = false) => ({ reason, phase, retryable });
6
+ export const digest = (bytes) => createHash("sha256").update(bytes).digest("hex");
7
+ /** References are opaque identifiers, never arbitrary provider prose or URLs. */
8
+ export function reference(value) {
9
+ return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u.test(value) ? value : null;
10
+ }
11
+ export function timestamp(value) {
12
+ return value && /^\d{4}-\d\d-\d\dT/u.test(value) && Number.isFinite(Date.parse(value)) ? new Date(value).toISOString() : null;
13
+ }
14
+ export function eventKind(value) {
15
+ return Object.hasOwn(EVENT_TO_STATUS, value) ? value : null;
16
+ }
17
+ export function publicUrl(value, approve) {
18
+ if (!value)
19
+ return null;
20
+ try {
21
+ const url = new URL(value);
22
+ // Query-free URLs only: signing tokens and credentials never enter durable tracking.
23
+ return url.protocol === "https:" && !url.username && !url.password && !url.search && !url.hash && approve(url.href) ? url.href : null;
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
29
+ function tracking(refs, approve) {
30
+ return refs.flatMap(item => {
31
+ const trackingNumber = reference(item.trackingNumber);
32
+ return trackingNumber ? [{ trackingNumber, carrierRef: reference(item.carrier), serviceRef: reference(item.service), publicUrl: publicUrl(item.trackingUrl, approve) }] : [];
33
+ });
34
+ }
35
+ export function observation(input) {
36
+ const evidence = input.evidence;
37
+ const externalRef = reference(evidence.providerOrderId);
38
+ const providerFulfillmentRef = reference(evidence.fulfilmentNumber);
39
+ const orderNumber = reference(evidence.orderNumber);
40
+ const fulfillmentRef = reference(input.fulfillmentRef) ?? providerFulfillmentRef ?? externalRef ?? orderNumber;
41
+ if (!fulfillmentRef)
42
+ throw refusal("missing_correlation", "normalize");
43
+ const occurredAt = timestamp(evidence.occurredAt);
44
+ if (evidence.occurredAt && !occurredAt)
45
+ throw refusal("malformed", "normalize");
46
+ const key = digest(JSON.stringify([input.event, externalRef ?? orderNumber, providerFulfillmentRef, occurredAt]));
47
+ const status = input.status ?? localStatusFor(EVENT_TO_STATUS[input.event]);
48
+ const fact = parseNormalizedFulfillmentFact({
49
+ schemaVersion: 1, mapperVersion: "1", factId: key, providerKind: "omnipack", fulfillmentReference: fulfillmentRef,
50
+ canonicalStatus: status, provenance: { source: input.source, authority: "provider_asserted" },
51
+ occurredAt, receivedAt: input.receivedAt,
52
+ rawEvent: { reference: input.evidenceRef, digestAlgorithm: "sha256", digest: input.rawDigest },
53
+ }, { isCanonicalStatus: (value) => ["provider_received", "picking", "packed", "in_transit", "delivered", "exception", "cancelled"].includes(value) });
54
+ return { fact, eventKind: input.event, eventKey: key, firstReceivedAt: input.receivedAt,
55
+ correlation: { orderRef: null, fulfillmentRef: reference(input.fulfillmentRef), externalRef, orderNumber, providerFulfillmentRef, parcelRef: null },
56
+ trackingRefs: tracking(evidence.trackingReferences, input.approveTrackingUrl) };
57
+ }
@@ -0,0 +1,36 @@
1
+ import { buildOmnipackOutboundOrderEvidence, type OmnipackOutboundOrderPayload, type OmnipackOutboundDeliverySelection } from "./omnipackOutboundOrderPayload.js";
2
+ export interface OmnipackDispatchCandidate {
3
+ orderId: string;
4
+ orderNumber: string | null;
5
+ deliveryContact: {
6
+ revision: number;
7
+ recipientName: string | null;
8
+ contactEmail: string | null;
9
+ contactPhone: string | null;
10
+ line1: string;
11
+ city: string;
12
+ postalCode: string;
13
+ country: string;
14
+ selectedDelivery: OmnipackOutboundDeliverySelection | null;
15
+ } | null;
16
+ lines: Array<{
17
+ sku: string;
18
+ quantity: number;
19
+ productSnapshot: Record<string, unknown>;
20
+ }>;
21
+ }
22
+ export { buildOmnipackOutboundOrderEvidence as buildSanitizedEvidence };
23
+ export declare function buildOmnipackDispatchCommand(candidate: OmnipackDispatchCandidate): {
24
+ providerPayload: OmnipackOutboundOrderPayload;
25
+ body: string;
26
+ sanitizedRequest: {
27
+ deliveryContactRevision: number;
28
+ };
29
+ requestFingerprint: string;
30
+ };
31
+ export declare function buildOmnipackDispatchPayloadFromCandidate(candidate: OmnipackDispatchCandidate): OmnipackOutboundOrderPayload;
32
+ export declare function stableDispatchHash(value: unknown): string;
33
+ export declare function serializeOmnipackDispatchPayload(value: unknown): {
34
+ body: string;
35
+ requestFingerprint: string;
36
+ };
@@ -0,0 +1,63 @@
1
+ import { createHash } from "node:crypto";
2
+ import { buildOmnipackOutboundOrderEvidence, buildOmnipackOutboundOrderPayload, } from "./omnipackOutboundOrderPayload.js";
3
+ export { buildOmnipackOutboundOrderEvidence as buildSanitizedEvidence };
4
+ export function buildOmnipackDispatchCommand(candidate) {
5
+ const providerPayload = buildOmnipackDispatchPayloadFromCandidate(candidate);
6
+ const sanitizedRequest = {
7
+ ...buildOmnipackOutboundOrderEvidence(providerPayload),
8
+ deliveryContactRevision: candidate.deliveryContact?.revision ?? 0,
9
+ };
10
+ const serialized = serializeOmnipackDispatchPayload(providerPayload);
11
+ return {
12
+ providerPayload,
13
+ body: serialized.body,
14
+ sanitizedRequest,
15
+ // The hash commits to the request that may create a real provider effect.
16
+ // Only its digest is persisted; the PII-bearing input is never evidence.
17
+ requestFingerprint: serialized.requestFingerprint,
18
+ };
19
+ }
20
+ export function buildOmnipackDispatchPayloadFromCandidate(candidate) {
21
+ const contact = candidate.deliveryContact;
22
+ if (!contact)
23
+ throw new Error("omnipack_order_payload_missing_delivery_contact");
24
+ return buildOmnipackOutboundOrderPayload({
25
+ orderNumber: candidate.orderNumber ?? candidate.orderId,
26
+ deliverySelection: contact.selectedDelivery,
27
+ recipient: {
28
+ name: contact.recipientName ?? "",
29
+ email: contact.contactEmail,
30
+ phone: contact.contactPhone,
31
+ },
32
+ address: {
33
+ line1: contact.line1,
34
+ city: contact.city,
35
+ postalCode: contact.postalCode,
36
+ country: contact.country,
37
+ },
38
+ items: candidate.lines.map((line) => ({
39
+ sku: line.sku,
40
+ quantity: line.quantity,
41
+ lotNumber: nullableText(line.productSnapshot.lotNumber ?? line.productSnapshot.lotCode),
42
+ expirationDate: nullableText(line.productSnapshot.expirationDate ?? line.productSnapshot.expiresAt),
43
+ })),
44
+ });
45
+ }
46
+ export function stableDispatchHash(value) {
47
+ return serializeOmnipackDispatchPayload(value).requestFingerprint;
48
+ }
49
+ // Materialize once: the digest and createOrder consume these exact UTF-8 bytes.
50
+ export function serializeOmnipackDispatchPayload(value) {
51
+ const body = JSON.stringify(sortRecord(value));
52
+ return { body, requestFingerprint: createHash("sha256").update(body).digest("hex") };
53
+ }
54
+ function sortRecord(value) {
55
+ if (Array.isArray(value))
56
+ return value.map(sortRecord);
57
+ if (!value || typeof value !== "object")
58
+ return value;
59
+ return Object.fromEntries(Object.entries(value).sort().map(([key, child]) => [key, sortRecord(child)]));
60
+ }
61
+ function nullableText(value) {
62
+ return typeof value === "string" && value.trim() ? value.trim() : null;
63
+ }
@@ -0,0 +1,83 @@
1
+ export type OmnipackOutboundDeliveryKind = "courier" | "parcel-locker";
2
+ export interface OmnipackOutboundOrderInput {
3
+ orderNumber: string;
4
+ description?: string | null;
5
+ additionalCustomerOrderNumber?: string | null;
6
+ deliverySelection: OmnipackOutboundDeliverySelection | null;
7
+ recipient: {
8
+ name: string;
9
+ email: string | null;
10
+ phone: string | null;
11
+ };
12
+ address: {
13
+ line1: string;
14
+ city: string;
15
+ postalCode: string;
16
+ country: string;
17
+ };
18
+ items: Array<{
19
+ sku: string;
20
+ quantity: number;
21
+ lotNumber?: string | null;
22
+ expirationDate?: string | null;
23
+ }>;
24
+ orderValue?: {
25
+ amount: number;
26
+ currency: string;
27
+ } | null;
28
+ }
29
+ export interface OmnipackOutboundDeliverySelection {
30
+ providerKind?: string | null;
31
+ carrierKind?: string | null;
32
+ carrierCode?: string | null;
33
+ serviceCode?: string | null;
34
+ service?: string | null;
35
+ deliveryKind?: string | null;
36
+ kind?: string | null;
37
+ pickupPoint?: {
38
+ id?: string | null;
39
+ pointId?: string | null;
40
+ name?: string | null;
41
+ address?: {
42
+ line1?: string | null;
43
+ postalCode?: string | null;
44
+ city?: string | null;
45
+ country?: string | null;
46
+ } | null;
47
+ } | null;
48
+ }
49
+ export interface OmnipackOutboundOrderPayload {
50
+ orderNumber: string;
51
+ description?: string;
52
+ additionalCustomerOrderNumber?: string;
53
+ items: Array<{
54
+ sku: string;
55
+ quantity: number;
56
+ lotNumber?: string;
57
+ expirationDate?: string;
58
+ }>;
59
+ shippingDetails: {
60
+ carrier: string;
61
+ service: string;
62
+ address: {
63
+ name: string;
64
+ street: string;
65
+ city: string;
66
+ postCode: string;
67
+ phone: string;
68
+ email?: string;
69
+ country: string;
70
+ };
71
+ pickUpPoint?: string;
72
+ };
73
+ orderValue?: {
74
+ amount: number;
75
+ currency: string;
76
+ };
77
+ }
78
+ export declare class OmnipackOutboundOrderPayloadError extends Error {
79
+ readonly code: string;
80
+ constructor(code: string);
81
+ }
82
+ export declare function buildOmnipackOutboundOrderPayload(input: OmnipackOutboundOrderInput): OmnipackOutboundOrderPayload;
83
+ export declare function buildOmnipackOutboundOrderEvidence(payload: OmnipackOutboundOrderPayload): Record<string, unknown>;
@@ -0,0 +1,113 @@
1
+ export class OmnipackOutboundOrderPayloadError extends Error {
2
+ code;
3
+ constructor(code) {
4
+ super(code);
5
+ this.code = code;
6
+ this.name = "OmnipackOutboundOrderPayloadError";
7
+ }
8
+ }
9
+ export function buildOmnipackOutboundOrderPayload(input) {
10
+ const orderNumber = requiredText(input.orderNumber, "omnipack_order_payload_missing_order_number");
11
+ const selection = input.deliverySelection;
12
+ const providerKind = optionalText(selection?.providerKind);
13
+ if (providerKind !== "omnipack") {
14
+ throw new OmnipackOutboundOrderPayloadError("omnipack_order_payload_missing_omnipack_delivery_selection");
15
+ }
16
+ const service = requiredText(selection?.serviceCode ?? selection?.service, "omnipack_order_payload_missing_service");
17
+ const carrier = service;
18
+ const deliveryKind = readDeliveryKind(selection);
19
+ const pickUpPoint = readPickUpPoint(deliveryKind, selection);
20
+ const items = input.items.map((item) => {
21
+ const lotNumber = optionalText(item.lotNumber);
22
+ const expirationDate = optionalText(item.expirationDate);
23
+ return {
24
+ sku: requiredText(item.sku, "omnipack_order_payload_missing_sku"),
25
+ quantity: requiredQuantity(item.quantity),
26
+ ...(lotNumber ? { lotNumber } : {}),
27
+ ...(expirationDate ? { expirationDate } : {}),
28
+ };
29
+ });
30
+ if (items.length === 0) {
31
+ throw new OmnipackOutboundOrderPayloadError("omnipack_order_payload_missing_items");
32
+ }
33
+ return compactRecord({
34
+ orderNumber,
35
+ description: optionalText(input.description),
36
+ additionalCustomerOrderNumber: optionalText(input.additionalCustomerOrderNumber),
37
+ items,
38
+ shippingDetails: compactRecord({
39
+ carrier,
40
+ service,
41
+ address: compactRecord({
42
+ name: requiredText(input.recipient.name, "omnipack_order_payload_missing_recipient_name"),
43
+ street: requiredText(input.address.line1, "omnipack_order_payload_missing_address_street"),
44
+ city: requiredText(input.address.city, "omnipack_order_payload_missing_address_city"),
45
+ postCode: requiredText(input.address.postalCode, "omnipack_order_payload_missing_address_post_code"),
46
+ phone: requiredText(input.recipient.phone, "omnipack_order_payload_missing_recipient_phone"),
47
+ email: optionalText(input.recipient.email),
48
+ country: requiredText(input.address.country, "omnipack_order_payload_missing_address_country"),
49
+ }),
50
+ pickUpPoint,
51
+ }),
52
+ orderValue: validOrderValue(input.orderValue),
53
+ });
54
+ }
55
+ export function buildOmnipackOutboundOrderEvidence(payload) {
56
+ return {
57
+ provider: "omnipack",
58
+ requestKind: "outbound_order",
59
+ orderNumber: payload.orderNumber,
60
+ carrier: payload.shippingDetails.carrier,
61
+ service: payload.shippingDetails.service,
62
+ pickUpPoint: payload.shippingDetails.pickUpPoint ?? null,
63
+ itemCount: payload.items.length,
64
+ items: payload.items.map((item) => ({
65
+ sku: item.sku,
66
+ quantity: item.quantity,
67
+ lotNumber: item.lotNumber ?? null,
68
+ expirationDate: item.expirationDate ?? null,
69
+ })),
70
+ stockTruth: "external_stock_master_with_local_reservations",
71
+ };
72
+ }
73
+ function readDeliveryKind(selection) {
74
+ const value = optionalText(selection?.deliveryKind ?? selection?.kind);
75
+ if (value === "courier" || value === "parcel-locker")
76
+ return value;
77
+ throw new OmnipackOutboundOrderPayloadError("omnipack_order_payload_missing_delivery_kind");
78
+ }
79
+ function readPickUpPoint(deliveryKind, selection) {
80
+ if (deliveryKind !== "parcel-locker")
81
+ return undefined;
82
+ const point = optionalText(selection?.pickupPoint?.id ?? selection?.pickupPoint?.pointId);
83
+ if (!point)
84
+ throw new OmnipackOutboundOrderPayloadError("omnipack_order_payload_missing_pickup_point");
85
+ return point;
86
+ }
87
+ function requiredText(value, code) {
88
+ const text = optionalText(value);
89
+ if (!text)
90
+ throw new OmnipackOutboundOrderPayloadError(code);
91
+ return text;
92
+ }
93
+ function optionalText(value) {
94
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
95
+ }
96
+ function requiredQuantity(value) {
97
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
98
+ throw new OmnipackOutboundOrderPayloadError("omnipack_order_payload_invalid_quantity");
99
+ }
100
+ return value;
101
+ }
102
+ function validOrderValue(value) {
103
+ if (!value)
104
+ return undefined;
105
+ if (typeof value.amount !== "number" || value.amount <= 0 || !Number.isFinite(value.amount)) {
106
+ throw new OmnipackOutboundOrderPayloadError("omnipack_order_payload_invalid_order_value");
107
+ }
108
+ const currency = requiredText(value.currency, "omnipack_order_payload_missing_order_value_currency");
109
+ return { amount: value.amount, currency };
110
+ }
111
+ function compactRecord(record) {
112
+ return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));
113
+ }
@@ -0,0 +1,11 @@
1
+ export type OmnipackPackKind = "unit" | "collective";
2
+ export interface OmnipackProductPackInput {
3
+ ean: string;
4
+ quantity: number;
5
+ }
6
+ export declare class OmnipackProductPackPayloadError extends Error {
7
+ readonly code: string;
8
+ constructor(code: string);
9
+ }
10
+ export declare function omnipackPackKindForQuantity(quantity: number): OmnipackPackKind;
11
+ export declare function buildOmnipackProductPackPayload(input: OmnipackProductPackInput): Record<string, unknown>;
@@ -0,0 +1,38 @@
1
+ // Pure builder for the OmniPack product-pack request (POST /products/{sku}/packs). A pack is
2
+ // one EAN bound to a product: quantity === 1 is a sellable unit, quantity > 1 is a collective
3
+ // carton (N units behind one barcode). One SKU therefore maps to MANY packs (unit barcode / alternate barcode
4
+ // / collective carton). Mirrors the product/inbound payload convention (pure builder in
5
+ // server/_lib, wired through the client). The exact OmniPack request key names live behind the
6
+ // constants below so finalizing them against the (auth-gated) OmniPack product API docs is a
7
+ // one-line edit.
8
+ // Product-pack request key names (confirm against the OmniPack product-pack API docs).
9
+ const KEY_EAN = "ean";
10
+ const KEY_QUANTITY = "quantity";
11
+ export class OmnipackProductPackPayloadError extends Error {
12
+ code;
13
+ constructor(code) {
14
+ super(`omnipack_product_pack_payload_invalid: ${code}`);
15
+ this.code = code;
16
+ this.name = "OmnipackProductPackPayloadError";
17
+ }
18
+ }
19
+ function requireNonEmpty(value, code) {
20
+ const trimmed = value?.trim();
21
+ if (!trimmed)
22
+ throw new OmnipackProductPackPayloadError(code);
23
+ return trimmed;
24
+ }
25
+ // A pack with quantity 1 is a sellable unit; quantity > 1 is a collective carton. Pure so the
26
+ // push worker and the DB layer derive the same `kind` from the same rule.
27
+ export function omnipackPackKindForQuantity(quantity) {
28
+ return quantity > 1 ? "collective" : "unit";
29
+ }
30
+ // Builds the product-pack payload. EAN is required (OmniPack matches physical goods by barcode);
31
+ // quantity must be a positive integer (the number of sellable units behind this EAN).
32
+ export function buildOmnipackProductPackPayload(input) {
33
+ const ean = requireNonEmpty(input.ean, "missing_ean");
34
+ if (!Number.isInteger(input.quantity) || input.quantity <= 0) {
35
+ throw new OmnipackProductPackPayloadError("invalid_quantity");
36
+ }
37
+ return { [KEY_EAN]: ean, [KEY_QUANTITY]: input.quantity };
38
+ }