@openlup/platform 0.16.0 → 0.18.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 (773) hide show
  1. package/CHANGELOG.md +180 -0
  2. package/README.md +564 -6
  3. package/dist/catalog/activeSkuSelection.d.ts +2 -0
  4. package/dist/catalog/activeSkuSelection.js +20 -0
  5. package/dist/catalog/adminBindings.d.ts +72 -0
  6. package/dist/catalog/adminBindings.js +1 -0
  7. package/dist/catalog/adminBundleHandler.d.ts +26 -0
  8. package/dist/catalog/adminBundleHandler.js +111 -0
  9. package/dist/catalog/adminBundleReadHandler.d.ts +20 -0
  10. package/dist/catalog/adminBundleReadHandler.js +185 -0
  11. package/dist/catalog/adminBundleWritePort.d.ts +85 -0
  12. package/dist/catalog/adminBundleWritePort.js +1 -0
  13. package/dist/catalog/bundleAvailability.d.ts +63 -0
  14. package/dist/catalog/bundleAvailability.js +78 -0
  15. package/dist/catalog/bundleAvailabilityService.d.ts +65 -0
  16. package/dist/catalog/bundleAvailabilityService.js +89 -0
  17. package/dist/catalog/bundleBindings.d.ts +33 -0
  18. package/dist/catalog/bundleBindings.js +1 -0
  19. package/dist/catalog/bundleCatalogQueries.d.ts +28 -0
  20. package/dist/catalog/bundleCatalogQueries.js +84 -0
  21. package/dist/catalog/bundleCatalogReadPort.d.ts +166 -0
  22. package/dist/catalog/bundleCatalogReadPort.js +36 -0
  23. package/dist/catalog/bundleCatalogStore.d.ts +3 -0
  24. package/dist/catalog/bundleCatalogStore.js +152 -0
  25. package/dist/catalog/bundleRuleCodes.d.ts +41 -0
  26. package/dist/catalog/bundleRuleCodes.js +110 -0
  27. package/dist/catalog/bundleRules.d.ts +69 -0
  28. package/dist/catalog/bundleRules.js +102 -0
  29. package/dist/catalog/catalogDraftStore.d.ts +4 -0
  30. package/dist/catalog/catalogDraftStore.js +63 -0
  31. package/dist/catalog/catalogSkuEnvelope.d.ts +7 -0
  32. package/dist/catalog/catalogSkuEnvelope.js +142 -0
  33. package/dist/catalog/catalogSkuEnvelopeMapper.d.ts +38 -0
  34. package/dist/catalog/catalogSkuEnvelopeMapper.js +88 -0
  35. package/dist/catalog/contracts/bundleAdmin.d.ts +143 -0
  36. package/dist/catalog/contracts/bundleAdmin.js +1 -0
  37. package/dist/catalog/contracts/bundleAvailability.d.ts +61 -0
  38. package/dist/catalog/contracts/bundleAvailability.js +1 -0
  39. package/dist/catalog/contracts/bundleRead.d.ts +223 -0
  40. package/dist/catalog/contracts/bundleRead.js +1 -0
  41. package/dist/catalog/contracts/draft.d.ts +79 -0
  42. package/dist/catalog/contracts/draft.js +47 -0
  43. package/dist/catalog/contracts/foundation.d.ts +78 -0
  44. package/dist/catalog/contracts/foundation.js +53 -0
  45. package/dist/catalog/contracts/index.d.ts +14 -0
  46. package/dist/catalog/contracts/index.js +6 -0
  47. package/dist/catalog/contracts/lifecycle.d.ts +77 -0
  48. package/dist/catalog/contracts/lifecycle.js +1 -0
  49. package/dist/catalog/contracts/productMediaContracts.d.ts +77 -0
  50. package/dist/catalog/contracts/productMediaContracts.js +149 -0
  51. package/dist/catalog/contracts/productTypes.d.ts +54 -0
  52. package/dist/catalog/contracts/productTypes.js +16 -0
  53. package/dist/catalog/contracts/resolveProductMedia.d.ts +3 -0
  54. package/dist/catalog/contracts/resolveProductMedia.js +78 -0
  55. package/dist/catalog/contracts/sellable.d.ts +23 -0
  56. package/dist/catalog/contracts/sellable.js +1 -0
  57. package/dist/catalog/draftHandler.d.ts +25 -0
  58. package/dist/catalog/draftHandler.js +118 -0
  59. package/dist/catalog/draftPorts.d.ts +18 -0
  60. package/dist/catalog/draftPorts.js +8 -0
  61. package/dist/catalog/draftSchemas.d.ts +423 -0
  62. package/dist/catalog/draftSchemas.js +89 -0
  63. package/dist/catalog/draftValidation.d.ts +21 -0
  64. package/dist/catalog/draftValidation.js +125 -0
  65. package/dist/catalog/foundationSchemas.d.ts +98 -0
  66. package/dist/catalog/foundationSchemas.js +110 -0
  67. package/dist/catalog/index.d.ts +43 -0
  68. package/dist/catalog/index.js +25 -0
  69. package/dist/catalog/mediaSourcePack.d.ts +51 -0
  70. package/dist/catalog/mediaSourcePack.js +247 -0
  71. package/dist/catalog/productTypeSchemas.d.ts +46 -0
  72. package/dist/catalog/productTypeSchemas.js +72 -0
  73. package/dist/catalog/publicationPorts.d.ts +42 -0
  74. package/dist/catalog/publicationPorts.js +1 -0
  75. package/dist/catalog/readPorts.d.ts +51 -0
  76. package/dist/catalog/readPorts.js +1 -0
  77. package/dist/catalog/referenceCatalogHandler.d.ts +7 -0
  78. package/dist/catalog/referenceCatalogHandler.js +27 -0
  79. package/dist/catalog/resolvedSkuProjection.d.ts +88 -0
  80. package/dist/catalog/resolvedSkuProjection.js +60 -0
  81. package/dist/catalog/sellableBundleHandler.d.ts +46 -0
  82. package/dist/catalog/sellableBundleHandler.js +84 -0
  83. package/dist/catalog/sellableSchemas.d.ts +46 -0
  84. package/dist/catalog/sellableSchemas.js +27 -0
  85. package/dist/catalog/sql.d.ts +46 -0
  86. package/dist/catalog/sql.js +13 -0
  87. package/dist/catalog/validation.d.ts +2 -0
  88. package/dist/catalog/validation.js +3 -0
  89. package/dist/communications/accountingDocumentDelivery.d.ts +35 -0
  90. package/dist/communications/accountingDocumentDelivery.js +33 -0
  91. package/dist/communications/authEmailError.d.ts +5 -0
  92. package/dist/communications/authEmailError.js +8 -0
  93. package/dist/communications/authEmailPorts.d.ts +2 -0
  94. package/dist/communications/authEmailPorts.js +1 -0
  95. package/dist/communications/authSendEmailHook.d.ts +35 -0
  96. package/dist/communications/authSendEmailHook.js +250 -0
  97. package/dist/communications/capturedTransactionalDelivery.d.ts +13 -0
  98. package/dist/communications/capturedTransactionalDelivery.js +14 -0
  99. package/dist/communications/communicationSync.d.ts +11 -0
  100. package/dist/communications/communicationSync.js +79 -0
  101. package/dist/communications/communicationSyncWorker.d.ts +68 -0
  102. package/dist/communications/communicationSyncWorker.js +218 -0
  103. package/dist/communications/consentPolicy.d.ts +19 -0
  104. package/dist/communications/consentPolicy.js +43 -0
  105. package/dist/communications/consentPurposeRegistry.d.ts +4 -0
  106. package/dist/communications/consentPurposeRegistry.js +24 -0
  107. package/dist/communications/contracts/abandonedCart.d.ts +27 -0
  108. package/dist/communications/contracts/abandonedCart.js +25 -0
  109. package/dist/communications/contracts/authEmail.d.ts +62 -0
  110. package/dist/communications/contracts/authEmail.js +1 -0
  111. package/dist/communications/contracts/backInStock.d.ts +28 -0
  112. package/dist/communications/contracts/backInStock.js +28 -0
  113. package/dist/communications/contracts/blocks.d.ts +24 -0
  114. package/dist/communications/contracts/blocks.js +23 -0
  115. package/dist/communications/contracts/checkoutExpired.d.ts +22 -0
  116. package/dist/communications/contracts/checkoutExpired.js +25 -0
  117. package/dist/communications/contracts/checkoutRecovery.d.ts +26 -0
  118. package/dist/communications/contracts/checkoutRecovery.js +37 -0
  119. package/dist/communications/contracts/commerceEmailContent.d.ts +176 -0
  120. package/dist/communications/contracts/commerceEmailContent.js +1 -0
  121. package/dist/communications/contracts/commerceEngagementEmailContent.d.ts +95 -0
  122. package/dist/communications/contracts/commerceEngagementEmailContent.js +1 -0
  123. package/dist/communications/contracts/consent.d.ts +12 -0
  124. package/dist/communications/contracts/consent.js +1 -0
  125. package/dist/communications/contracts/email.d.ts +182 -0
  126. package/dist/communications/contracts/email.js +1 -0
  127. package/dist/communications/contracts/guideCard.d.ts +3 -0
  128. package/dist/communications/contracts/guideCard.js +26 -0
  129. package/dist/communications/contracts/index.d.ts +52 -0
  130. package/dist/communications/contracts/index.js +42 -0
  131. package/dist/communications/contracts/inquiryContent.d.ts +32 -0
  132. package/dist/communications/contracts/inquiryContent.js +33 -0
  133. package/dist/communications/contracts/invoiceDocumentContent.d.ts +26 -0
  134. package/dist/communications/contracts/invoiceDocumentContent.js +36 -0
  135. package/dist/communications/contracts/marketingAutomation.d.ts +52 -0
  136. package/dist/communications/contracts/marketingAutomation.js +1 -0
  137. package/dist/communications/contracts/marketingSync.d.ts +194 -0
  138. package/dist/communications/contracts/marketingSync.js +1 -0
  139. package/dist/communications/contracts/newsletter.d.ts +63 -0
  140. package/dist/communications/contracts/newsletter.js +1 -0
  141. package/dist/communications/contracts/newsletterWebhook.d.ts +26 -0
  142. package/dist/communications/contracts/newsletterWebhook.js +1 -0
  143. package/dist/communications/contracts/optOutContent.d.ts +11 -0
  144. package/dist/communications/contracts/optOutContent.js +17 -0
  145. package/dist/communications/contracts/orderCanceled.d.ts +25 -0
  146. package/dist/communications/contracts/orderCanceled.js +27 -0
  147. package/dist/communications/contracts/orderDraft.d.ts +46 -0
  148. package/dist/communications/contracts/orderDraft.js +46 -0
  149. package/dist/communications/contracts/orderPaid.d.ts +53 -0
  150. package/dist/communications/contracts/orderPaid.js +71 -0
  151. package/dist/communications/contracts/orderRefunded.d.ts +24 -0
  152. package/dist/communications/contracts/orderRefunded.js +27 -0
  153. package/dist/communications/contracts/paymentFailed.d.ts +24 -0
  154. package/dist/communications/contracts/paymentFailed.js +24 -0
  155. package/dist/communications/contracts/publicIntake.d.ts +49 -0
  156. package/dist/communications/contracts/publicIntake.js +1 -0
  157. package/dist/communications/contracts/render.d.ts +2 -0
  158. package/dist/communications/contracts/render.js +229 -0
  159. package/dist/communications/contracts/reorderReminder.d.ts +24 -0
  160. package/dist/communications/contracts/reorderReminder.js +24 -0
  161. package/dist/communications/contracts/returnEmails.d.ts +25 -0
  162. package/dist/communications/contracts/returnEmails.js +62 -0
  163. package/dist/communications/contracts/reviewEffects.d.ts +26 -0
  164. package/dist/communications/contracts/reviewEffects.js +25 -0
  165. package/dist/communications/contracts/reviewRequest.d.ts +26 -0
  166. package/dist/communications/contracts/reviewRequest.js +24 -0
  167. package/dist/communications/contracts/roleNotificationContent.d.ts +25 -0
  168. package/dist/communications/contracts/roleNotificationContent.js +46 -0
  169. package/dist/communications/contracts/shipmentDelivered.d.ts +23 -0
  170. package/dist/communications/contracts/shipmentDelivered.js +24 -0
  171. package/dist/communications/contracts/shipmentDispatched.d.ts +27 -0
  172. package/dist/communications/contracts/shipmentDispatched.js +35 -0
  173. package/dist/communications/contracts/shipmentException.d.ts +21 -0
  174. package/dist/communications/contracts/shipmentException.js +26 -0
  175. package/dist/communications/contracts/subscriptionActivationActionRequired.d.ts +17 -0
  176. package/dist/communications/contracts/subscriptionActivationActionRequired.js +22 -0
  177. package/dist/communications/contracts/subscriptionAddressChanged.d.ts +19 -0
  178. package/dist/communications/contracts/subscriptionAddressChanged.js +25 -0
  179. package/dist/communications/contracts/subscriptionCancelled.d.ts +19 -0
  180. package/dist/communications/contracts/subscriptionCancelled.js +25 -0
  181. package/dist/communications/contracts/subscriptionCycleSkipped.d.ts +25 -0
  182. package/dist/communications/contracts/subscriptionCycleSkipped.js +40 -0
  183. package/dist/communications/contracts/subscriptionDeliveryRescheduled.d.ts +25 -0
  184. package/dist/communications/contracts/subscriptionDeliveryRescheduled.js +39 -0
  185. package/dist/communications/contracts/subscriptionEmailContent.d.ts +145 -0
  186. package/dist/communications/contracts/subscriptionEmailContent.js +1 -0
  187. package/dist/communications/contracts/subscriptionPackageChanged.d.ts +20 -0
  188. package/dist/communications/contracts/subscriptionPackageChanged.js +26 -0
  189. package/dist/communications/contracts/subscriptionPauseReminder.d.ts +23 -0
  190. package/dist/communications/contracts/subscriptionPauseReminder.js +29 -0
  191. package/dist/communications/contracts/subscriptionPaused.d.ts +21 -0
  192. package/dist/communications/contracts/subscriptionPaused.js +25 -0
  193. package/dist/communications/contracts/subscriptionPaymentExpired.d.ts +34 -0
  194. package/dist/communications/contracts/subscriptionPaymentExpired.js +37 -0
  195. package/dist/communications/contracts/subscriptionPaymentFailed.d.ts +49 -0
  196. package/dist/communications/contracts/subscriptionPaymentFailed.js +56 -0
  197. package/dist/communications/contracts/subscriptionPaymentRecovered.d.ts +19 -0
  198. package/dist/communications/contracts/subscriptionPaymentRecovered.js +22 -0
  199. package/dist/communications/contracts/subscriptionRenewalAtRisk.d.ts +36 -0
  200. package/dist/communications/contracts/subscriptionRenewalAtRisk.js +36 -0
  201. package/dist/communications/contracts/subscriptionRenewalUpcoming.d.ts +49 -0
  202. package/dist/communications/contracts/subscriptionRenewalUpcoming.js +43 -0
  203. package/dist/communications/contracts/subscriptionResumed.d.ts +23 -0
  204. package/dist/communications/contracts/subscriptionResumed.js +25 -0
  205. package/dist/communications/contracts/subscriptionWelcome.d.ts +44 -0
  206. package/dist/communications/contracts/subscriptionWelcome.js +45 -0
  207. package/dist/communications/contracts/subscriptionWinback.d.ts +21 -0
  208. package/dist/communications/contracts/subscriptionWinback.js +28 -0
  209. package/dist/communications/contracts/transactionalDelivery.d.ts +42 -0
  210. package/dist/communications/contracts/transactionalDelivery.js +1 -0
  211. package/dist/communications/contracts/types.d.ts +46 -0
  212. package/dist/communications/contracts/types.js +1 -0
  213. package/dist/communications/contribution.d.ts +10 -0
  214. package/dist/communications/contribution.js +24 -0
  215. package/dist/communications/deliveryReconciliation.d.ts +64 -0
  216. package/dist/communications/deliveryReconciliation.js +60 -0
  217. package/dist/communications/emailEgress.d.ts +38 -0
  218. package/dist/communications/emailEgress.js +100 -0
  219. package/dist/communications/emailHealthAssessment.d.ts +39 -0
  220. package/dist/communications/emailHealthAssessment.js +59 -0
  221. package/dist/communications/emailHealthMetricsPort.d.ts +17 -0
  222. package/dist/communications/emailHealthMetricsPort.js +1 -0
  223. package/dist/communications/emailNotificationControl.d.ts +27 -0
  224. package/dist/communications/emailNotificationControl.js +10 -0
  225. package/dist/communications/emailObservation.d.ts +28 -0
  226. package/dist/communications/emailObservation.js +23 -0
  227. package/dist/communications/emailTransport.d.ts +82 -0
  228. package/dist/communications/emailTransport.js +95 -0
  229. package/dist/communications/errors.d.ts +15 -0
  230. package/dist/communications/errors.js +30 -0
  231. package/dist/communications/index.d.ts +47 -0
  232. package/dist/communications/index.js +38 -0
  233. package/dist/communications/integrationEventSignature.d.ts +15 -0
  234. package/dist/communications/integrationEventSignature.js +37 -0
  235. package/dist/communications/klaviyo/consentPush.d.ts +51 -0
  236. package/dist/communications/klaviyo/consentPush.js +19 -0
  237. package/dist/communications/klaviyo/index.d.ts +110 -0
  238. package/dist/communications/klaviyo/index.js +860 -0
  239. package/dist/communications/managedTransactionalDeliveryStore.d.ts +12 -0
  240. package/dist/communications/managedTransactionalDeliveryStore.js +49 -0
  241. package/dist/communications/nativeOperations.d.ts +79 -0
  242. package/dist/communications/nativeOperations.js +3 -0
  243. package/dist/communications/newsletterIntegrationContracts.d.ts +130 -0
  244. package/dist/communications/newsletterIntegrationContracts.js +128 -0
  245. package/dist/communications/newsletterWebhookPort.d.ts +11 -0
  246. package/dist/communications/newsletterWebhookPort.js +84 -0
  247. package/dist/communications/newsletterWebhookProcessing.d.ts +17 -0
  248. package/dist/communications/newsletterWebhookProcessing.js +71 -0
  249. package/dist/communications/originPolicy.d.ts +40 -0
  250. package/dist/communications/originPolicy.js +100 -0
  251. package/dist/communications/postgresCommunicationSync.d.ts +79 -0
  252. package/dist/communications/postgresCommunicationSync.js +111 -0
  253. package/dist/communications/postgresConsentEvaluator.d.ts +19 -0
  254. package/dist/communications/postgresConsentEvaluator.js +43 -0
  255. package/dist/communications/postgresDeliveryReconciliation.d.ts +3 -0
  256. package/dist/communications/postgresDeliveryReconciliation.js +113 -0
  257. package/dist/communications/postgresNativeOperations.d.ts +13 -0
  258. package/dist/communications/postgresNativeOperations.js +63 -0
  259. package/dist/communications/postgresNotificationRecipients.d.ts +37 -0
  260. package/dist/communications/postgresNotificationRecipients.js +60 -0
  261. package/dist/communications/postgresTransactionalDeliveryStore.d.ts +7 -0
  262. package/dist/communications/postgresTransactionalDeliveryStore.js +55 -0
  263. package/dist/communications/preferencesToken.d.ts +10 -0
  264. package/dist/communications/preferencesToken.js +40 -0
  265. package/dist/communications/publicPreferenceToken.d.ts +24 -0
  266. package/dist/communications/publicPreferenceToken.js +53 -0
  267. package/dist/communications/resend/index.d.ts +40 -0
  268. package/dist/communications/resend/index.js +310 -0
  269. package/dist/communications/shipmentNotifications.d.ts +34 -0
  270. package/dist/communications/shipmentNotifications.js +61 -0
  271. package/dist/communications/sql.d.ts +26 -0
  272. package/dist/communications/sql.js +7 -0
  273. package/dist/communications/standardWebhooks.d.ts +14 -0
  274. package/dist/communications/standardWebhooks.js +73 -0
  275. package/dist/communications/status.d.ts +11 -0
  276. package/dist/communications/status.js +36 -0
  277. package/dist/communications/transactionalDelivery.d.ts +19 -0
  278. package/dist/communications/transactionalDelivery.js +96 -0
  279. package/dist/communications/transactionalDeliveryIdentifier.d.ts +3 -0
  280. package/dist/communications/transactionalDeliveryIdentifier.js +6 -0
  281. package/dist/communications/unsubscribeToken.d.ts +77 -0
  282. package/dist/communications/unsubscribeToken.js +150 -0
  283. package/dist/communications/validation.d.ts +2 -0
  284. package/dist/communications/validation.js +3 -0
  285. package/dist/composition/catalogContribution.d.ts +18 -0
  286. package/dist/composition/catalogContribution.js +21 -0
  287. package/dist/composition/index.d.ts +1 -0
  288. package/dist/composition/index.js +1 -0
  289. package/dist/http/index.d.ts +1 -0
  290. package/dist/http/index.js +1 -0
  291. package/dist/http/webhookSignature.d.ts +42 -0
  292. package/dist/http/webhookSignature.js +86 -0
  293. package/dist/identity/customerContracts.d.ts +2 -2
  294. package/dist/inventory/adminInventory.d.ts +13 -0
  295. package/dist/inventory/adminInventory.js +214 -0
  296. package/dist/inventory/contracts/forecast.d.ts +86 -0
  297. package/dist/inventory/contracts/forecast.js +1 -0
  298. package/dist/inventory/contracts/index.d.ts +4 -0
  299. package/dist/inventory/contracts/index.js +1 -0
  300. package/dist/inventory/contracts/inventory.d.ts +157 -0
  301. package/dist/inventory/contracts/inventory.js +1 -0
  302. package/dist/inventory/contracts/newPurchaseStock.d.ts +20 -0
  303. package/dist/inventory/contracts/newPurchaseStock.js +1 -0
  304. package/dist/inventory/contracts/reservation.d.ts +18 -0
  305. package/dist/inventory/contracts/reservation.js +1 -0
  306. package/dist/inventory/forecast.d.ts +24 -0
  307. package/dist/inventory/forecast.js +200 -0
  308. package/dist/inventory/index.d.ts +13 -0
  309. package/dist/inventory/index.js +10 -0
  310. package/dist/inventory/inventoryHandlers.d.ts +53 -0
  311. package/dist/inventory/inventoryHandlers.js +151 -0
  312. package/dist/inventory/newPurchaseStockAvailability.d.ts +47 -0
  313. package/dist/inventory/newPurchaseStockAvailability.js +75 -0
  314. package/dist/inventory/ports.d.ts +21 -0
  315. package/dist/inventory/ports.js +16 -0
  316. package/dist/inventory/renewalReservation.d.ts +27 -0
  317. package/dist/inventory/renewalReservation.js +61 -0
  318. package/dist/inventory/reservationPolicy.d.ts +6 -0
  319. package/dist/inventory/reservationPolicy.js +19 -0
  320. package/dist/inventory/schemas.d.ts +137 -0
  321. package/dist/inventory/schemas.js +112 -0
  322. package/dist/inventory/sql.d.ts +14 -0
  323. package/dist/inventory/sql.js +5 -0
  324. package/dist/inventory/subscriptionForecastCalculation.d.ts +4 -0
  325. package/dist/inventory/subscriptionForecastCalculation.js +133 -0
  326. package/dist/pricing/acquisitionFinancialPolicy.d.ts +26 -0
  327. package/dist/pricing/acquisitionFinancialPolicy.js +1 -0
  328. package/dist/pricing/acquisitionOfferPricing.d.ts +27 -0
  329. package/dist/pricing/acquisitionOfferPricing.js +25 -0
  330. package/dist/pricing/acquisitionOfferPricingHandler.d.ts +20 -0
  331. package/dist/pricing/acquisitionOfferPricingHandler.js +105 -0
  332. package/dist/pricing/acquisitionOfferPricingSchemas.d.ts +31 -0
  333. package/dist/pricing/acquisitionOfferPricingSchemas.js +33 -0
  334. package/dist/pricing/acquisitionQuoteBinding.d.ts +12 -0
  335. package/dist/pricing/acquisitionQuoteBinding.js +12 -0
  336. package/dist/pricing/acquisitionReadiness.d.ts +31 -0
  337. package/dist/pricing/acquisitionReadiness.js +117 -0
  338. package/dist/pricing/acquisitionTerms.d.ts +19 -0
  339. package/dist/pricing/acquisitionTerms.js +126 -0
  340. package/dist/pricing/acquisitionTermsSchemas.d.ts +59 -0
  341. package/dist/pricing/acquisitionTermsSchemas.js +42 -0
  342. package/dist/pricing/catalogFactsProvenance.d.ts +33 -0
  343. package/dist/pricing/catalogFactsProvenance.js +64 -0
  344. package/dist/pricing/catalogFactsSchemas.d.ts +45 -0
  345. package/dist/pricing/catalogFactsSchemas.js +58 -0
  346. package/dist/pricing/commerceOfferPricing.d.ts +25 -0
  347. package/dist/pricing/commerceOfferPricing.js +139 -0
  348. package/dist/pricing/commerceOfferPricingCache.d.ts +10 -0
  349. package/dist/pricing/commerceOfferPricingCache.js +44 -0
  350. package/dist/pricing/commerceOfferPricingHandler.d.ts +21 -0
  351. package/dist/pricing/commerceOfferPricingHandler.js +78 -0
  352. package/dist/pricing/commercePriceAuthority.d.ts +26 -0
  353. package/dist/pricing/commercePriceAuthority.js +79 -0
  354. package/dist/pricing/commercePricingPolicyErrors.d.ts +40 -0
  355. package/dist/pricing/commercePricingPolicyErrors.js +67 -0
  356. package/dist/pricing/commerceQuoteBatchHandler.d.ts +37 -0
  357. package/dist/pricing/commerceQuoteBatchHandler.js +83 -0
  358. package/dist/pricing/commerceQuoteCatalogReadPort.d.ts +27 -0
  359. package/dist/pricing/commerceQuoteCatalogReadPort.js +8 -0
  360. package/dist/pricing/commerceQuoteHandler.d.ts +31 -0
  361. package/dist/pricing/commerceQuoteHandler.js +110 -0
  362. package/dist/pricing/commerceQuoteSnapshotExpect.d.ts +9 -0
  363. package/dist/pricing/commerceQuoteSnapshotExpect.js +22 -0
  364. package/dist/pricing/contracts/acquisitionTerms.d.ts +32 -0
  365. package/dist/pricing/contracts/acquisitionTerms.js +2 -0
  366. package/dist/pricing/contracts/authority.d.ts +27 -0
  367. package/dist/pricing/contracts/authority.js +1 -0
  368. package/dist/pricing/contracts/evidence.d.ts +33 -0
  369. package/dist/pricing/contracts/evidence.js +1 -0
  370. package/dist/pricing/contracts/index.d.ts +17 -0
  371. package/dist/pricing/contracts/index.js +7 -0
  372. package/dist/pricing/contracts/money.d.ts +27 -0
  373. package/dist/pricing/contracts/money.js +1 -0
  374. package/dist/pricing/contracts/offer.d.ts +52 -0
  375. package/dist/pricing/contracts/offer.js +4 -0
  376. package/dist/pricing/contracts/offerPolicy.d.ts +16 -0
  377. package/dist/pricing/contracts/offerPolicy.js +5 -0
  378. package/dist/pricing/contracts/policy.d.ts +22 -0
  379. package/dist/pricing/contracts/policy.js +3 -0
  380. package/dist/pricing/contracts/provenance.d.ts +24 -0
  381. package/dist/pricing/contracts/provenance.js +2 -0
  382. package/dist/pricing/contracts/quote.d.ts +94 -0
  383. package/dist/pricing/contracts/quote.js +1 -0
  384. package/dist/pricing/dbBackedCommerceQuoteHelpers.d.ts +78 -0
  385. package/dist/pricing/dbBackedCommerceQuoteHelpers.js +146 -0
  386. package/dist/pricing/dbBackedCommerceQuotePort.d.ts +66 -0
  387. package/dist/pricing/dbBackedCommerceQuotePort.js +206 -0
  388. package/dist/pricing/dbBackedCommerceQuoteSnapshotVerifier.d.ts +4 -0
  389. package/dist/pricing/dbBackedCommerceQuoteSnapshotVerifier.js +25 -0
  390. package/dist/pricing/index.d.ts +51 -0
  391. package/dist/pricing/index.js +36 -0
  392. package/dist/pricing/offerPolicyReadiness.d.ts +21 -0
  393. package/dist/pricing/offerPolicyReadiness.js +79 -0
  394. package/dist/pricing/offerPolicySchemas.d.ts +25 -0
  395. package/dist/pricing/offerPolicySchemas.js +15 -0
  396. package/dist/pricing/offerPricingSchemas.d.ts +315 -0
  397. package/dist/pricing/offerPricingSchemas.js +65 -0
  398. package/dist/pricing/ports.d.ts +13 -0
  399. package/dist/pricing/ports.js +9 -0
  400. package/dist/pricing/pricingPolicyToken.d.ts +39 -0
  401. package/dist/pricing/pricingPolicyToken.js +84 -0
  402. package/dist/pricing/quoteAcquisitionTerms.d.ts +2 -0
  403. package/dist/pricing/quoteAcquisitionTerms.js +4 -0
  404. package/dist/pricing/quoteCodeRejectionDetails.d.ts +20 -0
  405. package/dist/pricing/quoteCodeRejectionDetails.js +22 -0
  406. package/dist/pricing/quotePorts.d.ts +30 -0
  407. package/dist/pricing/quotePorts.js +20 -0
  408. package/dist/pricing/quotePrimitives.d.ts +13 -0
  409. package/dist/pricing/quotePrimitives.js +18 -0
  410. package/dist/pricing/quotePromotionEvidence.d.ts +39 -0
  411. package/dist/pricing/quotePromotionEvidence.js +73 -0
  412. package/dist/pricing/quoteSchemas.d.ts +1176 -0
  413. package/dist/pricing/quoteSchemas.js +196 -0
  414. package/dist/pricing/subscriptionPricePolicy.d.ts +52 -0
  415. package/dist/pricing/subscriptionPricePolicy.js +96 -0
  416. package/dist/pricing/taxProfileGuard.d.ts +2 -0
  417. package/dist/pricing/taxProfileGuard.js +24 -0
  418. package/dist/pricing/validation.d.ts +2 -0
  419. package/dist/pricing/validation.js +3 -0
  420. package/dist/promotions/adminBindings.d.ts +72 -0
  421. package/dist/promotions/adminBindings.js +1 -0
  422. package/dist/promotions/adminPromotionCodesContracts.d.ts +498 -0
  423. package/dist/promotions/adminPromotionCodesContracts.js +211 -0
  424. package/dist/promotions/adminPromotionCodesDataPort.d.ts +47 -0
  425. package/dist/promotions/adminPromotionCodesDataPort.js +1 -0
  426. package/dist/promotions/adminPromotionCodesHandler.d.ts +14 -0
  427. package/dist/promotions/adminPromotionCodesHandler.js +194 -0
  428. package/dist/promotions/adminPromotionsContracts.d.ts +235 -0
  429. package/dist/promotions/adminPromotionsContracts.js +99 -0
  430. package/dist/promotions/adminPromotionsDataPort.d.ts +42 -0
  431. package/dist/promotions/adminPromotionsDataPort.js +1 -0
  432. package/dist/promotions/adminPromotionsHandler.d.ts +16 -0
  433. package/dist/promotions/adminPromotionsHandler.js +47 -0
  434. package/dist/promotions/contracts/index.d.ts +387 -0
  435. package/dist/promotions/contracts/index.js +1 -0
  436. package/dist/promotions/index.d.ts +22 -0
  437. package/dist/promotions/index.js +21 -0
  438. package/dist/promotions/promoDataPort.d.ts +47 -0
  439. package/dist/promotions/promoDataPort.js +14 -0
  440. package/dist/promotions/promotionAcceptanceTelemetry.d.ts +29 -0
  441. package/dist/promotions/promotionAcceptanceTelemetry.js +45 -0
  442. package/dist/promotions/promotionBenefitDefinition.d.ts +37 -0
  443. package/dist/promotions/promotionBenefitDefinition.js +33 -0
  444. package/dist/promotions/promotionClaimSweepPort.d.ts +14 -0
  445. package/dist/promotions/promotionClaimSweepPort.js +8 -0
  446. package/dist/promotions/promotionClaims.d.ts +5 -0
  447. package/dist/promotions/promotionClaims.js +57 -0
  448. package/dist/promotions/promotionCodePreview.d.ts +11 -0
  449. package/dist/promotions/promotionCodePreview.js +154 -0
  450. package/dist/promotions/promotionCodeQuotePort.d.ts +25 -0
  451. package/dist/promotions/promotionCodeQuotePort.js +1 -0
  452. package/dist/promotions/promotionQuoteAcceptance.d.ts +65 -0
  453. package/dist/promotions/promotionQuoteAcceptance.js +202 -0
  454. package/dist/promotions/promotionQuoteBinding.d.ts +71 -0
  455. package/dist/promotions/promotionQuoteBinding.js +85 -0
  456. package/dist/promotions/quoteAutomaticPromotions.d.ts +24 -0
  457. package/dist/promotions/quoteAutomaticPromotions.js +36 -0
  458. package/dist/promotions/quotePromoDiscounts.d.ts +32 -0
  459. package/dist/promotions/quotePromoDiscounts.js +140 -0
  460. package/dist/promotions/quotePromotionCodeAdjustments.d.ts +27 -0
  461. package/dist/promotions/quotePromotionCodeAdjustments.js +223 -0
  462. package/dist/promotions/quotePromotionV2.d.ts +29 -0
  463. package/dist/promotions/quotePromotionV2.js +174 -0
  464. package/dist/promotions/sql.d.ts +14 -0
  465. package/dist/promotions/sql.js +5 -0
  466. package/dist/promotions/validation.d.ts +2 -0
  467. package/dist/promotions/validation.js +3 -0
  468. package/dist/shipping/addressCanonLookupHandler.d.ts +7 -0
  469. package/dist/shipping/addressCanonLookupHandler.js +105 -0
  470. package/dist/shipping/addressCanonical.d.ts +2 -0
  471. package/dist/shipping/addressCanonical.js +26 -0
  472. package/dist/shipping/addressPorts.d.ts +39 -0
  473. package/dist/shipping/addressPorts.js +1 -0
  474. package/dist/shipping/addressSchemas.d.ts +30 -0
  475. package/dist/shipping/addressSchemas.js +1 -0
  476. package/dist/shipping/adminShippingRateHandler.d.ts +4 -0
  477. package/dist/shipping/adminShippingRateHandler.js +64 -0
  478. package/dist/shipping/contracts/address.d.ts +144 -0
  479. package/dist/shipping/contracts/address.js +1 -0
  480. package/dist/shipping/contracts/delivery.d.ts +110 -0
  481. package/dist/shipping/contracts/delivery.js +1 -0
  482. package/dist/shipping/contracts/index.d.ts +3 -0
  483. package/dist/shipping/contracts/index.js +1 -0
  484. package/dist/shipping/contracts/shippingRate.d.ts +11 -0
  485. package/dist/shipping/contracts/shippingRate.js +1 -0
  486. package/dist/shipping/customerAddressesHandler.d.ts +5 -0
  487. package/dist/shipping/customerAddressesHandler.js +80 -0
  488. package/dist/shipping/customerSelfServiceAddressModels.d.ts +27 -0
  489. package/dist/shipping/customerSelfServiceAddressModels.js +101 -0
  490. package/dist/shipping/deliverySelectionHandler.d.ts +10 -0
  491. package/dist/shipping/deliverySelectionHandler.js +77 -0
  492. package/dist/shipping/deliverySelectionPort.d.ts +8 -0
  493. package/dist/shipping/deliverySelectionPort.js +1 -0
  494. package/dist/shipping/deliverySelectionSummary.d.ts +2 -0
  495. package/dist/shipping/deliverySelectionSummary.js +53 -0
  496. package/dist/shipping/handlerSchemas.d.ts +21 -0
  497. package/dist/shipping/handlerSchemas.js +1 -0
  498. package/dist/shipping/index.d.ts +17 -0
  499. package/dist/shipping/index.js +8 -0
  500. package/dist/shipping/pickupPointSearchPort.d.ts +4 -0
  501. package/dist/shipping/pickupPointSearchPort.js +1 -0
  502. package/dist/shipping/readDeliverySelectionEvidence.d.ts +2 -0
  503. package/dist/shipping/readDeliverySelectionEvidence.js +44 -0
  504. package/dist/shipping/shippingRatePorts.d.ts +52 -0
  505. package/dist/shipping/shippingRatePorts.js +1 -0
  506. package/package.json +72 -2
  507. package/release-gates.json +249 -8
  508. package/sql/20260807140000_read_parity_catalog.sql +94 -0
  509. package/sql/20260807190000_comms_outbox_rail.sql +329 -0
  510. package/sql/20260810120000_storefront_catalog_attributes.sql +51 -0
  511. package/sql/20260810120001_transactional_delivery_receipts.sql +209 -0
  512. package/sql/20260812140000_sellable_bundle_catalog.sql +124 -0
  513. package/sql/20260812210000_bundle_operator_write_boundary.sql +567 -0
  514. package/sql/20260813120000_communications_control_plane.sql +568 -0
  515. package/sql/20260814000000_fulfillment_stock_evidence.sql +239 -0
  516. package/sql/20260815120000_automatic_subscription_renewal.sql +1083 -0
  517. package/sql/20260817180000_promotion_claim_lifecycle.sql +591 -0
  518. package/sql/20260817180100_promotion_claim_lifecycle_validation.sql +23 -0
  519. package/sql/20260827220000_catalog_document_revision_foundation.sql +226 -0
  520. package/sql/20260827220001_catalog_document_revision_foundation_validate.sql +10 -0
  521. package/sql/20260908100000_catalog_draft_foundation.sql +217 -0
  522. package/sql/20261019200000_communications_native_operations.sql +68 -0
  523. package/src/catalog/activeSkuSelection.ts +20 -0
  524. package/src/catalog/adminBindings.ts +59 -0
  525. package/src/catalog/adminBundleHandler.ts +165 -0
  526. package/src/catalog/adminBundleReadHandler.ts +261 -0
  527. package/src/catalog/adminBundleWritePort.ts +102 -0
  528. package/src/catalog/bundleAvailability.ts +129 -0
  529. package/src/catalog/bundleAvailabilityService.ts +171 -0
  530. package/src/catalog/bundleBindings.ts +29 -0
  531. package/src/catalog/bundleCatalogQueries.ts +98 -0
  532. package/src/catalog/bundleCatalogReadPort.ts +177 -0
  533. package/src/catalog/bundleCatalogStore.ts +269 -0
  534. package/src/catalog/bundleRuleCodes.ts +134 -0
  535. package/src/catalog/bundleRules.ts +153 -0
  536. package/src/catalog/catalogDraftStore.ts +71 -0
  537. package/src/catalog/catalogSkuEnvelope.ts +214 -0
  538. package/src/catalog/catalogSkuEnvelopeMapper.ts +160 -0
  539. package/src/catalog/contracts/bundleAdmin.ts +20 -0
  540. package/src/catalog/contracts/bundleAvailability.ts +5 -0
  541. package/src/catalog/contracts/bundleRead.ts +13 -0
  542. package/src/catalog/contracts/draft.ts +69 -0
  543. package/src/catalog/contracts/foundation.ts +104 -0
  544. package/src/catalog/contracts/index.ts +14 -0
  545. package/src/catalog/contracts/lifecycle.ts +74 -0
  546. package/src/catalog/contracts/productMediaContracts.ts +170 -0
  547. package/src/catalog/contracts/productTypes.ts +35 -0
  548. package/src/catalog/contracts/resolveProductMedia.ts +85 -0
  549. package/src/catalog/contracts/sellable.ts +12 -0
  550. package/src/catalog/draftHandler.ts +105 -0
  551. package/src/catalog/draftPorts.ts +18 -0
  552. package/src/catalog/draftSchemas.ts +88 -0
  553. package/src/catalog/draftValidation.ts +100 -0
  554. package/src/catalog/foundationSchemas.ts +123 -0
  555. package/src/catalog/index.ts +43 -0
  556. package/src/catalog/mediaSourcePack.ts +219 -0
  557. package/src/catalog/productTypeSchemas.ts +70 -0
  558. package/src/catalog/publicationPorts.ts +44 -0
  559. package/src/catalog/readPorts.ts +61 -0
  560. package/src/catalog/referenceCatalogHandler.ts +39 -0
  561. package/src/catalog/resolvedSkuProjection.ts +76 -0
  562. package/src/catalog/sellableBundleHandler.ts +133 -0
  563. package/src/catalog/sellableSchemas.ts +33 -0
  564. package/src/catalog/sql.ts +14 -0
  565. package/src/catalog/validation.ts +3 -0
  566. package/src/communications/accountingDocumentDelivery.ts +63 -0
  567. package/src/communications/authEmailError.ts +10 -0
  568. package/src/communications/authEmailPorts.ts +2 -0
  569. package/src/communications/authSendEmailHook.ts +310 -0
  570. package/src/communications/capturedTransactionalDelivery.ts +29 -0
  571. package/src/communications/communicationSync.ts +96 -0
  572. package/src/communications/communicationSyncWorker.ts +302 -0
  573. package/src/communications/consentPolicy.ts +82 -0
  574. package/src/communications/consentPurposeRegistry.ts +31 -0
  575. package/src/communications/contracts/abandonedCart.ts +64 -0
  576. package/src/communications/contracts/authEmail.ts +73 -0
  577. package/src/communications/contracts/backInStock.ts +69 -0
  578. package/src/communications/contracts/blocks.ts +47 -0
  579. package/src/communications/contracts/checkoutExpired.ts +62 -0
  580. package/src/communications/contracts/checkoutRecovery.ts +68 -0
  581. package/src/communications/contracts/commerceEmailContent.ts +189 -0
  582. package/src/communications/contracts/commerceEngagementEmailContent.ts +106 -0
  583. package/src/communications/contracts/consent.ts +13 -0
  584. package/src/communications/contracts/email.ts +210 -0
  585. package/src/communications/contracts/guideCard.ts +34 -0
  586. package/src/communications/contracts/index.ts +52 -0
  587. package/src/communications/contracts/inquiryContent.ts +53 -0
  588. package/src/communications/contracts/invoiceDocumentContent.ts +57 -0
  589. package/src/communications/contracts/marketingAutomation.ts +45 -0
  590. package/src/communications/contracts/marketingSync.ts +109 -0
  591. package/src/communications/contracts/newsletter.ts +78 -0
  592. package/src/communications/contracts/newsletterWebhook.ts +23 -0
  593. package/src/communications/contracts/optOutContent.ts +23 -0
  594. package/src/communications/contracts/orderCanceled.ts +64 -0
  595. package/src/communications/contracts/orderDraft.ts +112 -0
  596. package/src/communications/contracts/orderPaid.ts +147 -0
  597. package/src/communications/contracts/orderRefunded.ts +63 -0
  598. package/src/communications/contracts/paymentFailed.ts +59 -0
  599. package/src/communications/contracts/publicIntake.ts +53 -0
  600. package/src/communications/contracts/render.ts +271 -0
  601. package/src/communications/contracts/reorderReminder.ts +59 -0
  602. package/src/communications/contracts/returnEmails.ts +113 -0
  603. package/src/communications/contracts/reviewEffects.ts +60 -0
  604. package/src/communications/contracts/reviewRequest.ts +59 -0
  605. package/src/communications/contracts/roleNotificationContent.ts +65 -0
  606. package/src/communications/contracts/shipmentDelivered.ts +59 -0
  607. package/src/communications/contracts/shipmentDispatched.ts +77 -0
  608. package/src/communications/contracts/shipmentException.ts +62 -0
  609. package/src/communications/contracts/subscriptionActivationActionRequired.ts +37 -0
  610. package/src/communications/contracts/subscriptionAddressChanged.ts +56 -0
  611. package/src/communications/contracts/subscriptionCancelled.ts +57 -0
  612. package/src/communications/contracts/subscriptionCycleSkipped.ts +80 -0
  613. package/src/communications/contracts/subscriptionDeliveryRescheduled.ts +79 -0
  614. package/src/communications/contracts/subscriptionEmailContent.ts +163 -0
  615. package/src/communications/contracts/subscriptionPackageChanged.ts +59 -0
  616. package/src/communications/contracts/subscriptionPauseReminder.ts +63 -0
  617. package/src/communications/contracts/subscriptionPaused.ts +58 -0
  618. package/src/communications/contracts/subscriptionPaymentExpired.ts +83 -0
  619. package/src/communications/contracts/subscriptionPaymentFailed.ts +117 -0
  620. package/src/communications/contracts/subscriptionPaymentRecovered.ts +50 -0
  621. package/src/communications/contracts/subscriptionRenewalAtRisk.ts +85 -0
  622. package/src/communications/contracts/subscriptionRenewalUpcoming.ts +103 -0
  623. package/src/communications/contracts/subscriptionResumed.ts +60 -0
  624. package/src/communications/contracts/subscriptionWelcome.ts +102 -0
  625. package/src/communications/contracts/subscriptionWinback.ts +62 -0
  626. package/src/communications/contracts/transactionalDelivery.ts +43 -0
  627. package/src/communications/contracts/types.ts +58 -0
  628. package/src/communications/contribution.ts +33 -0
  629. package/src/communications/deliveryReconciliation.ts +108 -0
  630. package/src/communications/emailEgress.ts +111 -0
  631. package/src/communications/emailHealthAssessment.ts +106 -0
  632. package/src/communications/emailHealthMetricsPort.ts +17 -0
  633. package/src/communications/emailNotificationControl.ts +28 -0
  634. package/src/communications/emailObservation.ts +43 -0
  635. package/src/communications/emailTransport.ts +167 -0
  636. package/src/communications/errors.ts +34 -0
  637. package/src/communications/index.ts +47 -0
  638. package/src/communications/integrationEventSignature.ts +49 -0
  639. package/src/communications/klaviyo/consentPush.ts +19 -0
  640. package/src/communications/klaviyo/index.ts +649 -0
  641. package/src/communications/managedTransactionalDeliveryStore.ts +59 -0
  642. package/src/communications/nativeOperations.ts +40 -0
  643. package/src/communications/newsletterIntegrationContracts.ts +154 -0
  644. package/src/communications/newsletterWebhookPort.ts +104 -0
  645. package/src/communications/newsletterWebhookProcessing.ts +102 -0
  646. package/src/communications/originPolicy.ts +151 -0
  647. package/src/communications/postgresCommunicationSync.ts +127 -0
  648. package/src/communications/postgresConsentEvaluator.ts +49 -0
  649. package/src/communications/postgresDeliveryReconciliation.ts +101 -0
  650. package/src/communications/postgresNativeOperations.ts +55 -0
  651. package/src/communications/postgresNotificationRecipients.ts +57 -0
  652. package/src/communications/postgresTransactionalDeliveryStore.ts +79 -0
  653. package/src/communications/preferencesToken.ts +62 -0
  654. package/src/communications/publicPreferenceToken.ts +68 -0
  655. package/src/communications/resend/index.ts +350 -0
  656. package/src/communications/shipmentNotifications.ts +78 -0
  657. package/src/communications/sql.ts +7 -0
  658. package/src/communications/standardWebhooks.ts +84 -0
  659. package/src/communications/status.ts +51 -0
  660. package/src/communications/transactionalDelivery.ts +114 -0
  661. package/src/communications/transactionalDeliveryIdentifier.ts +9 -0
  662. package/src/communications/unsubscribeToken.ts +186 -0
  663. package/src/communications/validation.ts +3 -0
  664. package/src/composition/catalogContribution.ts +32 -0
  665. package/src/composition/index.ts +1 -0
  666. package/src/http/index.ts +1 -0
  667. package/src/http/webhookSignature.ts +96 -0
  668. package/src/inventory/adminInventory.ts +251 -0
  669. package/src/inventory/contracts/forecast.ts +96 -0
  670. package/src/inventory/contracts/index.ts +18 -0
  671. package/src/inventory/contracts/inventory.ts +14 -0
  672. package/src/inventory/contracts/newPurchaseStock.ts +23 -0
  673. package/src/inventory/contracts/reservation.ts +20 -0
  674. package/src/inventory/forecast.ts +239 -0
  675. package/src/inventory/index.ts +21 -0
  676. package/src/inventory/inventoryHandlers.ts +215 -0
  677. package/src/inventory/newPurchaseStockAvailability.ts +120 -0
  678. package/src/inventory/ports.ts +46 -0
  679. package/src/inventory/renewalReservation.ts +88 -0
  680. package/src/inventory/reservationPolicy.ts +27 -0
  681. package/src/inventory/schemas.ts +128 -0
  682. package/src/inventory/sql.ts +5 -0
  683. package/src/inventory/subscriptionForecastCalculation.ts +157 -0
  684. package/src/pricing/acquisitionFinancialPolicy.ts +26 -0
  685. package/src/pricing/acquisitionOfferPricing.ts +38 -0
  686. package/src/pricing/acquisitionOfferPricingHandler.ts +157 -0
  687. package/src/pricing/acquisitionOfferPricingSchemas.ts +35 -0
  688. package/src/pricing/acquisitionQuoteBinding.ts +12 -0
  689. package/src/pricing/acquisitionReadiness.ts +148 -0
  690. package/src/pricing/acquisitionTerms.ts +125 -0
  691. package/src/pricing/acquisitionTermsSchemas.ts +52 -0
  692. package/src/pricing/catalogFactsProvenance.ts +102 -0
  693. package/src/pricing/catalogFactsSchemas.ts +69 -0
  694. package/src/pricing/commerceOfferPricing.ts +224 -0
  695. package/src/pricing/commerceOfferPricingCache.ts +53 -0
  696. package/src/pricing/commerceOfferPricingHandler.ts +137 -0
  697. package/src/pricing/commercePriceAuthority.ts +104 -0
  698. package/src/pricing/commercePricingPolicyErrors.ts +88 -0
  699. package/src/pricing/commerceQuoteBatchHandler.ts +129 -0
  700. package/src/pricing/commerceQuoteCatalogReadPort.ts +42 -0
  701. package/src/pricing/commerceQuoteHandler.ts +184 -0
  702. package/src/pricing/commerceQuoteSnapshotExpect.ts +48 -0
  703. package/src/pricing/contracts/acquisitionTerms.ts +26 -0
  704. package/src/pricing/contracts/authority.ts +44 -0
  705. package/src/pricing/contracts/evidence.ts +25 -0
  706. package/src/pricing/contracts/index.ts +17 -0
  707. package/src/pricing/contracts/money.ts +32 -0
  708. package/src/pricing/contracts/offer.ts +42 -0
  709. package/src/pricing/contracts/offerPolicy.ts +17 -0
  710. package/src/pricing/contracts/policy.ts +26 -0
  711. package/src/pricing/contracts/provenance.ts +19 -0
  712. package/src/pricing/contracts/quote.ts +106 -0
  713. package/src/pricing/dbBackedCommerceQuoteHelpers.ts +256 -0
  714. package/src/pricing/dbBackedCommerceQuotePort.ts +260 -0
  715. package/src/pricing/dbBackedCommerceQuoteSnapshotVerifier.ts +49 -0
  716. package/src/pricing/index.ts +52 -0
  717. package/src/pricing/offerPolicyReadiness.ts +110 -0
  718. package/src/pricing/offerPolicySchemas.ts +23 -0
  719. package/src/pricing/offerPricingSchemas.ts +92 -0
  720. package/src/pricing/ports.ts +17 -0
  721. package/src/pricing/pricingPolicyToken.ts +119 -0
  722. package/src/pricing/quoteAcquisitionTerms.ts +10 -0
  723. package/src/pricing/quoteCodeRejectionDetails.ts +23 -0
  724. package/src/pricing/quotePorts.ts +58 -0
  725. package/src/pricing/quotePrimitives.ts +21 -0
  726. package/src/pricing/quotePromotionEvidence.ts +82 -0
  727. package/src/pricing/quoteSchemas.ts +230 -0
  728. package/src/pricing/subscriptionPricePolicy.ts +113 -0
  729. package/src/pricing/taxProfileGuard.ts +33 -0
  730. package/src/pricing/validation.ts +3 -0
  731. package/src/promotions/adminBindings.ts +53 -0
  732. package/src/promotions/adminPromotionCodesContracts.ts +244 -0
  733. package/src/promotions/adminPromotionCodesDataPort.ts +56 -0
  734. package/src/promotions/adminPromotionCodesHandler.ts +254 -0
  735. package/src/promotions/adminPromotionsContracts.ts +121 -0
  736. package/src/promotions/adminPromotionsDataPort.ts +48 -0
  737. package/src/promotions/adminPromotionsHandler.ts +72 -0
  738. package/src/promotions/contracts/index.ts +387 -0
  739. package/src/promotions/index.ts +22 -0
  740. package/src/promotions/promoDataPort.ts +65 -0
  741. package/src/promotions/promotionAcceptanceTelemetry.ts +73 -0
  742. package/src/promotions/promotionBenefitDefinition.ts +48 -0
  743. package/src/promotions/promotionClaimSweepPort.ts +23 -0
  744. package/src/promotions/promotionClaims.ts +70 -0
  745. package/src/promotions/promotionCodePreview.ts +183 -0
  746. package/src/promotions/promotionCodeQuotePort.ts +35 -0
  747. package/src/promotions/promotionQuoteAcceptance.ts +284 -0
  748. package/src/promotions/promotionQuoteBinding.ts +158 -0
  749. package/src/promotions/quoteAutomaticPromotions.ts +58 -0
  750. package/src/promotions/quotePromoDiscounts.ts +185 -0
  751. package/src/promotions/quotePromotionCodeAdjustments.ts +277 -0
  752. package/src/promotions/quotePromotionV2.ts +223 -0
  753. package/src/promotions/sql.ts +5 -0
  754. package/src/promotions/validation.ts +3 -0
  755. package/src/shipping/addressCanonLookupHandler.ts +114 -0
  756. package/src/shipping/addressCanonical.ts +31 -0
  757. package/src/shipping/addressPorts.ts +48 -0
  758. package/src/shipping/addressSchemas.ts +28 -0
  759. package/src/shipping/adminShippingRateHandler.ts +72 -0
  760. package/src/shipping/contracts/address.ts +71 -0
  761. package/src/shipping/contracts/delivery.ts +114 -0
  762. package/src/shipping/contracts/index.ts +18 -0
  763. package/src/shipping/contracts/shippingRate.ts +7 -0
  764. package/src/shipping/customerAddressesHandler.ts +100 -0
  765. package/src/shipping/customerSelfServiceAddressModels.ts +124 -0
  766. package/src/shipping/deliverySelectionHandler.ts +94 -0
  767. package/src/shipping/deliverySelectionPort.ts +10 -0
  768. package/src/shipping/deliverySelectionSummary.ts +56 -0
  769. package/src/shipping/handlerSchemas.ts +19 -0
  770. package/src/shipping/index.ts +23 -0
  771. package/src/shipping/pickupPointSearchPort.ts +8 -0
  772. package/src/shipping/readDeliverySelectionEvidence.ts +51 -0
  773. package/src/shipping/shippingRatePorts.ts +36 -0
