@openlup/platform 0.17.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.
- package/CHANGELOG.md +96 -0
- package/README.md +284 -6
- package/dist/catalog/activeSkuSelection.d.ts +2 -0
- package/dist/catalog/activeSkuSelection.js +20 -0
- package/dist/catalog/adminBindings.d.ts +72 -0
- package/dist/catalog/adminBindings.js +1 -0
- package/dist/catalog/adminBundleHandler.d.ts +26 -0
- package/dist/catalog/adminBundleHandler.js +111 -0
- package/dist/catalog/adminBundleReadHandler.d.ts +20 -0
- package/dist/catalog/adminBundleReadHandler.js +185 -0
- package/dist/catalog/adminBundleWritePort.d.ts +85 -0
- package/dist/catalog/adminBundleWritePort.js +1 -0
- package/dist/catalog/bundleAvailability.d.ts +63 -0
- package/dist/catalog/bundleAvailability.js +78 -0
- package/dist/catalog/bundleAvailabilityService.d.ts +65 -0
- package/dist/catalog/bundleAvailabilityService.js +89 -0
- package/dist/catalog/bundleBindings.d.ts +33 -0
- package/dist/catalog/bundleBindings.js +1 -0
- package/dist/catalog/bundleCatalogQueries.d.ts +28 -0
- package/dist/catalog/bundleCatalogQueries.js +84 -0
- package/dist/catalog/bundleCatalogReadPort.d.ts +166 -0
- package/dist/catalog/bundleCatalogReadPort.js +36 -0
- package/dist/catalog/bundleCatalogStore.d.ts +3 -0
- package/dist/catalog/bundleCatalogStore.js +152 -0
- package/dist/catalog/bundleRuleCodes.d.ts +41 -0
- package/dist/catalog/bundleRuleCodes.js +110 -0
- package/dist/catalog/bundleRules.d.ts +69 -0
- package/dist/catalog/bundleRules.js +102 -0
- package/dist/catalog/catalogDraftStore.d.ts +4 -0
- package/dist/catalog/catalogDraftStore.js +63 -0
- package/dist/catalog/catalogSkuEnvelope.d.ts +7 -0
- package/dist/catalog/catalogSkuEnvelope.js +142 -0
- package/dist/catalog/catalogSkuEnvelopeMapper.d.ts +38 -0
- package/dist/catalog/catalogSkuEnvelopeMapper.js +88 -0
- package/dist/catalog/contracts/bundleAdmin.d.ts +143 -0
- package/dist/catalog/contracts/bundleAdmin.js +1 -0
- package/dist/catalog/contracts/bundleAvailability.d.ts +61 -0
- package/dist/catalog/contracts/bundleAvailability.js +1 -0
- package/dist/catalog/contracts/bundleRead.d.ts +223 -0
- package/dist/catalog/contracts/bundleRead.js +1 -0
- package/dist/catalog/contracts/draft.d.ts +79 -0
- package/dist/catalog/contracts/draft.js +47 -0
- package/dist/catalog/contracts/foundation.d.ts +78 -0
- package/dist/catalog/contracts/foundation.js +53 -0
- package/dist/catalog/contracts/index.d.ts +14 -0
- package/dist/catalog/contracts/index.js +6 -0
- package/dist/catalog/contracts/lifecycle.d.ts +77 -0
- package/dist/catalog/contracts/lifecycle.js +1 -0
- package/dist/catalog/contracts/productMediaContracts.d.ts +77 -0
- package/dist/catalog/contracts/productMediaContracts.js +149 -0
- package/dist/catalog/contracts/productTypes.d.ts +54 -0
- package/dist/catalog/contracts/productTypes.js +16 -0
- package/dist/catalog/contracts/resolveProductMedia.d.ts +3 -0
- package/dist/catalog/contracts/resolveProductMedia.js +78 -0
- package/dist/catalog/contracts/sellable.d.ts +23 -0
- package/dist/catalog/contracts/sellable.js +1 -0
- package/dist/catalog/draftHandler.d.ts +25 -0
- package/dist/catalog/draftHandler.js +118 -0
- package/dist/catalog/draftPorts.d.ts +18 -0
- package/dist/catalog/draftPorts.js +8 -0
- package/dist/catalog/draftSchemas.d.ts +423 -0
- package/dist/catalog/draftSchemas.js +89 -0
- package/dist/catalog/draftValidation.d.ts +21 -0
- package/dist/catalog/draftValidation.js +125 -0
- package/dist/catalog/foundationSchemas.d.ts +98 -0
- package/dist/catalog/foundationSchemas.js +110 -0
- package/dist/catalog/index.d.ts +43 -0
- package/dist/catalog/index.js +25 -0
- package/dist/catalog/mediaSourcePack.d.ts +51 -0
- package/dist/catalog/mediaSourcePack.js +247 -0
- package/dist/catalog/productTypeSchemas.d.ts +46 -0
- package/dist/catalog/productTypeSchemas.js +72 -0
- package/dist/catalog/publicationPorts.d.ts +42 -0
- package/dist/catalog/publicationPorts.js +1 -0
- package/dist/catalog/readPorts.d.ts +51 -0
- package/dist/catalog/readPorts.js +1 -0
- package/dist/catalog/referenceCatalogHandler.d.ts +7 -0
- package/dist/catalog/referenceCatalogHandler.js +27 -0
- package/dist/catalog/resolvedSkuProjection.d.ts +88 -0
- package/dist/catalog/resolvedSkuProjection.js +60 -0
- package/dist/catalog/sellableBundleHandler.d.ts +46 -0
- package/dist/catalog/sellableBundleHandler.js +84 -0
- package/dist/catalog/sellableSchemas.d.ts +46 -0
- package/dist/catalog/sellableSchemas.js +27 -0
- package/dist/catalog/sql.d.ts +46 -0
- package/dist/catalog/sql.js +13 -0
- package/dist/catalog/validation.d.ts +2 -0
- package/dist/catalog/validation.js +3 -0
- package/dist/communications/contracts/index.d.ts +1 -0
- package/dist/communications/contracts/marketingSync.d.ts +194 -0
- package/dist/communications/contracts/marketingSync.js +1 -0
- package/dist/communications/index.d.ts +1 -0
- package/dist/communications/klaviyo/consentPush.d.ts +51 -0
- package/dist/communications/klaviyo/consentPush.js +19 -0
- package/dist/communications/klaviyo/index.d.ts +110 -0
- package/dist/communications/klaviyo/index.js +860 -0
- package/dist/communications/newsletterIntegrationContracts.d.ts +3 -3
- package/dist/communications/resend/index.d.ts +40 -0
- package/dist/communications/resend/index.js +310 -0
- package/dist/composition/catalogContribution.d.ts +18 -0
- package/dist/composition/catalogContribution.js +21 -0
- package/dist/composition/index.d.ts +1 -0
- package/dist/composition/index.js +1 -0
- package/dist/identity/customerContracts.d.ts +2 -2
- package/dist/inventory/adminInventory.d.ts +13 -0
- package/dist/inventory/adminInventory.js +214 -0
- package/dist/inventory/contracts/forecast.d.ts +86 -0
- package/dist/inventory/contracts/forecast.js +1 -0
- package/dist/inventory/contracts/index.d.ts +4 -0
- package/dist/inventory/contracts/index.js +1 -0
- package/dist/inventory/contracts/inventory.d.ts +157 -0
- package/dist/inventory/contracts/inventory.js +1 -0
- package/dist/inventory/contracts/newPurchaseStock.d.ts +20 -0
- package/dist/inventory/contracts/newPurchaseStock.js +1 -0
- package/dist/inventory/contracts/reservation.d.ts +18 -0
- package/dist/inventory/contracts/reservation.js +1 -0
- package/dist/inventory/forecast.d.ts +24 -0
- package/dist/inventory/forecast.js +200 -0
- package/dist/inventory/index.d.ts +13 -0
- package/dist/inventory/index.js +10 -0
- package/dist/inventory/inventoryHandlers.d.ts +53 -0
- package/dist/inventory/inventoryHandlers.js +151 -0
- package/dist/inventory/newPurchaseStockAvailability.d.ts +47 -0
- package/dist/inventory/newPurchaseStockAvailability.js +75 -0
- package/dist/inventory/ports.d.ts +21 -0
- package/dist/inventory/ports.js +16 -0
- package/dist/inventory/renewalReservation.d.ts +27 -0
- package/dist/inventory/renewalReservation.js +61 -0
- package/dist/inventory/reservationPolicy.d.ts +6 -0
- package/dist/inventory/reservationPolicy.js +19 -0
- package/dist/inventory/schemas.d.ts +137 -0
- package/dist/inventory/schemas.js +112 -0
- package/dist/inventory/sql.d.ts +14 -0
- package/dist/inventory/sql.js +5 -0
- package/dist/inventory/subscriptionForecastCalculation.d.ts +4 -0
- package/dist/inventory/subscriptionForecastCalculation.js +133 -0
- package/dist/pricing/acquisitionFinancialPolicy.d.ts +26 -0
- package/dist/pricing/acquisitionFinancialPolicy.js +1 -0
- package/dist/pricing/acquisitionOfferPricing.d.ts +27 -0
- package/dist/pricing/acquisitionOfferPricing.js +25 -0
- package/dist/pricing/acquisitionOfferPricingHandler.d.ts +20 -0
- package/dist/pricing/acquisitionOfferPricingHandler.js +105 -0
- package/dist/pricing/acquisitionOfferPricingSchemas.d.ts +31 -0
- package/dist/pricing/acquisitionOfferPricingSchemas.js +33 -0
- package/dist/pricing/acquisitionQuoteBinding.d.ts +12 -0
- package/dist/pricing/acquisitionQuoteBinding.js +12 -0
- package/dist/pricing/acquisitionReadiness.d.ts +31 -0
- package/dist/pricing/acquisitionReadiness.js +117 -0
- package/dist/pricing/acquisitionTerms.d.ts +19 -0
- package/dist/pricing/acquisitionTerms.js +126 -0
- package/dist/pricing/acquisitionTermsSchemas.d.ts +59 -0
- package/dist/pricing/acquisitionTermsSchemas.js +42 -0
- package/dist/pricing/catalogFactsProvenance.d.ts +33 -0
- package/dist/pricing/catalogFactsProvenance.js +64 -0
- package/dist/pricing/catalogFactsSchemas.d.ts +45 -0
- package/dist/pricing/catalogFactsSchemas.js +58 -0
- package/dist/pricing/commerceOfferPricing.d.ts +25 -0
- package/dist/pricing/commerceOfferPricing.js +139 -0
- package/dist/pricing/commerceOfferPricingCache.d.ts +10 -0
- package/dist/pricing/commerceOfferPricingCache.js +44 -0
- package/dist/pricing/commerceOfferPricingHandler.d.ts +21 -0
- package/dist/pricing/commerceOfferPricingHandler.js +78 -0
- package/dist/pricing/commercePriceAuthority.d.ts +26 -0
- package/dist/pricing/commercePriceAuthority.js +79 -0
- package/dist/pricing/commercePricingPolicyErrors.d.ts +40 -0
- package/dist/pricing/commercePricingPolicyErrors.js +67 -0
- package/dist/pricing/commerceQuoteBatchHandler.d.ts +37 -0
- package/dist/pricing/commerceQuoteBatchHandler.js +83 -0
- package/dist/pricing/commerceQuoteCatalogReadPort.d.ts +27 -0
- package/dist/pricing/commerceQuoteCatalogReadPort.js +8 -0
- package/dist/pricing/commerceQuoteHandler.d.ts +31 -0
- package/dist/pricing/commerceQuoteHandler.js +110 -0
- package/dist/pricing/commerceQuoteSnapshotExpect.d.ts +9 -0
- package/dist/pricing/commerceQuoteSnapshotExpect.js +22 -0
- package/dist/pricing/contracts/acquisitionTerms.d.ts +32 -0
- package/dist/pricing/contracts/acquisitionTerms.js +2 -0
- package/dist/pricing/contracts/authority.d.ts +27 -0
- package/dist/pricing/contracts/authority.js +1 -0
- package/dist/pricing/contracts/evidence.d.ts +33 -0
- package/dist/pricing/contracts/evidence.js +1 -0
- package/dist/pricing/contracts/index.d.ts +17 -0
- package/dist/pricing/contracts/index.js +7 -0
- package/dist/pricing/contracts/money.d.ts +27 -0
- package/dist/pricing/contracts/money.js +1 -0
- package/dist/pricing/contracts/offer.d.ts +52 -0
- package/dist/pricing/contracts/offer.js +4 -0
- package/dist/pricing/contracts/offerPolicy.d.ts +16 -0
- package/dist/pricing/contracts/offerPolicy.js +5 -0
- package/dist/pricing/contracts/policy.d.ts +22 -0
- package/dist/pricing/contracts/policy.js +3 -0
- package/dist/pricing/contracts/provenance.d.ts +24 -0
- package/dist/pricing/contracts/provenance.js +2 -0
- package/dist/pricing/contracts/quote.d.ts +94 -0
- package/dist/pricing/contracts/quote.js +1 -0
- package/dist/pricing/dbBackedCommerceQuoteHelpers.d.ts +78 -0
- package/dist/pricing/dbBackedCommerceQuoteHelpers.js +146 -0
- package/dist/pricing/dbBackedCommerceQuotePort.d.ts +66 -0
- package/dist/pricing/dbBackedCommerceQuotePort.js +206 -0
- package/dist/pricing/dbBackedCommerceQuoteSnapshotVerifier.d.ts +4 -0
- package/dist/pricing/dbBackedCommerceQuoteSnapshotVerifier.js +25 -0
- package/dist/pricing/index.d.ts +51 -0
- package/dist/pricing/index.js +36 -0
- package/dist/pricing/offerPolicyReadiness.d.ts +21 -0
- package/dist/pricing/offerPolicyReadiness.js +79 -0
- package/dist/pricing/offerPolicySchemas.d.ts +25 -0
- package/dist/pricing/offerPolicySchemas.js +15 -0
- package/dist/pricing/offerPricingSchemas.d.ts +315 -0
- package/dist/pricing/offerPricingSchemas.js +65 -0
- package/dist/pricing/ports.d.ts +13 -0
- package/dist/pricing/ports.js +9 -0
- package/dist/pricing/pricingPolicyToken.d.ts +39 -0
- package/dist/pricing/pricingPolicyToken.js +84 -0
- package/dist/pricing/quoteAcquisitionTerms.d.ts +2 -0
- package/dist/pricing/quoteAcquisitionTerms.js +4 -0
- package/dist/pricing/quoteCodeRejectionDetails.d.ts +20 -0
- package/dist/pricing/quoteCodeRejectionDetails.js +22 -0
- package/dist/pricing/quotePorts.d.ts +30 -0
- package/dist/pricing/quotePorts.js +20 -0
- package/dist/pricing/quotePrimitives.d.ts +13 -0
- package/dist/pricing/quotePrimitives.js +18 -0
- package/dist/pricing/quotePromotionEvidence.d.ts +39 -0
- package/dist/pricing/quotePromotionEvidence.js +73 -0
- package/dist/pricing/quoteSchemas.d.ts +1176 -0
- package/dist/pricing/quoteSchemas.js +196 -0
- package/dist/pricing/subscriptionPricePolicy.d.ts +52 -0
- package/dist/pricing/subscriptionPricePolicy.js +96 -0
- package/dist/pricing/taxProfileGuard.d.ts +2 -0
- package/dist/pricing/taxProfileGuard.js +24 -0
- package/dist/pricing/validation.d.ts +2 -0
- package/dist/pricing/validation.js +3 -0
- package/dist/promotions/adminBindings.d.ts +72 -0
- package/dist/promotions/adminBindings.js +1 -0
- package/dist/promotions/adminPromotionCodesContracts.d.ts +498 -0
- package/dist/promotions/adminPromotionCodesContracts.js +211 -0
- package/dist/promotions/adminPromotionCodesDataPort.d.ts +47 -0
- package/dist/promotions/adminPromotionCodesDataPort.js +1 -0
- package/dist/promotions/adminPromotionCodesHandler.d.ts +14 -0
- package/dist/promotions/adminPromotionCodesHandler.js +194 -0
- package/dist/promotions/adminPromotionsContracts.d.ts +235 -0
- package/dist/promotions/adminPromotionsContracts.js +99 -0
- package/dist/promotions/adminPromotionsDataPort.d.ts +42 -0
- package/dist/promotions/adminPromotionsDataPort.js +1 -0
- package/dist/promotions/adminPromotionsHandler.d.ts +16 -0
- package/dist/promotions/adminPromotionsHandler.js +47 -0
- package/dist/promotions/contracts/index.d.ts +387 -0
- package/dist/promotions/contracts/index.js +1 -0
- package/dist/promotions/index.d.ts +22 -0
- package/dist/promotions/index.js +21 -0
- package/dist/promotions/promoDataPort.d.ts +47 -0
- package/dist/promotions/promoDataPort.js +14 -0
- package/dist/promotions/promotionAcceptanceTelemetry.d.ts +29 -0
- package/dist/promotions/promotionAcceptanceTelemetry.js +45 -0
- package/dist/promotions/promotionBenefitDefinition.d.ts +37 -0
- package/dist/promotions/promotionBenefitDefinition.js +33 -0
- package/dist/promotions/promotionClaimSweepPort.d.ts +14 -0
- package/dist/promotions/promotionClaimSweepPort.js +8 -0
- package/dist/promotions/promotionClaims.d.ts +5 -0
- package/dist/promotions/promotionClaims.js +57 -0
- package/dist/promotions/promotionCodePreview.d.ts +11 -0
- package/dist/promotions/promotionCodePreview.js +154 -0
- package/dist/promotions/promotionCodeQuotePort.d.ts +25 -0
- package/dist/promotions/promotionCodeQuotePort.js +1 -0
- package/dist/promotions/promotionQuoteAcceptance.d.ts +65 -0
- package/dist/promotions/promotionQuoteAcceptance.js +202 -0
- package/dist/promotions/promotionQuoteBinding.d.ts +71 -0
- package/dist/promotions/promotionQuoteBinding.js +85 -0
- package/dist/promotions/quoteAutomaticPromotions.d.ts +24 -0
- package/dist/promotions/quoteAutomaticPromotions.js +36 -0
- package/dist/promotions/quotePromoDiscounts.d.ts +32 -0
- package/dist/promotions/quotePromoDiscounts.js +140 -0
- package/dist/promotions/quotePromotionCodeAdjustments.d.ts +27 -0
- package/dist/promotions/quotePromotionCodeAdjustments.js +223 -0
- package/dist/promotions/quotePromotionV2.d.ts +29 -0
- package/dist/promotions/quotePromotionV2.js +174 -0
- package/dist/promotions/sql.d.ts +14 -0
- package/dist/promotions/sql.js +5 -0
- package/dist/promotions/validation.d.ts +2 -0
- package/dist/promotions/validation.js +3 -0
- package/dist/shipping/addressCanonLookupHandler.d.ts +7 -0
- package/dist/shipping/addressCanonLookupHandler.js +105 -0
- package/dist/shipping/addressCanonical.d.ts +2 -0
- package/dist/shipping/addressCanonical.js +26 -0
- package/dist/shipping/addressPorts.d.ts +39 -0
- package/dist/shipping/addressPorts.js +1 -0
- package/dist/shipping/addressSchemas.d.ts +30 -0
- package/dist/shipping/addressSchemas.js +1 -0
- package/dist/shipping/adminShippingRateHandler.d.ts +4 -0
- package/dist/shipping/adminShippingRateHandler.js +64 -0
- package/dist/shipping/contracts/address.d.ts +144 -0
- package/dist/shipping/contracts/address.js +1 -0
- package/dist/shipping/contracts/delivery.d.ts +110 -0
- package/dist/shipping/contracts/delivery.js +1 -0
- package/dist/shipping/contracts/index.d.ts +3 -0
- package/dist/shipping/contracts/index.js +1 -0
- package/dist/shipping/contracts/shippingRate.d.ts +11 -0
- package/dist/shipping/contracts/shippingRate.js +1 -0
- package/dist/shipping/customerAddressesHandler.d.ts +5 -0
- package/dist/shipping/customerAddressesHandler.js +80 -0
- package/dist/shipping/customerSelfServiceAddressModels.d.ts +27 -0
- package/dist/shipping/customerSelfServiceAddressModels.js +101 -0
- package/dist/shipping/deliverySelectionHandler.d.ts +10 -0
- package/dist/shipping/deliverySelectionHandler.js +77 -0
- package/dist/shipping/deliverySelectionPort.d.ts +8 -0
- package/dist/shipping/deliverySelectionPort.js +1 -0
- package/dist/shipping/deliverySelectionSummary.d.ts +2 -0
- package/dist/shipping/deliverySelectionSummary.js +53 -0
- package/dist/shipping/handlerSchemas.d.ts +21 -0
- package/dist/shipping/handlerSchemas.js +1 -0
- package/dist/shipping/index.d.ts +17 -0
- package/dist/shipping/index.js +8 -0
- package/dist/shipping/pickupPointSearchPort.d.ts +4 -0
- package/dist/shipping/pickupPointSearchPort.js +1 -0
- package/dist/shipping/readDeliverySelectionEvidence.d.ts +2 -0
- package/dist/shipping/readDeliverySelectionEvidence.js +44 -0
- package/dist/shipping/shippingRatePorts.d.ts +52 -0
- package/dist/shipping/shippingRatePorts.js +1 -0
- package/package.json +62 -2
- package/release-gates.json +218 -10
- package/sql/20260807140000_read_parity_catalog.sql +94 -0
- package/sql/20260810120000_storefront_catalog_attributes.sql +51 -0
- package/sql/20260812140000_sellable_bundle_catalog.sql +124 -0
- package/sql/20260812210000_bundle_operator_write_boundary.sql +567 -0
- package/sql/20260814000000_fulfillment_stock_evidence.sql +239 -0
- package/sql/20260815120000_automatic_subscription_renewal.sql +1083 -0
- package/sql/20260817180000_promotion_claim_lifecycle.sql +591 -0
- package/sql/20260817180100_promotion_claim_lifecycle_validation.sql +23 -0
- package/sql/20260827220000_catalog_document_revision_foundation.sql +226 -0
- package/sql/20260827220001_catalog_document_revision_foundation_validate.sql +10 -0
- package/sql/20260908100000_catalog_draft_foundation.sql +217 -0
- package/src/catalog/activeSkuSelection.ts +20 -0
- package/src/catalog/adminBindings.ts +59 -0
- package/src/catalog/adminBundleHandler.ts +165 -0
- package/src/catalog/adminBundleReadHandler.ts +261 -0
- package/src/catalog/adminBundleWritePort.ts +102 -0
- package/src/catalog/bundleAvailability.ts +129 -0
- package/src/catalog/bundleAvailabilityService.ts +171 -0
- package/src/catalog/bundleBindings.ts +29 -0
- package/src/catalog/bundleCatalogQueries.ts +98 -0
- package/src/catalog/bundleCatalogReadPort.ts +177 -0
- package/src/catalog/bundleCatalogStore.ts +269 -0
- package/src/catalog/bundleRuleCodes.ts +134 -0
- package/src/catalog/bundleRules.ts +153 -0
- package/src/catalog/catalogDraftStore.ts +71 -0
- package/src/catalog/catalogSkuEnvelope.ts +214 -0
- package/src/catalog/catalogSkuEnvelopeMapper.ts +160 -0
- package/src/catalog/contracts/bundleAdmin.ts +20 -0
- package/src/catalog/contracts/bundleAvailability.ts +5 -0
- package/src/catalog/contracts/bundleRead.ts +13 -0
- package/src/catalog/contracts/draft.ts +69 -0
- package/src/catalog/contracts/foundation.ts +104 -0
- package/src/catalog/contracts/index.ts +14 -0
- package/src/catalog/contracts/lifecycle.ts +74 -0
- package/src/catalog/contracts/productMediaContracts.ts +170 -0
- package/src/catalog/contracts/productTypes.ts +35 -0
- package/src/catalog/contracts/resolveProductMedia.ts +85 -0
- package/src/catalog/contracts/sellable.ts +12 -0
- package/src/catalog/draftHandler.ts +105 -0
- package/src/catalog/draftPorts.ts +18 -0
- package/src/catalog/draftSchemas.ts +88 -0
- package/src/catalog/draftValidation.ts +100 -0
- package/src/catalog/foundationSchemas.ts +123 -0
- package/src/catalog/index.ts +43 -0
- package/src/catalog/mediaSourcePack.ts +219 -0
- package/src/catalog/productTypeSchemas.ts +70 -0
- package/src/catalog/publicationPorts.ts +44 -0
- package/src/catalog/readPorts.ts +61 -0
- package/src/catalog/referenceCatalogHandler.ts +39 -0
- package/src/catalog/resolvedSkuProjection.ts +76 -0
- package/src/catalog/sellableBundleHandler.ts +133 -0
- package/src/catalog/sellableSchemas.ts +33 -0
- package/src/catalog/sql.ts +14 -0
- package/src/catalog/validation.ts +3 -0
- package/src/communications/contracts/index.ts +1 -0
- package/src/communications/contracts/marketingSync.ts +109 -0
- package/src/communications/index.ts +1 -0
- package/src/communications/klaviyo/consentPush.ts +19 -0
- package/src/communications/klaviyo/index.ts +649 -0
- package/src/communications/resend/index.ts +350 -0
- package/src/composition/catalogContribution.ts +32 -0
- package/src/composition/index.ts +1 -0
- package/src/inventory/adminInventory.ts +251 -0
- package/src/inventory/contracts/forecast.ts +96 -0
- package/src/inventory/contracts/index.ts +18 -0
- package/src/inventory/contracts/inventory.ts +14 -0
- package/src/inventory/contracts/newPurchaseStock.ts +23 -0
- package/src/inventory/contracts/reservation.ts +20 -0
- package/src/inventory/forecast.ts +239 -0
- package/src/inventory/index.ts +21 -0
- package/src/inventory/inventoryHandlers.ts +215 -0
- package/src/inventory/newPurchaseStockAvailability.ts +120 -0
- package/src/inventory/ports.ts +46 -0
- package/src/inventory/renewalReservation.ts +88 -0
- package/src/inventory/reservationPolicy.ts +27 -0
- package/src/inventory/schemas.ts +128 -0
- package/src/inventory/sql.ts +5 -0
- package/src/inventory/subscriptionForecastCalculation.ts +157 -0
- package/src/pricing/acquisitionFinancialPolicy.ts +26 -0
- package/src/pricing/acquisitionOfferPricing.ts +38 -0
- package/src/pricing/acquisitionOfferPricingHandler.ts +157 -0
- package/src/pricing/acquisitionOfferPricingSchemas.ts +35 -0
- package/src/pricing/acquisitionQuoteBinding.ts +12 -0
- package/src/pricing/acquisitionReadiness.ts +148 -0
- package/src/pricing/acquisitionTerms.ts +125 -0
- package/src/pricing/acquisitionTermsSchemas.ts +52 -0
- package/src/pricing/catalogFactsProvenance.ts +102 -0
- package/src/pricing/catalogFactsSchemas.ts +69 -0
- package/src/pricing/commerceOfferPricing.ts +224 -0
- package/src/pricing/commerceOfferPricingCache.ts +53 -0
- package/src/pricing/commerceOfferPricingHandler.ts +137 -0
- package/src/pricing/commercePriceAuthority.ts +104 -0
- package/src/pricing/commercePricingPolicyErrors.ts +88 -0
- package/src/pricing/commerceQuoteBatchHandler.ts +129 -0
- package/src/pricing/commerceQuoteCatalogReadPort.ts +42 -0
- package/src/pricing/commerceQuoteHandler.ts +184 -0
- package/src/pricing/commerceQuoteSnapshotExpect.ts +48 -0
- package/src/pricing/contracts/acquisitionTerms.ts +26 -0
- package/src/pricing/contracts/authority.ts +44 -0
- package/src/pricing/contracts/evidence.ts +25 -0
- package/src/pricing/contracts/index.ts +17 -0
- package/src/pricing/contracts/money.ts +32 -0
- package/src/pricing/contracts/offer.ts +42 -0
- package/src/pricing/contracts/offerPolicy.ts +17 -0
- package/src/pricing/contracts/policy.ts +26 -0
- package/src/pricing/contracts/provenance.ts +19 -0
- package/src/pricing/contracts/quote.ts +106 -0
- package/src/pricing/dbBackedCommerceQuoteHelpers.ts +256 -0
- package/src/pricing/dbBackedCommerceQuotePort.ts +260 -0
- package/src/pricing/dbBackedCommerceQuoteSnapshotVerifier.ts +49 -0
- package/src/pricing/index.ts +52 -0
- package/src/pricing/offerPolicyReadiness.ts +110 -0
- package/src/pricing/offerPolicySchemas.ts +23 -0
- package/src/pricing/offerPricingSchemas.ts +92 -0
- package/src/pricing/ports.ts +17 -0
- package/src/pricing/pricingPolicyToken.ts +119 -0
- package/src/pricing/quoteAcquisitionTerms.ts +10 -0
- package/src/pricing/quoteCodeRejectionDetails.ts +23 -0
- package/src/pricing/quotePorts.ts +58 -0
- package/src/pricing/quotePrimitives.ts +21 -0
- package/src/pricing/quotePromotionEvidence.ts +82 -0
- package/src/pricing/quoteSchemas.ts +230 -0
- package/src/pricing/subscriptionPricePolicy.ts +113 -0
- package/src/pricing/taxProfileGuard.ts +33 -0
- package/src/pricing/validation.ts +3 -0
- package/src/promotions/adminBindings.ts +53 -0
- package/src/promotions/adminPromotionCodesContracts.ts +244 -0
- package/src/promotions/adminPromotionCodesDataPort.ts +56 -0
- package/src/promotions/adminPromotionCodesHandler.ts +254 -0
- package/src/promotions/adminPromotionsContracts.ts +121 -0
- package/src/promotions/adminPromotionsDataPort.ts +48 -0
- package/src/promotions/adminPromotionsHandler.ts +72 -0
- package/src/promotions/contracts/index.ts +387 -0
- package/src/promotions/index.ts +22 -0
- package/src/promotions/promoDataPort.ts +65 -0
- package/src/promotions/promotionAcceptanceTelemetry.ts +73 -0
- package/src/promotions/promotionBenefitDefinition.ts +48 -0
- package/src/promotions/promotionClaimSweepPort.ts +23 -0
- package/src/promotions/promotionClaims.ts +70 -0
- package/src/promotions/promotionCodePreview.ts +183 -0
- package/src/promotions/promotionCodeQuotePort.ts +35 -0
- package/src/promotions/promotionQuoteAcceptance.ts +284 -0
- package/src/promotions/promotionQuoteBinding.ts +158 -0
- package/src/promotions/quoteAutomaticPromotions.ts +58 -0
- package/src/promotions/quotePromoDiscounts.ts +185 -0
- package/src/promotions/quotePromotionCodeAdjustments.ts +277 -0
- package/src/promotions/quotePromotionV2.ts +223 -0
- package/src/promotions/sql.ts +5 -0
- package/src/promotions/validation.ts +3 -0
- package/src/shipping/addressCanonLookupHandler.ts +114 -0
- package/src/shipping/addressCanonical.ts +31 -0
- package/src/shipping/addressPorts.ts +48 -0
- package/src/shipping/addressSchemas.ts +28 -0
- package/src/shipping/adminShippingRateHandler.ts +72 -0
- package/src/shipping/contracts/address.ts +71 -0
- package/src/shipping/contracts/delivery.ts +114 -0
- package/src/shipping/contracts/index.ts +18 -0
- package/src/shipping/contracts/shippingRate.ts +7 -0
- package/src/shipping/customerAddressesHandler.ts +100 -0
- package/src/shipping/customerSelfServiceAddressModels.ts +124 -0
- package/src/shipping/deliverySelectionHandler.ts +94 -0
- package/src/shipping/deliverySelectionPort.ts +10 -0
- package/src/shipping/deliverySelectionSummary.ts +56 -0
- package/src/shipping/handlerSchemas.ts +19 -0
- package/src/shipping/index.ts +23 -0
- package/src/shipping/pickupPointSearchPort.ts +8 -0
- package/src/shipping/readDeliverySelectionEvidence.ts +51 -0
- package/src/shipping/shippingRatePorts.ts +36 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** The server cannot assign a policy right now. Caller-independent: retrying an
|
|
2
|
+
* identical request only succeeds once production configuration changes. */
|
|
3
|
+
export class CommercePricingPolicyUnavailableError extends Error {
|
|
4
|
+
reason;
|
|
5
|
+
constructor(reason) {
|
|
6
|
+
super("commerce_pricing_policy_v2_unavailable");
|
|
7
|
+
this.reason = reason;
|
|
8
|
+
this.name = "CommercePricingPolicyUnavailableError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Every reason a caller-side refusal can carry. ⛔ Each one answers `400`, which
|
|
13
|
+
* puts it outside every 5xx monitor, so each one owes a dedicated monitor of its
|
|
14
|
+
* own; a host's observability check can read this tuple and fail when a reason
|
|
15
|
+
* has none. Adding a member here without adding a monitor is the regression this
|
|
16
|
+
* tuple exists to prevent: reclassifying `v2_capability_required` from `503` to
|
|
17
|
+
* `400` once silently removed the only alert on a site-wide unpriceable-quote
|
|
18
|
+
* outage.
|
|
19
|
+
*/
|
|
20
|
+
export const PRICING_POLICY_REQUEST_REASONS = [
|
|
21
|
+
"v2_capability_required",
|
|
22
|
+
"v2_visitor_id_required",
|
|
23
|
+
];
|
|
24
|
+
/** The request itself lacks the context a v2 assignment needs. Caller-fixable,
|
|
25
|
+
* and never evidence that pricing is down. The reason is typed off
|
|
26
|
+
* PRICING_POLICY_REQUEST_REASONS so a new one cannot skip its monitor. */
|
|
27
|
+
export class CommercePricingPolicyRequestError extends Error {
|
|
28
|
+
reason;
|
|
29
|
+
constructor(reason) {
|
|
30
|
+
super("commerce_pricing_policy_v2_request_invalid");
|
|
31
|
+
this.reason = reason;
|
|
32
|
+
this.name = "CommercePricingPolicyRequestError";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const SAFE_PRICING_POLICY_REASONS = new Set([
|
|
36
|
+
"v2_capability_required",
|
|
37
|
+
"v2_visitor_id_required",
|
|
38
|
+
"signing_secret_unavailable", // gitleaks:allow — closed-set diagnostic code, never a credential
|
|
39
|
+
"v1_assignment_rejected",
|
|
40
|
+
"v2_assignment_config_invalid",
|
|
41
|
+
"v2_readiness_not_ready",
|
|
42
|
+
"other",
|
|
43
|
+
]);
|
|
44
|
+
/**
|
|
45
|
+
* Single owner of the status a pricing-policy refusal earns, shared by every
|
|
46
|
+
* route that resolves one. A caller-attributable gap answers `400`; only a
|
|
47
|
+
* server that genuinely cannot price answers `503`, so a `503` on these routes
|
|
48
|
+
* stays a truthful outage signal.
|
|
49
|
+
*/
|
|
50
|
+
export function mapPricingPolicyFailure(error) {
|
|
51
|
+
const caller = error instanceof CommercePricingPolicyRequestError;
|
|
52
|
+
if (!caller && !(error instanceof CommercePricingPolicyUnavailableError))
|
|
53
|
+
return null;
|
|
54
|
+
return {
|
|
55
|
+
code: caller ? "BAD_REQUEST" : "UPSTREAM_UNAVAILABLE",
|
|
56
|
+
details: {
|
|
57
|
+
reason: caller ? "pricing_policy_request_invalid" : "pricing_policy_unavailable",
|
|
58
|
+
stage: "pricing_policy",
|
|
59
|
+
policyReason: safePricingPolicyReason(error.reason),
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function safePricingPolicyReason(value) {
|
|
64
|
+
return SAFE_PRICING_POLICY_REASONS.has(value)
|
|
65
|
+
? value
|
|
66
|
+
: "other";
|
|
67
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ResolvedAcquisitionTerms } from "./contracts/acquisitionTerms.js";
|
|
2
|
+
import type { HttpRequest, HttpResponse } from "../http/index.js";
|
|
3
|
+
import type { BffResponder } from "../bff/index.js";
|
|
4
|
+
import type { z } from "zod";
|
|
5
|
+
import { type CreateQuoteRequest, type CreateQuoteResponse } from "./contracts/quote.js";
|
|
6
|
+
import { COMMERCE_CONTRACT_VERSION } from "./contracts/index.js";
|
|
7
|
+
import { type CommerceQuotePort } from "./quotePorts.js";
|
|
8
|
+
import type { PricingPolicySnapshot } from "./contracts/offerPolicy.js";
|
|
9
|
+
export interface CommerceQuoteBatchHandlerDeps<Request extends CreateQuoteRequest = CreateQuoteRequest, Response extends CreateQuoteResponse = CreateQuoteResponse> {
|
|
10
|
+
responder: BffResponder;
|
|
11
|
+
acquisition?: {
|
|
12
|
+
terms(quote: Response["quote"]): ResolvedAcquisitionTerms | undefined;
|
|
13
|
+
};
|
|
14
|
+
createQuoteBatchRequestSchema: z.ZodType<{
|
|
15
|
+
quotes: Request[];
|
|
16
|
+
}>;
|
|
17
|
+
publicCreateQuoteBatchResponseSchema: z.ZodType<{
|
|
18
|
+
contractVersion: typeof COMMERCE_CONTRACT_VERSION;
|
|
19
|
+
quotes: Response["quote"][];
|
|
20
|
+
}>;
|
|
21
|
+
quotePort: CommerceQuotePort<Request, Response>;
|
|
22
|
+
resolveCustomerEligibility?: (request: Request) => Promise<{
|
|
23
|
+
clientId: string | null;
|
|
24
|
+
source: "anonymous" | "resolved_client";
|
|
25
|
+
}>;
|
|
26
|
+
resolvePricingPolicy?: (request: Request) => PricingPolicySnapshot | undefined | Promise<PricingPolicySnapshot | undefined>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Batch quote BFF handler: prices N independent quotes in one request so the
|
|
30
|
+
* configurator stops fanning out one HTTP call per length tile. The injected
|
|
31
|
+
* `quotePort` is expected to share its catalog + active price-list reads across
|
|
32
|
+
* the batch (single `atTime` + memoized catalog), so this is one DB warm-up, not
|
|
33
|
+
* N. Output is identical to calling the single-quote endpoint N times, and order
|
|
34
|
+
* is preserved (`quotes[i]` ⇔ the i-th request). A failure in any quote fails
|
|
35
|
+
* the whole batch, mirroring the single-endpoint error mapping.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createCommerceQuoteBatchHandler<Request extends CreateQuoteRequest, Response extends CreateQuoteResponse>({ responder, createQuoteBatchRequestSchema, publicCreateQuoteBatchResponseSchema, quotePort, acquisition, resolveCustomerEligibility, resolvePricingPolicy, }: CommerceQuoteBatchHandlerDeps<Request, Response>): (req: HttpRequest, res: HttpResponse) => Promise<void>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { mapAcquisitionTermsFailure } from "./acquisitionQuoteBinding.js";
|
|
2
|
+
import { COMMERCE_CONTRACT_VERSION } from "./contracts/index.js";
|
|
3
|
+
import { CommerceQuoteError, } from "./quotePorts.js";
|
|
4
|
+
import { CommerceQuoteCatalogReadError } from "./commerceQuoteCatalogReadPort.js";
|
|
5
|
+
import { mapPricingPolicyFailure } from "./commercePricingPolicyErrors.js";
|
|
6
|
+
/**
|
|
7
|
+
* Batch quote BFF handler: prices N independent quotes in one request so the
|
|
8
|
+
* configurator stops fanning out one HTTP call per length tile. The injected
|
|
9
|
+
* `quotePort` is expected to share its catalog + active price-list reads across
|
|
10
|
+
* the batch (single `atTime` + memoized catalog), so this is one DB warm-up, not
|
|
11
|
+
* N. Output is identical to calling the single-quote endpoint N times, and order
|
|
12
|
+
* is preserved (`quotes[i]` ⇔ the i-th request). A failure in any quote fails
|
|
13
|
+
* the whole batch, mirroring the single-endpoint error mapping.
|
|
14
|
+
*/
|
|
15
|
+
export function createCommerceQuoteBatchHandler({ responder, createQuoteBatchRequestSchema, publicCreateQuoteBatchResponseSchema, quotePort, acquisition, resolveCustomerEligibility, resolvePricingPolicy, }) {
|
|
16
|
+
const { sendBffError, sendBffSuccess, sendMethodNotAllowed } = responder;
|
|
17
|
+
return async function handler(req, res) {
|
|
18
|
+
if (req.method !== "POST") {
|
|
19
|
+
sendMethodNotAllowed(res, ["POST"]);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const request = createQuoteBatchRequestSchema.safeParse(req.body);
|
|
23
|
+
if (!request.success) {
|
|
24
|
+
sendBffError(res, "BAD_REQUEST", "Invalid commerce quote batch request", {
|
|
25
|
+
details: request.error.flatten(),
|
|
26
|
+
});
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const results = await Promise.all(request.data.quotes.map(async (quote) => {
|
|
31
|
+
const eligibility = resolveCustomerEligibility
|
|
32
|
+
? await resolveCustomerEligibility(quote)
|
|
33
|
+
: { clientId: null, source: "anonymous" };
|
|
34
|
+
const pricingPolicy = await resolvePricingPolicy?.(quote);
|
|
35
|
+
return quotePort.createQuote(quote, {
|
|
36
|
+
clientId: eligibility.clientId,
|
|
37
|
+
...(pricingPolicy ? { pricingPolicy } : {}),
|
|
38
|
+
});
|
|
39
|
+
}));
|
|
40
|
+
const payload = {
|
|
41
|
+
contractVersion: COMMERCE_CONTRACT_VERSION,
|
|
42
|
+
quotes: results.map((result) => result.quote),
|
|
43
|
+
};
|
|
44
|
+
const response = publicCreateQuoteBatchResponseSchema.safeParse(payload);
|
|
45
|
+
if (!response.success) {
|
|
46
|
+
sendBffError(res, "INVALID_RESPONSE", "Commerce quote batch returned invalid response");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
sendBffSuccess(res, response.data, {
|
|
50
|
+
contractVersion: COMMERCE_CONTRACT_VERSION,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
const acquisitionFailure = acquisition ? mapAcquisitionTermsFailure(error) : null;
|
|
55
|
+
if (acquisitionFailure) {
|
|
56
|
+
sendBffError(res, acquisitionFailure.code, "Acquisition terms unavailable", { details: acquisitionFailure.details });
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (error instanceof CommerceQuoteCatalogReadError) {
|
|
60
|
+
sendBffError(res, "UPSTREAM_UNAVAILABLE", "Commerce catalog is unavailable", {
|
|
61
|
+
details: { reason: "catalog_unavailable", refusalCode: error.code },
|
|
62
|
+
});
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (error instanceof CommerceQuoteError) {
|
|
66
|
+
sendBffError(res, error.code === "UNKNOWN_SKU" ? "BAD_REQUEST" : "CONFLICT", error.message, { details: error.details });
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// Without this the batch route answered every pricing-policy refusal with
|
|
70
|
+
// a detail-free 503, so the one route the configurator actually fans out
|
|
71
|
+
// to said the least about why it refused.
|
|
72
|
+
const policyFailure = mapPricingPolicyFailure(error);
|
|
73
|
+
if (policyFailure) {
|
|
74
|
+
console.error("[commerce-quote-batch] pricing policy refused:", JSON.stringify(policyFailure.details));
|
|
75
|
+
sendBffError(res, policyFailure.code, policyFailure.code === "BAD_REQUEST"
|
|
76
|
+
? "Commerce quote batch request is missing offer policy context"
|
|
77
|
+
: "Commerce quote batch failed", { details: policyFailure.details });
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
sendBffError(res, "UPSTREAM_UNAVAILABLE", "Commerce quote batch failed");
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Quote-only facts: no copy, route, price, or inventory authority. */
|
|
2
|
+
export interface CommerceQuoteCatalogItem {
|
|
3
|
+
skuId: string;
|
|
4
|
+
skuCode: string;
|
|
5
|
+
variantId: string;
|
|
6
|
+
productSlug: string;
|
|
7
|
+
netWeightG: number;
|
|
8
|
+
/** Identifies the product primary SKU for offer selection; secondary SKUs are excluded. */
|
|
9
|
+
isPrimarySku?: boolean;
|
|
10
|
+
isAddon: boolean;
|
|
11
|
+
sellability: {
|
|
12
|
+
oneTime: boolean;
|
|
13
|
+
subscription: boolean;
|
|
14
|
+
};
|
|
15
|
+
documentRevision: {
|
|
16
|
+
id: string | null;
|
|
17
|
+
digest: string | null;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface CommerceQuoteCatalogReadPort {
|
|
21
|
+
listQuoteCatalogItems(): Promise<CommerceQuoteCatalogItem[]>;
|
|
22
|
+
}
|
|
23
|
+
export type CommerceQuoteCatalogReadRefusalCode = "catalog_read_not_configured" | "catalog_authority_unavailable" | "catalog_authority_changed" | "catalog_revision_invalid" | "catalog_document_schema_invalid" | "catalog_document_digest_mismatch" | "catalog_primary_trade_item_invalid" | "catalog_cursor_invalid" | "catalog_cardinality_exceeded";
|
|
24
|
+
export declare class CommerceQuoteCatalogReadError extends Error {
|
|
25
|
+
readonly code: CommerceQuoteCatalogReadRefusalCode;
|
|
26
|
+
constructor(code: CommerceQuoteCatalogReadRefusalCode);
|
|
27
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ResolvedAcquisitionTerms } from "./contracts/acquisitionTerms.js";
|
|
2
|
+
import type { HttpRequest, HttpResponse } from "../http/index.js";
|
|
3
|
+
import type { BffResponder } from "../bff/index.js";
|
|
4
|
+
import type { z } from "zod";
|
|
5
|
+
import { type CreateQuoteRequest, type CreateQuoteResponse } from "./contracts/quote.js";
|
|
6
|
+
import { type CommerceQuotePort } from "./quotePorts.js";
|
|
7
|
+
import type { PricingPolicySnapshot } from "./contracts/offerPolicy.js";
|
|
8
|
+
export interface CommerceQuoteHandlerDeps<Request extends CreateQuoteRequest = CreateQuoteRequest, Response extends CreateQuoteResponse = CreateQuoteResponse> {
|
|
9
|
+
responder: BffResponder;
|
|
10
|
+
acquisition?: {
|
|
11
|
+
terms(quote: Response["quote"]): ResolvedAcquisitionTerms | undefined;
|
|
12
|
+
};
|
|
13
|
+
createQuoteRequestSchema: z.ZodType<Request>;
|
|
14
|
+
createQuoteResponseSchema: z.ZodType<Response>;
|
|
15
|
+
publicCreateQuoteRequestSchema: z.ZodType<Request & {
|
|
16
|
+
promotionAcceptanceToken?: string;
|
|
17
|
+
}>;
|
|
18
|
+
publicCreateQuoteResponseSchema: z.ZodType<Response & {
|
|
19
|
+
promotionAcceptanceToken?: string;
|
|
20
|
+
}>;
|
|
21
|
+
quotePort: CommerceQuotePort<Request, Response>;
|
|
22
|
+
fallbackQuotePort?: CommerceQuotePort<Request, Response>;
|
|
23
|
+
resolveCustomerEligibility?: (request: Request) => Promise<{
|
|
24
|
+
clientId: string | null;
|
|
25
|
+
source: "anonymous" | "resolved_client";
|
|
26
|
+
}>;
|
|
27
|
+
resolvePricingPolicy?: (request: Request) => PricingPolicySnapshot | undefined | Promise<PricingPolicySnapshot | undefined>;
|
|
28
|
+
createPromotionAcceptance?: (request: Request, quote: Awaited<ReturnType<CommerceQuotePort<Request, Response>["createQuote"]>>["quote"], acquisitionTerms?: ResolvedAcquisitionTerms) => string | null;
|
|
29
|
+
honorPromotionAcceptance?: (token: string, request: Request, quote: Awaited<ReturnType<CommerceQuotePort<Request, Response>["createQuote"]>>["quote"], acquisitionTerms?: ResolvedAcquisitionTerms) => boolean;
|
|
30
|
+
}
|
|
31
|
+
export declare function createCommerceQuoteHandler<Request extends CreateQuoteRequest, Response extends CreateQuoteResponse>({ responder, createQuoteRequestSchema, createQuoteResponseSchema, publicCreateQuoteRequestSchema, publicCreateQuoteResponseSchema, quotePort, acquisition, fallbackQuotePort, resolveCustomerEligibility, resolvePricingPolicy, createPromotionAcceptance, honorPromotionAcceptance, }: CommerceQuoteHandlerDeps<Request, Response>): (req: HttpRequest, res: HttpResponse) => Promise<void>;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { mapAcquisitionTermsFailure } from "./acquisitionQuoteBinding.js";
|
|
2
|
+
import { COMMERCE_CONTRACT_VERSION } from "./contracts/index.js";
|
|
3
|
+
import { CommerceQuoteError, } from "./quotePorts.js";
|
|
4
|
+
import { mapPricingPolicyFailure } from "./commercePricingPolicyErrors.js";
|
|
5
|
+
import { CommerceQuoteCatalogReadError } from "./commerceQuoteCatalogReadPort.js";
|
|
6
|
+
function commerceQuoteFailureDetails(stage) {
|
|
7
|
+
return { reason: "quote_dependency_failed", stage };
|
|
8
|
+
}
|
|
9
|
+
export function createCommerceQuoteHandler({ responder, createQuoteRequestSchema, createQuoteResponseSchema, publicCreateQuoteRequestSchema, publicCreateQuoteResponseSchema, quotePort, acquisition, fallbackQuotePort, resolveCustomerEligibility, resolvePricingPolicy, createPromotionAcceptance, honorPromotionAcceptance, }) {
|
|
10
|
+
const { sendBffError, sendBffSuccess, sendMethodNotAllowed } = responder;
|
|
11
|
+
return async function handler(req, res) {
|
|
12
|
+
if (req.method !== "POST") {
|
|
13
|
+
sendMethodNotAllowed(res, ["POST"]);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const publicRequest = publicCreateQuoteRequestSchema.safeParse(req.body);
|
|
17
|
+
if (!publicRequest.success) {
|
|
18
|
+
sendBffError(res, "BAD_REQUEST", "Invalid commerce quote request", {
|
|
19
|
+
details: publicRequest.error.flatten(),
|
|
20
|
+
});
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const { promotionAcceptanceToken, ...canonicalInput } = publicRequest.data;
|
|
24
|
+
const request = createQuoteRequestSchema.safeParse(canonicalInput);
|
|
25
|
+
if (!request.success) {
|
|
26
|
+
sendBffError(res, "BAD_REQUEST", "Invalid commerce quote request");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
let stage = "customer_eligibility";
|
|
30
|
+
try {
|
|
31
|
+
const eligibility = resolveCustomerEligibility
|
|
32
|
+
? await resolveCustomerEligibility(request.data)
|
|
33
|
+
: { clientId: null, source: "anonymous" };
|
|
34
|
+
console.info("commerce_quote_promo_eligibility_context", JSON.stringify({ promoEligibilityContext: eligibility.source }));
|
|
35
|
+
stage = "pricing_policy";
|
|
36
|
+
const pricingPolicy = await resolvePricingPolicy?.(request.data);
|
|
37
|
+
stage = "quote_evaluation";
|
|
38
|
+
const rawQuote = await quotePort.createQuote(request.data, {
|
|
39
|
+
clientId: eligibility.clientId,
|
|
40
|
+
...(pricingPolicy ? { pricingPolicy } : {}),
|
|
41
|
+
});
|
|
42
|
+
const canonicalQuote = createQuoteResponseSchema.safeParse(rawQuote);
|
|
43
|
+
if (!canonicalQuote.success) {
|
|
44
|
+
sendBffError(res, "INVALID_RESPONSE", "Commerce quote returned invalid response");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
let quote = canonicalQuote.data;
|
|
48
|
+
stage = "promotion_acceptance";
|
|
49
|
+
const acquisitionTerms = acquisition?.terms(quote.quote);
|
|
50
|
+
const honoredToken = promotionAcceptanceToken && honorPromotionAcceptance?.(promotionAcceptanceToken, request.data, quote.quote, acquisitionTerms) ? promotionAcceptanceToken : undefined;
|
|
51
|
+
const issuedToken = honoredToken ?? createPromotionAcceptance?.(request.data, quote.quote, acquisitionTerms) ?? undefined;
|
|
52
|
+
const containsV2Promotion = quote.quote.discounts.some((discount) => discount.promotionEngineVersion === "promotion-engine.v2");
|
|
53
|
+
if ((containsV2Promotion || acquisitionTerms) && !issuedToken) {
|
|
54
|
+
stage = "promotion_fallback";
|
|
55
|
+
const fallback = fallbackQuotePort
|
|
56
|
+
? createQuoteResponseSchema.safeParse(await fallbackQuotePort.createQuote(request.data, {
|
|
57
|
+
clientId: eligibility.clientId,
|
|
58
|
+
...(pricingPolicy ? { pricingPolicy } : {}),
|
|
59
|
+
}))
|
|
60
|
+
: null;
|
|
61
|
+
if (!fallback?.success || acquisition?.terms(fallback.data.quote) || fallback.data.quote.discounts.some((discount) => discount.promotionEngineVersion === "promotion-engine.v2")) {
|
|
62
|
+
sendBffError(res, "CONFLICT", "Promotion quote must be refreshed", {
|
|
63
|
+
details: { feature: "quote", reason: "promotion_acceptance_refresh_required" },
|
|
64
|
+
});
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
quote = fallback.data;
|
|
68
|
+
}
|
|
69
|
+
const response = publicCreateQuoteResponseSchema.safeParse({
|
|
70
|
+
...quote,
|
|
71
|
+
promotionAcceptanceToken: quote === canonicalQuote.data ? issuedToken : undefined,
|
|
72
|
+
});
|
|
73
|
+
if (!response.success) {
|
|
74
|
+
sendBffError(res, "INVALID_RESPONSE", "Commerce quote returned invalid response");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
sendBffSuccess(res, response.data, {
|
|
78
|
+
contractVersion: COMMERCE_CONTRACT_VERSION,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const acquisitionFailure = acquisition ? mapAcquisitionTermsFailure(error) : null;
|
|
83
|
+
if (acquisitionFailure) {
|
|
84
|
+
sendBffError(res, acquisitionFailure.code, "Acquisition terms unavailable", { details: acquisitionFailure.details });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (error instanceof CommerceQuoteCatalogReadError) {
|
|
88
|
+
sendBffError(res, "UPSTREAM_UNAVAILABLE", "Commerce catalog is unavailable", {
|
|
89
|
+
details: { reason: "catalog_unavailable", refusalCode: error.code },
|
|
90
|
+
});
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (error instanceof CommerceQuoteError) {
|
|
94
|
+
sendBffError(res, error.code === "UNKNOWN_SKU" ? "BAD_REQUEST" : "CONFLICT", error.message, { details: error.details });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const policyFailure = stage === "pricing_policy" ? mapPricingPolicyFailure(error) : null;
|
|
98
|
+
if (policyFailure) {
|
|
99
|
+
console.error("[commerce-quote] pricing policy refused:", JSON.stringify(policyFailure.details));
|
|
100
|
+
sendBffError(res, policyFailure.code, policyFailure.code === "BAD_REQUEST"
|
|
101
|
+
? "Commerce quote request is missing offer policy context"
|
|
102
|
+
: "Commerce quote failed", { details: policyFailure.details });
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const details = commerceQuoteFailureDetails(stage);
|
|
106
|
+
console.error("[commerce-quote] dependency failed:", JSON.stringify(details));
|
|
107
|
+
sendBffError(res, "UPSTREAM_UNAVAILABLE", "Commerce quote failed", { details });
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import { type CommerceQuotePort } from "./quotePorts.js";
|
|
3
|
+
export interface QuoteSnapshotExpectMessages {
|
|
4
|
+
/** Thrown when the re-quoted response fails schema validation. */
|
|
5
|
+
invalidResponseMessage: string;
|
|
6
|
+
/** Thrown when re-quoting raises a CommerceQuoteError (pricing changed). */
|
|
7
|
+
catalogMismatchMessage: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function createExpectedQuote<Request, Response>(quotePort: CommerceQuotePort<Request, Response>, request: Request, messages: QuoteSnapshotExpectMessages, createQuoteResponseSchema: z.ZodType<Response>): Promise<Response>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CommerceQuoteError, CommerceQuoteSnapshotError, } from "./quotePorts.js";
|
|
2
|
+
export async function createExpectedQuote(quotePort, request, messages, createQuoteResponseSchema) {
|
|
3
|
+
try {
|
|
4
|
+
const expected = await quotePort.createQuote(request);
|
|
5
|
+
const parsed = createQuoteResponseSchema.safeParse(expected);
|
|
6
|
+
if (!parsed.success) {
|
|
7
|
+
throw new CommerceQuoteSnapshotError("QUOTE_SNAPSHOT_MISMATCH", messages.invalidResponseMessage, { reason: "invalid_expected_quote" });
|
|
8
|
+
}
|
|
9
|
+
return parsed.data;
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
if (error instanceof CommerceQuoteSnapshotError)
|
|
13
|
+
throw error;
|
|
14
|
+
if (error instanceof CommerceQuoteError) {
|
|
15
|
+
throw new CommerceQuoteSnapshotError("QUOTE_SNAPSHOT_MISMATCH", messages.catalogMismatchMessage, {
|
|
16
|
+
reason: error.code,
|
|
17
|
+
...error.details,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Opt-in protocol identity; financial schedules belong to the injected policy. */
|
|
2
|
+
export declare const ACQUISITION_TERMS_CAPABILITY: "subscription-acquisition.v1";
|
|
3
|
+
export type AcquisitionCapability = typeof ACQUISITION_TERMS_CAPABILITY;
|
|
4
|
+
export interface AcquisitionTermsMetadata {
|
|
5
|
+
schemaVersion: AcquisitionCapability;
|
|
6
|
+
revision: string;
|
|
7
|
+
delivery2DiscountBps: number;
|
|
8
|
+
}
|
|
9
|
+
export interface AcquisitionTerms extends AcquisitionTermsMetadata {
|
|
10
|
+
initialDiscountBps: number;
|
|
11
|
+
effectiveFrom: string;
|
|
12
|
+
effectiveTo: string | null;
|
|
13
|
+
}
|
|
14
|
+
export interface ResolvedAcquisitionTerms extends AcquisitionTerms {
|
|
15
|
+
sourcePromotionId: string;
|
|
16
|
+
}
|
|
17
|
+
export interface AcquisitionTermsExpectation {
|
|
18
|
+
revision: string;
|
|
19
|
+
delivery2DiscountBps: number;
|
|
20
|
+
}
|
|
21
|
+
import type { CreateQuoteRequest, CommerceQuoteContext, CommerceQuote } from "./quote.js";
|
|
22
|
+
/** Separate opt-in DTOs; incumbent request/response admission is unchanged. */
|
|
23
|
+
export interface AcquisitionQuoteRequest extends CreateQuoteRequest {
|
|
24
|
+
acquisitionCapability?: AcquisitionCapability;
|
|
25
|
+
}
|
|
26
|
+
export interface AcquisitionQuoteContext extends CommerceQuoteContext {
|
|
27
|
+
acquisitionCapability?: AcquisitionCapability;
|
|
28
|
+
atTime?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface AcquisitionQuote extends CommerceQuote {
|
|
31
|
+
acquisitionTerms?: ResolvedAcquisitionTerms;
|
|
32
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ResolvedPrice } from "@openlup/core/pricing";
|
|
2
|
+
import type { SubscriptionPricePolicyRevision } from "./policy.js";
|
|
3
|
+
/** Exact settlement context for a current quote price; tiers and open-mode fallbacks are excluded. */
|
|
4
|
+
export interface CommercePriceAuthorityQuery {
|
|
5
|
+
variantId: string;
|
|
6
|
+
mode: "one_time" | "subscription";
|
|
7
|
+
regionCode: string;
|
|
8
|
+
currency: string;
|
|
9
|
+
channel: string;
|
|
10
|
+
atTime?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface CommerceBasePriceObservation {
|
|
13
|
+
/** The sole active/effective `one_time`, `min_qty=1` entry. */
|
|
14
|
+
base: ResolvedPrice;
|
|
15
|
+
unitPriceMinor: number;
|
|
16
|
+
}
|
|
17
|
+
export type CommercePriceAuthorityResult = (CommerceBasePriceObservation & {
|
|
18
|
+
kind: "one_time";
|
|
19
|
+
}) | (CommerceBasePriceObservation & {
|
|
20
|
+
kind: "subscription_policy";
|
|
21
|
+
policy: SubscriptionPricePolicyRevision;
|
|
22
|
+
}) | (CommerceBasePriceObservation & {
|
|
23
|
+
/** Explicit compatibility observation allowed only before this context has policy history. */
|
|
24
|
+
kind: "subscription_legacy";
|
|
25
|
+
legacyResolved: ResolvedPrice;
|
|
26
|
+
});
|
|
27
|
+
export type CommercePriceAuthorityRefusal = "active_price_list_not_found" | "active_price_list_ambiguous" | "base_price_not_found" | "base_price_ambiguous" | "base_price_amount_kind_invalid" | "legacy_subscription_price_not_found" | "legacy_subscription_price_ambiguous" | "subscription_price_policy_not_effective" | "subscription_price_policy_ambiguous" | "subscription_price_policy_invalid" | "subscription_price_policy_digest_mismatch";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** UI-safe, additive explanation for a frozen `codeRejections` item. */
|
|
2
|
+
export type CommerceCodeRejectionDetail = {
|
|
3
|
+
code: string;
|
|
4
|
+
reason: "scope_not_applicable";
|
|
5
|
+
allowedScopes: Array<"one_time" | "subscription_initial">;
|
|
6
|
+
} | {
|
|
7
|
+
code: string;
|
|
8
|
+
reason: "minimum_not_met";
|
|
9
|
+
minimumReferenceMinor: number;
|
|
10
|
+
} | {
|
|
11
|
+
code: string;
|
|
12
|
+
reason: "not_yet_active";
|
|
13
|
+
validFrom: string;
|
|
14
|
+
} | {
|
|
15
|
+
code: string;
|
|
16
|
+
reason: "global_limit_reached";
|
|
17
|
+
};
|
|
18
|
+
export interface QuotePromotionEvidence {
|
|
19
|
+
promotionId: string;
|
|
20
|
+
code?: string | null;
|
|
21
|
+
reasonCode: string;
|
|
22
|
+
promotionEngineVersion?: "promotion-engine.v2";
|
|
23
|
+
promotionCodeId?: string;
|
|
24
|
+
promotionCodeRevision?: number;
|
|
25
|
+
promotionDefinitionFingerprint?: string;
|
|
26
|
+
promotionCodeScopes?: Array<"one_time" | "subscription_initial">;
|
|
27
|
+
promotionMinimumReferenceMinor?: number;
|
|
28
|
+
promotionCodeValidTo?: string | null;
|
|
29
|
+
promotionBenefitKind?: "target_percentage" | "percentage" | "fixed_amount" | "free_shipping";
|
|
30
|
+
promotionBenefitValueBps?: number;
|
|
31
|
+
promotionBenefitValueMinor?: number;
|
|
32
|
+
floorApplied?: boolean;
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type { CommercePriceAuthorityQuery, CommerceBasePriceObservation, CommercePriceAuthorityResult, CommercePriceAuthorityRefusal } from "./authority.js";
|
|
2
|
+
export { SUBSCRIPTION_PRICE_POLICY_SCHEMA_VERSION, SUBSCRIPTION_PRICE_POLICY_DEFAULT_DISCOUNT_BPS, SUBSCRIPTION_PRICE_POLICY_DEFAULT_QUANTUM_MINOR } from "./policy.js";
|
|
3
|
+
export type { SubscriptionPricePolicySemantics, SubscriptionPricePolicyCanonicalInput, SubscriptionPricePolicyRevision, SubscriptionPricePolicyDigestRefusal } from "./policy.js";
|
|
4
|
+
export { OFFER_POLICY_V1, OFFER_POLICY_V2, PROMOTION_ENGINE_V1, PROMOTION_ENGINE_V2, OFFER_POLICY_V2_CAPABILITY } from "./offerPolicy.js";
|
|
5
|
+
export type { OfferPolicyVersion, PromotionEngineVersion, PricingPolicyRequest, PricingPolicySnapshot } from "./offerPolicy.js";
|
|
6
|
+
export type { CommerceCurrency, CommerceTaxCountry, CommerceTaxCategory, CommerceTaxLegalBasis, CommerceMoney, CartLineInput, CommerceTaxProfile, CommerceTaxBreakdown } from "./money.js";
|
|
7
|
+
export { COMMERCE_CONTRACT_VERSION } from "./quote.js";
|
|
8
|
+
export type { CommerceQuotePricingComponent, CommerceQuoteContext, CommerceQuoteLine, CommercePromotionCustomerSemantic, CommerceQuoteDiscount, CommerceCodeRejectionReason, CommerceCodeRejection, CommerceQuote, CreateQuoteRequest, CreateQuoteResponse } from "./quote.js";
|
|
9
|
+
export type { QuotePromotionEvidence, CommerceCodeRejectionDetail } from "./evidence.js";
|
|
10
|
+
export { CATALOG_FACTS_PROVENANCE_VERSION, CATALOG_FACTS_POLICY_PROVENANCE_VERSION } from "./provenance.js";
|
|
11
|
+
export type { CatalogFactsProvenance } from "./provenance.js";
|
|
12
|
+
export { COMMERCE_OFFER_PRICING_CONTRACT_VERSION, COMMERCE_OFFER_PRICING_V2_CONTRACT_VERSION } from "./offer.js";
|
|
13
|
+
export type { CommerceOfferPrice, CommerceProductOfferPricing, CommerceOfferPricingResponse } from "./offer.js";
|
|
14
|
+
export { ACQUISITION_TERMS_CAPABILITY } from "./acquisitionTerms.js";
|
|
15
|
+
export type { AcquisitionQuoteRequest, AcquisitionQuoteContext, AcquisitionQuote, AcquisitionCapability, AcquisitionTermsMetadata, AcquisitionTerms, ResolvedAcquisitionTerms, AcquisitionTermsExpectation } from "./acquisitionTerms.js";
|
|
16
|
+
export { COMMERCE_OFFER_PRICING_V3_CONTRACT_VERSION } from "./offer.js";
|
|
17
|
+
export type { AcquisitionOfferPricingResponse } from "./offer.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { SUBSCRIPTION_PRICE_POLICY_SCHEMA_VERSION, SUBSCRIPTION_PRICE_POLICY_DEFAULT_DISCOUNT_BPS, SUBSCRIPTION_PRICE_POLICY_DEFAULT_QUANTUM_MINOR } from "./policy.js";
|
|
2
|
+
export { OFFER_POLICY_V1, OFFER_POLICY_V2, PROMOTION_ENGINE_V1, PROMOTION_ENGINE_V2, OFFER_POLICY_V2_CAPABILITY } from "./offerPolicy.js";
|
|
3
|
+
export { COMMERCE_CONTRACT_VERSION } from "./quote.js";
|
|
4
|
+
export { CATALOG_FACTS_PROVENANCE_VERSION, CATALOG_FACTS_POLICY_PROVENANCE_VERSION } from "./provenance.js";
|
|
5
|
+
export { COMMERCE_OFFER_PRICING_CONTRACT_VERSION, COMMERCE_OFFER_PRICING_V2_CONTRACT_VERSION } from "./offer.js";
|
|
6
|
+
export { ACQUISITION_TERMS_CAPABILITY } from "./acquisitionTerms.js";
|
|
7
|
+
export { COMMERCE_OFFER_PRICING_V3_CONTRACT_VERSION } from "./offer.js";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type CommerceCurrency = string;
|
|
2
|
+
export type CommerceTaxCountry = string;
|
|
3
|
+
export type CommerceTaxCategory = string;
|
|
4
|
+
export type CommerceTaxLegalBasis = string;
|
|
5
|
+
export interface CommerceMoney {
|
|
6
|
+
amountMinor: number;
|
|
7
|
+
currency: CommerceCurrency;
|
|
8
|
+
}
|
|
9
|
+
export interface CartLineInput {
|
|
10
|
+
sku: string;
|
|
11
|
+
quantity: number;
|
|
12
|
+
variantId?: string;
|
|
13
|
+
modeAtLine?: "one_time" | "subscription";
|
|
14
|
+
isAddon?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface CommerceTaxProfile {
|
|
17
|
+
included: true;
|
|
18
|
+
country: CommerceTaxCountry;
|
|
19
|
+
category: CommerceTaxCategory;
|
|
20
|
+
vatRateBps: number;
|
|
21
|
+
legalBasis: CommerceTaxLegalBasis;
|
|
22
|
+
}
|
|
23
|
+
export interface CommerceTaxBreakdown extends CommerceTaxProfile {
|
|
24
|
+
netAmount: CommerceMoney;
|
|
25
|
+
vatAmount: CommerceMoney;
|
|
26
|
+
grossAmount: CommerceMoney;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { CommerceMoney } from "./money.js";
|
|
2
|
+
import type { PricingPolicySnapshot } from "./offerPolicy.js";
|
|
3
|
+
export declare const COMMERCE_OFFER_PRICING_CONTRACT_VERSION: "commerce.offer-pricing.v1";
|
|
4
|
+
export declare const COMMERCE_OFFER_PRICING_V2_CONTRACT_VERSION: "commerce.offer-pricing.v2";
|
|
5
|
+
export interface CommerceOfferPrice {
|
|
6
|
+
packageGross: CommerceMoney;
|
|
7
|
+
unitGross: CommerceMoney;
|
|
8
|
+
}
|
|
9
|
+
export interface CommerceProductOfferPricing {
|
|
10
|
+
productSlug: string;
|
|
11
|
+
unitCount: number;
|
|
12
|
+
oneTime: CommerceOfferPrice;
|
|
13
|
+
subscriptionInitial: CommerceOfferPrice;
|
|
14
|
+
subscriptionRecurring: CommerceOfferPrice;
|
|
15
|
+
catalogAnchorUnitGross: CommerceMoney;
|
|
16
|
+
initialDiscountPercent: number;
|
|
17
|
+
recurringDiscountPercent: number;
|
|
18
|
+
}
|
|
19
|
+
export type CommerceOfferPricingResponse<ScopeV1 extends string = string, ScopeV2 extends string = string> = {
|
|
20
|
+
contractVersion: typeof COMMERCE_OFFER_PRICING_CONTRACT_VERSION;
|
|
21
|
+
scope: ScopeV1;
|
|
22
|
+
products: CommerceProductOfferPricing[];
|
|
23
|
+
minimum: {
|
|
24
|
+
oneTime: CommerceProductOfferPricing;
|
|
25
|
+
subscription: CommerceProductOfferPricing;
|
|
26
|
+
};
|
|
27
|
+
} | {
|
|
28
|
+
contractVersion: typeof COMMERCE_OFFER_PRICING_V2_CONTRACT_VERSION;
|
|
29
|
+
scope: ScopeV2;
|
|
30
|
+
products: CommerceProductOfferPricing[];
|
|
31
|
+
minimum: {
|
|
32
|
+
oneTime: CommerceProductOfferPricing;
|
|
33
|
+
subscription: CommerceProductOfferPricing;
|
|
34
|
+
};
|
|
35
|
+
pricingPolicy: PricingPolicySnapshot;
|
|
36
|
+
shipping: {
|
|
37
|
+
gross: CommerceMoney;
|
|
38
|
+
discountGross: CommerceMoney;
|
|
39
|
+
payable: CommerceMoney;
|
|
40
|
+
};
|
|
41
|
+
minimumProductPayable: CommerceMoney;
|
|
42
|
+
};
|
|
43
|
+
/** Complete opt-in v3 response; the incumbent v1/v2 union stays unchanged. */
|
|
44
|
+
export declare const COMMERCE_OFFER_PRICING_V3_CONTRACT_VERSION: "commerce.offer-pricing.v3";
|
|
45
|
+
export type AcquisitionOfferPricingResponse<ScopeV2 extends string = string> = Omit<Extract<CommerceOfferPricingResponse<string, ScopeV2>, {
|
|
46
|
+
contractVersion: typeof COMMERCE_OFFER_PRICING_V2_CONTRACT_VERSION;
|
|
47
|
+
}>, "contractVersion"> & {
|
|
48
|
+
contractVersion: typeof COMMERCE_OFFER_PRICING_V3_CONTRACT_VERSION;
|
|
49
|
+
acquisitionTerms: import("./acquisitionTerms.js").AcquisitionTerms;
|
|
50
|
+
observedAt: string;
|
|
51
|
+
validUntil: string;
|
|
52
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export const COMMERCE_OFFER_PRICING_CONTRACT_VERSION = "commerce.offer-pricing.v1";
|
|
2
|
+
export const COMMERCE_OFFER_PRICING_V2_CONTRACT_VERSION = "commerce.offer-pricing.v2";
|
|
3
|
+
/** Complete opt-in v3 response; the incumbent v1/v2 union stays unchanged. */
|
|
4
|
+
export const COMMERCE_OFFER_PRICING_V3_CONTRACT_VERSION = "commerce.offer-pricing.v3";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const OFFER_POLICY_V1: "commerce.offer-policy.v1";
|
|
2
|
+
export declare const OFFER_POLICY_V2: "commerce.offer-policy.v2";
|
|
3
|
+
export declare const PROMOTION_ENGINE_V1: "promotion-engine.v1";
|
|
4
|
+
export declare const PROMOTION_ENGINE_V2: "promotion-engine.v2";
|
|
5
|
+
export declare const OFFER_POLICY_V2_CAPABILITY: "commerce.offer-policy.v2";
|
|
6
|
+
export type OfferPolicyVersion = typeof OFFER_POLICY_V1 | typeof OFFER_POLICY_V2;
|
|
7
|
+
export type PromotionEngineVersion = typeof PROMOTION_ENGINE_V1 | typeof PROMOTION_ENGINE_V2;
|
|
8
|
+
export interface PricingPolicyRequest {
|
|
9
|
+
capability?: typeof OFFER_POLICY_V2_CAPABILITY;
|
|
10
|
+
token?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface PricingPolicySnapshot {
|
|
13
|
+
offerPolicyVersion: OfferPolicyVersion;
|
|
14
|
+
promotionEngineVersion: PromotionEngineVersion;
|
|
15
|
+
pricingPolicyToken?: string;
|
|
16
|
+
}
|