@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,38 @@
1
+ export const FULFILLMENT_REPLACEMENT_COMMAND_REFUSALS = [
2
+ "invalid_input",
3
+ "idempotency_conflict",
4
+ "order_not_found",
5
+ "order_not_replaceable",
6
+ "missing_client",
7
+ "missing_shipping_address",
8
+ "shipping_address_not_found",
9
+ "payment_not_succeeded",
10
+ "subscription_cycle_not_paid",
11
+ "no_parcel_to_replace",
12
+ "undispatched_replacement_exists",
13
+ "missing_order_items",
14
+ "missing_catalog_sku",
15
+ "missing_inventory_reservation",
16
+ "blocked_by_payment_not_succeeded_hold",
17
+ "blocked_by_inventory_review_hold",
18
+ "blocked_by_risk_review_hold",
19
+ "blocked_by_address_review_hold",
20
+ "blocked_by_manual_support_hold",
21
+ ];
22
+ export const FULFILLMENT_REPLACEMENT_RESERVATION_REFUSALS = [
23
+ "inventory_external_provider_insufficient_available_stock",
24
+ "inventory_external_provider_stock_stale",
25
+ "inventory_external_provider_stock_missing",
26
+ "inventory_external_provider_sku_not_found",
27
+ "inventory_external_provider_location_missing",
28
+ "inventory_reservation_insufficient_available_stock",
29
+ "inventory_reservation_allocation_incomplete",
30
+ "inventory_reservation_payment_status_not_reservable",
31
+ "inventory_reservation_invalid_quantity",
32
+ ];
33
+ export const UNSPECIFIED_FULFILLMENT_REPLACEMENT_REFUSAL = "unspecified_refusal";
34
+ export const FULFILLMENT_REPLACEMENT_REFUSALS = [
35
+ ...FULFILLMENT_REPLACEMENT_COMMAND_REFUSALS,
36
+ ...FULFILLMENT_REPLACEMENT_RESERVATION_REFUSALS,
37
+ UNSPECIFIED_FULFILLMENT_REPLACEMENT_REFUSAL,
38
+ ];
@@ -0,0 +1,5 @@
1
+ import { type BaseDeps, type FulfillmentHandlerRequest } from './handlerSupport.js';
2
+ import type { FulfillmentReplacementPort } from './contracts/replacement.js';
3
+ export declare function createAdminCommerceOrderRequestReplacementShipmentHandler<Response>({ authorizeAdmin, respond, omsPort, }: BaseDeps<Response> & {
4
+ omsPort: FulfillmentReplacementPort;
5
+ }): (req: FulfillmentHandlerRequest, res: Response) => Promise<void>;
@@ -0,0 +1,46 @@
1
+ import { adminCommerceOrderRequestReplacementShipmentRequestSchema, adminCommerceOrderRequestReplacementShipmentResponseSchema } from './handlerSchemas.js';
2
+ import { authorize, CommerceFulfillmentConflictError, isNativeUnsupported } from './handlerSupport.js';
3
+ export function createAdminCommerceOrderRequestReplacementShipmentHandler({ authorizeAdmin, respond, omsPort, }) {
4
+ const { sendMethodNotAllowed } = respond;
5
+ return async function handler(req, res) {
6
+ if (req.method !== "POST")
7
+ return sendMethodNotAllowed(res, ["POST"]);
8
+ const auth = await authorize(req, res, authorizeAdmin, respond);
9
+ if (!auth)
10
+ return;
11
+ const request = parseOmsRequest(res, respond, adminCommerceOrderRequestReplacementShipmentRequestSchema, req.body ?? {}, "Invalid admin commerce replacement shipment request");
12
+ if (request === undefined)
13
+ return;
14
+ await sendOmsMutationResponse(res, respond, () => omsPort.requestReplacementShipment({ ...request, actorUserId: auth.userId }), adminCommerceOrderRequestReplacementShipmentResponseSchema, "Admin commerce replacement shipment returned invalid response", "Admin commerce replacement shipment failed");
15
+ };
16
+ }
17
+ function parseOmsRequest(res, respond, schema, input, message) {
18
+ const request = schema.safeParse(input);
19
+ if (!request.success) {
20
+ respond.sendBffError(res, 'BAD_REQUEST', message, { details: request.error.flatten() });
21
+ return undefined;
22
+ }
23
+ return request.data;
24
+ }
25
+ async function sendOmsMutationResponse(res, respond, action, schema, invalidMessage, failureMessage) {
26
+ try {
27
+ const result = await action();
28
+ if (isNativeUnsupported(result)) {
29
+ respond.sendBffError(res, 'UPSTREAM_UNAVAILABLE', 'Native fulfillment operation unsupported', { details: result });
30
+ return;
31
+ }
32
+ const response = schema.safeParse(result);
33
+ if (!response.success) {
34
+ respond.sendBffError(res, 'INVALID_RESPONSE', invalidMessage);
35
+ return;
36
+ }
37
+ respond.sendBffSuccess(res, response.data);
38
+ }
39
+ catch (error) {
40
+ if (error instanceof CommerceFulfillmentConflictError) {
41
+ respond.sendBffError(res, 'CONFLICT', error.message, { details: error.details });
42
+ return;
43
+ }
44
+ respond.sendBffError(res, 'UPSTREAM_UNAVAILABLE', failureMessage);
45
+ }
46
+ }
@@ -0,0 +1,13 @@
1
+ /** Sparse projections require the full canonical graph and a trusted native binding. */
2
+ export declare const FULFILLMENT_NATIVE_CAPABILITIES: {
3
+ readonly shipment: "supported";
4
+ readonly commandFence: "supported";
5
+ readonly deliveryAlignment: "supported";
6
+ readonly stockEvidence: "supported";
7
+ readonly observationPersistence: "supported";
8
+ readonly localInventoryBalances: "host_required";
9
+ readonly dispatchContactPreparation: "host_required";
10
+ readonly productPacks: "unsupported";
11
+ readonly providerAccess: "unsupported";
12
+ readonly automaticReplacementConfirmation: "unsupported";
13
+ };
@@ -0,0 +1,7 @@
1
+ /** Sparse projections require the full canonical graph and a trusted native binding. */
2
+ export const FULFILLMENT_NATIVE_CAPABILITIES = {
3
+ shipment: 'supported', commandFence: 'supported', deliveryAlignment: 'supported',
4
+ stockEvidence: 'supported', observationPersistence: 'supported',
5
+ localInventoryBalances: 'host_required', dispatchContactPreparation: 'host_required',
6
+ productPacks: 'unsupported', providerAccess: 'unsupported', automaticReplacementConfirmation: 'unsupported',
7
+ };
@@ -0,0 +1,16 @@
1
+ import { type FulfillmentHandlerRequest, type FulfillmentHandlerResponder } from './handlerSupport.js';
2
+ import type { FulfillmentShipmentsOverviewPort, FulfillmentShipmentsOverviewResponse } from './contracts/read.js';
3
+ export interface FulfillmentShipmentsOverviewHandlerDeps<Response> {
4
+ respond: FulfillmentHandlerResponder<Response>;
5
+ overviewPort: FulfillmentShipmentsOverviewPort;
6
+ responseSchema: {
7
+ safeParse(input: unknown): {
8
+ success: true;
9
+ data: FulfillmentShipmentsOverviewResponse;
10
+ } | {
11
+ success: false;
12
+ };
13
+ };
14
+ authorizeAdmin: (req: FulfillmentHandlerRequest) => Promise<boolean>;
15
+ }
16
+ export declare function createFulfillmentShipmentsOverviewHandler<Response>({ respond, overviewPort, responseSchema: adminShipmentsOverviewResponseSchema, authorizeAdmin, }: FulfillmentShipmentsOverviewHandlerDeps<Response>): (req: FulfillmentHandlerRequest, res: Response) => Promise<void>;
@@ -0,0 +1,54 @@
1
+ import { isNativeUnsupported } from './handlerSupport.js';
2
+ import { z } from 'zod';
3
+ const adminShipmentsOverviewRequestSchema = z.object({
4
+ shippedFilter: z.enum(['today', '7d', '30d', 'all']).default('7d'),
5
+ });
6
+ export function createFulfillmentShipmentsOverviewHandler({ respond, overviewPort, responseSchema: adminShipmentsOverviewResponseSchema, authorizeAdmin, }) {
7
+ const { sendBffError, sendBffSuccess, sendMethodNotAllowed } = respond;
8
+ return async function handler(req, res) {
9
+ if (req.method !== "GET") {
10
+ sendMethodNotAllowed(res, ["GET"]);
11
+ return;
12
+ }
13
+ let authorized = false;
14
+ try {
15
+ authorized = await authorizeAdmin(req);
16
+ }
17
+ catch {
18
+ sendBffError(res, "UPSTREAM_UNAVAILABLE", "Admin authorization failed");
19
+ return;
20
+ }
21
+ if (!authorized) {
22
+ sendBffError(res, "UNAUTHORIZED", "Admin session required");
23
+ return;
24
+ }
25
+ const request = adminShipmentsOverviewRequestSchema.safeParse({
26
+ shippedFilter: scalarQuery(req.query.shippedFilter),
27
+ });
28
+ if (!request.success) {
29
+ sendBffError(res, "BAD_REQUEST", "Invalid shipments overview request", {
30
+ details: request.error.flatten(),
31
+ });
32
+ return;
33
+ }
34
+ try {
35
+ const result = await overviewPort.getShipmentsOverview(request.data);
36
+ if (isNativeUnsupported(result)) {
37
+ sendBffError(res, "UPSTREAM_UNAVAILABLE", "Native fulfillment operation unsupported", { details: result });
38
+ return;
39
+ }
40
+ const response = adminShipmentsOverviewResponseSchema.safeParse(result);
41
+ if (!response.success) {
42
+ sendBffError(res, "INVALID_RESPONSE", "Shipments overview returned invalid response");
43
+ return;
44
+ }
45
+ sendBffSuccess(res, response.data);
46
+ }
47
+ catch {
48
+ sendBffError(res, "UPSTREAM_UNAVAILABLE", "Shipments overview read failed");
49
+ }
50
+ };
51
+ }
52
+ function scalarQuery(value) {
53
+ return Array.isArray(value) ? value[0] : value;
54
+ }
@@ -0,0 +1,2 @@
1
+ export { FULFILLMENT_STATUS_MAP, CANONICAL_LOCAL_FULFILLMENT_STATUSES, CUSTOMER_STEP_SEQUENCE, canonicalStatusToken, stepForToken, customerStepFromSignals, phaseIndexForStep, stepLabelKey, timelineLabelForStep, trackingPhaseKeyForStep, stepUsesTruckIcon } from "@openlup/core/fulfillment";
2
+ export type { FulfillmentStatusStage, FulfillmentStatusMap } from "@openlup/core/fulfillment";
@@ -0,0 +1 @@
1
+ export { FULFILLMENT_STATUS_MAP, CANONICAL_LOCAL_FULFILLMENT_STATUSES, CUSTOMER_STEP_SEQUENCE, canonicalStatusToken, stepForToken, customerStepFromSignals, phaseIndexForStep, stepLabelKey, timelineLabelForStep, trackingPhaseKeyForStep, stepUsesTruckIcon } from "@openlup/core/fulfillment";
@@ -0,0 +1 @@
1
+ export { fulfillmentProgressPresentation } from "@openlup/core/fulfillment";
@@ -0,0 +1 @@
1
+ export { fulfillmentProgressPresentation } from "@openlup/core/fulfillment";
@@ -0,0 +1,79 @@
1
+ import type { FulfillmentObservation, FulfillmentObservationCodecs, FulfillmentObservationPort, FulfillmentRefusal } from "./contracts/index.js";
2
+ import { applyFulfillmentObservationEffects } from "./fulfillmentObservationEffects.js";
3
+ type EffectInput = Parameters<typeof applyFulfillmentObservationEffects<FulfillmentObservation["fact"]["canonicalStatus"], "in_transit" | "delivered">>[0];
4
+ type DispatchRef = {
5
+ orderRef: string;
6
+ fulfillmentRef: string;
7
+ dispatchRef: string;
8
+ externalRef: string | null;
9
+ };
10
+ export interface FulfillmentIngressCounts {
11
+ invalidTimestamps: number;
12
+ rejectedCorrelationRefs: number;
13
+ rejectedTrackingRefs: number;
14
+ rejectedTrackingUrls: number;
15
+ }
16
+ export type FulfillmentIngressResult = {
17
+ counts: FulfillmentIngressCounts;
18
+ } & ({
19
+ kind: "refused";
20
+ receiptId: null;
21
+ refusal: FulfillmentRefusal;
22
+ diagnostics?: {
23
+ invalidTimestamp?: true;
24
+ rejectedCorrelationRefs?: number;
25
+ };
26
+ } | {
27
+ kind: "processed" | "ignored" | "superseded";
28
+ receiptId: string;
29
+ observation: FulfillmentObservation;
30
+ replayed: boolean;
31
+ trackingRefs: number;
32
+ trackingReadBacks: number;
33
+ supersededCause?: string;
34
+ });
35
+ /** Safe response classes only; the host owns HTTP and localized message text. */
36
+ export declare function fulfillmentIngressHttpResult(result: FulfillmentIngressResult): {
37
+ status: 200 | 400 | 403 | 503;
38
+ messageClass: "accepted" | "bad_request" | "forbidden" | "upstream_unavailable";
39
+ };
40
+ /** Adapter verification owns auth-before-parse; the host owns durable replay. */
41
+ export declare function verifyAndNormalizeFulfillmentObservation(input: {
42
+ enabled: boolean;
43
+ approveTrackingUrl?(url: string): boolean;
44
+ observationCodecs?: FulfillmentObservationCodecs;
45
+ provider: FulfillmentObservationPort;
46
+ verification: Parameters<FulfillmentObservationPort["verifyAndNormalize"]>[0];
47
+ localPersistence: {
48
+ /** G17: atomic insert by eventKey; retries keep the first stored firstReceivedAt. */
49
+ recordObservation(observation: FulfillmentObservation): Promise<{
50
+ replayed: boolean;
51
+ receiptId?: string;
52
+ }>;
53
+ /** Idempotent; only called after completion or a classified superseding conflict. */
54
+ markProcessed(eventKey: string, outcome: {
55
+ status: "processed" | "ignored";
56
+ refusal?: FulfillmentRefusal;
57
+ supersededCause?: string;
58
+ }): Promise<void>;
59
+ };
60
+ lifecycle: {
61
+ findDispatchRef(observation: FulfillmentObservation): Promise<DispatchRef | null>;
62
+ acknowledgeDispatchAcceptance(ref: DispatchRef, observation: FulfillmentObservation): Promise<void>;
63
+ recordStatusEvidence(ref: DispatchRef, observation: FulfillmentObservation): Promise<{
64
+ replayed: boolean;
65
+ }>;
66
+ effects: EffectInput["port"];
67
+ keys: {
68
+ stock(ref: string): string;
69
+ handoff(ref: string): string;
70
+ tracking(eventKey: string, number: string): string;
71
+ };
72
+ issueAccountingInvoice?(ref: string): Promise<void>;
73
+ /** Return a machine identity, never exception prose. */
74
+ supersededCause?(error: unknown): string | null;
75
+ classifyFailure(error: unknown): "stock_contention" | "state_conflict" | "other";
76
+ annotateStockContention?(eventKey: string, fulfillmentRef: string): Promise<void>;
77
+ };
78
+ }): Promise<FulfillmentIngressResult>;
79
+ export {};
@@ -0,0 +1,94 @@
1
+ import { safeDiagnosticCode } from "./dispatchProjection.js";
2
+ import { applyFulfillmentObservationEffects } from "./fulfillmentObservationEffects.js";
3
+ import { observationStatusPolicy, projectObservation } from "./observationProjection.js";
4
+ import { uniqueTrackingReferences } from "./providerTrackingReferences.js";
5
+ /** Safe response classes only; the host owns HTTP and localized message text. */
6
+ export function fulfillmentIngressHttpResult(result) {
7
+ if (result.kind !== "refused")
8
+ return { status: 200, messageClass: "accepted" };
9
+ if (result.refusal.reason === "untrusted")
10
+ return { status: 403, messageClass: "forbidden" };
11
+ if (result.refusal.reason === "disabled" || result.refusal.reason === "not_ready" || result.refusal.retryable)
12
+ return { status: 503, messageClass: "upstream_unavailable" };
13
+ return { status: 400, messageClass: "bad_request" };
14
+ }
15
+ /** Adapter verification owns auth-before-parse; the host owns durable replay. */
16
+ export async function verifyAndNormalizeFulfillmentObservation(input) {
17
+ const counts = { invalidTimestamps: 0, rejectedCorrelationRefs: 0, rejectedTrackingRefs: 0, rejectedTrackingUrls: 0 };
18
+ if (!input.enabled)
19
+ return { kind: "refused", receiptId: null, counts, refusal: { reason: "disabled", phase: "verify", retryable: false } };
20
+ const verified = await input.provider.verifyAndNormalize(input.verification);
21
+ if (verified.kind === "refused") {
22
+ if (verified.diagnostics?.invalidTimestamp)
23
+ counts.invalidTimestamps++;
24
+ const rejected = verified.diagnostics?.rejectedCorrelationRefs;
25
+ if (typeof rejected === "number" && Number.isSafeInteger(rejected) && rejected > 0)
26
+ counts.rejectedCorrelationRefs = rejected;
27
+ return { kind: "refused", receiptId: null, refusal: verified.refusal, counts,
28
+ ...(counts.invalidTimestamps || counts.rejectedCorrelationRefs ? { diagnostics: {
29
+ ...(counts.invalidTimestamps ? { invalidTimestamp: true } : {}),
30
+ ...(counts.rejectedCorrelationRefs ? { rejectedCorrelationRefs: counts.rejectedCorrelationRefs } : {}),
31
+ } } : {}) };
32
+ }
33
+ const observation = projectObservation(verified.observation, input.approveTrackingUrl, input.observationCodecs);
34
+ counts.rejectedTrackingRefs = observation.diagnostics?.admission?.rejectedTrackingRefs ?? 0;
35
+ counts.rejectedTrackingUrls = observation.diagnostics?.admission?.rejectedTrackingUrls ?? 0;
36
+ const inbound = await input.localPersistence.recordObservation(observation);
37
+ const receiptId = inbound.receiptId ?? observation.eventKey;
38
+ const ref = await input.lifecycle.findDispatchRef(observation);
39
+ if (!ref) {
40
+ await input.localPersistence.markProcessed(observation.eventKey, { status: "ignored", refusal: { reason: "local_missing", phase: "apply", retryable: false } });
41
+ return { kind: "ignored", receiptId, counts, observation, replayed: inbound.replayed, trackingRefs: 0, trackingReadBacks: 0 };
42
+ }
43
+ const externalRef = observation.correlation.externalRef?.trim() || ref.externalRef?.trim();
44
+ if (!externalRef)
45
+ throw new TypeError("fulfillment_dispatch_acceptance_external_ref_missing");
46
+ await input.lifecycle.acknowledgeDispatchAcceptance(ref, observation);
47
+ const statusEvidence = await input.lifecycle.recordStatusEvidence(ref, observation);
48
+ let trackingRefs = 0;
49
+ let trackingReadBacks = 0;
50
+ const effectPort = {
51
+ ...input.lifecycle.effects,
52
+ async markProviderStockConsumed(request) {
53
+ try {
54
+ return await input.lifecycle.effects.markProviderStockConsumed(request);
55
+ }
56
+ catch (error) {
57
+ if (input.lifecycle.classifyFailure(error) === "stock_contention") {
58
+ try {
59
+ await input.lifecycle.annotateStockContention?.(observation.eventKey, ref.fulfillmentRef);
60
+ }
61
+ catch { /* Annotation is best-effort; preserve the original stock failure. */ }
62
+ }
63
+ throw error;
64
+ }
65
+ },
66
+ };
67
+ const localStatus = observation.fact.canonicalStatus;
68
+ const effects = {
69
+ port: effectPort, localStatus, ids: { orderId: ref.orderRef, fulfillmentOrderId: ref.fulfillmentRef }, observation,
70
+ trackingRefs: uniqueTrackingReferences(observation.trackingRefs).map(tracking => ({ trackingNumber: tracking.trackingNumber, trackingUrl: tracking.publicUrl, carrierKind: tracking.carrierRef, service: tracking.serviceRef })),
71
+ stockIdempotencyKey: input.lifecycle.keys.stock(ref.fulfillmentRef), handoffIdempotencyKey: input.lifecycle.keys.handoff(ref.fulfillmentRef),
72
+ trackingIdempotencyKey: number => input.lifecycle.keys.tracking(observation.eventKey, number),
73
+ issueAccountingInvoice: input.lifecycle.issueAccountingInvoice ? () => input.lifecycle.issueAccountingInvoice(ref.fulfillmentRef) : undefined,
74
+ onTrackingRecorded: result => { trackingRefs += result.replayed ? 0 : 1; trackingReadBacks += result.readBack ? 1 : 0; },
75
+ };
76
+ if (!observationStatusPolicy.handsOver(localStatus))
77
+ await applyFulfillmentObservationEffects({ ...effects, trackingRefs: [] }, observationStatusPolicy);
78
+ else {
79
+ try {
80
+ await applyFulfillmentObservationEffects(effects, observationStatusPolicy);
81
+ }
82
+ catch (error) {
83
+ if (input.lifecycle.classifyFailure(error) !== "state_conflict")
84
+ throw error;
85
+ const cause = input.lifecycle.supersededCause ? input.lifecycle.supersededCause(error)
86
+ : error && typeof error === "object" && "reason" in error ? error.reason : null;
87
+ const supersededCause = safeDiagnosticCode(cause) ?? "fulfillment_state_conflict";
88
+ await input.localPersistence.markProcessed(observation.eventKey, { status: "processed", supersededCause });
89
+ return { kind: "superseded", receiptId, counts, supersededCause, observation, replayed: inbound.replayed || statusEvidence.replayed, trackingRefs, trackingReadBacks };
90
+ }
91
+ }
92
+ await input.localPersistence.markProcessed(observation.eventKey, { status: "processed" });
93
+ return { kind: "processed", receiptId, counts, observation, replayed: inbound.replayed || statusEvidence.replayed, trackingRefs, trackingReadBacks };
94
+ }
@@ -0,0 +1,11 @@
1
+ import type { InvoiceCapabilities, InvoiceCapabilitySelection } from "./contracts/capabilities.js";
2
+ /** @consumer Host readiness / installed cold consumer. Default off and explicit
3
+ * provider selection precede capability use; construction never selects a provider.
4
+ */
5
+ export declare function readInvoiceCapabilities(input: {
6
+ readonly enabled?: boolean;
7
+ readonly selection: {
8
+ readonly providerRef: string;
9
+ } | null;
10
+ readonly capability: InvoiceCapabilities | null;
11
+ }): InvoiceCapabilitySelection;
@@ -0,0 +1,10 @@
1
+ /** @consumer Host readiness / installed cold consumer. Default off and explicit
2
+ * provider selection precede capability use; construction never selects a provider.
3
+ */
4
+ export function readInvoiceCapabilities(input) {
5
+ if (input.enabled !== true)
6
+ return { kind: "refused", code: "disabled", retryable: false, effectMayHaveSucceeded: false };
7
+ if (!input.selection || !input.capability || input.selection.providerRef !== input.capability.providerRef)
8
+ return { kind: "refused", code: "selection_required", retryable: false, effectMayHaveSucceeded: false };
9
+ return { kind: "ready", capability: input.capability };
10
+ }
@@ -0,0 +1,40 @@
1
+ import type { InvoiceDiagnosticCode, InvoiceUnsupported } from "./provider.js";
2
+ export interface InvoiceCapabilities {
3
+ readonly version: "invoicing.capabilities.v1";
4
+ readonly providerRef: string;
5
+ readonly fiscalScope: {
6
+ readonly scopeRef: string;
7
+ readonly version: string;
8
+ };
9
+ readonly policies: {
10
+ readonly identifierRef: string;
11
+ readonly taxRef: string;
12
+ readonly roundingRef: string;
13
+ };
14
+ readonly documentKinds: readonly string[];
15
+ readonly correctionKinds: readonly "full_reversal"[];
16
+ readonly numberingOwner: "provider";
17
+ readonly sellerTiming: "execution" | "first_claim";
18
+ readonly operations: Readonly<Record<"issue" | "correction" | "recovery" | "readback" | "exactAbsence" | "artifact" | "clearance" | "settlement" | "companyLookup", {
19
+ readonly supported: true;
20
+ } | {
21
+ readonly supported: false;
22
+ readonly reason: "host_required" | "not_implemented" | "not_exposed";
23
+ }>> & {
24
+ readonly remoteVoid: {
25
+ readonly supported: false;
26
+ readonly reason: "not_implemented";
27
+ };
28
+ };
29
+ readonly defaultOff: true;
30
+ }
31
+ /** Interpretation only: no environment discovery, activation, writes or provider calls. */
32
+ export type InvoiceCapabilitySelection = InvoiceUnsupported | {
33
+ readonly kind: "ready";
34
+ readonly capability: InvoiceCapabilities;
35
+ } | {
36
+ readonly kind: "refused";
37
+ readonly code: Extract<InvoiceDiagnosticCode, "disabled" | "selection_required">;
38
+ readonly retryable: false;
39
+ readonly effectMayHaveSucceeded: false;
40
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,49 @@
1
+ import type { InvoiceProof, InvoiceUnsupported } from "./provider.js";
2
+ /** Injected registry seam. Host owns identifier validation, freshness and fallback;
3
+ * lookup evidence never overwrites checkout truth or becomes a renewal prerequisite.
4
+ * Carrier: accountingControlContracts lookup fields, generalized per A5 fit probe.
5
+ */
6
+ export interface InvoiceCompanyLookupPort {
7
+ lookup(input: {
8
+ readonly identifier: {
9
+ readonly scheme: string;
10
+ readonly value: string;
11
+ readonly country?: string;
12
+ };
13
+ readonly asOf: string;
14
+ readonly sourceRef: string;
15
+ }): Promise<{
16
+ readonly kind: "found" | "partial";
17
+ readonly identifier: {
18
+ readonly scheme: string;
19
+ readonly value: string;
20
+ readonly country?: string;
21
+ };
22
+ readonly legalName: string | null;
23
+ readonly registrationIds: readonly {
24
+ readonly scheme: string;
25
+ readonly value: string;
26
+ }[];
27
+ readonly address: {
28
+ readonly line1: string;
29
+ readonly postalCode: string;
30
+ readonly city: string;
31
+ readonly country: string;
32
+ } | null;
33
+ readonly taxRegistrations: readonly {
34
+ readonly scheme: string;
35
+ readonly status: "active" | "not_registered" | "exempt" | "unknown";
36
+ }[];
37
+ readonly sourceRef: string;
38
+ readonly proof: InvoiceProof;
39
+ } | {
40
+ readonly kind: "not_found";
41
+ readonly identifier: Parameters<InvoiceCompanyLookupPort["lookup"]>[0]["identifier"];
42
+ readonly sourceRef: string;
43
+ readonly proof: InvoiceProof;
44
+ } | {
45
+ readonly kind: "unknown";
46
+ readonly sourceRef: string;
47
+ readonly code: "unknown";
48
+ } | InvoiceUnsupported>;
49
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ import type { InvoiceDocumentIdentity, InvoiceProof, InvoiceUnsupported } from "./provider.js";
2
+ /** Durable opaque references; signed URLs and downloaded bytes are transient. */
3
+ export type InvoiceArtifactResult = {
4
+ readonly kind: "found";
5
+ readonly identity: InvoiceDocumentIdentity;
6
+ readonly artifact: {
7
+ readonly kind: "pdf" | "structured_document" | "clearance_receipt";
8
+ readonly ref: string;
9
+ readonly owner: "provider" | "host_storage";
10
+ readonly mediaType: string;
11
+ readonly proof: InvoiceProof;
12
+ };
13
+ } | {
14
+ readonly kind: "absent";
15
+ readonly identity: InvoiceDocumentIdentity;
16
+ readonly evidence: InvoiceProof & {
17
+ readonly exact: true;
18
+ readonly complete: true;
19
+ readonly scope: {
20
+ readonly identity: InvoiceDocumentIdentity;
21
+ readonly kind: "pdf" | "structured_document" | "clearance_receipt";
22
+ readonly artifactRef: string | null;
23
+ };
24
+ };
25
+ } | {
26
+ readonly kind: "unknown";
27
+ readonly identity: InvoiceDocumentIdentity;
28
+ readonly code: "unknown";
29
+ } | InvoiceUnsupported;
30
+ /** Observation only; unsupported is never not_required. No clearance submission. */
31
+ export type InvoiceClearanceObservation = {
32
+ readonly proof: InvoiceProof;
33
+ } & ({
34
+ readonly state: "accepted";
35
+ readonly reference: string;
36
+ } | {
37
+ readonly state: "not_submitted" | "pending" | "rejected" | "not_required" | "unsupported";
38
+ readonly reference: string | null;
39
+ });
40
+ export interface InvoiceDeliveryPort {
41
+ /** Host M04 content/transport; provider acceptance is not inbox delivery.
42
+ * Preserve delivery/request keys, recipient, filename and bytes. Validate PDF
43
+ * type, size and signature before send; uncertain send must never repeat sending.
44
+ */
45
+ send(input: {
46
+ readonly deliveryRef: string;
47
+ readonly requestKey: string;
48
+ readonly attemptCount: number;
49
+ readonly documentRef: string;
50
+ readonly orderId: string;
51
+ readonly orderRef: string;
52
+ readonly invoiceRef: string;
53
+ readonly providerDocumentRef: string;
54
+ readonly clientRef: string | null;
55
+ readonly recipient: string;
56
+ readonly source: string | null;
57
+ readonly providerDocumentNumber: string | null;
58
+ readonly filename: string;
59
+ readonly content: Uint8Array;
60
+ readonly contentType: string;
61
+ }): Promise<{
62
+ readonly kind: "provider_accepted";
63
+ readonly receiptRef: string;
64
+ readonly proof: InvoiceProof;
65
+ } | {
66
+ readonly kind: "failed_before_send";
67
+ readonly retryable: boolean;
68
+ readonly code: "retryable" | "invalid_artifact";
69
+ } | {
70
+ readonly kind: "uncertain";
71
+ readonly code: "uncertain_delivery";
72
+ readonly receiptRef: string | null;
73
+ } | InvoiceUnsupported>;
74
+ }
@@ -0,0 +1 @@
1
+ export {};