@openlup/platform 0.21.0 → 0.23.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 (349) hide show
  1. package/CHANGELOG.md +432 -146
  2. package/README.md +82 -589
  3. package/dist/composition/composeBundle.d.ts +7 -0
  4. package/dist/composition/composeBundle.js +2 -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 +1 -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 +95 -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 +143 -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 +72 -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 +59 -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 +89 -0
  46. package/dist/fulfillment/contracts/store.js +1 -0
  47. package/dist/fulfillment/contracts/sync.d.ts +226 -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 +26 -0
  56. package/dist/fulfillment/dispatchProjection.js +107 -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 +38 -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 +32 -0
  70. package/dist/fulfillment/migrations.js +9 -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 +32 -0
  76. package/dist/fulfillment/observationProjection.js +90 -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 +39 -0
  80. package/dist/fulfillment/omnipack/client.js +172 -0
  81. package/dist/fulfillment/omnipack/index.d.ts +55 -0
  82. package/dist/fulfillment/omnipack/index.js +408 -0
  83. package/dist/fulfillment/omnipack/mappers.d.ts +79 -0
  84. package/dist/fulfillment/omnipack/mappers.js +199 -0
  85. package/dist/fulfillment/omnipack/observation.d.ts +28 -0
  86. package/dist/fulfillment/omnipack/observation.js +72 -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/reconciliation.d.ts +15 -0
  106. package/dist/fulfillment/omnipack/reconciliation.js +55 -0
  107. package/dist/fulfillment/omnipack/trackingReferences.d.ts +16 -0
  108. package/dist/fulfillment/omnipack/trackingReferences.js +52 -0
  109. package/dist/fulfillment/paidFulfillmentRecovery.d.ts +67 -0
  110. package/dist/fulfillment/paidFulfillmentRecovery.js +154 -0
  111. package/dist/fulfillment/paidHandoff.d.ts +27 -0
  112. package/dist/fulfillment/paidHandoff.js +86 -0
  113. package/dist/fulfillment/paidHandoffPorts.d.ts +24 -0
  114. package/dist/fulfillment/paidHandoffPorts.js +3 -0
  115. package/dist/fulfillment/postgresDeliveryAlignment.d.ts +4 -0
  116. package/dist/fulfillment/postgresDeliveryAlignment.js +12 -0
  117. package/dist/fulfillment/postgresDispatchStore.d.ts +16 -0
  118. package/dist/fulfillment/postgresDispatchStore.js +44 -0
  119. package/dist/fulfillment/postgresEvidenceReadPort.d.ts +25 -0
  120. package/dist/fulfillment/postgresEvidenceReadPort.js +45 -0
  121. package/dist/fulfillment/postgresPaidFulfillmentRecovery.d.ts +25 -0
  122. package/dist/fulfillment/postgresPaidFulfillmentRecovery.js +26 -0
  123. package/dist/fulfillment/postgresPaidHandoffStore.d.ts +4 -0
  124. package/dist/fulfillment/postgresPaidHandoffStore.js +10 -0
  125. package/dist/fulfillment/postgresShipmentSpine.d.ts +70 -0
  126. package/dist/fulfillment/postgresShipmentSpine.js +246 -0
  127. package/dist/fulfillment/postgresStockSyncPort.d.ts +8 -0
  128. package/dist/fulfillment/postgresStockSyncPort.js +66 -0
  129. package/dist/fulfillment/productReconciliationEvidenceHandler.d.ts +36 -0
  130. package/dist/fulfillment/productReconciliationEvidenceHandler.js +50 -0
  131. package/dist/fulfillment/providerCapabilities.d.ts +9 -0
  132. package/dist/fulfillment/providerCapabilities.js +17 -0
  133. package/dist/fulfillment/providerCommandLedger.d.ts +143 -0
  134. package/dist/fulfillment/providerCommandLedger.js +14 -0
  135. package/dist/fulfillment/providerDispatchAcceptance.d.ts +27 -0
  136. package/dist/fulfillment/providerDispatchAcceptance.js +29 -0
  137. package/dist/fulfillment/providerDispatchError.d.ts +6 -0
  138. package/dist/fulfillment/providerDispatchError.js +5 -0
  139. package/dist/fulfillment/providerDispatchWorker.d.ts +44 -0
  140. package/dist/fulfillment/providerDispatchWorker.js +199 -0
  141. package/dist/fulfillment/providerProductSyncWorker.d.ts +28 -0
  142. package/dist/fulfillment/providerProductSyncWorker.js +122 -0
  143. package/dist/fulfillment/providerReconciliationError.d.ts +9 -0
  144. package/dist/fulfillment/providerReconciliationError.js +17 -0
  145. package/dist/fulfillment/providerReconciliationTerminalSkip.d.ts +2 -0
  146. package/dist/fulfillment/providerReconciliationTerminalSkip.js +6 -0
  147. package/dist/fulfillment/providerReconciliationTimestamp.d.ts +1 -0
  148. package/dist/fulfillment/providerReconciliationTimestamp.js +27 -0
  149. package/dist/fulfillment/providerReconciliationWorker.d.ts +90 -0
  150. package/dist/fulfillment/providerReconciliationWorker.js +207 -0
  151. package/dist/fulfillment/providerStockAvailability.d.ts +13 -0
  152. package/dist/fulfillment/providerStockAvailability.js +51 -0
  153. package/dist/fulfillment/providerStockSyncWorker.d.ts +41 -0
  154. package/dist/fulfillment/providerStockSyncWorker.js +295 -0
  155. package/dist/fulfillment/providerTrackingReferences.d.ts +16 -0
  156. package/dist/fulfillment/providerTrackingReferences.js +23 -0
  157. package/dist/fulfillment/replacementRefusals.d.ts +5 -0
  158. package/dist/fulfillment/replacementRefusals.js +38 -0
  159. package/dist/fulfillment/replacementShipmentHandler.d.ts +5 -0
  160. package/dist/fulfillment/replacementShipmentHandler.js +46 -0
  161. package/dist/fulfillment/schemaCapabilities.d.ts +13 -0
  162. package/dist/fulfillment/schemaCapabilities.js +7 -0
  163. package/dist/fulfillment/shipmentsOverviewHandler.d.ts +16 -0
  164. package/dist/fulfillment/shipmentsOverviewHandler.js +54 -0
  165. package/dist/fulfillment/statusMap.d.ts +2 -0
  166. package/dist/fulfillment/statusMap.js +1 -0
  167. package/dist/fulfillment/trackingProgress.d.ts +1 -0
  168. package/dist/fulfillment/trackingProgress.js +1 -0
  169. package/dist/fulfillment/verifiedIngress.d.ts +79 -0
  170. package/dist/fulfillment/verifiedIngress.js +94 -0
  171. package/dist/invoicing/capabilities.d.ts +11 -0
  172. package/dist/invoicing/capabilities.js +10 -0
  173. package/dist/invoicing/contracts/capabilities.d.ts +40 -0
  174. package/dist/invoicing/contracts/capabilities.js +1 -0
  175. package/dist/invoicing/contracts/companyLookup.d.ts +49 -0
  176. package/dist/invoicing/contracts/companyLookup.js +1 -0
  177. package/dist/invoicing/contracts/delivery.d.ts +74 -0
  178. package/dist/invoicing/contracts/delivery.js +1 -0
  179. package/dist/invoicing/contracts/facts.d.ts +100 -0
  180. package/dist/invoicing/contracts/facts.js +1 -0
  181. package/dist/invoicing/contracts/host.d.ts +246 -0
  182. package/dist/invoicing/contracts/host.js +1 -0
  183. package/dist/invoicing/contracts/index.d.ts +16 -0
  184. package/dist/invoicing/contracts/index.js +1 -0
  185. package/dist/invoicing/contracts/provider.d.ts +126 -0
  186. package/dist/invoicing/contracts/provider.js +1 -0
  187. package/dist/invoicing/contracts/settlement.d.ts +66 -0
  188. package/dist/invoicing/contracts/settlement.js +1 -0
  189. package/dist/invoicing/contracts/store.d.ts +267 -0
  190. package/dist/invoicing/contracts/store.js +1 -0
  191. package/dist/invoicing/index.d.ts +1 -0
  192. package/dist/invoicing/index.js +1 -0
  193. package/dist/payments/stripe/index.d.ts +25 -0
  194. package/dist/payments/stripe/index.js +25 -0
  195. package/dist/payments/tpay/index.d.ts +30 -0
  196. package/dist/payments/tpay/index.js +30 -0
  197. package/dist/subscriptions/automaticRenewal.d.ts +44 -0
  198. package/dist/subscriptions/automaticRenewal.js +81 -0
  199. package/dist/subscriptions/automaticRenewalExecution.d.ts +21 -0
  200. package/dist/subscriptions/automaticRenewalExecution.js +44 -0
  201. package/dist/subscriptions/contracts/commands.d.ts +115 -0
  202. package/dist/subscriptions/contracts/commands.js +1 -0
  203. package/dist/subscriptions/contracts/dunning.d.ts +133 -0
  204. package/dist/subscriptions/contracts/dunning.js +1 -0
  205. package/dist/subscriptions/contracts/index.d.ts +6 -0
  206. package/dist/subscriptions/contracts/index.js +1 -0
  207. package/dist/subscriptions/contracts/messages.d.ts +43 -0
  208. package/dist/subscriptions/contracts/messages.js +1 -0
  209. package/dist/subscriptions/contracts/renewal.d.ts +533 -0
  210. package/dist/subscriptions/contracts/renewal.js +1 -0
  211. package/dist/subscriptions/contracts/stockWait.d.ts +73 -0
  212. package/dist/subscriptions/contracts/stockWait.js +1 -0
  213. package/dist/subscriptions/index.d.ts +39 -0
  214. package/dist/subscriptions/index.js +17 -0
  215. package/dist/subscriptions/paymentOutcomes.d.ts +8 -0
  216. package/dist/subscriptions/paymentOutcomes.js +27 -0
  217. package/dist/subscriptions/postgresRenewalStore.d.ts +20 -0
  218. package/dist/subscriptions/postgresRenewalStore.js +61 -0
  219. package/dist/subscriptions/postgresRetryStore.d.ts +78 -0
  220. package/dist/subscriptions/postgresRetryStore.js +142 -0
  221. package/dist/subscriptions/renewalCycleFailureMechanism.d.ts +34 -0
  222. package/dist/subscriptions/renewalCycleFailureMechanism.js +79 -0
  223. package/dist/subscriptions/renewalCycleMechanism.d.ts +46 -0
  224. package/dist/subscriptions/renewalCycleMechanism.js +157 -0
  225. package/dist/subscriptions/renewalCycleRefusalMechanism.d.ts +41 -0
  226. package/dist/subscriptions/renewalCycleRefusalMechanism.js +160 -0
  227. package/dist/subscriptions/renewalIdentity.d.ts +3 -0
  228. package/dist/subscriptions/renewalIdentity.js +4 -0
  229. package/package.json +37 -2
  230. package/release-gates.json +97 -3
  231. package/sql/20260808210000_fulfillment_shipment_rail.sql +810 -0
  232. package/sql/20260819150000_fulfillment_shipment_sequence.sql +98 -0
  233. package/sql/20261022080000_fulfillment_command_ledger.sql +786 -0
  234. package/sql/20261022090000_fulfillment_delivery_alignment.sql +1106 -0
  235. package/sql/20261022160000_subscription_retry_lifecycle.sql +328 -0
  236. package/sql/20261022165000_fulfillment_stock_evidence_replay_reopen.sql +30 -0
  237. package/src/composition/composeBundle.ts +4 -0
  238. package/src/composition/fulfillmentContribution.ts +28 -0
  239. package/src/composition/index.ts +1 -0
  240. package/src/fulfillment/adapterConformance.ts +195 -0
  241. package/src/fulfillment/bindings.ts +26 -0
  242. package/src/fulfillment/commerceFulfillmentHandlers.ts +263 -0
  243. package/src/fulfillment/commerceFulfillmentReadModel.ts +257 -0
  244. package/src/fulfillment/contracts/alignment.ts +13 -0
  245. package/src/fulfillment/contracts/bindings.ts +30 -0
  246. package/src/fulfillment/contracts/capabilities.ts +15 -0
  247. package/src/fulfillment/contracts/conformance.ts +63 -0
  248. package/src/fulfillment/contracts/customerAlignment.ts +4 -0
  249. package/src/fulfillment/contracts/dispatch.ts +73 -0
  250. package/src/fulfillment/contracts/index.ts +18 -0
  251. package/src/fulfillment/contracts/label.ts +9 -0
  252. package/src/fulfillment/contracts/nativeUnsupported.ts +6 -0
  253. package/src/fulfillment/contracts/observation.ts +26 -0
  254. package/src/fulfillment/contracts/operator.ts +31 -0
  255. package/src/fulfillment/contracts/read.ts +42 -0
  256. package/src/fulfillment/contracts/readback.ts +24 -0
  257. package/src/fulfillment/contracts/replacement.ts +15 -0
  258. package/src/fulfillment/contracts/store.ts +27 -0
  259. package/src/fulfillment/contracts/sync.ts +72 -0
  260. package/src/fulfillment/currentFulfillmentParcel.ts +2 -0
  261. package/src/fulfillment/delayReadModel.ts +60 -0
  262. package/src/fulfillment/deliveryAlignmentReadModel.ts +15 -0
  263. package/src/fulfillment/dispatchProjection.ts +105 -0
  264. package/src/fulfillment/fulfillmentObservationEffects.ts +86 -0
  265. package/src/fulfillment/handlerSchemas.ts +255 -0
  266. package/src/fulfillment/handlerSupport.ts +25 -0
  267. package/src/fulfillment/index.ts +39 -0
  268. package/src/fulfillment/labelLifecycle.ts +11 -0
  269. package/src/fulfillment/lowStockEvidenceHandler.ts +60 -0
  270. package/src/fulfillment/migrations.ts +9 -0
  271. package/src/fulfillment/nativeUnsupported.ts +23 -0
  272. package/src/fulfillment/normalizedFulfillmentFacts.ts +2 -0
  273. package/src/fulfillment/observationProjection.ts +92 -0
  274. package/src/fulfillment/omnipack/capabilities.ts +18 -0
  275. package/src/fulfillment/omnipack/client.ts +270 -0
  276. package/src/fulfillment/omnipack/index.ts +369 -0
  277. package/src/fulfillment/omnipack/mappers.ts +282 -0
  278. package/src/fulfillment/omnipack/observation.ts +79 -0
  279. package/src/fulfillment/omnipack/omnipackDispatchPayload.ts +93 -0
  280. package/src/fulfillment/omnipack/omnipackOutboundOrderPayload.ts +194 -0
  281. package/src/fulfillment/omnipack/omnipackProductPackPayload.ts +47 -0
  282. package/src/fulfillment/omnipack/omnipackProductPayload.ts +67 -0
  283. package/src/fulfillment/omnipack/omnipackReconciliationPayload.ts +7 -0
  284. package/src/fulfillment/omnipack/omnipackStatusVocabulary.ts +103 -0
  285. package/src/fulfillment/omnipack/omnipackWebhookPayload.ts +73 -0
  286. package/src/fulfillment/omnipack/productSyncMappers.ts +74 -0
  287. package/src/fulfillment/omnipack/providerError.ts +64 -0
  288. package/src/fulfillment/omnipack/reconciliation.ts +56 -0
  289. package/src/fulfillment/omnipack/trackingReferences.ts +77 -0
  290. package/src/fulfillment/paidFulfillmentRecovery.ts +252 -0
  291. package/src/fulfillment/paidHandoff.ts +122 -0
  292. package/src/fulfillment/paidHandoffPorts.ts +21 -0
  293. package/src/fulfillment/postgresDeliveryAlignment.ts +14 -0
  294. package/src/fulfillment/postgresDispatchStore.ts +55 -0
  295. package/src/fulfillment/postgresEvidenceReadPort.ts +59 -0
  296. package/src/fulfillment/postgresPaidFulfillmentRecovery.ts +29 -0
  297. package/src/fulfillment/postgresPaidHandoffStore.ts +11 -0
  298. package/src/fulfillment/postgresShipmentSpine.ts +338 -0
  299. package/src/fulfillment/postgresStockSyncPort.ts +68 -0
  300. package/src/fulfillment/productReconciliationEvidenceHandler.ts +64 -0
  301. package/src/fulfillment/providerCapabilities.ts +18 -0
  302. package/src/fulfillment/providerCommandLedger.ts +53 -0
  303. package/src/fulfillment/providerDispatchAcceptance.ts +37 -0
  304. package/src/fulfillment/providerDispatchError.ts +7 -0
  305. package/src/fulfillment/providerDispatchWorker.ts +159 -0
  306. package/src/fulfillment/providerProductSyncWorker.ts +154 -0
  307. package/src/fulfillment/providerReconciliationError.ts +20 -0
  308. package/src/fulfillment/providerReconciliationTerminalSkip.ts +8 -0
  309. package/src/fulfillment/providerReconciliationTimestamp.ts +34 -0
  310. package/src/fulfillment/providerReconciliationWorker.ts +206 -0
  311. package/src/fulfillment/providerStockAvailability.ts +60 -0
  312. package/src/fulfillment/providerStockSyncWorker.ts +318 -0
  313. package/src/fulfillment/providerTrackingReferences.ts +32 -0
  314. package/src/fulfillment/replacementRefusals.ts +43 -0
  315. package/src/fulfillment/replacementShipmentHandler.ts +47 -0
  316. package/src/fulfillment/schemaCapabilities.ts +7 -0
  317. package/src/fulfillment/shipmentsOverviewHandler.ts +73 -0
  318. package/src/fulfillment/statusMap.ts +2 -0
  319. package/src/fulfillment/trackingProgress.ts +1 -0
  320. package/src/fulfillment/verifiedIngress.ts +113 -0
  321. package/src/invoicing/capabilities.ts +9 -0
  322. package/src/invoicing/contracts/capabilities.ts +15 -0
  323. package/src/invoicing/contracts/companyLookup.ts +13 -0
  324. package/src/invoicing/contracts/delivery.ts +24 -0
  325. package/src/invoicing/contracts/facts.ts +60 -0
  326. package/src/invoicing/contracts/host.ts +85 -0
  327. package/src/invoicing/contracts/index.ts +16 -0
  328. package/src/invoicing/contracts/provider.ts +78 -0
  329. package/src/invoicing/contracts/settlement.ts +39 -0
  330. package/src/invoicing/contracts/store.ts +98 -0
  331. package/src/invoicing/index.ts +1 -0
  332. package/src/payments/stripe/index.ts +30 -0
  333. package/src/payments/tpay/index.ts +36 -0
  334. package/src/subscriptions/automaticRenewal.ts +87 -0
  335. package/src/subscriptions/automaticRenewalExecution.ts +39 -0
  336. package/src/subscriptions/contracts/commands.ts +46 -0
  337. package/src/subscriptions/contracts/dunning.ts +48 -0
  338. package/src/subscriptions/contracts/index.ts +6 -0
  339. package/src/subscriptions/contracts/messages.ts +18 -0
  340. package/src/subscriptions/contracts/renewal.ts +325 -0
  341. package/src/subscriptions/contracts/stockWait.ts +34 -0
  342. package/src/subscriptions/index.ts +24 -0
  343. package/src/subscriptions/paymentOutcomes.ts +23 -0
  344. package/src/subscriptions/postgresRenewalStore.ts +76 -0
  345. package/src/subscriptions/postgresRetryStore.ts +174 -0
  346. package/src/subscriptions/renewalCycleFailureMechanism.ts +119 -0
  347. package/src/subscriptions/renewalCycleMechanism.ts +225 -0
  348. package/src/subscriptions/renewalCycleRefusalMechanism.ts +215 -0
  349. package/src/subscriptions/renewalIdentity.ts +5 -0
