@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,269 @@
1
+ import {
2
+ BundleCatalogReadError,
3
+ } from "./bundleCatalogReadPort.js";
4
+ import type {
5
+ ActiveBundleComposition,
6
+ BundleCatalogReadPort,
7
+ BundleComponentRow,
8
+ BundleDetail,
9
+ BundleHistoryInput,
10
+ BundleHistoryResult,
11
+ BundleSummary,
12
+ GetBundleInput,
13
+ ListBundlesInput,
14
+ ListBundlesResult,
15
+ } from "./bundleCatalogReadPort.js";
16
+ import type { PgQueryExecutor } from "../data/index.js";
17
+ import {
18
+ LIST_SQL,
19
+ COUNT_SQL,
20
+ DETAIL_SQL,
21
+ COMPONENT_SQL,
22
+ FEED_COMPONENT_SQL,
23
+ PRICE_SQL,
24
+ OWN_LIST_SQL,
25
+ CURRENCY_LIST_SQL,
26
+ FEED_SQL,
27
+ HISTORY_SQL,
28
+ HISTORY_COUNT_SQL,
29
+ } from "./bundleCatalogQueries.js";
30
+
31
+
32
+ /**
33
+ * Direct-Postgres adapter for the bundle read port. A real adapter: it renders the
34
+ * joins itself, against the same three relations both chains declare, and reads no
35
+ * row the port's contract does not name.
36
+ *
37
+ * It goes through no transaction lane and switches no role. A read needs no
38
+ * principal, and the public platform manifest declares no managed role to switch
39
+ * into; the port contract has no write operation, so read-only is a property of
40
+ * the shape rather than a promise in a comment.
41
+ *
42
+ * The one place the two chains genuinely differ is the operator trail: this chain
43
+ * reads the neutral `catalog_bundle_write_events` ledger the platform forward
44
+ * created, because it has no audit table and no operator registry to name.
45
+ */
46
+
47
+ interface BundleRow {
48
+ id: string;
49
+ code: string;
50
+ title: string;
51
+ status: string;
52
+ fulfillment_mode: string;
53
+ updated_at: string;
54
+ component_count: string | number;
55
+ has_active_target_price: boolean;
56
+ composition_constraint: Record<string, unknown> | null;
57
+ metadata: Record<string, unknown> | null;
58
+ }
59
+
60
+ interface ComponentRow {
61
+ bundle_id: string;
62
+ sku: string;
63
+ title: string | null;
64
+ product_slug: string;
65
+ variant_id: string;
66
+ quantity: number;
67
+ is_addon: boolean;
68
+ sort_order: number;
69
+ reference_unit_price_minor: number | null;
70
+ }
71
+
72
+ interface PriceRow {
73
+ mode: string;
74
+ target_price_minor: number;
75
+ currency: string;
76
+ amount_kind: string;
77
+ active: boolean;
78
+ valid_from: string;
79
+ valid_to: string | null;
80
+ }
81
+
82
+ interface ActiveBundleRow {
83
+ id: string;
84
+ code: string;
85
+ title: string;
86
+ fulfillment_mode: string;
87
+ mode: string;
88
+ target_price_minor: number;
89
+ price_list_id: string;
90
+ currency: string;
91
+ }
92
+
93
+ interface WriteEventRow {
94
+ id: string;
95
+ bundle_code: string;
96
+ action: string;
97
+ before_state: unknown;
98
+ after_state: unknown;
99
+ created_at: string;
100
+ }
101
+
102
+ export function createPostgresBundleCatalogStore(
103
+ executor: PgQueryExecutor,
104
+ ): BundleCatalogReadPort {
105
+ async function rows<T>(sql: string, values: unknown[]): Promise<T[]> {
106
+ // A driver failure becomes the port's own read error, so a caller sees the
107
+ // same distinction between "found nothing" and "could not ask" on both chains.
108
+ const result = await executor.query(sql, values).catch((error: unknown) => {
109
+ throw new BundleCatalogReadError(error instanceof Error ? error.message : String(error));
110
+ });
111
+ return (result.rows ?? []) as unknown as T[];
112
+ }
113
+
114
+ async function components(bundleId: string, priceListId: string | null) {
115
+ return (await rows<ComponentRow>(COMPONENT_SQL, [bundleId, priceListId])).map(toComponent);
116
+ }
117
+
118
+ async function selectPriceList(
119
+ bundleId: string,
120
+ input: GetBundleInput,
121
+ ): Promise<{ id: string; currency: string } | null> {
122
+ const list = input.currency
123
+ ? await rows<{ id: string; currency: string }>(CURRENCY_LIST_SQL, [input.currency])
124
+ : await rows<{ id: string; currency: string }>(OWN_LIST_SQL, [bundleId, input.mode ?? null]);
125
+ return list[0] ?? null;
126
+ }
127
+
128
+ return {
129
+ async listBundles(input: ListBundlesInput): Promise<ListBundlesResult> {
130
+ const filter = [input.status, input.query ?? null];
131
+ const [page, counted] = await Promise.all([
132
+ rows<BundleRow>(LIST_SQL, [...filter, input.limit, input.offset]),
133
+ rows<{ total: string | number }>(COUNT_SQL, filter),
134
+ ]);
135
+ return { bundles: page.map(toSummary), total: Number(counted[0]?.total ?? page.length) };
136
+ },
137
+
138
+ async getBundle(input: GetBundleInput): Promise<BundleDetail | null> {
139
+ const bundle = (await rows<BundleRow>(DETAIL_SQL, [input.code]))[0];
140
+ if (!bundle) return null;
141
+ const list = await selectPriceList(bundle.id, input);
142
+ const [componentRows, priceRows] = await Promise.all([
143
+ components(bundle.id, list?.id ?? null),
144
+ rows<PriceRow>(PRICE_SQL, [bundle.id]),
145
+ ]);
146
+ return {
147
+ ...toSummary(bundle),
148
+ compositionConstraint: toConstraint(bundle.composition_constraint),
149
+ metadata: bundle.metadata ?? {},
150
+ components: componentRows,
151
+ prices: priceRows.map(toPrice),
152
+ resolvedCurrency: list?.currency ?? null,
153
+ resolvedPriceListId: list?.id ?? null,
154
+ };
155
+ },
156
+
157
+ async listActiveBundleCompositions(
158
+ input: { currency?: string } = {},
159
+ ): Promise<ActiveBundleComposition[]> {
160
+ // A bundle may carry several active prices (a scheduled successor); the feed
161
+ // takes the newest window per bundle, which is what the ORDER BY already put first.
162
+ const selected = new Map<string, ActiveBundleRow>();
163
+ for (const row of await rows<ActiveBundleRow>(FEED_SQL, [input.currency ?? null])) {
164
+ if (!selected.has(row.id)) selected.set(row.id, row);
165
+ }
166
+ if (selected.size === 0) return [];
167
+
168
+ const chosen = [...selected.values()];
169
+ const byBundle = groupComponents(
170
+ await rows<ComponentRow>(FEED_COMPONENT_SQL, [
171
+ chosen.map((row) => row.id),
172
+ chosen.map((row) => row.price_list_id),
173
+ ]),
174
+ );
175
+ return chosen.map((row) => ({
176
+ code: row.code,
177
+ title: row.title,
178
+ fulfillmentMode: row.fulfillment_mode,
179
+ currency: row.currency,
180
+ targetPriceMinor: row.target_price_minor,
181
+ mode: row.mode,
182
+ components: byBundle.get(row.id) ?? [],
183
+ }));
184
+ },
185
+
186
+ async listBundleHistory(input: BundleHistoryInput): Promise<BundleHistoryResult> {
187
+ const [page, counted] = await Promise.all([
188
+ rows<WriteEventRow>(HISTORY_SQL, [input.code, input.limit, input.offset]),
189
+ rows<{ total: string | number }>(HISTORY_COUNT_SQL, [input.code]),
190
+ ]);
191
+ return {
192
+ // This chain has no operator registry, so it can record WHICH principal
193
+ // wrote but never what kind of actor it was; both fields stay null rather
194
+ // than being invented from the principal id.
195
+ events: page.map((row) => ({
196
+ id: row.id,
197
+ action: row.action,
198
+ actorKind: null,
199
+ actorEmail: null,
200
+ entityId: row.bundle_code,
201
+ oldValue: row.before_state ?? null,
202
+ newValue: row.after_state ?? null,
203
+ occurredAt: row.created_at,
204
+ })),
205
+ total: Number(counted[0]?.total ?? page.length),
206
+ };
207
+ },
208
+ };
209
+ }
210
+
211
+ function groupComponents(rows: readonly ComponentRow[]): Map<string, BundleComponentRow[]> {
212
+ const grouped = new Map<string, BundleComponentRow[]>();
213
+ for (const row of rows) {
214
+ const bucket = grouped.get(row.bundle_id) ?? [];
215
+ bucket.push(toComponent(row));
216
+ grouped.set(row.bundle_id, bucket);
217
+ }
218
+ return grouped;
219
+ }
220
+
221
+ function toComponent(row: ComponentRow): BundleComponentRow {
222
+ return {
223
+ sku: row.sku,
224
+ title: row.title ?? null,
225
+ productSlug: row.product_slug,
226
+ variantId: row.variant_id,
227
+ quantity: Number(row.quantity),
228
+ isAddon: row.is_addon === true,
229
+ sortOrder: Number(row.sort_order),
230
+ referenceUnitPriceMinor:
231
+ row.reference_unit_price_minor === null || row.reference_unit_price_minor === undefined
232
+ ? null
233
+ : Number(row.reference_unit_price_minor),
234
+ };
235
+ }
236
+
237
+ function toSummary(row: BundleRow): BundleSummary {
238
+ return {
239
+ code: row.code,
240
+ title: row.title,
241
+ status: row.status,
242
+ fulfillmentMode: row.fulfillment_mode,
243
+ componentCount: Number(row.component_count ?? 0),
244
+ hasActiveTargetPrice: row.has_active_target_price === true,
245
+ updatedAt: row.updated_at,
246
+ };
247
+ }
248
+
249
+ function toPrice(row: PriceRow) {
250
+ return {
251
+ mode: row.mode,
252
+ targetPriceMinor: Number(row.target_price_minor),
253
+ currency: row.currency,
254
+ amountKind: row.amount_kind,
255
+ active: row.active === true,
256
+ validFrom: row.valid_from,
257
+ validTo: row.valid_to ?? null,
258
+ };
259
+ }
260
+
261
+ /** An empty envelope is stored as `{}`; that is "unconstrained", not a constraint. */
262
+ function toConstraint(value: Record<string, unknown> | null) {
263
+ if (!value || typeof value.kind !== "string" || value.kind.trim() === "") return null;
264
+ return {
265
+ kind: value.kind,
266
+ version: typeof value.version === "number" ? value.version : 0,
267
+ data: (value.data ?? {}) as Record<string, unknown>,
268
+ };
269
+ }
@@ -0,0 +1,134 @@
1
+ import type { BundleAllocationFailureCode } from "@openlup/core/pricing";
2
+
3
+
4
+
5
+ /**
6
+ * Bundle write rules — the named, enforced invariants of the agent-operable
7
+ * bundle write path. These codes are the single vocabulary shared by the request
8
+ * contracts, the pure rule predicates (`bundleRules.ts`), managed write routines
9
+ * and the over-the-wire error taxonomy. Managed routines re-derive state rules;
10
+ * native actor-kind enforcement relies on the handler, not an independent
11
+ * database gate.
12
+ *
13
+ * The catalog rules use this same shape; the lifecycle subset is expressed
14
+ * through the host lifecycle kit, and the codes stay here as
15
+ * this domain's registry.
16
+ */
17
+ export const BUNDLE_RULE_CODES = [
18
+ // Machine (agent) actors compose, price and archive drafts, but may NOT
19
+ // activate or deactivate. Enforced by the handler (allowedActorKinds); the
20
+ // managed activate/deactivate routines also re-derive and RAISE it, while the
21
+ // native routines rely on the handler gate.
22
+ "DRAFT_ONLY_FOR_MACHINE",
23
+ // A bundle with no components is not a bill of materials. Request-decidable on
24
+ // the whole-set composition replace.
25
+ "MIN_COMPONENTS",
26
+ // Every component being an add-on leaves nothing that is always in the box.
27
+ // At least one non-addon component is required. Request-decidable.
28
+ "ADDON_ONLY_COMPOSITION",
29
+ // One row per unit per bundle: multiplicity is the quantity, never a repeated
30
+ // component. Request-decidable on the whole-set replace.
31
+ "DUPLICATE_COMPONENT",
32
+ // Creating a bundle whose code is already used is rejected (unique code).
33
+ "CODE_TAKEN",
34
+ // A composition entry naming a unit that does not exist is rejected.
35
+ "COMPONENT_NOT_FOUND",
36
+ // A component must itself be sellable: active AND sellable on its own. A bundle
37
+ // must not become the only way an unsellable unit reaches a customer.
38
+ "COMPONENT_NOT_SELLABLE",
39
+ // Every component must be priced in the currency of the bundle's price list;
40
+ // a mixed-currency bill of materials has no single reference total.
41
+ "COMPONENT_CURRENCY_MISMATCH",
42
+ // A bundle is never priced above the sum of its parts. Hard refusal, not a
43
+ // warning: the discount framing is the product, and the kernel allocator
44
+ // returns the same decision as one comparison.
45
+ "TARGET_ABOVE_COMPONENT_SUM",
46
+ // The target cannot cover every component's minimum payable amount.
47
+ "TARGET_BELOW_FLOOR",
48
+ // Activation requires an active target price on the bundle.
49
+ "PRICE_REQUIRED_TO_SELL",
50
+ // Activation requires a non-empty composition.
51
+ "COMPOSITION_REQUIRED_TO_SELL",
52
+ // Target-price changes INSERT a new price row and deactivate the old one; an
53
+ // existing row is never mutated in place.
54
+ "APPEND_ONLY_PRICE",
55
+ // A bundle referenced by an order or a subscription is never hard-deleted;
56
+ // removal is an archive (status flip).
57
+ "NO_HARD_DELETE",
58
+ // Restore is the inverse of archive: it applies only to an ARCHIVED bundle.
59
+ "RESTORE_REQUIRES_ARCHIVED",
60
+ // Deactivate (unpublish) applies only to a LIVE bundle.
61
+ "DEACTIVATE_REQUIRES_ACTIVE",
62
+ // Only the exploded fulfillment mode has a runtime. The stored column admits
63
+ // the pre-packed mode so it never has to be widened; the refusal lives here.
64
+ "FULFILLMENT_MODE_UNSUPPORTED",
65
+ // A non-empty composition constraint is validated by the injected
66
+ // CompositionRulesPort; its refusal surfaces under this code.
67
+ "CONSTRAINT_VALIDATION_FAILED",
68
+ // Clone reads its source before replaying a fresh draft; a missing source is
69
+ // rejected before the replay.
70
+ "CLONE_SOURCE_NOT_FOUND",
71
+ ] as const;
72
+
73
+ export type BundleRuleCode = (typeof BUNDLE_RULE_CODES)[number];
74
+
75
+ /**
76
+ * The two target-price codes are NOT re-derived here — they are the kernel
77
+ * allocator's own failure vocabulary, projected onto this domain's registry.
78
+ *
79
+ * Declared as an exhaustive `Record` over `BundleAllocationFailureCode` on
80
+ * purpose: when `@openlup/core/pricing` learns a new failure code, this object
81
+ * stops compiling until the domain decides which rule it is. `REFERENCE_TOTAL_ZERO`
82
+ * means the composition weighed nothing, which is the same condition
83
+ * `MIN_COMPONENTS` names from the request side.
84
+ */
85
+ export const BUNDLE_ALLOCATION_RULE_CODE: Record<BundleAllocationFailureCode, BundleRuleCode> = {
86
+ REFERENCE_TOTAL_ZERO: "MIN_COMPONENTS",
87
+ TARGET_ABOVE_COMPONENT_SUM: "TARGET_ABOVE_COMPONENT_SUM",
88
+ TARGET_BELOW_FLOOR: "TARGET_BELOW_FLOOR",
89
+ };
90
+
91
+ /**
92
+ * Which rules are decidable from the request alone (pure, pre-flight) and which
93
+ * are state-dependent and authoritatively enforced by the write routine. This
94
+ * documents intent and keeps the handler honest about what it can decide before
95
+ * the write. `CONSTRAINT_VALIDATION_FAILED` is `port`: it is decided by the
96
+ * injected `CompositionRulesPort`, which is neither the request nor the database.
97
+ */
98
+ export const BUNDLE_RULE_ENFORCEMENT: Record<BundleRuleCode, "request" | "port" | "rpc"> = {
99
+ DRAFT_ONLY_FOR_MACHINE: "request",
100
+ MIN_COMPONENTS: "request",
101
+ ADDON_ONLY_COMPOSITION: "request",
102
+ DUPLICATE_COMPONENT: "request",
103
+ FULFILLMENT_MODE_UNSUPPORTED: "request",
104
+ CONSTRAINT_VALIDATION_FAILED: "port",
105
+ CODE_TAKEN: "rpc",
106
+ COMPONENT_NOT_FOUND: "rpc",
107
+ COMPONENT_NOT_SELLABLE: "rpc",
108
+ COMPONENT_CURRENCY_MISMATCH: "rpc",
109
+ TARGET_ABOVE_COMPONENT_SUM: "rpc",
110
+ TARGET_BELOW_FLOOR: "rpc",
111
+ PRICE_REQUIRED_TO_SELL: "rpc",
112
+ COMPOSITION_REQUIRED_TO_SELL: "rpc",
113
+ APPEND_ONLY_PRICE: "rpc",
114
+ NO_HARD_DELETE: "rpc",
115
+ RESTORE_REQUIRES_ARCHIVED: "rpc",
116
+ DEACTIVATE_REQUIRES_ACTIVE: "rpc",
117
+ CLONE_SOURCE_NOT_FOUND: "rpc",
118
+ };
119
+
120
+ export type BundleActorKind = "human" | "machine";
121
+
122
+ export type BundleWriteOperation =
123
+ | "create_draft"
124
+ | "update_draft"
125
+ | "set_composition"
126
+ | "set_target_price"
127
+ | "archive"
128
+ | "restore"
129
+ | "clone_draft"
130
+ | "activate"
131
+ | "deactivate";
132
+
133
+ /** The domain's rule result, projected from the generic kit `RuleResult`. */
134
+ export type BundleRuleResult = { ok: boolean; violations: BundleRuleCode[] };
@@ -0,0 +1,153 @@
1
+ import { allocateBundleTargetPrice } from "@openlup/core/pricing";
2
+ import type { BundleComponentInput } from "@openlup/core/pricing";
3
+ import type { CompositionConstraint, CompositionRulesPort } from "@openlup/core/bundle";
4
+
5
+ import type { BundleRuleBindings } from "./bundleBindings.js";
6
+ import {
7
+ BUNDLE_ALLOCATION_RULE_CODE,
8
+ type BundleActorKind,
9
+ type BundleRuleResult,
10
+ } from "./bundleRuleCodes.js";
11
+
12
+ /**
13
+ * Pure, request-checkable bundle write rules.
14
+ *
15
+ * Only what is decidable from the request alone lives here. The state-dependent
16
+ * rules (code uniqueness, component existence/sellability/currency, the target
17
+ * price against real component prices, the activation preconditions, append-only
18
+ * pricing, archive-not-delete) are re-derived by the managed write routines.
19
+ * This layer fast-fails request-checkable violations without replacing those
20
+ * state checks. Actor-kind enforcement is separate: managed publication routines
21
+ * independently check it, while native publication relies on the handler gate.
22
+ */
23
+
24
+ /** The composition shape the request-layer rules can reason about. */
25
+ export interface BundleCompositionEntry {
26
+ readonly sku: string;
27
+ readonly quantity: number;
28
+ readonly isAddon: boolean;
29
+ }
30
+
31
+ /** The only fulfillment mode with a runtime. The column admits more; this does not. */
32
+ export const SUPPORTED_BUNDLE_FULFILLMENT_MODES = ["virtual"] as const;
33
+
34
+ export type SupportedBundleFulfillmentMode = (typeof SUPPORTED_BUNDLE_FULFILLMENT_MODES)[number];
35
+
36
+ function isSupportedFulfillmentMode(mode: string): boolean {
37
+ return (SUPPORTED_BUNDLE_FULFILLMENT_MODES as readonly string[]).includes(mode);
38
+ }
39
+
40
+ /**
41
+ * The lifecycle/actor gate every operation passes. Machine actors are confined to
42
+ * drafts: they may compose, price, archive, restore and clone, but neither
43
+ * activate nor deactivate.
44
+ */
45
+ export function createBundleWriteRules({ assertActivateNotMachineActor }: Pick<BundleRuleBindings, "assertActivateNotMachineActor">) {
46
+ function evaluateBundleWriteRules(input: {
47
+ operation: string;
48
+ actorKind: BundleActorKind;
49
+ }): BundleRuleResult {
50
+ const violations: BundleRuleResult["violations"] = [];
51
+
52
+ const activateViolation = assertActivateNotMachineActor(input);
53
+ if (activateViolation) violations.push(activateViolation);
54
+ // `assertActivateNotMachineActor` only knows the publish direction it was written
55
+ // for. Unpublish is the same class of transition and carries the same code.
56
+ if (input.operation === "deactivate" && input.actorKind === "machine") {
57
+ violations.push("DRAFT_ONLY_FOR_MACHINE");
58
+ }
59
+
60
+ return { ok: violations.length === 0, violations };
61
+ }
62
+
63
+ return { evaluateBundleWriteRules };
64
+ }
65
+
66
+ /**
67
+ * Whole-set composition rules, decidable from the replacement set alone: it must
68
+ * carry at least one entry, at least one entry that is not an add-on, and no unit
69
+ * twice (multiplicity is the quantity, never a repeated row).
70
+ */
71
+ export function evaluateBundleComposition(components: readonly BundleCompositionEntry[]): BundleRuleResult {
72
+ const violations: BundleRuleResult["violations"] = [];
73
+
74
+ if (components.length === 0) violations.push("MIN_COMPONENTS");
75
+ else if (components.every((component) => component.isAddon)) violations.push("ADDON_ONLY_COMPOSITION");
76
+
77
+ const seen = new Set<string>();
78
+ for (const component of components) {
79
+ if (seen.has(component.sku)) {
80
+ violations.push("DUPLICATE_COMPONENT");
81
+ break;
82
+ }
83
+ seen.add(component.sku);
84
+ }
85
+
86
+ return { ok: violations.length === 0, violations };
87
+ }
88
+
89
+ /** The runtime refusal of every fulfillment mode the stored column admits but no code honours. */
90
+ export function evaluateBundleFulfillmentMode(mode: string): BundleRuleResult {
91
+ return isSupportedFulfillmentMode(mode)
92
+ ? { ok: true, violations: [] }
93
+ : { ok: false, violations: ["FULFILLMENT_MODE_UNSUPPORTED"] };
94
+ }
95
+
96
+ /**
97
+ * Project the kernel allocator's decision onto this domain's rule vocabulary.
98
+ *
99
+ * The allocator (`@openlup/core/pricing`) owns the arithmetic and the two
100
+ * refusals a target price can earn; this maps its failure code through the
101
+ * exhaustive `BUNDLE_ALLOCATION_RULE_CODE` table so the codes cannot drift apart.
102
+ * It is pure: the caller supplies the component reference prices it already holds.
103
+ * The authority for a committed write remains the write routine, which holds the
104
+ * live prices.
105
+ */
106
+ export function evaluateBundleTargetPrice(input: {
107
+ components: readonly BundleComponentInput[];
108
+ targetPriceMinor: number;
109
+ minimumUnitPayableMinor?: number;
110
+ }): BundleRuleResult {
111
+ const outcome = allocateBundleTargetPrice({
112
+ components: input.components,
113
+ targetPriceMinor: input.targetPriceMinor,
114
+ ...(input.minimumUnitPayableMinor === undefined
115
+ ? {}
116
+ : { minimumUnitPayableMinor: input.minimumUnitPayableMinor }),
117
+ });
118
+ // Narrowed by presence rather than by the `ok` literal: the app compiler runs
119
+ // without strictNullChecks, where a boolean-literal discriminant does not narrow.
120
+ if (!("code" in outcome)) return { ok: true, violations: [] };
121
+ return { ok: false, violations: [BUNDLE_ALLOCATION_RULE_CODE[outcome.code]] };
122
+ }
123
+
124
+ /** An empty envelope means "unconstrained"; there is nothing for the port to decide. */
125
+ export function isEmptyCompositionConstraint(constraint: CompositionConstraint | null | undefined): boolean {
126
+ return !constraint || constraint.kind.trim() === "";
127
+ }
128
+
129
+ /**
130
+ * Delegate a non-empty composition constraint to the injected rules port. The
131
+ * platform stores the envelope and never interprets it, so this domain does not
132
+ * either: it asks the adopter's port and reports the refusal under one code.
133
+ */
134
+ export async function evaluateBundleCompositionConstraint(
135
+ port: CompositionRulesPort | undefined,
136
+ input: {
137
+ readonly components: readonly BundleCompositionEntry[];
138
+ readonly constraint: CompositionConstraint | null | undefined;
139
+ },
140
+ ): Promise<BundleRuleResult> {
141
+ if (isEmptyCompositionConstraint(input.constraint) || !port) return { ok: true, violations: [] };
142
+ const constraint = input.constraint as CompositionConstraint;
143
+ const outcome = await port.validateComposition({
144
+ coreLines: input.components
145
+ .filter((component) => !component.isAddon)
146
+ .map((component) => ({ variantId: component.sku, qty: component.quantity, isAddon: false })),
147
+ addonLines: input.components
148
+ .filter((component) => component.isAddon)
149
+ .map((component) => ({ variantId: component.sku, qty: component.quantity, isAddon: true })),
150
+ constraint,
151
+ });
152
+ return outcome.ok ? { ok: true, violations: [] } : { ok: false, violations: ["CONSTRAINT_VALIDATION_FAILED"] };
153
+ }
@@ -0,0 +1,71 @@
1
+ import {
2
+ catalogDraftApplyResultSchema,
3
+ catalogDraftGetQuerySchema,
4
+ catalogDraftListQuerySchema,
5
+ catalogDraftPageSchema,
6
+ catalogDraftRecordSchema,
7
+ type CatalogDraftRefusal,
8
+ } from "./draftSchemas.js";
9
+ import { CatalogDraftStoreError, type CatalogDraftStorePort } from "./draftPorts.js";
10
+ import type { PgQueryExecutor } from "../data/index.js";
11
+
12
+ /** Dark owner-only storage. Composition must verify the operator before use. */
13
+ export function createPostgresCatalogDraftStore(client: PgQueryExecutor): CatalogDraftStorePort {
14
+ async function call(sql: string, values: unknown[]): Promise<unknown> {
15
+ try {
16
+ const { rows } = await client.query(sql, values);
17
+ if (rows.length !== 1 || !("result" in rows[0]!)) {
18
+ throw new CatalogDraftStoreError({ outcome: "dependency_unavailable", reason: "invalid_store_response" });
19
+ }
20
+ return rows[0]!.result;
21
+ } catch (error) {
22
+ if (error instanceof CatalogDraftStoreError) throw error;
23
+ throw new CatalogDraftStoreError(refusal(error));
24
+ }
25
+ }
26
+ return {
27
+ async apply(request) {
28
+ try {
29
+ const result = await call(
30
+ "SELECT public.catalog_draft_apply($1::text, $2::text, $3::text) AS result",
31
+ [request.canonicalCommand, request.fingerprint, request.actorId],
32
+ );
33
+ const parsed = catalogDraftApplyResultSchema.safeParse(result);
34
+ if (!parsed.success) return { outcome: "dependency_unavailable", reason: "invalid_store_response" };
35
+ return parsed.data;
36
+ } catch (error) {
37
+ return error instanceof CatalogDraftStoreError ? error.refusal : refusal(error);
38
+ }
39
+ },
40
+ async get(query) {
41
+ const input = catalogDraftGetQuerySchema.safeParse(query);
42
+ if (!input.success) throw new CatalogDraftStoreError({ outcome: "validation_issue", reason: "invalid_get_query" });
43
+ const result = await call(
44
+ "SELECT public.catalog_draft_get($1::uuid, $2::integer, $3::text) AS result",
45
+ [input.data.draftId, input.data.revision ?? null, input.data.commandKey ?? null],
46
+ );
47
+ const parsed = catalogDraftRecordSchema.nullable().safeParse(result);
48
+ if (!parsed.success) throw new CatalogDraftStoreError({ outcome: "dependency_unavailable", reason: "invalid_store_response" });
49
+ return parsed.data;
50
+ },
51
+ async list(query) {
52
+ const input = catalogDraftListQuerySchema.safeParse(query);
53
+ if (!input.success) throw new CatalogDraftStoreError({ outcome: "validation_issue", reason: "invalid_list_query" });
54
+ const result = await call(
55
+ "SELECT public.catalog_draft_list($1::uuid, $2::integer) AS result",
56
+ [input.data.afterDraftId ?? null, input.data.limit],
57
+ );
58
+ const parsed = catalogDraftPageSchema.safeParse(result);
59
+ if (!parsed.success) throw new CatalogDraftStoreError({ outcome: "dependency_unavailable", reason: "invalid_store_response" });
60
+ return parsed.data;
61
+ },
62
+ };
63
+ }
64
+
65
+ function refusal(error: unknown): CatalogDraftRefusal {
66
+ const code = error && typeof error === "object" && "code" in error ? error.code : null;
67
+ if (code === "42501") return { outcome: "unauthorized", reason: "operator_required" };
68
+ if (code === "22023") return { outcome: "validation_issue", reason: "invalid_store_request" };
69
+ if (code === "23505") return { outcome: "conflict", reason: "identity_reserved" };
70
+ return { outcome: "dependency_unavailable", reason: "store_unavailable" };
71
+ }