@@ -0,0 +1,65 @@
1
+ import type { BundleAvailability, BundleAvailabilityComponent } from "./bundleAvailability.js";
2
+ import type { BundleStockPort as CommerceOfferAvailabilityPort } from "./bundleBindings.js";
3
+ import type { ActiveBundleComposition, BundleCatalogReadPort } from "./bundleCatalogReadPort.js";
4
+ /**
5
+ * Derived bundle stock, composed from the two ports that already know the halves:
6
+ * the bundle read port knows the bill of materials, the EXISTING commerce offer
7
+ * availability port knows what a unit's stock is. Nothing here re-derives stock and
8
+ * nothing here opens a database handle.
9
+ *
10
+ * ONE BATCHED CALL, ALWAYS. Every component of every bundle in the request is
11
+ * asked for in a single `getAvailability`, deduplicated by sku, because the
12
+ * underlying port answers a set in three queries — asking per bundle would turn a
13
+ * catalogue listing into a query storm and would let two bundles sharing a unit
14
+ * disagree about its stock inside one response.
15
+ *
16
+ * A sku the availability port does not answer for is a MISSING figure, not zero:
17
+ * it is folded in as `sellableNow: null`, so the pure kernel reports the bundle as
18
+ * unknown and names the component rather than quietly overselling or hiding it.
19
+ */
20
+ export interface BundleAvailabilityServiceDeps {
21
+ bundleCatalogReadPort: BundleCatalogReadPort;
22
+ offerAvailabilityPort: CommerceOfferAvailabilityPort;
23
+ /** Threshold handed to the pure kernel; its own default applies when omitted. */
24
+ lowStockThreshold?: number;
25
+ includeAddonsInStock?: boolean;
26
+ }
27
+ export interface BundleAvailabilityRow {
28
+ composition: ActiveBundleComposition;
29
+ availability: BundleAvailability;
30
+ /**
31
+ * The EXACT rows the kernel was given, carried out again rather than recomputed.
32
+ *
33
+ * The bundle-level answer names one limiting component; an operator staring at a bundle that
34
+ * cannot ship needs to know how far off every OTHER component is too, so they can tell "order one
35
+ * more of this" from "this bundle is months away". These rows are the only place that figure
36
+ * exists — the kernel folds them into a single number and the sellable feed's components carry
37
+ * price, never stock. Returning them costs nothing here and is the alternative to a second stock
38
+ * derivation somewhere that can disagree with this one.
39
+ */
40
+ components: readonly BundleAvailabilityComponent[];
41
+ }
42
+ export interface BundleAvailabilityService {
43
+ /** Fold stock into a set of compositions the caller already holds. */
44
+ describeCompositions(compositions: readonly ActiveBundleComposition[]): Promise<BundleAvailabilityRow[]>;
45
+ /** Read the live sellable set and fold stock into it. */
46
+ describeActiveBundles(input?: {
47
+ currency?: string;
48
+ }): Promise<BundleAvailabilityRow[]>;
49
+ }
50
+ export declare function createBundleAvailabilityServices({ deriveBundleAvailability }: {
51
+ deriveBundleAvailability: (input: import("./bundleAvailability.js").DeriveBundleAvailabilityInput) => BundleAvailability;
52
+ }): {
53
+ createBundleAvailabilityService: (deps: BundleAvailabilityServiceDeps) => BundleAvailabilityService;
54
+ };
55
+ /**
56
+ * The port to use where no stock source is bound at all.
57
+ *
58
+ * It answers every item with `sellableNow: null`, which the kernel reads as
59
+ * unknown — so a deployment without an inventory rail publishes bundles whose
60
+ * price is exact and whose stock is honestly unstated. The alternative, omitting
61
+ * the availability block, would have made "we do not know" indistinguishable from
62
+ * "we did not ask", and the alternative to THAT — defaulting to available —
63
+ * oversells on a deployment that never counted anything.
64
+ */
65
+ export declare function createUnknownOfferAvailabilityPort(): CommerceOfferAvailabilityPort;
@@ -0,0 +1,89 @@
1
+ export function createBundleAvailabilityServices({ deriveBundleAvailability }) {
2
+ function createBundleAvailabilityService(deps) {
3
+ async function describeCompositions(compositions) {
4
+ if (compositions.length === 0)
5
+ return [];
6
+ const items = requestItems(compositions);
7
+ const stock = items.length === 0
8
+ ? new Map()
9
+ : sellableBySku(await deps.offerAvailabilityPort.getAvailability({ items }));
10
+ return compositions.map((composition) => {
11
+ const components = composition.components.map((component) => ({
12
+ sku: component.sku,
13
+ quantity: component.quantity,
14
+ isAddon: component.isAddon,
15
+ // `has` distinguishes "answered null" from "never answered"; both fold to
16
+ // null, and neither is allowed to become a number here.
17
+ sellableNow: stock.has(component.sku) ? (stock.get(component.sku) ?? null) : null,
18
+ }));
19
+ return {
20
+ composition,
21
+ components,
22
+ availability: deriveBundleAvailability({
23
+ components,
24
+ lowStockThreshold: deps.lowStockThreshold,
25
+ includeAddonsInStock: deps.includeAddonsInStock,
26
+ }),
27
+ };
28
+ });
29
+ }
30
+ return {
31
+ describeCompositions,
32
+ async describeActiveBundles(input = {}) {
33
+ return describeCompositions(await deps.bundleCatalogReadPort.listActiveBundleCompositions(input));
34
+ },
35
+ };
36
+ }
37
+ return { createBundleAvailabilityService };
38
+ }
39
+ /**
40
+ * The port to use where no stock source is bound at all.
41
+ *
42
+ * It answers every item with `sellableNow: null`, which the kernel reads as
43
+ * unknown — so a deployment without an inventory rail publishes bundles whose
44
+ * price is exact and whose stock is honestly unstated. The alternative, omitting
45
+ * the availability block, would have made "we do not know" indistinguishable from
46
+ * "we did not ask", and the alternative to THAT — defaulting to available —
47
+ * oversells on a deployment that never counted anything.
48
+ */
49
+ export function createUnknownOfferAvailabilityPort() {
50
+ return {
51
+ getAvailability({ items }) {
52
+ return Promise.resolve(items.map((item) => ({
53
+ sku: item.sku,
54
+ productSlug: item.productSlug,
55
+ variantId: item.variantId,
56
+ status: "unknown",
57
+ visibleInConfigurator: true,
58
+ sellableNow: null,
59
+ reasonCode: "stock_unknown",
60
+ source: "unbound",
61
+ })));
62
+ },
63
+ };
64
+ }
65
+ /**
66
+ * One request item per distinct sku across every bundle. `requestedQuantity` stays
67
+ * at the port's own default of one: the question asked is "how many units exist",
68
+ * and the multiplication by the bill of materials belongs to the pure kernel,
69
+ * which is the only place that knows how many bundles a figure buys.
70
+ */
71
+ function requestItems(compositions) {
72
+ const bySku = new Map();
73
+ for (const composition of compositions) {
74
+ for (const component of composition.components) {
75
+ if (!bySku.has(component.sku))
76
+ bySku.set(component.sku, component);
77
+ }
78
+ }
79
+ return [...bySku.values()].map((component) => ({
80
+ sku: component.sku,
81
+ productSlug: component.productSlug,
82
+ variantId: component.variantId,
83
+ requestedQuantity: 1,
84
+ checkoutMode: "one_time",
85
+ }));
86
+ }
87
+ function sellableBySku(answers) {
88
+ return new Map(answers.map((answer) => [answer.sku, answer.sellableNow ?? null]));
89
+ }
@@ -0,0 +1,33 @@
1
+ import type { BundleActorKind } from "./bundleRuleCodes.js";
2
+ /** The host's normalized stock seam; no inventory implementation is owned here. */
3
+ export type BundleStockStatus = "available" | "low_stock" | "out_of_stock" | "unknown";
4
+ export interface BundleStockRequestItem {
5
+ sku: string;
6
+ productSlug: string;
7
+ variantId: string;
8
+ requestedQuantity: number;
9
+ checkoutMode: "one_time" | "subscription";
10
+ }
11
+ export interface BundleStockAvailability {
12
+ sku: string;
13
+ productSlug: string;
14
+ variantId: string;
15
+ status: BundleStockStatus;
16
+ visibleInConfigurator: boolean;
17
+ sellableNow: number | null;
18
+ reasonCode: string;
19
+ source: string;
20
+ }
21
+ export interface BundleStockPort {
22
+ getAvailability(input: {
23
+ items: readonly BundleStockRequestItem[];
24
+ }): Promise<BundleStockAvailability[]>;
25
+ }
26
+ export interface BundleRuleBindings {
27
+ assertActivateNotMachineActor(input: {
28
+ operation: string;
29
+ actorKind: BundleActorKind;
30
+ }): "DRAFT_ONLY_FOR_MACHINE" | null;
31
+ offerAvailabilityStatusFor(sellableNow: number | null, lowStockThreshold?: number): BundleStockStatus;
32
+ offerAvailabilityReasonCode(status: BundleStockStatus): string;
33
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The statements the direct-Postgres bundle read adapter renders.
3
+ *
4
+ * They live beside the adapter rather than inside it because they are the part a
5
+ * reader comes here to check — which relations are touched, which columns are
6
+ * asked for, and how a component's reference price is resolved — and reading them
7
+ * should not mean scrolling past the row marshalling that consumes them.
8
+ */
9
+ export declare const SUMMARY_COLUMNS = "\n b.id, b.code, b.title, b.status, b.fulfillment_mode, b.updated_at,\n b.composition_constraint, b.metadata,\n (SELECT count(*) FROM public.catalog_bundle_components c WHERE c.bundle_id = b.id)\n AS component_count,\n EXISTS (SELECT 1 FROM public.catalog_bundle_prices p WHERE p.bundle_id = b.id AND p.active)\n AS has_active_target_price";
10
+ export declare const LIST_FILTER = "\n WHERE ($1::text = 'all' OR b.status = $1::text)\n AND ($2::text IS NULL OR b.code ILIKE '%' || $2 || '%' OR b.title ILIKE '%' || $2 || '%')";
11
+ export declare const LIST_SQL = "SELECT \n b.id, b.code, b.title, b.status, b.fulfillment_mode, b.updated_at,\n b.composition_constraint, b.metadata,\n (SELECT count(*) FROM public.catalog_bundle_components c WHERE c.bundle_id = b.id)\n AS component_count,\n EXISTS (SELECT 1 FROM public.catalog_bundle_prices p WHERE p.bundle_id = b.id AND p.active)\n AS has_active_target_price FROM public.catalog_bundles b \n WHERE ($1::text = 'all' OR b.status = $1::text)\n AND ($2::text IS NULL OR b.code ILIKE '%' || $2 || '%' OR b.title ILIKE '%' || $2 || '%')\n ORDER BY b.code LIMIT $3 OFFSET $4";
12
+ export declare const COUNT_SQL = "SELECT count(*) AS total FROM public.catalog_bundles b \n WHERE ($1::text = 'all' OR b.status = $1::text)\n AND ($2::text IS NULL OR b.code ILIKE '%' || $2 || '%' OR b.title ILIKE '%' || $2 || '%')";
13
+ export declare const DETAIL_SQL = "SELECT \n b.id, b.code, b.title, b.status, b.fulfillment_mode, b.updated_at,\n b.composition_constraint, b.metadata,\n (SELECT count(*) FROM public.catalog_bundle_components c WHERE c.bundle_id = b.id)\n AS component_count,\n EXISTS (SELECT 1 FROM public.catalog_bundle_prices p WHERE p.bundle_id = b.id AND p.active)\n AS has_active_target_price FROM public.catalog_bundles b WHERE b.code = $1";
14
+ /**
15
+ * The unit's reference price in ONE named list: the lowest tier that is active,
16
+ * newest window first. A unit the list prices nothing for resolves to NULL rather
17
+ * than dropping the component, so a caller sees an unpriced part instead of a
18
+ * shorter bill of materials.
19
+ */
20
+ export declare const REFERENCE_PRICE = "(\n SELECT pe.unit_price_minor FROM public.price_entries pe\n WHERE pe.variant_id = s.id AND pe.price_list_id = %LIST% AND pe.active\n ORDER BY pe.min_qty ASC, pe.valid_from DESC LIMIT 1)";
21
+ export declare const COMPONENT_SQL: string;
22
+ export declare const FEED_COMPONENT_SQL: string;
23
+ export declare const PRICE_SQL = "\n SELECT p.mode, p.target_price_minor, list.currency, p.amount_kind, p.active,\n p.valid_from, p.valid_to\n FROM public.catalog_bundle_prices p\n JOIN public.price_lists AS list ON list.id = p.price_list_id\n WHERE p.bundle_id = $1::uuid\n ORDER BY p.valid_from DESC";
24
+ export declare const OWN_LIST_SQL = "\n SELECT list.id, list.currency\n FROM public.catalog_bundle_prices p\n JOIN public.price_lists AS list ON list.id = p.price_list_id\n WHERE p.bundle_id = $1::uuid AND p.active AND ($2::text IS NULL OR p.mode = $2::text)\n ORDER BY p.valid_from DESC LIMIT 1";
25
+ export declare const CURRENCY_LIST_SQL = "\n SELECT id, currency FROM public.price_lists\n WHERE currency = $1::text AND status = 'active'\n ORDER BY created_at DESC LIMIT 1";
26
+ export declare const FEED_SQL = "\n SELECT b.id, b.code, b.title, b.fulfillment_mode, p.mode, p.target_price_minor,\n p.price_list_id, list.currency\n FROM public.catalog_bundles b\n JOIN public.catalog_bundle_prices p ON p.bundle_id = b.id AND p.active\n JOIN public.price_lists AS list ON list.id = p.price_list_id\n WHERE b.status = 'active' AND ($1::text IS NULL OR list.currency = $1::text)\n ORDER BY b.code, p.valid_from DESC";
27
+ export declare const HISTORY_SQL = "\n SELECT id, bundle_code, action, before_state, after_state, created_at\n FROM public.catalog_bundle_write_events\n WHERE bundle_code = $1::text\n ORDER BY created_at DESC LIMIT $2 OFFSET $3";
28
+ export declare const HISTORY_COUNT_SQL = "\n SELECT count(*) AS total FROM public.catalog_bundle_write_events WHERE bundle_code = $1::text";
@@ -0,0 +1,84 @@
1
+ /**
2
+ * The statements the direct-Postgres bundle read adapter renders.
3
+ *
4
+ * They live beside the adapter rather than inside it because they are the part a
5
+ * reader comes here to check — which relations are touched, which columns are
6
+ * asked for, and how a component's reference price is resolved — and reading them
7
+ * should not mean scrolling past the row marshalling that consumes them.
8
+ */
9
+ export const SUMMARY_COLUMNS = `
10
+ b.id, b.code, b.title, b.status, b.fulfillment_mode, b.updated_at,
11
+ b.composition_constraint, b.metadata,
12
+ (SELECT count(*) FROM public.catalog_bundle_components c WHERE c.bundle_id = b.id)
13
+ AS component_count,
14
+ EXISTS (SELECT 1 FROM public.catalog_bundle_prices p WHERE p.bundle_id = b.id AND p.active)
15
+ AS has_active_target_price`;
16
+ export const LIST_FILTER = `
17
+ WHERE ($1::text = 'all' OR b.status = $1::text)
18
+ AND ($2::text IS NULL OR b.code ILIKE '%' || $2 || '%' OR b.title ILIKE '%' || $2 || '%')`;
19
+ export const LIST_SQL = `SELECT ${SUMMARY_COLUMNS} FROM public.catalog_bundles b ${LIST_FILTER}
20
+ ORDER BY b.code LIMIT $3 OFFSET $4`;
21
+ export const COUNT_SQL = `SELECT count(*) AS total FROM public.catalog_bundles b ${LIST_FILTER}`;
22
+ export const DETAIL_SQL = `SELECT ${SUMMARY_COLUMNS} FROM public.catalog_bundles b WHERE b.code = $1`;
23
+ /**
24
+ * The unit's reference price in ONE named list: the lowest tier that is active,
25
+ * newest window first. A unit the list prices nothing for resolves to NULL rather
26
+ * than dropping the component, so a caller sees an unpriced part instead of a
27
+ * shorter bill of materials.
28
+ */
29
+ export const REFERENCE_PRICE = `(
30
+ SELECT pe.unit_price_minor FROM public.price_entries pe
31
+ WHERE pe.variant_id = s.id AND pe.price_list_id = %LIST% AND pe.active
32
+ ORDER BY pe.min_qty ASC, pe.valid_from DESC LIMIT 1)`;
33
+ export const COMPONENT_SQL = `
34
+ SELECT c.bundle_id, s.sku, s.title, pr.slug AS product_slug, s.id AS variant_id,
35
+ c.quantity, c.is_addon, c.sort_order,
36
+ ${REFERENCE_PRICE.replace("%LIST%", "$2::uuid")} AS reference_unit_price_minor
37
+ FROM public.catalog_bundle_components c
38
+ JOIN public.catalog_skus s ON s.id = c.catalog_sku_id
39
+ JOIN public.catalog_products pr ON pr.id = s.product_id
40
+ WHERE c.bundle_id = $1::uuid
41
+ ORDER BY c.sort_order, s.sku`;
42
+ // One statement for the whole feed: each bundle carries its own price list, so the
43
+ // per-bundle list is zipped in rather than looped over.
44
+ export const FEED_COMPONENT_SQL = `
45
+ SELECT c.bundle_id, s.sku, s.title, pr.slug AS product_slug, s.id AS variant_id,
46
+ c.quantity, c.is_addon, c.sort_order,
47
+ ${REFERENCE_PRICE.replace("%LIST%", "selected.price_list_id")} AS reference_unit_price_minor
48
+ FROM unnest($1::uuid[], $2::uuid[]) AS selected(bundle_id, price_list_id)
49
+ JOIN public.catalog_bundle_components c ON c.bundle_id = selected.bundle_id
50
+ JOIN public.catalog_skus s ON s.id = c.catalog_sku_id
51
+ JOIN public.catalog_products pr ON pr.id = s.product_id
52
+ ORDER BY c.bundle_id, c.sort_order, s.sku`;
53
+ export const PRICE_SQL = `
54
+ SELECT p.mode, p.target_price_minor, list.currency, p.amount_kind, p.active,
55
+ p.valid_from, p.valid_to
56
+ FROM public.catalog_bundle_prices p
57
+ JOIN public.price_lists AS list ON list.id = p.price_list_id
58
+ WHERE p.bundle_id = $1::uuid
59
+ ORDER BY p.valid_from DESC`;
60
+ export const OWN_LIST_SQL = `
61
+ SELECT list.id, list.currency
62
+ FROM public.catalog_bundle_prices p
63
+ JOIN public.price_lists AS list ON list.id = p.price_list_id
64
+ WHERE p.bundle_id = $1::uuid AND p.active AND ($2::text IS NULL OR p.mode = $2::text)
65
+ ORDER BY p.valid_from DESC LIMIT 1`;
66
+ export const CURRENCY_LIST_SQL = `
67
+ SELECT id, currency FROM public.price_lists
68
+ WHERE currency = $1::text AND status = 'active'
69
+ ORDER BY created_at DESC LIMIT 1`;
70
+ export const FEED_SQL = `
71
+ SELECT b.id, b.code, b.title, b.fulfillment_mode, p.mode, p.target_price_minor,
72
+ p.price_list_id, list.currency
73
+ FROM public.catalog_bundles b
74
+ JOIN public.catalog_bundle_prices p ON p.bundle_id = b.id AND p.active
75
+ JOIN public.price_lists AS list ON list.id = p.price_list_id
76
+ WHERE b.status = 'active' AND ($1::text IS NULL OR list.currency = $1::text)
77
+ ORDER BY b.code, p.valid_from DESC`;
78
+ export const HISTORY_SQL = `
79
+ SELECT id, bundle_code, action, before_state, after_state, created_at
80
+ FROM public.catalog_bundle_write_events
81
+ WHERE bundle_code = $1::text
82
+ ORDER BY created_at DESC LIMIT $2 OFFSET $3`;
83
+ export const HISTORY_COUNT_SQL = `
84
+ SELECT count(*) AS total FROM public.catalog_bundle_write_events WHERE bundle_code = $1::text`;
@@ -0,0 +1,166 @@
1
+ /**
2
+ * The semantic READ port for bundles.
3
+ *
4
+ * This file names the CAPABILITY, never the storage: no table, no routine, no
5
+ * data-client type and no vendor appears here, and the domain layer opens no
6
+ * database handle of its own. Both shipped read adapters implement exactly this
7
+ * interface and are proved against ONE shared scenario table, so a caller cannot
8
+ * tell them apart. It is the same shape the write port
9
+ * (`adminBundleWritePort.ts`) established in the previous wave.
10
+ *
11
+ * Reads are plain SELECTs rather than security-definer routines: the write
12
+ * boundary is where authority lives, and a read that re-implemented it would be a
13
+ * second place for the same rules to be written down. The admin surface reads the
14
+ * whole lifecycle (draft, active, archived); the sellable feed asks a separate
15
+ * question and gets only what is live.
16
+ *
17
+ * COMPONENT PRICES ARE RESOLVED, NOT STORED. A bundle stores one target price for
18
+ * the whole set; a component's REFERENCE unit price is whatever the selected
19
+ * price list says today. The adapters therefore join the catalogue and the price
20
+ * list themselves, and hand back a resolved figure (or `null` when the list
21
+ * prices nothing for that unit) so the allocator upstream never re-reads storage.
22
+ */
23
+ /**
24
+ * A read that FAILED, as opposed to a read that found nothing.
25
+ *
26
+ * Both adapters raise this rather than returning an empty page, because the two
27
+ * outcomes are opposite: an empty catalogue is a fact a storefront may cache and
28
+ * show, and a failed query is not. The class lives on the port so neither chain
29
+ * owns the distinction.
30
+ */
31
+ export declare class BundleCatalogReadError extends Error {
32
+ constructor(message: string);
33
+ }
34
+ /** Which lifecycle rows an admin list asks for. `all` is the admin default. */
35
+ export type BundleListStatusFilter = "draft" | "active" | "archived" | "all";
36
+ export interface ListBundlesInput {
37
+ status: BundleListStatusFilter;
38
+ /** Free-text match over code and title; absent means no narrowing. */
39
+ query?: string;
40
+ limit: number;
41
+ offset: number;
42
+ }
43
+ export interface BundleSummary {
44
+ code: string;
45
+ title: string;
46
+ status: string;
47
+ fulfillmentMode: string;
48
+ componentCount: number;
49
+ hasActiveTargetPrice: boolean;
50
+ updatedAt: string;
51
+ }
52
+ export interface ListBundlesResult {
53
+ bundles: BundleSummary[];
54
+ total: number;
55
+ }
56
+ /**
57
+ * One line of the bill of materials, already joined to the catalogue.
58
+ *
59
+ * `productSlug` and `variantId` are carried because the availability port
60
+ * addresses stock by all three coordinates; a caller that had only the sku would
61
+ * have to re-open the catalogue to ask about stock, which is exactly the
62
+ * round-trip this DTO exists to remove.
63
+ */
64
+ export interface BundleComponentRow {
65
+ sku: string;
66
+ title: string | null;
67
+ productSlug: string;
68
+ variantId: string;
69
+ quantity: number;
70
+ isAddon: boolean;
71
+ sortOrder: number;
72
+ /** Resolved from the selected price list; `null` when it prices no such unit. */
73
+ referenceUnitPriceMinor: number | null;
74
+ }
75
+ export interface BundleTargetPriceRow {
76
+ mode: string;
77
+ targetPriceMinor: number;
78
+ currency: string;
79
+ amountKind: string;
80
+ active: boolean;
81
+ validFrom: string;
82
+ validTo: string | null;
83
+ }
84
+ export interface BundleDetail extends BundleSummary {
85
+ /** The opaque `{kind, version, data}` envelope; `null` for an unconstrained bundle. */
86
+ compositionConstraint: {
87
+ kind: string;
88
+ version: number;
89
+ data: Record<string, unknown>;
90
+ } | null;
91
+ metadata: Record<string, unknown>;
92
+ components: BundleComponentRow[];
93
+ prices: BundleTargetPriceRow[];
94
+ /** The currency whose list resolved `referenceUnitPriceMinor`; `null` if none did. */
95
+ resolvedCurrency: string | null;
96
+ /**
97
+ * The price list those reference figures came from. Carried because a price
98
+ * preview has to name the list it priced against — an amount without the list
99
+ * that gave it meaning is not reproducible.
100
+ */
101
+ resolvedPriceListId: string | null;
102
+ }
103
+ export interface GetBundleInput {
104
+ code: string;
105
+ /**
106
+ * Price the components against THIS currency's active list. Omitted means "the
107
+ * list this bundle's own active target price is written into", which is the
108
+ * only currency an operator has actually chosen for it.
109
+ */
110
+ currency?: string;
111
+ /** Narrow the target price whose list is selected; omitted means any mode. */
112
+ mode?: string;
113
+ }
114
+ /**
115
+ * One live, sellable bundle: active status, an active target price, and its
116
+ * components priced in that price's own currency. This is the feed's row, and it
117
+ * is deliberately a different question from `getBundle` — the storefront must
118
+ * never be able to see a draft by asking the read port nicely.
119
+ */
120
+ export interface ActiveBundleComposition {
121
+ code: string;
122
+ title: string;
123
+ fulfillmentMode: string;
124
+ currency: string;
125
+ targetPriceMinor: number;
126
+ mode: string;
127
+ components: BundleComponentRow[];
128
+ }
129
+ export interface BundleHistoryEvent {
130
+ id: string;
131
+ action: string;
132
+ actorKind: string | null;
133
+ actorEmail: string | null;
134
+ entityId: string | null;
135
+ oldValue: unknown;
136
+ newValue: unknown;
137
+ occurredAt: string;
138
+ }
139
+ export interface BundleHistoryInput {
140
+ code: string;
141
+ limit: number;
142
+ offset: number;
143
+ }
144
+ export interface BundleHistoryResult {
145
+ events: BundleHistoryEvent[];
146
+ total: number;
147
+ }
148
+ export interface BundleCatalogReadPort {
149
+ /** Admin list across the whole lifecycle, newest-agnostic and code-ordered. */
150
+ listBundles(input: ListBundlesInput): Promise<ListBundlesResult>;
151
+ /** Full admin detail, or `null` when no bundle carries that code. */
152
+ getBundle(input: GetBundleInput): Promise<BundleDetail | null>;
153
+ /**
154
+ * Every bundle a storefront may sell right now. Never returns a draft or an
155
+ * archived bundle, and never a bundle without an active target price.
156
+ */
157
+ listActiveBundleCompositions(input?: {
158
+ currency?: string;
159
+ }): Promise<ActiveBundleComposition[]>;
160
+ /**
161
+ * The operator trail for one bundle. The two chains answer from different
162
+ * ledgers — a managed audit table and the platform's neutral write-event
163
+ * relation — which is why this is a port method rather than a shared query.
164
+ */
165
+ listBundleHistory(input: BundleHistoryInput): Promise<BundleHistoryResult>;
166
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The semantic READ port for bundles.
3
+ *
4
+ * This file names the CAPABILITY, never the storage: no table, no routine, no
5
+ * data-client type and no vendor appears here, and the domain layer opens no
6
+ * database handle of its own. Both shipped read adapters implement exactly this
7
+ * interface and are proved against ONE shared scenario table, so a caller cannot
8
+ * tell them apart. It is the same shape the write port
9
+ * (`adminBundleWritePort.ts`) established in the previous wave.
10
+ *
11
+ * Reads are plain SELECTs rather than security-definer routines: the write
12
+ * boundary is where authority lives, and a read that re-implemented it would be a
13
+ * second place for the same rules to be written down. The admin surface reads the
14
+ * whole lifecycle (draft, active, archived); the sellable feed asks a separate
15
+ * question and gets only what is live.
16
+ *
17
+ * COMPONENT PRICES ARE RESOLVED, NOT STORED. A bundle stores one target price for
18
+ * the whole set; a component's REFERENCE unit price is whatever the selected
19
+ * price list says today. The adapters therefore join the catalogue and the price
20
+ * list themselves, and hand back a resolved figure (or `null` when the list
21
+ * prices nothing for that unit) so the allocator upstream never re-reads storage.
22
+ */
23
+ /**
24
+ * A read that FAILED, as opposed to a read that found nothing.
25
+ *
26
+ * Both adapters raise this rather than returning an empty page, because the two
27
+ * outcomes are opposite: an empty catalogue is a fact a storefront may cache and
28
+ * show, and a failed query is not. The class lives on the port so neither chain
29
+ * owns the distinction.
30
+ */
31
+ export class BundleCatalogReadError extends Error {
32
+ constructor(message) {
33
+ super(message);
34
+ this.name = "BundleCatalogReadError";
35
+ }
36
+ }
@@ -0,0 +1,3 @@
1
+ import type { BundleCatalogReadPort } from "./bundleCatalogReadPort.js";
2
+ import type { PgQueryExecutor } from "../data/index.js";
3
+ export declare function createPostgresBundleCatalogStore(executor: PgQueryExecutor): BundleCatalogReadPort;
@@ -0,0 +1,152 @@
1
+ import { BundleCatalogReadError, } from "./bundleCatalogReadPort.js";
2
+ import { LIST_SQL, COUNT_SQL, DETAIL_SQL, COMPONENT_SQL, FEED_COMPONENT_SQL, PRICE_SQL, OWN_LIST_SQL, CURRENCY_LIST_SQL, FEED_SQL, HISTORY_SQL, HISTORY_COUNT_SQL, } from "./bundleCatalogQueries.js";
3
+ export function createPostgresBundleCatalogStore(executor) {
4
+ async function rows(sql, values) {
5
+ // A driver failure becomes the port's own read error, so a caller sees the
6
+ // same distinction between "found nothing" and "could not ask" on both chains.
7
+ const result = await executor.query(sql, values).catch((error) => {
8
+ throw new BundleCatalogReadError(error instanceof Error ? error.message : String(error));
9
+ });
10
+ return (result.rows ?? []);
11
+ }
12
+ async function components(bundleId, priceListId) {
13
+ return (await rows(COMPONENT_SQL, [bundleId, priceListId])).map(toComponent);
14
+ }
15
+ async function selectPriceList(bundleId, input) {
16
+ const list = input.currency
17
+ ? await rows(CURRENCY_LIST_SQL, [input.currency])
18
+ : await rows(OWN_LIST_SQL, [bundleId, input.mode ?? null]);
19
+ return list[0] ?? null;
20
+ }
21
+ return {
22
+ async listBundles(input) {
23
+ const filter = [input.status, input.query ?? null];
24
+ const [page, counted] = await Promise.all([
25
+ rows(LIST_SQL, [...filter, input.limit, input.offset]),
26
+ rows(COUNT_SQL, filter),
27
+ ]);
28
+ return { bundles: page.map(toSummary), total: Number(counted[0]?.total ?? page.length) };
29
+ },
30
+ async getBundle(input) {
31
+ const bundle = (await rows(DETAIL_SQL, [input.code]))[0];
32
+ if (!bundle)
33
+ return null;
34
+ const list = await selectPriceList(bundle.id, input);
35
+ const [componentRows, priceRows] = await Promise.all([
36
+ components(bundle.id, list?.id ?? null),
37
+ rows(PRICE_SQL, [bundle.id]),
38
+ ]);
39
+ return {
40
+ ...toSummary(bundle),
41
+ compositionConstraint: toConstraint(bundle.composition_constraint),
42
+ metadata: bundle.metadata ?? {},
43
+ components: componentRows,
44
+ prices: priceRows.map(toPrice),
45
+ resolvedCurrency: list?.currency ?? null,
46
+ resolvedPriceListId: list?.id ?? null,
47
+ };
48
+ },
49
+ async listActiveBundleCompositions(input = {}) {
50
+ // A bundle may carry several active prices (a scheduled successor); the feed
51
+ // takes the newest window per bundle, which is what the ORDER BY already put first.
52
+ const selected = new Map();
53
+ for (const row of await rows(FEED_SQL, [input.currency ?? null])) {
54
+ if (!selected.has(row.id))
55
+ selected.set(row.id, row);
56
+ }
57
+ if (selected.size === 0)
58
+ return [];
59
+ const chosen = [...selected.values()];
60
+ const byBundle = groupComponents(await rows(FEED_COMPONENT_SQL, [
61
+ chosen.map((row) => row.id),
62
+ chosen.map((row) => row.price_list_id),
63
+ ]));
64
+ return chosen.map((row) => ({
65
+ code: row.code,
66
+ title: row.title,
67
+ fulfillmentMode: row.fulfillment_mode,
68
+ currency: row.currency,
69
+ targetPriceMinor: row.target_price_minor,
70
+ mode: row.mode,
71
+ components: byBundle.get(row.id) ?? [],
72
+ }));
73
+ },
74
+ async listBundleHistory(input) {
75
+ const [page, counted] = await Promise.all([
76
+ rows(HISTORY_SQL, [input.code, input.limit, input.offset]),
77
+ rows(HISTORY_COUNT_SQL, [input.code]),
78
+ ]);
79
+ return {
80
+ // This chain has no operator registry, so it can record WHICH principal
81
+ // wrote but never what kind of actor it was; both fields stay null rather
82
+ // than being invented from the principal id.
83
+ events: page.map((row) => ({
84
+ id: row.id,
85
+ action: row.action,
86
+ actorKind: null,
87
+ actorEmail: null,
88
+ entityId: row.bundle_code,
89
+ oldValue: row.before_state ?? null,
90
+ newValue: row.after_state ?? null,
91
+ occurredAt: row.created_at,
92
+ })),
93
+ total: Number(counted[0]?.total ?? page.length),
94
+ };
95
+ },
96
+ };
97
+ }
98
+ function groupComponents(rows) {
99
+ const grouped = new Map();
100
+ for (const row of rows) {
101
+ const bucket = grouped.get(row.bundle_id) ?? [];
102
+ bucket.push(toComponent(row));
103
+ grouped.set(row.bundle_id, bucket);
104
+ }
105
+ return grouped;
106
+ }
107
+ function toComponent(row) {
108
+ return {
109
+ sku: row.sku,
110
+ title: row.title ?? null,
111
+ productSlug: row.product_slug,
112
+ variantId: row.variant_id,
113
+ quantity: Number(row.quantity),
114
+ isAddon: row.is_addon === true,
115
+ sortOrder: Number(row.sort_order),
116
+ referenceUnitPriceMinor: row.reference_unit_price_minor === null || row.reference_unit_price_minor === undefined
117
+ ? null
118
+ : Number(row.reference_unit_price_minor),
119
+ };
120
+ }
121
+ function toSummary(row) {
122
+ return {
123
+ code: row.code,
124
+ title: row.title,
125
+ status: row.status,
126
+ fulfillmentMode: row.fulfillment_mode,
127
+ componentCount: Number(row.component_count ?? 0),
128
+ hasActiveTargetPrice: row.has_active_target_price === true,
129
+ updatedAt: row.updated_at,
130
+ };
131
+ }
132
+ function toPrice(row) {
133
+ return {
134
+ mode: row.mode,
135
+ targetPriceMinor: Number(row.target_price_minor),
136
+ currency: row.currency,
137
+ amountKind: row.amount_kind,
138
+ active: row.active === true,
139
+ validFrom: row.valid_from,
140
+ validTo: row.valid_to ?? null,
141
+ };
142
+ }
143
+ /** An empty envelope is stored as `{}`; that is "unconstrained", not a constraint. */
144
+ function toConstraint(value) {
145
+ if (!value || typeof value.kind !== "string" || value.kind.trim() === "")
146
+ return null;
147
+ return {
148
+ kind: value.kind,
149
+ version: typeof value.version === "number" ? value.version : 0,
150
+ data: (value.data ?? {}),
151
+ };
152
+ }