@@ -0,0 +1 @@
1
+ export { parcelSequenceNo, compareParcelPrecedence, currentParcel, currentParcelFor, currentParcelPerOrder, currentParcelFirst, belongsToParcel, rowsForParcel } from "@openlup/core/fulfillment";
@@ -0,0 +1,11 @@
1
+ import type { CustomerDeliveryAlignment, FulfillmentCustomerAlignmentRowsReader } from './contracts/customerAlignment.js';
2
+ import type { FulfillmentNativeUnsupported } from './contracts/nativeUnsupported.js';
3
+ export type DeliveryAlignmentRow = Record<string, unknown>;
4
+ export type DeliveryAlignmentRowsReader = FulfillmentCustomerAlignmentRowsReader;
5
+ /**
6
+ * Reads only customer-safe current cases. An aligned case remains current while
7
+ * its aligned schedule is still the subscription's next schedule; once a paid
8
+ * cycle advances `next_cycle_at`, the historical ledger row disappears from UI.
9
+ */
10
+ export declare function readFulfillmentDelay(readRows: DeliveryAlignmentRowsReader | undefined, nextCycleAtBySubscription: ReadonlyMap<string, string | null>): Promise<Map<string, CustomerDeliveryAlignment> | FulfillmentNativeUnsupported>;
11
+ export declare function mapCurrentDeliveryAlignments(rows: DeliveryAlignmentRow[], nextCycleAtBySubscription: ReadonlyMap<string, string | null>): Map<string, CustomerDeliveryAlignment>;
@@ -0,0 +1,45 @@
1
+ import { isNativeUnsupported } from './handlerSupport.js';
2
+ /**
3
+ * Reads only customer-safe current cases. An aligned case remains current while
4
+ * its aligned schedule is still the subscription's next schedule; once a paid
5
+ * cycle advances `next_cycle_at`, the historical ledger row disappears from UI.
6
+ */
7
+ export async function readFulfillmentDelay(readRows, nextCycleAtBySubscription) {
8
+ const subscriptionIds = [...nextCycleAtBySubscription.keys()].filter(Boolean);
9
+ if (!readRows || subscriptionIds.length === 0)
10
+ return new Map();
11
+ const rows = await readRows(subscriptionIds);
12
+ if (isNativeUnsupported(rows))
13
+ return rows;
14
+ return mapCurrentDeliveryAlignments(rows, nextCycleAtBySubscription);
15
+ }
16
+ export function mapCurrentDeliveryAlignments(rows, nextCycleAtBySubscription) {
17
+ const result = new Map();
18
+ for (const row of rows) {
19
+ const subscriptionId = text(row.subscription_id);
20
+ if (!subscriptionId || result.has(subscriptionId))
21
+ continue;
22
+ const state = text(row.state);
23
+ if (state === "protected") {
24
+ result.set(subscriptionId, { state });
25
+ continue;
26
+ }
27
+ if (state === "aligned" && sameInstant(nullableText(row.aligned_next_cycle_at), nextCycleAtBySubscription.get(subscriptionId) ?? null)) {
28
+ result.set(subscriptionId, { state });
29
+ }
30
+ }
31
+ return result;
32
+ }
33
+ function sameInstant(left, right) {
34
+ if (!left || !right)
35
+ return false;
36
+ const leftTime = new Date(left).getTime();
37
+ const rightTime = new Date(right).getTime();
38
+ return Number.isFinite(leftTime) && leftTime === rightTime;
39
+ }
40
+ function text(value) {
41
+ return typeof value === "string" ? value : "";
42
+ }
43
+ function nullableText(value) {
44
+ return typeof value === "string" && value ? value : null;
45
+ }
@@ -0,0 +1,4 @@
1
+ import type { DeliveryAlignmentPort } from './contracts/index.js';
2
+ import type { PgExecutor } from './postgresDispatchStore.js';
3
+ /** Server-authorized projection; database browser roles have no direct access. */
4
+ export declare function readDeliveryAlignment(db: PgExecutor, fulfillmentRef: string): ReturnType<DeliveryAlignmentPort['read']>;
@@ -0,0 +1,12 @@
1
+ /** Server-authorized projection; database browser roles have no direct access. */
2
+ export async function readDeliveryAlignment(db, fulfillmentRef) {
3
+ const result = await db.query(`SELECT alignment.state, alignment.aligned_next_cycle_at
4
+ FROM public.fulfillment_shipments shipment
5
+ LEFT JOIN public.subscription_delivery_alignment_cases alignment ON alignment.predecessor_order_id=shipment.order_id
6
+ WHERE shipment.id=$1::uuid
7
+ ORDER BY (alignment.state IN ('protected','manual_review')) DESC, alignment.created_at ASC LIMIT 1`, [fulfillmentRef]);
8
+ const row = result.rows[0];
9
+ const date = row?.aligned_next_cycle_at;
10
+ return { disposition: row?.state === 'aligned' ? 'aligned' : row?.state === 'protected' ? 'outstanding' : 'manual_review',
11
+ nextCycleAt: date instanceof Date ? date.toISOString() : typeof date === 'string' ? date : null };
12
+ }
@@ -0,0 +1,26 @@
1
+ import type { DispatchEvidence, DispatchRecord, FulfillmentDispatchRequest, FulfillmentDispatchResult, FulfillmentOperationError } from "./contracts/index.js";
2
+ /** Machine identities only: arbitrary exception prose, URLs and credentials are omitted. */
3
+ export declare function safeDiagnosticCode(value: unknown): string | null;
4
+ export declare function localFailureReason(stage: string, error: unknown, privacy?: {
5
+ token(value: string | null | undefined, codec?: (value: string) => string | null): string | null;
6
+ readonly redactedFieldCount: number;
7
+ }): string;
8
+ export declare function operationError(error: Omit<FulfillmentOperationError, "cause"> & {
9
+ cause?: unknown;
10
+ }): FulfillmentOperationError;
11
+ export declare const reference: (value: unknown) => string | null;
12
+ /** Opaque by default; an explicit allowlist can admit wider incumbent references. */
13
+ export declare function admittedReference(value: string | null | undefined, approve?: (value: string) => boolean): string | null;
14
+ /** One counted sanitizer for durable projections; codecs are explicit host policy. */
15
+ export declare function durableStrings(priorCount?: number): {
16
+ token(value: string | null | undefined, codec?: (value: string) => string | null): string | null;
17
+ readonly redactedFieldCount: number;
18
+ };
19
+ /** Copy only the durable allowlist, including when an adapter object has extra runtime properties. */
20
+ export declare function dispatchEvidence(evidence: DispatchEvidence): DispatchEvidence;
21
+ /** Shadow has a local command identity; it never invokes a provider or resolves credentials. */
22
+ export declare function shadowDispatchEvidence(request: FulfillmentDispatchRequest): DispatchEvidence;
23
+ export declare function dispatchResult(result: FulfillmentDispatchResult): FulfillmentDispatchResult;
24
+ export declare function acceptedProviderProof(record: DispatchRecord | null): record is DispatchRecord & {
25
+ externalRef: string;
26
+ };
@@ -0,0 +1,107 @@
1
+ import { createHash } from "node:crypto";
2
+ /** Machine identities only: arbitrary exception prose, URLs and credentials are omitted. */
3
+ export function safeDiagnosticCode(value) {
4
+ return reference(value) && typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9_]{0,95}$/u.test(value) ? value : null;
5
+ }
6
+ export function localFailureReason(stage, error, privacy = durableStrings()) {
7
+ if (!error || typeof error !== "object")
8
+ return stage;
9
+ const fields = error;
10
+ const diagnostic = (value) => typeof value === "string" ? privacy.token(value, safeDiagnosticCode) : null;
11
+ const ownCode = diagnostic(fields.code), causeCode = diagnostic(fields.causeCode), causeMessage = diagnostic(fields.causeMessage);
12
+ const messagePattern = /^([A-Za-z][A-Za-z0-9_]*)(?::([A-Z0-9]{5}))?$/u;
13
+ const safeMessage = typeof fields.message === "string" ? privacy.token(fields.message, value => messagePattern.test(value) ? value : null) : null;
14
+ const message = safeMessage?.match(messagePattern);
15
+ const cause = causeMessage ?? (message && (message[2] || /_(?:failed|down|missing|invalid|conflict|not_found)$/u.test(message[1])) ? safeDiagnosticCode(message[1]) : null);
16
+ const code = causeCode ?? ownCode ?? message?.[2];
17
+ return [stage, cause, code].filter(Boolean).join(":");
18
+ }
19
+ export function operationError(error) {
20
+ const privacy = durableStrings(error.redactedFieldCount);
21
+ const code = privacy.token(error.code, safeDiagnosticCode) ?? "operation_failed";
22
+ const cause = typeof error.cause === "string" ? privacy.token(error.cause, value => /^ack(?::[A-Za-z0-9_]{1,96}){0,2}$/u.test(value) ? value.slice(0, 180) : null) : null;
23
+ return { code, status: Number.isInteger(error.status) && error.status >= 100 && error.status <= 599 ? error.status : null,
24
+ retryable: error.retryable === true, mayHaveSucceeded: error.mayHaveSucceeded === true,
25
+ ...(cause ? { cause } : {}), ...(privacy.redactedFieldCount ? { redactedFieldCount: privacy.redactedFieldCount } : {}) };
26
+ }
27
+ // The fulfillment opaque-ID rule; never accept free-form metadata as a reference.
28
+ export const reference = (value) => typeof value === "string"
29
+ && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u.test(value) ? value : null;
30
+ /** Opaque by default; an explicit allowlist can admit wider incumbent references. */
31
+ export function admittedReference(value, approve) {
32
+ if (typeof value !== "string" || /[\p{Cc}\p{Cf}]/u.test(value))
33
+ return null;
34
+ const admitted = approve ? approve(value) : reference(value) !== null;
35
+ const text = value.trim();
36
+ return admitted && text && text.length <= 256 && !/[@]|[a-z][a-z0-9+.-]*:\/\//iu.test(text) ? text : null;
37
+ }
38
+ const isoDate = (value) => typeof value === "string"
39
+ && /^\d{4}-\d\d-\d\d$/u.test(value) && Number.isFinite(Date.parse(value))
40
+ && new Date(value).toISOString().slice(0, 10) === value ? value : null;
41
+ /** One counted sanitizer for durable projections; codecs are explicit host policy. */
42
+ export function durableStrings(priorCount = 0) {
43
+ let count = Number.isSafeInteger(priorCount) && priorCount > 0 ? priorCount : 0;
44
+ return {
45
+ token(value, codec = reference) {
46
+ if (value == null)
47
+ return null;
48
+ const safe = codec(value);
49
+ if (safe === null)
50
+ count += 1;
51
+ return safe;
52
+ },
53
+ get redactedFieldCount() { return count; },
54
+ };
55
+ }
56
+ /** Copy only the durable allowlist, including when an adapter object has extra runtime properties. */
57
+ export function dispatchEvidence(evidence) {
58
+ const privacy = durableStrings(evidence.redactedFieldCount ?? evidence.transcript?.redactedFieldCount);
59
+ const sanitize = privacy.token;
60
+ const commandFingerprint = evidence.commandFingerprint;
61
+ const source = evidence.contactRevision.source;
62
+ const providerRef = sanitize(evidence.providerRef) ?? "redacted", carrierRef = sanitize(evidence.carrierRef), serviceRef = sanitize(evidence.serviceRef);
63
+ const mode = evidence.mapping ? (sanitize(evidence.mapping.mode) ?? "shadow") : null;
64
+ const transcript = evidence.transcript ? {
65
+ itemCount: evidence.transcript.items.length,
66
+ items: evidence.transcript.items.map(item => ({ skuRef: sanitize(item.skuRef) ?? "redacted", quantity: Number.isSafeInteger(item.quantity) && item.quantity > 0 ? item.quantity : 0,
67
+ lotRef: sanitize(item.lotRef), expirationDate: sanitize(item.expirationDate, isoDate) })),
68
+ deliveryKind: evidence.transcript.deliveryKind === "parcel-locker" ? "parcel-locker" : "courier",
69
+ pickupPointRef: sanitize(evidence.transcript.pickupPointRef),
70
+ ...(privacy.redactedFieldCount > 0 ? { redactedFieldCount: privacy.redactedFieldCount } : {}),
71
+ } : null;
72
+ return {
73
+ commandFingerprint,
74
+ contactRevision: { schemaVersion: evidence.contactRevision.schemaVersion, source, revision: evidence.contactRevision.revision },
75
+ providerRef, carrierRef, serviceRef,
76
+ ...(transcript ? { transcript } : privacy.redactedFieldCount ? { redactedFieldCount: privacy.redactedFieldCount } : {}),
77
+ ...(evidence.mapping ? { mapping: { source: "dispatch_worker", mode: mode, shadowMode: evidence.mapping.mode === "shadow" } } : {}),
78
+ };
79
+ }
80
+ /** Shadow has a local command identity; it never invokes a provider or resolves credentials. */
81
+ export function shadowDispatchEvidence(request) {
82
+ if (!request.selection.providerRef || !request.lines.length || request.lines.some(line => !Number.isSafeInteger(line.quantity) || line.quantity <= 0))
83
+ throw new Error("dispatch_shadow_command_invalid");
84
+ return dispatchEvidence({ commandFingerprint: createHash("sha256").update(JSON.stringify(request)).digest("hex"),
85
+ contactRevision: request.contactRevision, providerRef: request.selection.providerRef,
86
+ carrierRef: request.selection.carrierRef, serviceRef: request.selection.serviceRef,
87
+ transcript: { itemCount: request.lines.length, items: request.lines.map(line => ({ skuRef: line.skuRef, quantity: line.quantity,
88
+ lotRef: line.lotRef ?? null, expirationDate: line.expirationDate ?? null })),
89
+ deliveryKind: request.selection.deliveryKind, pickupPointRef: request.selection.pickupPoint?.id ?? null } });
90
+ }
91
+ export function dispatchResult(result) {
92
+ const privacy = durableStrings(result.redactedFieldCount);
93
+ const externalRef = result.kind === "accepted" ? privacy.token(result.externalRef) ?? "redacted" : null;
94
+ const refusal = result.kind !== "accepted" ? { reason: (privacy.token(result.refusal.reason) ?? "malformed"),
95
+ phase: (privacy.token(result.refusal.phase) ?? "normalize"), retryable: result.refusal.retryable } : null;
96
+ const redactions = privacy.redactedFieldCount ? { redactedFieldCount: privacy.redactedFieldCount } : {};
97
+ const error = result.error ? { error: operationError({ ...result.error, mayHaveSucceeded: result.kind !== "not_dispatched" }) } : {};
98
+ switch (result.kind) {
99
+ case "accepted": return { kind: "accepted", externalRef: externalRef, providerAttemptKey: result.providerAttemptKey, labelKey: result.labelKey, ...redactions, evidence: dispatchEvidence(result.evidence), ...error,
100
+ ...(result.recovery ? { recovery: { source: "persisted_acceptance", proof: "persisted_external_ref", noProviderPost: true } } : {}) };
101
+ case "not_dispatched": return { kind: "not_dispatched", effectMayHaveSucceeded: false, refusal: refusal, ...redactions, ...error };
102
+ case "unknown": return { kind: "unknown", effectMayHaveSucceeded: true, refusal: refusal, ...redactions, ...error };
103
+ }
104
+ }
105
+ export function acceptedProviderProof(record) {
106
+ return Boolean(record?.externalRef && (record.status === "created" || record.status === "uncertain"));
107
+ }
@@ -0,0 +1,66 @@
1
+ import type { FulfillmentObservation } from "./contracts/index.js";
2
+ /** Ledger effects for an already accepted observation; acceptance and retry belong to the caller. */
3
+ interface FulfillmentObservationPort<TrackingStatus> {
4
+ markProviderStockConsumed(input: {
5
+ idempotencyKey: string;
6
+ fulfillmentOrderId: string;
7
+ }): Promise<{
8
+ replayed: boolean;
9
+ }>;
10
+ markHandedOver(input: {
11
+ idempotencyKey: string;
12
+ fulfillmentOrderId: string;
13
+ suppressDispatched: boolean;
14
+ }): Promise<{
15
+ replayed: boolean;
16
+ }>;
17
+ recordTrackingReference(input: {
18
+ idempotencyKey: string;
19
+ orderId: string;
20
+ fulfillmentOrderId: string;
21
+ trackingNumber: string;
22
+ trackingUrl: string | null;
23
+ carrierKind: string | null;
24
+ service: string | null;
25
+ status: TrackingStatus;
26
+ observation: FulfillmentObservation;
27
+ }): Promise<{
28
+ replayed: boolean;
29
+ readBack: boolean;
30
+ }>;
31
+ }
32
+ interface FulfillmentObservationTrackingReference {
33
+ trackingNumber: string;
34
+ trackingUrl?: string | null;
35
+ carrierKind?: string | null;
36
+ service?: string | null;
37
+ }
38
+ interface FulfillmentObservationInput<LocalStatus, TrackingStatus> {
39
+ port: FulfillmentObservationPort<TrackingStatus>;
40
+ localStatus: LocalStatus;
41
+ ids: {
42
+ orderId: string;
43
+ fulfillmentOrderId: string;
44
+ };
45
+ observation: FulfillmentObservation;
46
+ trackingRefs: readonly FulfillmentObservationTrackingReference[];
47
+ stockIdempotencyKey: string;
48
+ handoffIdempotencyKey: string;
49
+ trackingIdempotencyKey: (trackingNumber: string) => string;
50
+ issueAccountingInvoice?: () => Promise<void>;
51
+ onReplayed?: () => void;
52
+ onTrackingRecorded?: (result: {
53
+ replayed: boolean;
54
+ readBack: boolean;
55
+ }) => void;
56
+ }
57
+ /** Pure status decisions/projection; the mechanism owns every effect and await. */
58
+ interface FulfillmentObservationStatusPolicy<LocalStatus, TrackingStatus> {
59
+ consumesStock(status: LocalStatus): boolean;
60
+ handsOver(status: LocalStatus): boolean;
61
+ suppressDispatched(status: LocalStatus): boolean;
62
+ trackingStatus(status: LocalStatus): TrackingStatus;
63
+ }
64
+ /** Stock → durable handover → every tracking reference → optional invoice. No catches or retries. */
65
+ export declare function applyFulfillmentObservationEffects<LocalStatus, TrackingStatus>(input: FulfillmentObservationInput<LocalStatus, TrackingStatus>, policy: FulfillmentObservationStatusPolicy<LocalStatus, TrackingStatus>): Promise<void>;
66
+ export {};
@@ -0,0 +1,36 @@
1
+ /** Stock → durable handover → every tracking reference → optional invoice. No catches or retries. */
2
+ export async function applyFulfillmentObservationEffects(input, policy) {
3
+ const { fulfillmentOrderId, orderId } = input.ids;
4
+ if (policy.consumesStock(input.localStatus)) {
5
+ const consumed = await input.port.markProviderStockConsumed({
6
+ idempotencyKey: input.stockIdempotencyKey,
7
+ fulfillmentOrderId,
8
+ });
9
+ if (consumed.replayed)
10
+ input.onReplayed?.();
11
+ }
12
+ if (!policy.handsOver(input.localStatus))
13
+ return;
14
+ const handoff = await input.port.markHandedOver({
15
+ idempotencyKey: input.handoffIdempotencyKey,
16
+ fulfillmentOrderId,
17
+ suppressDispatched: policy.suppressDispatched(input.localStatus),
18
+ });
19
+ if (handoff.replayed)
20
+ input.onReplayed?.();
21
+ for (const trackingRef of input.trackingRefs) {
22
+ const tracking = await input.port.recordTrackingReference({
23
+ idempotencyKey: input.trackingIdempotencyKey(trackingRef.trackingNumber),
24
+ orderId,
25
+ fulfillmentOrderId,
26
+ trackingNumber: trackingRef.trackingNumber,
27
+ trackingUrl: trackingRef.trackingUrl ?? null,
28
+ carrierKind: trackingRef.carrierKind ?? null,
29
+ service: trackingRef.service ?? null,
30
+ status: policy.trackingStatus(input.localStatus),
31
+ observation: input.observation,
32
+ });
33
+ input.onTrackingRecorded?.(tracking);
34
+ }
35
+ await input.issueAccountingInvoice?.();
36
+ }