@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,46 @@
1
+ type COMMUNICATION_CHANNEL = "email";
2
+ type EMAIL_SEND_STATUSES = "queued" | "sent" | "delivered" | "bounced" | "complained" | "failed" | "skipped";
3
+ type EMAIL_SEND_SKIP_REASONS = "sequence_paused" | "already_sent" | "template_unavailable" | "race_lost" | "policy_blocked" | "admin_disabled";
4
+ export type CommunicationChannel = COMMUNICATION_CHANNEL;
5
+ /** The host supplies its persisted provider vocabulary. */
6
+ export type CommunicationProvider<Provider extends string = string> = Provider;
7
+ export type EmailSendStatus = EMAIL_SEND_STATUSES;
8
+ export type EmailSendSkipReason = EMAIL_SEND_SKIP_REASONS;
9
+ type COMMUNICATION_PURPOSES = "transactional" | "tester_program" | "marketing_launch_offer" | "marketing_newsletter" | "subscription_dunning" | "admin_notification";
10
+ type COMMUNICATION_PERMISSION_STATES = "unknown" | "granted" | "denied" | "suppressed";
11
+ type COMMUNICATION_POLICY_DECISIONS = "allowed" | "blocked";
12
+ export type CommunicationPurpose = COMMUNICATION_PURPOSES;
13
+ export type CommunicationPermissionState = COMMUNICATION_PERMISSION_STATES;
14
+ export type CommunicationPolicyDecision = COMMUNICATION_POLICY_DECISIONS;
15
+ export interface CommunicationRecipientRef {
16
+ system: "supabase";
17
+ table: "testers";
18
+ id: string;
19
+ email: string | null;
20
+ }
21
+ export interface EmailTemplateRef {
22
+ slug: string;
23
+ locale: string | null;
24
+ }
25
+ export interface EmailSendDedupeKeyInput {
26
+ recipientId: string;
27
+ templateSlug: string;
28
+ }
29
+ export type EmailSendDecision = {
30
+ outcome: "send";
31
+ } | {
32
+ outcome: "skip";
33
+ reason: EmailSendSkipReason;
34
+ existingMessageId: string | null;
35
+ };
36
+ export interface EmailMessageReadModel<Provider extends string = string> {
37
+ id: string;
38
+ channel: CommunicationChannel;
39
+ recipientId: string;
40
+ templateSlug: string;
41
+ status: EmailSendStatus;
42
+ provider: CommunicationProvider<Provider> | null;
43
+ providerMessageId: string | null;
44
+ skippedReason: EmailSendSkipReason | null;
45
+ }
46
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { Contribution, RequiredSchema } from "@openlup/core/readiness";
2
+ /** Host-selected schema inventory: managed and direct installations have different objects. */
3
+ export declare function createCommunicationsContribution(options: {
4
+ version: string;
5
+ requiredSchema: RequiredSchema;
6
+ routes?: Contribution["routes"];
7
+ handlers?: Contribution["handlers"];
8
+ schedules?: Contribution["schedules"];
9
+ requiredPorts?: readonly string[];
10
+ }): Contribution;
@@ -0,0 +1,24 @@
1
+ /** Host-selected schema inventory: managed and direct installations have different objects. */
2
+ export function createCommunicationsContribution(options) {
3
+ const routes = options.routes ?? [];
4
+ const handlers = options.handlers ?? [];
5
+ const schedules = options.schedules ?? [];
6
+ return {
7
+ manifest: {
8
+ name: "@openlup/platform", version: options.version, kind: "rail",
9
+ module: {
10
+ id: "communications", kind: "capability", provides: ["./communications", "./communications/contracts"],
11
+ dependsOn: [
12
+ { module: "data", entries: ["./data"] },
13
+ { module: "identity", entries: ["./identity"] },
14
+ { module: "http", entries: ["./http"] },
15
+ ],
16
+ },
17
+ requiredSchema: options.requiredSchema,
18
+ emits: [], handles: handlers.map((handler) => handler.eventType),
19
+ schedules: schedules.map(({ id, cadenceSeconds }) => ({ id, cadenceSeconds })), routes: routes.map((route) => route.id),
20
+ requiredPorts: [...new Set(options.requiredPorts ?? [])], env: [],
21
+ },
22
+ handlers, schedules, routes,
23
+ };
24
+ }
@@ -0,0 +1,64 @@
1
+ export interface DeliveryPollCandidate {
2
+ id: string;
3
+ messageId: string;
4
+ }
5
+ export interface DeliveryStatusRead {
6
+ ok: boolean;
7
+ httpStatus: number;
8
+ recipientEmail: string | null;
9
+ }
10
+ /** The host maps its protocol to an opaque event type and terminal classification. */
11
+ export interface DeliveryPollObservation {
12
+ eventType: string;
13
+ terminal: boolean;
14
+ }
15
+ export interface DeliveryReconciliationPort {
16
+ findFrozenSends(input: {
17
+ now: string;
18
+ graceMinutes: number;
19
+ limit: number;
20
+ }): Promise<DeliveryPollCandidate[]>;
21
+ applyPolledEvent(input: {
22
+ sendId: string;
23
+ messageId: string;
24
+ eventType: string;
25
+ eventAt: string;
26
+ recipientEmail: string | null;
27
+ }): Promise<void>;
28
+ recordPollAttempt(input: {
29
+ sendId: string;
30
+ attemptedAt: string;
31
+ }): Promise<void>;
32
+ recordSendNotFound(input: {
33
+ sendId: string;
34
+ threshold: number;
35
+ }): Promise<{
36
+ abandoned: boolean;
37
+ }>;
38
+ }
39
+ export declare const DELIVERY_POLL_ABANDON_AFTER_NOT_FOUND = 3;
40
+ export interface DeliveryReadFailureBreakdown {
41
+ notFound: number;
42
+ authFailed: number;
43
+ network: number;
44
+ providerError: number;
45
+ other: number;
46
+ }
47
+ export interface DeliveryReconciliationResult {
48
+ checked: number;
49
+ reconciled: number;
50
+ stillPending: number;
51
+ terminalPolled: number;
52
+ failures: number;
53
+ abandoned: number;
54
+ failureBreakdown: DeliveryReadFailureBreakdown;
55
+ }
56
+ /** Sequential bounded polling around one host-owned atomic convergence writer. */
57
+ export declare function runDeliveryReconciliation<Read extends DeliveryStatusRead>(input: {
58
+ port: DeliveryReconciliationPort;
59
+ readEmail: (messageId: string) => Promise<Read>;
60
+ observationFor: (read: Read) => DeliveryPollObservation | null;
61
+ now: string;
62
+ graceMinutes: number;
63
+ limit: number;
64
+ }): Promise<DeliveryReconciliationResult>;
@@ -0,0 +1,60 @@
1
+ export const DELIVERY_POLL_ABANDON_AFTER_NOT_FOUND = 3;
2
+ function classifyReadFailure(breakdown, httpStatus) {
3
+ if (httpStatus === 404)
4
+ breakdown.notFound += 1;
5
+ else if (httpStatus === 401 || httpStatus === 403)
6
+ breakdown.authFailed += 1;
7
+ else if (httpStatus === 0)
8
+ breakdown.network += 1;
9
+ else if (httpStatus >= 500 && httpStatus <= 599)
10
+ breakdown.providerError += 1;
11
+ else
12
+ breakdown.other += 1;
13
+ }
14
+ /** Sequential bounded polling around one host-owned atomic convergence writer. */
15
+ export async function runDeliveryReconciliation(input) {
16
+ const result = {
17
+ checked: 0, reconciled: 0, stillPending: 0, terminalPolled: 0, failures: 0, abandoned: 0,
18
+ failureBreakdown: { notFound: 0, authFailed: 0, network: 0, providerError: 0, other: 0 },
19
+ };
20
+ const frozen = await input.port.findFrozenSends({ now: input.now, graceMinutes: input.graceMinutes, limit: input.limit });
21
+ for (const send of frozen) {
22
+ result.checked += 1;
23
+ const read = await input.readEmail(send.messageId);
24
+ if (read.httpStatus !== 404) {
25
+ try {
26
+ await input.port.recordPollAttempt({ sendId: send.id, attemptedAt: input.now });
27
+ }
28
+ catch {
29
+ // Fairness bookkeeping failure must not discard observed delivery truth.
30
+ result.failures += 1;
31
+ }
32
+ }
33
+ if (!read.ok) {
34
+ result.failures += 1;
35
+ classifyReadFailure(result.failureBreakdown, read.httpStatus);
36
+ if (read.httpStatus === 404) {
37
+ const { abandoned } = await input.port.recordSendNotFound({ sendId: send.id, threshold: DELIVERY_POLL_ABANDON_AFTER_NOT_FOUND });
38
+ if (abandoned)
39
+ result.abandoned += 1;
40
+ }
41
+ continue;
42
+ }
43
+ const observation = input.observationFor(read);
44
+ if (!observation) {
45
+ result.stillPending += 1;
46
+ continue;
47
+ }
48
+ try {
49
+ await input.port.applyPolledEvent({ sendId: send.id, messageId: send.messageId,
50
+ eventType: observation.eventType, eventAt: input.now, recipientEmail: read.recipientEmail });
51
+ result.reconciled += 1;
52
+ if (observation.terminal)
53
+ result.terminalPolled += 1;
54
+ }
55
+ catch {
56
+ result.failures += 1;
57
+ }
58
+ }
59
+ return result;
60
+ }
@@ -0,0 +1,38 @@
1
+ import type { AuthEmailTransportPort } from "./contracts/authEmail.js";
2
+ import type { EmailMessage, EmailSendResult, EmailTransport } from "./emailTransport.js";
3
+ export interface EmailEgressContext {
4
+ mode: "production" | "sandbox_direct" | "sandbox_sink";
5
+ reason: string;
6
+ intendedRecipient: string;
7
+ recipient: string;
8
+ /** Selected by the host; consumed only by its concrete sender, never logged. */
9
+ credential: string;
10
+ environmentTag: "production" | "non_production";
11
+ }
12
+ export type EmailEgressDecision = EmailEgressContext | {
13
+ mode: "drop";
14
+ reason: string;
15
+ } | {
16
+ mode: "blocked";
17
+ reason: string;
18
+ };
19
+ export type EmailEgressPolicy = (intendedRecipient: string) => EmailEgressDecision | Promise<EmailEgressDecision>;
20
+ /**
21
+ * Host composition bridge for an implementation that already enforces egress
22
+ * internally. This is a trust boundary: its sender must itself refuse unknown
23
+ * policy before effects. New network adapters should use createGuardedEmailTransport.
24
+ * Neither a provider name nor an object property establishes admission.
25
+ */
26
+ export declare function admitPolicyEnforcedEmailTransport<T extends EmailTransport>(transport: T): T;
27
+ /** Mandatory boundary for supported injected transports; raw objects fail closed. */
28
+ export declare function guardEmailTransport(transport: EmailTransport): EmailTransport;
29
+ /** Construct a network adapter whose sender sees only a validated host decision. */
30
+ export declare function createGuardedEmailTransport(input: {
31
+ providerKind: string;
32
+ policy: EmailEgressPolicy;
33
+ send: (message: EmailMessage, context: Readonly<EmailEgressContext>) => Promise<EmailSendResult>;
34
+ }): EmailTransport;
35
+ /** Preserve the Auth envelope/result mapping while retaining package admission. */
36
+ export declare function createAuthEmailTransport(transport: EmailTransport): AuthEmailTransportPort;
37
+ /** Raw Auth closures must compose through the admitted email transport bridge. */
38
+ export declare function guardAuthEmailTransport(transport: AuthEmailTransportPort): AuthEmailTransportPort;
@@ -0,0 +1,100 @@
1
+ const admitted = new WeakSet();
2
+ const admittedAuth = new WeakSet();
3
+ /**
4
+ * Host composition bridge for an implementation that already enforces egress
5
+ * internally. This is a trust boundary: its sender must itself refuse unknown
6
+ * policy before effects. New network adapters should use createGuardedEmailTransport.
7
+ * Neither a provider name nor an object property establishes admission.
8
+ */
9
+ export function admitPolicyEnforcedEmailTransport(transport) {
10
+ admitted.add(transport);
11
+ return transport;
12
+ }
13
+ /** Mandatory boundary for supported injected transports; raw objects fail closed. */
14
+ export function guardEmailTransport(transport) {
15
+ if (admitted.has(transport))
16
+ return transport;
17
+ return { providerKind: transport.providerKind, send: async () => refused("email_egress_unadmitted") };
18
+ }
19
+ /** Construct a network adapter whose sender sees only a validated host decision. */
20
+ export function createGuardedEmailTransport(input) {
21
+ return admitPolicyEnforcedEmailTransport({
22
+ providerKind: input.providerKind,
23
+ async send(message) {
24
+ let decision;
25
+ try {
26
+ decision = await input.policy(message.to);
27
+ }
28
+ catch {
29
+ return refused("email_egress_policy_unavailable");
30
+ }
31
+ if (!validDecision(decision, message.to))
32
+ return refused("email_egress_policy_invalid");
33
+ if (decision.mode === "blocked")
34
+ return refused("email_egress_blocked", decision.reason);
35
+ if (decision.mode === "drop")
36
+ return {
37
+ outcome: { ok: true, resendId: null, httpStatus: 0, providerError: null, aborted: false,
38
+ suppressed: "drop", egressMode: "drop", egressReason: decision.reason },
39
+ providerResponse: { suppressed: "drop", egress_reason: decision.reason },
40
+ };
41
+ const context = Object.freeze({ ...decision });
42
+ const result = await input.send({ ...message, to: context.recipient }, context);
43
+ return { ...result, outcome: { ...result.outcome, egressMode: context.mode, egressReason: context.reason } };
44
+ },
45
+ });
46
+ }
47
+ function validDecision(value, intended) {
48
+ if (!value || typeof value !== "object" || Array.isArray(value))
49
+ return false;
50
+ const d = value;
51
+ // Policy diagnostics are bounded codes, never arbitrary exception/secret text.
52
+ if (typeof d.reason !== "string" || !/^[a-z][a-z0-9_]{0,79}$/.test(d.reason))
53
+ return false;
54
+ if (d.mode === "drop" || d.mode === "blocked")
55
+ return Object.keys(d).every((key) => key === "mode" || key === "reason");
56
+ if (d.mode !== "production" && d.mode !== "sandbox_direct" && d.mode !== "sandbox_sink")
57
+ return false;
58
+ if (!Object.keys(d).every((key) => ["mode", "reason", "intendedRecipient", "recipient", "credential", "environmentTag"].includes(key)))
59
+ return false;
60
+ if (!mailbox(intended) || d.intendedRecipient !== intended || !mailbox(d.recipient))
61
+ return false;
62
+ if (d.mode !== "sandbox_sink" && d.recipient !== intended)
63
+ return false;
64
+ if (typeof d.credential !== "string" || !d.credential.trim())
65
+ return false;
66
+ return d.environmentTag === (d.mode === "production" ? "production" : "non_production");
67
+ }
68
+ function mailbox(value) {
69
+ return typeof value === "string" && /^[^\s@,;<>]+@[^\s@,;<>]+\.[^\s@,;<>]+$/.test(value);
70
+ }
71
+ function refused(code, reason) {
72
+ return { outcome: { ok: false, resendId: null, httpStatus: 0, providerError: code, aborted: false,
73
+ ...(reason ? { egressReason: reason } : {}) }, providerResponse: { egress_reason: code } };
74
+ }
75
+ /** Preserve the Auth envelope/result mapping while retaining package admission. */
76
+ export function createAuthEmailTransport(transport) {
77
+ const guarded = guardEmailTransport(transport);
78
+ const auth = {
79
+ providerKind: transport.providerKind,
80
+ async send(message) {
81
+ const result = await guarded.send({ from: message.sender, to: message.recipient,
82
+ subject: message.subject, html: message.html, text: message.text });
83
+ return { outcome: { ...result.outcome, messageId: result.outcome.resendId }, providerResponse: result.providerResponse };
84
+ },
85
+ };
86
+ admittedAuth.add(auth);
87
+ return auth;
88
+ }
89
+ /** Raw Auth closures must compose through the admitted email transport bridge. */
90
+ export function guardAuthEmailTransport(transport) {
91
+ if (admittedAuth.has(transport))
92
+ return transport;
93
+ return {
94
+ providerKind: transport.providerKind,
95
+ async send() {
96
+ const result = refused("email_egress_unadmitted");
97
+ return { outcome: { ...result.outcome, messageId: null }, providerResponse: result.providerResponse };
98
+ },
99
+ };
100
+ }
@@ -0,0 +1,39 @@
1
+ import type { EmailHealthMetrics } from "./emailHealthMetricsPort.js";
2
+ /**
3
+ * Pure email-health assessment layer: env-derived thresholds plus the
4
+ * healthy/unhealthy verdict over the delivery metrics. Extracted from
5
+ * `api/_cron/emailHealthWatchdogJob.ts` (which sat at the 300-LOC source cap)
6
+ * so the incident-driven `permanent_delivery_failure` breach could land here
7
+ * with unit coverage and no database in the loop.
8
+ */
9
+ type Env = Record<string, string | undefined>;
10
+ export interface EmailHealthThresholds {
11
+ windowMinutes: number;
12
+ stuckMinutes: number;
13
+ minAttemptsForRatio: number;
14
+ maxFailureRatio: number;
15
+ maxStuck: number;
16
+ /**
17
+ * Absolute ceiling on in-window deliveries that ended `status='failed'`
18
+ * (handler-final loss of a customer notification: outbox discard,
19
+ * max-attempts exhaustion). Default 0 — a single lost email breaches.
20
+ * Bounces/complaints are separate statuses and stay ratio-only.
21
+ */
22
+ maxPermanentFailures: number;
23
+ }
24
+ export interface EmailHealthBreach {
25
+ code: string;
26
+ detail: string;
27
+ }
28
+ export interface EmailHealthAssessment {
29
+ healthy: boolean;
30
+ failureRatio: number;
31
+ breaches: EmailHealthBreach[];
32
+ }
33
+ export declare function readEmailHealthThresholds(env: Env): EmailHealthThresholds;
34
+ /**
35
+ * Pure decision: turn raw counts into a healthy/unhealthy verdict. Kept side
36
+ * effect-free so the thresholds logic is unit-tested without a database.
37
+ */
38
+ export declare function evaluateEmailHealth(metrics: EmailHealthMetrics, thresholds: EmailHealthThresholds): EmailHealthAssessment;
39
+ export {};
@@ -0,0 +1,59 @@
1
+ export function readEmailHealthThresholds(env) {
2
+ return {
3
+ windowMinutes: positiveInt(env.EMAIL_HEALTH_WINDOW_MINUTES, 60),
4
+ stuckMinutes: positiveInt(env.EMAIL_HEALTH_STUCK_MINUTES, 30),
5
+ minAttemptsForRatio: positiveInt(env.EMAIL_HEALTH_MIN_ATTEMPTS_FOR_RATIO, 5),
6
+ maxFailureRatio: clampRatio(env.EMAIL_HEALTH_MAX_FAILURE_RATIO, 0.5),
7
+ maxStuck: nonNegativeInt(env.EMAIL_HEALTH_MAX_STUCK, 0),
8
+ maxPermanentFailures: nonNegativeInt(env.EMAIL_HEALTH_MAX_PERMANENT_FAILURES, 0),
9
+ };
10
+ }
11
+ /**
12
+ * Pure decision: turn raw counts into a healthy/unhealthy verdict. Kept side
13
+ * effect-free so the thresholds logic is unit-tested without a database.
14
+ */
15
+ export function evaluateEmailHealth(metrics, thresholds) {
16
+ const failureRatio = metrics.attempted > 0 ? metrics.failed / metrics.attempted : 0;
17
+ const breaches = [];
18
+ if (metrics.attempted >= thresholds.minAttemptsForRatio && failureRatio > thresholds.maxFailureRatio) {
19
+ breaches.push({
20
+ code: "failure_ratio",
21
+ detail: `${metrics.failed}/${metrics.attempted} (${(failureRatio * 100).toFixed(1)}%) > ${(thresholds.maxFailureRatio * 100).toFixed(1)}%`,
22
+ });
23
+ }
24
+ // Absolute, ratio-independent: one terminally-failed delivery is one
25
+ // customer notification we finally did not send. Incident 2026-07-24: a
26
+ // single discarded payment-recovery email stayed invisible because the
27
+ // ratio breach needs minAttemptsForRatio sends in the window.
28
+ if (metrics.permanentFailures > thresholds.maxPermanentFailures) {
29
+ breaches.push({
30
+ code: "permanent_delivery_failure",
31
+ detail: `${metrics.permanentFailures} delivery(ies) terminally failed > ${thresholds.maxPermanentFailures}`,
32
+ });
33
+ }
34
+ if (metrics.stuckProcessing > thresholds.maxStuck) {
35
+ breaches.push({
36
+ code: "stuck_processing",
37
+ detail: `${metrics.stuckProcessing} email(s) stuck in 'processing' > ${thresholds.stuckMinutes}m`,
38
+ });
39
+ }
40
+ if (metrics.stuckScheduled > thresholds.maxStuck) {
41
+ breaches.push({
42
+ code: "stuck_scheduled",
43
+ detail: `${metrics.stuckScheduled} scheduled email(s) overdue and undispatched`,
44
+ });
45
+ }
46
+ return { healthy: breaches.length === 0, failureRatio, breaches };
47
+ }
48
+ function positiveInt(raw, fallback) {
49
+ const n = Number(raw);
50
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;
51
+ }
52
+ function nonNegativeInt(raw, fallback) {
53
+ const n = Number(raw);
54
+ return Number.isFinite(n) && n >= 0 ? Math.floor(n) : fallback;
55
+ }
56
+ function clampRatio(raw, fallback) {
57
+ const n = Number(raw);
58
+ return Number.isFinite(n) && n >= 0 && n <= 1 ? n : fallback;
59
+ }
@@ -0,0 +1,17 @@
1
+ export interface EmailHealthMetrics {
2
+ attempted: number;
3
+ sent: number;
4
+ failed: number;
5
+ delayed: number;
6
+ /**
7
+ * In-window rows that ended `status='failed'` — handler-final loss of a
8
+ * customer notification (outbox discard / max-attempts). Distinct from
9
+ * `failed` above, which also counts bounces/complaints/missed for the
10
+ * ratio signal.
11
+ */
12
+ permanentFailures: number;
13
+ /** `processing` rows whose last transition is older than the stuck threshold. */
14
+ stuckProcessing: number;
15
+ /** `planned`/`queued` rows past their `expected_send_at` but still not sent. */
16
+ stuckScheduled: number;
17
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ export interface EmailNotificationControlPort {
2
+ isEnabled(slug: string, signal: AbortSignal): Promise<boolean>;
3
+ }
4
+ export interface EmailNotificationControlClient {
5
+ from(table: string): EmailNotificationControlQueryBuilder;
6
+ }
7
+ interface EmailNotificationControlQueryBuilder {
8
+ select(columns: string): EmailNotificationControlQueryBuilder;
9
+ eq(column: string, value: unknown): EmailNotificationControlQueryBuilder;
10
+ maybeSingle(): PromiseLike<{
11
+ data: unknown;
12
+ error: {
13
+ code?: string;
14
+ message?: string;
15
+ } | null;
16
+ }>;
17
+ }
18
+ export declare function createEmailNotificationControlPort(client: EmailNotificationControlClient, createPolicy: (client: EmailNotificationControlClient) => {
19
+ shouldDeliver(input: {
20
+ slug: string;
21
+ signal: AbortSignal;
22
+ }): Promise<{
23
+ allow: boolean;
24
+ }>;
25
+ }): EmailNotificationControlPort;
26
+ export declare const createSupabaseEmailNotificationControlPort: typeof createEmailNotificationControlPort;
27
+ export {};
@@ -0,0 +1,10 @@
1
+ export function createEmailNotificationControlPort(client, createPolicy) {
2
+ const policy = createPolicy(client);
3
+ return {
4
+ isEnabled(slug, signal) {
5
+ return policy.shouldDeliver({ slug, signal }).then((decision) => decision.allow);
6
+ },
7
+ };
8
+ }
9
+ // Compatibility alias for the pre-neutralization lifecycle consumer.
10
+ export const createSupabaseEmailNotificationControlPort = createEmailNotificationControlPort;
@@ -0,0 +1,28 @@
1
+ /** An authenticated, decoded, environment-admitted observation. Evidence is opaque. */
2
+ export interface EmailObservation {
3
+ eventType: string;
4
+ eventAt: string;
5
+ metadata: Record<string, unknown>;
6
+ }
7
+ export interface EmailObservationPort {
8
+ findSend(messageId: string): Promise<{
9
+ id: string;
10
+ } | null>;
11
+ applyObservation(observation: EmailObservation & {
12
+ sendId: string;
13
+ messageId: string;
14
+ }): Promise<void>;
15
+ recordAttempt(attempt: EmailObservationDisposition): Promise<void>;
16
+ }
17
+ export type EmailObservationDisposition = {
18
+ outcome: "send_not_found";
19
+ } | {
20
+ outcome: "processed";
21
+ sendId: string;
22
+ };
23
+ /** Lookup/apply failures propagate; attempt telemetry cannot overturn authoritative success. */
24
+ export declare function processEmailObservation(input: {
25
+ port: EmailObservationPort;
26
+ messageId: string;
27
+ observation: () => EmailObservation;
28
+ }): Promise<EmailObservationDisposition>;
@@ -0,0 +1,23 @@
1
+ /** Lookup/apply failures propagate; attempt telemetry cannot overturn authoritative success. */
2
+ export async function processEmailObservation(input) {
3
+ const send = await input.port.findSend(input.messageId);
4
+ let disposition;
5
+ if (!send) {
6
+ disposition = { outcome: "send_not_found" };
7
+ }
8
+ else {
9
+ await input.port.applyObservation({
10
+ sendId: send.id,
11
+ messageId: input.messageId,
12
+ ...input.observation(),
13
+ });
14
+ disposition = { outcome: "processed", sendId: send.id };
15
+ }
16
+ try {
17
+ await input.port.recordAttempt(disposition);
18
+ }
19
+ catch {
20
+ // Best-effort telemetry is separate from durable convergence.
21
+ }
22
+ return disposition;
23
+ }
@@ -0,0 +1,82 @@
1
+ /** Provider-agnostic transport contract, outcome projection and capture transport. */
2
+ export interface EmailMessage {
3
+ from: string;
4
+ to: string;
5
+ subject: string;
6
+ html: string;
7
+ /** Optional plain-text alternative; omitted from the outbound payload when absent. */
8
+ text?: string;
9
+ /** Optional reply mailbox; omitted entirely when the caller does not set it. */
10
+ replyTo?: string;
11
+ /** Stable outbound request key retained by the concrete transport for a limited window. */
12
+ idempotencyKey?: string;
13
+ /** Base64 content only; remote URLs and filesystem paths are not supported. */
14
+ attachments?: ReadonlyArray<{
15
+ filename: string;
16
+ content: string;
17
+ }>;
18
+ /** Cancels the in-flight send when the worker's per-row timeout fires. */
19
+ signal?: AbortSignal;
20
+ }
21
+ /** Transport results preserve existing reference wire shapes. */
22
+ export interface EmailSendOutcome {
23
+ ok: boolean;
24
+ /** Legacy identifier retained for reference result compatibility. */
25
+ resendId: string | null;
26
+ httpStatus: number;
27
+ providerError: string | null;
28
+ providerErrorCode?: string | null;
29
+ aborted: boolean;
30
+ suppressed?: "drop" | null;
31
+ egressMode?: "production" | "sandbox_direct" | "sandbox_sink" | "drop";
32
+ egressReason?: string;
33
+ }
34
+ export interface EmailSendResult {
35
+ outcome: EmailSendOutcome;
36
+ providerResponse: Record<string, unknown>;
37
+ }
38
+ export type EmailSendSkipReason = "admin_disabled" | "egress_suppressed";
39
+ export interface EmailSendOutcomeLike {
40
+ ok: boolean;
41
+ resendId: string | null;
42
+ providerError: string | null;
43
+ aborted?: boolean;
44
+ adminDisabled?: boolean;
45
+ suppressed?: "drop" | null;
46
+ skipReason?: EmailSendSkipReason | null;
47
+ }
48
+ /** Converts the transport's legacy identifier field at the transport boundary. */
49
+ export declare function emailTransportMessageId(outcome: EmailSendOutcomeLike): string | null;
50
+ /** Maps the neutral message identifier onto the deployed ledger's legacy field. */
51
+ export declare function emailTransportLedgerIdentifier(messageId: string | null): Record<string, string | null>;
52
+ /** Synthesizes the canonical terminal transport shape when `send` throws. */
53
+ export declare function failedEmailTransportResult(): EmailSendResult;
54
+ export interface EmailSendOutcomeProjection {
55
+ skipReason: EmailSendSkipReason | null;
56
+ timelineStatus: "sent" | "skipped" | "delivery_delayed" | "failed";
57
+ ledgerStatus: "sent" | "skipped" | "failed";
58
+ sentAtEligible: boolean;
59
+ lastErrorCode: string | null;
60
+ }
61
+ /** One truth projection for every Node email ledger, timeline and caller. */
62
+ export declare function classifyEmailSendOutcome(outcome: EmailSendOutcomeLike): EmailSendOutcomeProjection;
63
+ /** Adds a provider-neutral skip reason without changing ordinary wire shapes. */
64
+ export declare function withEmailSendSkipReason<T extends EmailSendOutcomeLike>(outcome: T): T;
65
+ export interface EmailTransport {
66
+ /** Stable provider tag for ledgers/observability (e.g. "mailProvider", "in-memory"). */
67
+ readonly providerKind: string;
68
+ send(message: EmailMessage): Promise<EmailSendResult>;
69
+ }
70
+ export interface InMemoryEmailTransport extends EmailTransport {
71
+ /** Every message handed to send(), in order — for tests and dry runs. */
72
+ readonly sent: ReadonlyArray<EmailMessage>;
73
+ }
74
+ /**
75
+ * Reference capture transport: captures sends in memory and never makes a
76
+ * network call. Proves the seam is real — a port wired to this sends email with
77
+ * no HTTP client — and doubles as the substitute an OSS fork starts from
78
+ * before writing its own SES/SMTP adapter.
79
+ */
80
+ export declare function createInMemoryEmailTransport(opts?: {
81
+ idPrefix?: string;
82
+ }): InMemoryEmailTransport;