@openlup/platform 0.26.0 → 0.28.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 +305 -327
- package/README.md +332 -16
- package/dist/account-support/accountReadFacade.d.ts +8 -0
- package/dist/account-support/accountReadFacade.js +10 -0
- package/dist/account-support/accountReadModels.d.ts +69 -0
- package/dist/account-support/accountReadModels.js +272 -0
- package/dist/account-support/bindings.d.ts +23 -0
- package/dist/account-support/bindings.js +16 -0
- package/dist/account-support/contracts/account.d.ts +281 -0
- package/dist/account-support/contracts/account.js +1 -0
- package/dist/account-support/contracts/capabilities.d.ts +44 -0
- package/dist/account-support/contracts/capabilities.js +1 -0
- package/dist/account-support/contracts/commands.d.ts +307 -0
- package/dist/account-support/contracts/commands.js +1 -0
- package/dist/account-support/contracts/customer360.d.ts +154 -0
- package/dist/account-support/contracts/customer360.js +1 -0
- package/dist/account-support/contracts/index.d.ts +10 -0
- package/dist/account-support/contracts/index.js +1 -0
- package/dist/account-support/contracts/invoice.d.ts +79 -0
- package/dist/account-support/contracts/invoice.js +1 -0
- package/dist/account-support/contracts/operator.d.ts +289 -0
- package/dist/account-support/contracts/operator.js +1 -0
- package/dist/account-support/contribution.d.ts +24 -0
- package/dist/account-support/contribution.js +22 -0
- package/dist/account-support/customer360.d.ts +106 -0
- package/dist/account-support/customer360.js +163 -0
- package/dist/account-support/customerAccountReadDiagnostics.d.ts +11 -0
- package/dist/account-support/customerAccountReadDiagnostics.js +71 -0
- package/dist/account-support/index.d.ts +26 -0
- package/dist/account-support/index.js +15 -0
- package/dist/account-support/invoiceAccess.d.ts +57 -0
- package/dist/account-support/invoiceAccess.js +40 -0
- package/dist/account-support/migrations.d.ts +14 -0
- package/dist/account-support/migrations.js +7 -0
- package/dist/account-support/operatorAuthority.d.ts +67 -0
- package/dist/account-support/operatorAuthority.js +379 -0
- package/dist/account-support/operatorRecovery.d.ts +66 -0
- package/dist/account-support/operatorRecovery.js +129 -0
- package/dist/account-support/orderHistory.d.ts +50 -0
- package/dist/account-support/orderHistory.js +188 -0
- package/dist/account-support/paymentMethodComposition.d.ts +5 -0
- package/dist/account-support/paymentMethodComposition.js +4 -0
- package/dist/account-support/postgresOperatorAuthority.d.ts +16 -0
- package/dist/account-support/postgresOperatorAuthority.js +93 -0
- package/dist/account-support/selfService.d.ts +6 -0
- package/dist/account-support/selfService.js +81 -0
- package/dist/account-support/subscriptionCommandCodec.d.ts +10 -0
- package/dist/account-support/subscriptionCommandCodec.js +38 -0
- package/dist/catalog/draftSchemas.d.ts +1 -1
- package/dist/catalog/foundationSchemas.d.ts +3 -3
- package/dist/catalog/resolvedSkuProjection.d.ts +2 -2
- package/dist/catalog/sellableSchemas.d.ts +2 -2
- package/dist/commerce/adapters/managed/commerceOmsControlPlane.d.ts +3 -0
- package/dist/commerce/adapters/managed/commerceOmsControlPlane.js +71 -0
- package/dist/commerce/adapters/managed/commerceOmsMutations.d.ts +10 -0
- package/dist/commerce/adapters/managed/commerceOmsMutations.js +119 -0
- package/dist/commerce/adapters/managed/commerceOmsPort.d.ts +28 -0
- package/dist/commerce/adapters/managed/commerceOmsPort.js +101 -0
- package/dist/commerce/adapters/managed/oms/accounting.d.ts +3 -0
- package/dist/commerce/adapters/managed/oms/accounting.js +13 -0
- package/dist/commerce/adapters/managed/oms/fulfillmentReads.d.ts +17 -0
- package/dist/commerce/adapters/managed/oms/fulfillmentReads.js +81 -0
- package/dist/commerce/adapters/managed/oms/inboundEvents.d.ts +9 -0
- package/dist/commerce/adapters/managed/oms/inboundEvents.js +40 -0
- package/dist/commerce/adapters/managed/oms/outboxEvents.d.ts +2 -0
- package/dist/commerce/adapters/managed/oms/outboxEvents.js +23 -0
- package/dist/commerce/adapters/managed/oms/paymentAttempts.d.ts +3 -0
- package/dist/commerce/adapters/managed/oms/paymentAttempts.js +15 -0
- package/dist/commerce/adapters/managed/oms/queueSelection.d.ts +12 -0
- package/dist/commerce/adapters/managed/oms/queueSelection.js +109 -0
- package/dist/commerce/adapters/managed/oms/readProjections.d.ts +18 -0
- package/dist/commerce/adapters/managed/oms/readProjections.js +13 -0
- package/dist/commerce/adapters/managed/oms/readQueries.d.ts +16 -0
- package/dist/commerce/adapters/managed/oms/readQueries.js +276 -0
- package/dist/commerce/adapters/managed/oms/types.d.ts +2 -0
- package/dist/commerce/adapters/managed/oms/types.js +7 -0
- package/dist/commerce/checkoutCommandSchemas.d.ts +89 -0
- package/dist/commerce/checkoutCommandSchemas.js +70 -0
- package/dist/commerce/checkoutHelpers.d.ts +21 -0
- package/dist/commerce/checkoutHelpers.js +29 -0
- package/dist/commerce/checkoutResumeSchemas.d.ts +158 -0
- package/dist/commerce/checkoutResumeSchemas.js +145 -0
- package/dist/commerce/checkoutSchemas.d.ts +158 -0
- package/dist/commerce/checkoutSchemas.js +161 -0
- package/dist/commerce/commerceReturnsPort.d.ts +97 -0
- package/dist/commerce/commerceReturnsPort.js +39 -0
- package/dist/commerce/configuratorIntentPersistenceSchemas.d.ts +20 -0
- package/dist/commerce/configuratorIntentPersistenceSchemas.js +21 -0
- package/dist/commerce/configuratorIntentSchemas.d.ts +63 -0
- package/dist/commerce/configuratorIntentSchemas.js +43 -0
- package/dist/commerce/contractPrimitives.d.ts +50 -0
- package/dist/commerce/contractPrimitives.js +25 -0
- package/dist/commerce/contracts/availability.d.ts +23 -0
- package/dist/commerce/contracts/availability.js +1 -0
- package/dist/commerce/contracts/fulfillmentRecovery.d.ts +25 -0
- package/dist/commerce/contracts/fulfillmentRecovery.js +1 -0
- package/dist/commerce/contracts/index.d.ts +13 -0
- package/dist/commerce/contracts/index.js +1 -0
- package/dist/commerce/contracts/intent.d.ts +86 -0
- package/dist/commerce/contracts/intent.js +1 -0
- package/dist/commerce/contracts/omsTypes.d.ts +1216 -0
- package/dist/commerce/contracts/omsTypes.js +1 -0
- package/dist/commerce/contracts/order.d.ts +39 -0
- package/dist/commerce/contracts/order.js +1 -0
- package/dist/commerce/contracts/orderMoney.d.ts +52 -0
- package/dist/commerce/contracts/orderMoney.js +1 -0
- package/dist/commerce/contracts/ports.d.ts +113 -0
- package/dist/commerce/contracts/ports.js +1 -0
- package/dist/commerce/contracts/recovery.d.ts +11 -0
- package/dist/commerce/contracts/recovery.js +1 -0
- package/dist/commerce/contracts/runtimePorts.d.ts +196 -0
- package/dist/commerce/contracts/runtimePorts.js +1 -0
- package/dist/commerce/contracts/state.d.ts +26 -0
- package/dist/commerce/contracts/state.js +43 -0
- package/dist/commerce/customerDefaultsSnapshotSchemas.d.ts +51 -0
- package/dist/commerce/customerDefaultsSnapshotSchemas.js +106 -0
- package/dist/commerce/errors.d.ts +18 -0
- package/dist/commerce/errors.js +36 -0
- package/dist/commerce/fulfillmentEligibility.d.ts +6 -0
- package/dist/commerce/fulfillmentEligibility.js +31 -0
- package/dist/commerce/index.d.ts +72 -0
- package/dist/commerce/index.js +67 -0
- package/dist/commerce/model/customerFulfillmentRecovery.d.ts +40 -0
- package/dist/commerce/model/customerFulfillmentRecovery.js +144 -0
- package/dist/commerce/model/fulfillmentCancellationEligibility.d.ts +7 -0
- package/dist/commerce/model/fulfillmentCancellationEligibility.js +9 -0
- package/dist/commerce/model/omsAccountingVisibility.d.ts +12 -0
- package/dist/commerce/model/omsAccountingVisibility.js +118 -0
- package/dist/commerce/model/omsBillingInvoiceBuyer.d.ts +2 -0
- package/dist/commerce/model/omsBillingInvoiceBuyer.js +15 -0
- package/dist/commerce/model/omsCurrency.d.ts +4 -0
- package/dist/commerce/model/omsCurrency.js +5 -0
- package/dist/commerce/model/omsFulfillmentDebug.d.ts +20 -0
- package/dist/commerce/model/omsFulfillmentDebug.js +122 -0
- package/dist/commerce/model/omsFulfillmentSummary.d.ts +16 -0
- package/dist/commerce/model/omsFulfillmentSummary.js +189 -0
- package/dist/commerce/model/omsListTotals.d.ts +13 -0
- package/dist/commerce/model/omsListTotals.js +32 -0
- package/dist/commerce/model/omsOperationalLadder.d.ts +51 -0
- package/dist/commerce/model/omsOperationalLadder.js +158 -0
- package/dist/commerce/model/omsOrderLineMoney.d.ts +4 -0
- package/dist/commerce/model/omsOrderLineMoney.js +25 -0
- package/dist/commerce/model/omsPaymentMethodSummary.d.ts +5 -0
- package/dist/commerce/model/omsPaymentMethodSummary.js +11 -0
- package/dist/commerce/model/omsReadModel.d.ts +43 -0
- package/dist/commerce/model/omsReadModel.js +211 -0
- package/dist/commerce/model/omsReadModelCommunication.d.ts +3 -0
- package/dist/commerce/model/omsReadModelCommunication.js +29 -0
- package/dist/commerce/model/omsReadModelHelpers.d.ts +125 -0
- package/dist/commerce/model/omsReadModelHelpers.js +212 -0
- package/dist/commerce/model/omsReadModelList.d.ts +33 -0
- package/dist/commerce/model/omsReadModelList.js +50 -0
- package/dist/commerce/model/omsReadModelListSummary.d.ts +3 -0
- package/dist/commerce/model/omsReadModelListSummary.js +13 -0
- package/dist/commerce/model/omsReadModelPricing.d.ts +5 -0
- package/dist/commerce/model/omsReadModelPricing.js +36 -0
- package/dist/commerce/model/omsReadModelProjections.d.ts +1 -0
- package/dist/commerce/model/omsReadModelProjections.js +1 -0
- package/dist/commerce/model/omsReadModelRowCore.d.ts +79 -0
- package/dist/commerce/model/omsReadModelRowCore.js +149 -0
- package/dist/commerce/model/omsReadModelRows.d.ts +1 -0
- package/dist/commerce/model/omsReadModelRows.js +6 -0
- package/dist/commerce/offerAvailability.d.ts +18 -0
- package/dist/commerce/offerAvailability.js +53 -0
- package/dist/commerce/offerAvailabilitySchemas.d.ts +43 -0
- package/dist/commerce/offerAvailabilitySchemas.js +42 -0
- package/dist/commerce/offerEvidenceSchemas.d.ts +7 -0
- package/dist/commerce/offerEvidenceSchemas.js +13 -0
- package/dist/commerce/oms/omsContractBase.d.ts +130 -0
- package/dist/commerce/oms/omsContractBase.js +86 -0
- package/dist/commerce/oms/omsContractReadAuxSchemas.d.ts +222 -0
- package/dist/commerce/oms/omsContractReadAuxSchemas.js +123 -0
- package/dist/commerce/oms/omsContractReadSchemas.d.ts +2266 -0
- package/dist/commerce/oms/omsContractReadSchemas.js +277 -0
- package/dist/commerce/oms/omsContractRequests.d.ts +196 -0
- package/dist/commerce/oms/omsContractRequests.js +118 -0
- package/dist/commerce/oms/omsContracts.d.ts +5 -0
- package/dist/commerce/oms/omsContracts.js +4 -0
- package/dist/commerce/oms/omsControlPlane.d.ts +275 -0
- package/dist/commerce/oms/omsControlPlane.js +72 -0
- package/dist/commerce/oms/omsFulfillmentContractSchemas.d.ts +203 -0
- package/dist/commerce/oms/omsFulfillmentContractSchemas.js +94 -0
- package/dist/commerce/oms/omsFulfillmentDebugSchemas.d.ts +69 -0
- package/dist/commerce/oms/omsFulfillmentDebugSchemas.js +33 -0
- package/dist/commerce/oms/omsFulfillmentHealthSchemas.d.ts +67 -0
- package/dist/commerce/oms/omsFulfillmentHealthSchemas.js +44 -0
- package/dist/commerce/oms/omsPorts.d.ts +84 -0
- package/dist/commerce/oms/omsPorts.js +148 -0
- package/dist/commerce/oms/omsPrimitives.d.ts +5 -0
- package/dist/commerce/oms/omsPrimitives.js +3 -0
- package/dist/commerce/oms/omsProviderEvidenceSchemas.d.ts +15 -0
- package/dist/commerce/oms/omsProviderEvidenceSchemas.js +12 -0
- package/dist/commerce/orderDraftErrors.d.ts +13 -0
- package/dist/commerce/orderDraftErrors.js +20 -0
- package/dist/commerce/orderEmailEligibility.d.ts +54 -0
- package/dist/commerce/orderEmailEligibility.js +123 -0
- package/dist/commerce/orderEmailLines.d.ts +12 -0
- package/dist/commerce/orderEmailLines.js +8 -0
- package/dist/commerce/orderFeedbackContracts.d.ts +41 -0
- package/dist/commerce/orderFeedbackContracts.js +33 -0
- package/dist/commerce/orderMoney.d.ts +6 -0
- package/dist/commerce/orderMoney.js +168 -0
- package/dist/commerce/orderReviewContracts.d.ts +475 -0
- package/dist/commerce/orderReviewContracts.js +94 -0
- package/dist/commerce/orderReviewPorts.d.ts +140 -0
- package/dist/commerce/orderReviewPorts.js +1 -0
- package/dist/commerce/outboxDispatchContracts.d.ts +30 -0
- package/dist/commerce/outboxDispatchContracts.js +1 -0
- package/dist/commerce/outboxEventSchemas.d.ts +162 -0
- package/dist/commerce/outboxEventSchemas.js +164 -0
- package/dist/commerce/outboxOrderDraftEmailPorts.d.ts +207 -0
- package/dist/commerce/outboxOrderDraftEmailPorts.js +12 -0
- package/dist/commerce/paymentContinuation.d.ts +4 -0
- package/dist/commerce/paymentContinuation.js +4 -0
- package/dist/commerce/ports.d.ts +8 -0
- package/dist/commerce/ports.js +1 -0
- package/dist/commerce/recoveryDestination.d.ts +3 -0
- package/dist/commerce/recoveryDestination.js +17 -0
- package/dist/commerce/runtimeErrors.d.ts +8 -0
- package/dist/commerce/runtimeErrors.js +16 -0
- package/dist/commerce/salesChannelEnvelope.d.ts +20 -0
- package/dist/commerce/salesChannelEnvelope.js +7 -0
- package/dist/commerce/schemas.d.ts +174 -0
- package/dist/commerce/schemas.js +84 -0
- package/dist/commerce/server/checkoutCompensation.d.ts +21 -0
- package/dist/commerce/server/checkoutCompensation.js +32 -0
- package/dist/commerce/server/checkoutConflictClassifiers.d.ts +17 -0
- package/dist/commerce/server/checkoutConflictClassifiers.js +38 -0
- package/dist/commerce/server/checkoutExpiredRecoveryPolicy.d.ts +38 -0
- package/dist/commerce/server/checkoutExpiredRecoveryPolicy.js +85 -0
- package/dist/commerce/server/checkoutInvoiceBuyerSnapshot.d.ts +22 -0
- package/dist/commerce/server/checkoutInvoiceBuyerSnapshot.js +30 -0
- package/dist/commerce/server/checkoutOfferPolicyPort.d.ts +33 -0
- package/dist/commerce/server/checkoutOfferPolicyPort.js +49 -0
- package/dist/commerce/server/checkoutPaymentContinuationCredential.d.ts +58 -0
- package/dist/commerce/server/checkoutPaymentContinuationCredential.js +154 -0
- package/dist/commerce/server/checkoutQuoteTypes.d.ts +19 -0
- package/dist/commerce/server/checkoutQuoteTypes.js +1 -0
- package/dist/commerce/server/checkoutRecoveryOrderPort.d.ts +42 -0
- package/dist/commerce/server/checkoutRecoveryOrderPort.js +1 -0
- package/dist/commerce/server/checkoutRecoveryToken.d.ts +40 -0
- package/dist/commerce/server/checkoutRecoveryToken.js +26 -0
- package/dist/commerce/server/checkoutRefusalContinuation.d.ts +24 -0
- package/dist/commerce/server/checkoutRefusalContinuation.js +18 -0
- package/dist/commerce/server/checkoutRuntimeTypes.d.ts +81 -0
- package/dist/commerce/server/checkoutRuntimeTypes.js +1 -0
- package/dist/commerce/server/commerceCheckoutCommandExecution.d.ts +60 -0
- package/dist/commerce/server/commerceCheckoutCommandExecution.js +136 -0
- package/dist/commerce/server/commerceCheckoutCompensation.d.ts +26 -0
- package/dist/commerce/server/commerceCheckoutCompensation.js +46 -0
- package/dist/commerce/server/commerceCheckoutContinuationTerms.d.ts +50 -0
- package/dist/commerce/server/commerceCheckoutContinuationTerms.js +66 -0
- package/dist/commerce/server/commerceCheckoutCustomerDefaults.d.ts +18 -0
- package/dist/commerce/server/commerceCheckoutCustomerDefaults.js +17 -0
- package/dist/commerce/server/commerceCheckoutFailureHandler.d.ts +51 -0
- package/dist/commerce/server/commerceCheckoutFailureHandler.js +90 -0
- package/dist/commerce/server/commerceCheckoutHandler.d.ts +213 -0
- package/dist/commerce/server/commerceCheckoutHandler.js +196 -0
- package/dist/commerce/server/commerceCheckoutHandlerAdmission.d.ts +58 -0
- package/dist/commerce/server/commerceCheckoutHandlerAdmission.js +94 -0
- package/dist/commerce/server/commerceCheckoutHandlerHelpers.d.ts +67 -0
- package/dist/commerce/server/commerceCheckoutHandlerHelpers.js +155 -0
- package/dist/commerce/server/commerceCheckoutOrchestrationError.d.ts +9 -0
- package/dist/commerce/server/commerceCheckoutOrchestrationError.js +14 -0
- package/dist/commerce/server/commerceCheckoutPromotionPriceChange.d.ts +47 -0
- package/dist/commerce/server/commerceCheckoutPromotionPriceChange.js +43 -0
- package/dist/commerce/server/commerceCheckoutProviderPayment.d.ts +34 -0
- package/dist/commerce/server/commerceCheckoutProviderPayment.js +37 -0
- package/dist/commerce/server/commerceCheckoutQuoteGuard.d.ts +62 -0
- package/dist/commerce/server/commerceCheckoutQuoteGuard.js +106 -0
- package/dist/commerce/server/commerceCheckoutResume.d.ts +29 -0
- package/dist/commerce/server/commerceCheckoutResume.js +81 -0
- package/dist/commerce/server/commerceCheckoutResumeGuard.d.ts +54 -0
- package/dist/commerce/server/commerceCheckoutResumeGuard.js +138 -0
- package/dist/commerce/server/commerceCheckoutSavedPaymentMethod.d.ts +39 -0
- package/dist/commerce/server/commerceCheckoutSavedPaymentMethod.js +44 -0
- package/dist/commerce/server/commerceCheckoutStartRuntimeFailure.d.ts +7 -0
- package/dist/commerce/server/commerceCheckoutStartRuntimeFailure.js +39 -0
- package/dist/commerce/server/commerceCheckoutTiming.d.ts +8 -0
- package/dist/commerce/server/commerceCheckoutTiming.js +31 -0
- package/dist/commerce/server/commerceDiagnostics.d.ts +6 -0
- package/dist/commerce/server/commerceDiagnostics.js +31 -0
- package/dist/commerce/server/commerceOmsCancelOrderHandler.d.ts +7 -0
- package/dist/commerce/server/commerceOmsCancelOrderHandler.js +22 -0
- package/dist/commerce/server/commerceOmsControlPlaneHandlers.d.ts +18 -0
- package/dist/commerce/server/commerceOmsControlPlaneHandlers.js +60 -0
- package/dist/commerce/server/commerceOmsHandlers.d.ts +47 -0
- package/dist/commerce/server/commerceOmsHandlers.js +176 -0
- package/dist/commerce/server/commerceOmsMarkRefundedHandler.d.ts +7 -0
- package/dist/commerce/server/commerceOmsMarkRefundedHandler.js +19 -0
- package/dist/commerce/server/commerceOrderDraft.d.ts +24 -0
- package/dist/commerce/server/commerceOrderDraft.js +92 -0
- package/dist/commerce/server/commercePaidOrderOrchestration.d.ts +131 -0
- package/dist/commerce/server/commercePaidOrderOrchestration.js +140 -0
- package/dist/commerce/server/commerceProviderAttemptFailure.d.ts +133 -0
- package/dist/commerce/server/commerceProviderAttemptFailure.js +175 -0
- package/dist/commerce/server/commerceReturnsHandlers.d.ts +41 -0
- package/dist/commerce/server/commerceReturnsHandlers.js +100 -0
- package/dist/commerce/server/commerceRuntimePort.d.ts +16 -0
- package/dist/commerce/server/commerceRuntimePort.js +57 -0
- package/dist/commerce/server/commerceRuntimeService.d.ts +98 -0
- package/dist/commerce/server/commerceRuntimeService.js +186 -0
- package/dist/commerce/server/commerceRuntimeStartResponse.d.ts +37 -0
- package/dist/commerce/server/commerceRuntimeStartResponse.js +56 -0
- package/dist/commerce/server/commerceStarterOfferGuard.d.ts +55 -0
- package/dist/commerce/server/commerceStarterOfferGuard.js +128 -0
- package/dist/commerce/server/configuratorIntentPersistence.d.ts +47 -0
- package/dist/commerce/server/configuratorIntentPersistence.js +85 -0
- package/dist/commerce/server/configuratorIntentPersistenceHandler.d.ts +14 -0
- package/dist/commerce/server/configuratorIntentPersistenceHandler.js +42 -0
- package/dist/commerce/server/emailRuntime.d.ts +47 -0
- package/dist/commerce/server/emailRuntime.js +1 -0
- package/dist/commerce/server/handlerSupport.d.ts +68 -0
- package/dist/commerce/server/handlerSupport.js +1 -0
- package/dist/commerce/server/index.d.ts +178 -0
- package/dist/commerce/server/index.js +127 -0
- package/dist/commerce/server/offerAvailability.d.ts +21 -0
- package/dist/commerce/server/offerAvailability.js +163 -0
- package/dist/commerce/server/orderDraftRpcPayload.d.ts +20 -0
- package/dist/commerce/server/orderDraftRpcPayload.js +21 -0
- package/dist/commerce/server/orderFeedbackSubmit.d.ts +20 -0
- package/dist/commerce/server/orderFeedbackSubmit.js +16 -0
- package/dist/commerce/server/orderFeedbackTokenCheck.d.ts +17 -0
- package/dist/commerce/server/orderFeedbackTokenCheck.js +14 -0
- package/dist/commerce/server/orderReviewAdminHandlers.d.ts +47 -0
- package/dist/commerce/server/orderReviewAdminHandlers.js +41 -0
- package/dist/commerce/server/orderReviewHandlers.d.ts +114 -0
- package/dist/commerce/server/orderReviewHandlers.js +42 -0
- package/dist/commerce/server/orderReviewLifecycle.d.ts +10 -0
- package/dist/commerce/server/orderReviewLifecycle.js +121 -0
- package/dist/commerce/server/orderReviewMedia.d.ts +11 -0
- package/dist/commerce/server/orderReviewMedia.js +172 -0
- package/dist/commerce/server/orderReviewRawUploadHandler.d.ts +40 -0
- package/dist/commerce/server/orderReviewRawUploadHandler.js +316 -0
- package/dist/commerce/server/outboxCheckoutExpiredEmailHandler.d.ts +14 -0
- package/dist/commerce/server/outboxCheckoutExpiredEmailHandler.js +57 -0
- package/dist/commerce/server/outboxCheckoutRecoveryEmailHandler.d.ts +13 -0
- package/dist/commerce/server/outboxCheckoutRecoveryEmailHandler.js +150 -0
- package/dist/commerce/server/outboxDispatchRegistry.d.ts +46 -0
- package/dist/commerce/server/outboxDispatchRegistry.js +184 -0
- package/dist/commerce/server/outboxDispatchRegistryComposition.d.ts +6 -0
- package/dist/commerce/server/outboxDispatchRegistryComposition.js +23 -0
- package/dist/commerce/server/outboxOrderDraftEmailHandler.d.ts +14 -0
- package/dist/commerce/server/outboxOrderDraftEmailHandler.js +130 -0
- package/dist/commerce/server/outboxOrderPaidEmailHandler.d.ts +21 -0
- package/dist/commerce/server/outboxOrderPaidEmailHandler.js +93 -0
- package/dist/commerce/server/outboxOrderPaidFulfillmentHandler.d.ts +3 -0
- package/dist/commerce/server/outboxOrderPaidFulfillmentHandler.js +1 -0
- package/dist/commerce/server/outboxOrderPaidFulfillmentPorts.d.ts +3 -0
- package/dist/commerce/server/outboxOrderPaidFulfillmentPorts.js +1 -0
- package/dist/commerce/server/outboxOrderRefundedEmailHandler.d.ts +13 -0
- package/dist/commerce/server/outboxOrderRefundedEmailHandler.js +42 -0
- package/dist/commerce/server/outboxPaymentFailedEmailHandler.d.ts +14 -0
- package/dist/commerce/server/outboxPaymentFailedEmailHandler.js +65 -0
- package/dist/commerce/server/outboxReturnEmailHandlers.d.ts +26 -0
- package/dist/commerce/server/outboxReturnEmailHandlers.js +53 -0
- package/dist/commerce/server/outboxShipmentDeliveredEmailHandler.d.ts +17 -0
- package/dist/commerce/server/outboxShipmentDeliveredEmailHandler.js +52 -0
- package/dist/commerce/server/outboxShipmentDispatchedEmailHandler.d.ts +13 -0
- package/dist/commerce/server/outboxShipmentDispatchedEmailHandler.js +87 -0
- package/dist/commerce/server/outboxShipmentExceptionEmailHandler.d.ts +13 -0
- package/dist/commerce/server/outboxShipmentExceptionEmailHandler.js +46 -0
- package/dist/commerce/server/referenceCheckoutHandler.d.ts +48 -0
- package/dist/commerce/server/referenceCheckoutHandler.js +68 -0
- package/dist/commerce/server/reservationSweepPort.d.ts +31 -0
- package/dist/commerce/server/reservationSweepPort.js +45 -0
- package/dist/commerce/server/starterTermsPort.d.ts +22 -0
- package/dist/commerce/server/starterTermsPort.js +1 -0
- package/dist/commerce/server/supabaseCommerceReturnsPort.d.ts +13 -0
- package/dist/commerce/server/supabaseCommerceReturnsPort.js +56 -0
- package/dist/communications/consentPurposeRegistry.d.ts +1 -1
- package/dist/communications/newsletterIntegrationContracts.d.ts +10 -10
- package/dist/composition/accountSupportContribution.d.ts +18 -0
- package/dist/composition/accountSupportContribution.js +21 -0
- package/dist/composition/commerceContribution.d.ts +21 -0
- package/dist/composition/commerceContribution.js +27 -0
- package/dist/composition/index.d.ts +2 -0
- package/dist/composition/index.js +2 -0
- package/dist/fulfillment/handlerSchemas.d.ts +69 -69
- package/dist/fulfillment/index.d.ts +1 -1
- package/dist/fulfillment/index.js +1 -1
- package/dist/fulfillment/paidHandoff.d.ts +12 -1
- package/dist/fulfillment/paidHandoff.js +2 -2
- package/dist/fulfillment/providerDispatchWorker.d.ts +4 -4
- package/dist/identity/customerContracts.d.ts +4 -4
- package/dist/inventory/bindings.d.ts +3 -0
- package/dist/inventory/bindings.js +10 -4
- package/dist/inventory/index.d.ts +1 -0
- package/dist/inventory/index.js +1 -0
- package/dist/inventory/managedStockAvailability.d.ts +15 -0
- package/dist/inventory/managedStockAvailability.js +16 -0
- package/dist/inventory/postgresStockAvailability.js +2 -25
- package/dist/inventory/schemas.d.ts +1 -1
- package/dist/inventory/stockReadResponse.d.ts +4 -0
- package/dist/inventory/stockReadResponse.js +27 -0
- package/dist/invoicing/snapshot.d.ts +1 -1
- package/dist/pricing/acquisitionQuoteBinding.d.ts +1 -1
- package/dist/pricing/browser/index.d.ts +6 -0
- package/dist/pricing/browser/index.js +6 -0
- package/dist/pricing/catalogFactsSchemas.d.ts +1 -1
- package/dist/pricing/quotePromotionEvidence.d.ts +1 -1
- package/dist/pricing/quoteSchemas.d.ts +56 -56
- package/dist/promotions/adminPromotionCodesContracts.d.ts +30 -30
- package/dist/promotions/adminPromotionsContracts.d.ts +16 -16
- package/dist/subscriptions/index.d.ts +3 -2
- package/dist/subscriptions/index.js +3 -2
- package/package.json +32 -2
- package/release-gates.json +90 -8
- package/sql/20261026120000_account_support_operator_authority.sql +693 -0
- package/src/account-support/accountReadFacade.ts +15 -0
- package/src/account-support/accountReadModels.ts +371 -0
- package/src/account-support/bindings.ts +28 -0
- package/src/account-support/contracts/account.ts +306 -0
- package/src/account-support/contracts/capabilities.ts +30 -0
- package/src/account-support/contracts/commands.ts +243 -0
- package/src/account-support/contracts/customer360.ts +150 -0
- package/src/account-support/contracts/index.ts +141 -0
- package/src/account-support/contracts/invoice.ts +44 -0
- package/src/account-support/contracts/operator.ts +123 -0
- package/src/account-support/contribution.ts +35 -0
- package/src/account-support/customer360.ts +268 -0
- package/src/account-support/customerAccountReadDiagnostics.ts +83 -0
- package/src/account-support/index.ts +72 -0
- package/src/account-support/invoiceAccess.ts +63 -0
- package/src/account-support/migrations.ts +7 -0
- package/src/account-support/operatorAuthority.ts +393 -0
- package/src/account-support/operatorRecovery.ts +136 -0
- package/src/account-support/orderHistory.ts +309 -0
- package/src/account-support/paymentMethodComposition.ts +8 -0
- package/src/account-support/postgresOperatorAuthority.ts +92 -0
- package/src/account-support/selfService.ts +83 -0
- package/src/account-support/subscriptionCommandCodec.ts +48 -0
- package/src/commerce/adapters/managed/commerceOmsControlPlane.ts +80 -0
- package/src/commerce/adapters/managed/commerceOmsMutations.ts +145 -0
- package/src/commerce/adapters/managed/commerceOmsPort.ts +158 -0
- package/src/commerce/adapters/managed/oms/accounting.ts +18 -0
- package/src/commerce/adapters/managed/oms/fulfillmentReads.ts +82 -0
- package/src/commerce/adapters/managed/oms/inboundEvents.ts +45 -0
- package/src/commerce/adapters/managed/oms/outboxEvents.ts +30 -0
- package/src/commerce/adapters/managed/oms/paymentAttempts.ts +19 -0
- package/src/commerce/adapters/managed/oms/queueSelection.ts +132 -0
- package/src/commerce/adapters/managed/oms/readProjections.ts +22 -0
- package/src/commerce/adapters/managed/oms/readQueries.ts +292 -0
- package/src/commerce/adapters/managed/oms/types.ts +9 -0
- package/src/commerce/checkoutCommandSchemas.ts +93 -0
- package/src/commerce/checkoutHelpers.ts +47 -0
- package/src/commerce/checkoutResumeSchemas.ts +164 -0
- package/src/commerce/checkoutSchemas.ts +182 -0
- package/src/commerce/commerceReturnsPort.ts +67 -0
- package/src/commerce/configuratorIntentPersistenceSchemas.ts +26 -0
- package/src/commerce/configuratorIntentSchemas.ts +47 -0
- package/src/commerce/contractPrimitives.ts +30 -0
- package/src/commerce/contracts/availability.ts +21 -0
- package/src/commerce/contracts/fulfillmentRecovery.ts +26 -0
- package/src/commerce/contracts/index.ts +17 -0
- package/src/commerce/contracts/intent.ts +58 -0
- package/src/commerce/contracts/omsTypes.ts +1217 -0
- package/src/commerce/contracts/order.ts +44 -0
- package/src/commerce/contracts/orderMoney.ts +75 -0
- package/src/commerce/contracts/ports.ts +124 -0
- package/src/commerce/contracts/recovery.ts +24 -0
- package/src/commerce/contracts/runtimePorts.ts +201 -0
- package/src/commerce/contracts/state.ts +64 -0
- package/src/commerce/customerDefaultsSnapshotSchemas.ts +117 -0
- package/src/commerce/errors.ts +53 -0
- package/src/commerce/fulfillmentEligibility.ts +32 -0
- package/src/commerce/index.ts +82 -0
- package/src/commerce/model/customerFulfillmentRecovery.ts +185 -0
- package/src/commerce/model/fulfillmentCancellationEligibility.ts +18 -0
- package/src/commerce/model/omsAccountingVisibility.ts +135 -0
- package/src/commerce/model/omsBillingInvoiceBuyer.ts +20 -0
- package/src/commerce/model/omsCurrency.ts +8 -0
- package/src/commerce/model/omsFulfillmentDebug.ts +157 -0
- package/src/commerce/model/omsFulfillmentSummary.ts +225 -0
- package/src/commerce/model/omsListTotals.ts +38 -0
- package/src/commerce/model/omsOperationalLadder.ts +181 -0
- package/src/commerce/model/omsOrderLineMoney.ts +34 -0
- package/src/commerce/model/omsPaymentMethodSummary.ts +19 -0
- package/src/commerce/model/omsReadModel.ts +302 -0
- package/src/commerce/model/omsReadModelCommunication.ts +32 -0
- package/src/commerce/model/omsReadModelHelpers.ts +279 -0
- package/src/commerce/model/omsReadModelList.ts +90 -0
- package/src/commerce/model/omsReadModelListSummary.ts +19 -0
- package/src/commerce/model/omsReadModelPricing.ts +57 -0
- package/src/commerce/model/omsReadModelProjections.ts +1 -0
- package/src/commerce/model/omsReadModelRowCore.ts +193 -0
- package/src/commerce/model/omsReadModelRows.ts +7 -0
- package/src/commerce/offerAvailability.ts +75 -0
- package/src/commerce/offerAvailabilitySchemas.ts +56 -0
- package/src/commerce/offerEvidenceSchemas.ts +17 -0
- package/src/commerce/oms/omsContractBase.ts +92 -0
- package/src/commerce/oms/omsContractReadAuxSchemas.ts +130 -0
- package/src/commerce/oms/omsContractReadSchemas.ts +303 -0
- package/src/commerce/oms/omsContractRequests.ts +143 -0
- package/src/commerce/oms/omsContracts.ts +6 -0
- package/src/commerce/oms/omsControlPlane.ts +85 -0
- package/src/commerce/oms/omsFulfillmentContractSchemas.ts +113 -0
- package/src/commerce/oms/omsFulfillmentDebugSchemas.ts +38 -0
- package/src/commerce/oms/omsFulfillmentHealthSchemas.ts +46 -0
- package/src/commerce/oms/omsPorts.ts +165 -0
- package/src/commerce/oms/omsPrimitives.ts +3 -0
- package/src/commerce/oms/omsProviderEvidenceSchemas.ts +13 -0
- package/src/commerce/orderDraftErrors.ts +28 -0
- package/src/commerce/orderEmailEligibility.ts +131 -0
- package/src/commerce/orderEmailLines.ts +22 -0
- package/src/commerce/orderFeedbackContracts.ts +47 -0
- package/src/commerce/orderMoney.ts +207 -0
- package/src/commerce/orderReviewContracts.ts +124 -0
- package/src/commerce/orderReviewPorts.ts +94 -0
- package/src/commerce/outboxDispatchContracts.ts +30 -0
- package/src/commerce/outboxEventSchemas.ts +230 -0
- package/src/commerce/outboxOrderDraftEmailPorts.ts +241 -0
- package/src/commerce/paymentContinuation.ts +5 -0
- package/src/commerce/ports.ts +7 -0
- package/src/commerce/recoveryDestination.ts +23 -0
- package/src/commerce/runtimeErrors.ts +19 -0
- package/src/commerce/salesChannelEnvelope.ts +28 -0
- package/src/commerce/schemas.ts +104 -0
- package/src/commerce/server/checkoutCompensation.ts +49 -0
- package/src/commerce/server/checkoutConflictClassifiers.ts +53 -0
- package/src/commerce/server/checkoutExpiredRecoveryPolicy.ts +107 -0
- package/src/commerce/server/checkoutInvoiceBuyerSnapshot.ts +36 -0
- package/src/commerce/server/checkoutOfferPolicyPort.ts +60 -0
- package/src/commerce/server/checkoutPaymentContinuationCredential.ts +222 -0
- package/src/commerce/server/checkoutQuoteTypes.ts +9 -0
- package/src/commerce/server/checkoutRecoveryOrderPort.ts +40 -0
- package/src/commerce/server/checkoutRecoveryToken.ts +63 -0
- package/src/commerce/server/checkoutRefusalContinuation.ts +29 -0
- package/src/commerce/server/checkoutRuntimeTypes.ts +26 -0
- package/src/commerce/server/commerceCheckoutCommandExecution.ts +188 -0
- package/src/commerce/server/commerceCheckoutCompensation.ts +66 -0
- package/src/commerce/server/commerceCheckoutContinuationTerms.ts +87 -0
- package/src/commerce/server/commerceCheckoutCustomerDefaults.ts +24 -0
- package/src/commerce/server/commerceCheckoutFailureHandler.ts +144 -0
- package/src/commerce/server/commerceCheckoutHandler.ts +269 -0
- package/src/commerce/server/commerceCheckoutHandlerAdmission.ts +157 -0
- package/src/commerce/server/commerceCheckoutHandlerHelpers.ts +223 -0
- package/src/commerce/server/commerceCheckoutOrchestrationError.ts +15 -0
- package/src/commerce/server/commerceCheckoutPromotionPriceChange.ts +83 -0
- package/src/commerce/server/commerceCheckoutProviderPayment.ts +45 -0
- package/src/commerce/server/commerceCheckoutQuoteGuard.ts +172 -0
- package/src/commerce/server/commerceCheckoutResume.ts +132 -0
- package/src/commerce/server/commerceCheckoutResumeGuard.ts +195 -0
- package/src/commerce/server/commerceCheckoutSavedPaymentMethod.ts +85 -0
- package/src/commerce/server/commerceCheckoutStartRuntimeFailure.ts +59 -0
- package/src/commerce/server/commerceCheckoutTiming.ts +53 -0
- package/src/commerce/server/commerceDiagnostics.ts +37 -0
- package/src/commerce/server/commerceOmsCancelOrderHandler.ts +43 -0
- package/src/commerce/server/commerceOmsControlPlaneHandlers.ts +71 -0
- package/src/commerce/server/commerceOmsHandlers.ts +275 -0
- package/src/commerce/server/commerceOmsMarkRefundedHandler.ts +39 -0
- package/src/commerce/server/commerceOrderDraft.ts +131 -0
- package/src/commerce/server/commercePaidOrderOrchestration.ts +275 -0
- package/src/commerce/server/commerceProviderAttemptFailure.ts +257 -0
- package/src/commerce/server/commerceReturnsHandlers.ts +143 -0
- package/src/commerce/server/commerceRuntimePort.ts +75 -0
- package/src/commerce/server/commerceRuntimeService.ts +229 -0
- package/src/commerce/server/commerceRuntimeStartResponse.ts +76 -0
- package/src/commerce/server/commerceStarterOfferGuard.ts +200 -0
- package/src/commerce/server/configuratorIntentPersistence.ts +161 -0
- package/src/commerce/server/configuratorIntentPersistenceHandler.ts +54 -0
- package/src/commerce/server/emailRuntime.ts +30 -0
- package/src/commerce/server/handlerSupport.ts +22 -0
- package/src/commerce/server/index.ts +181 -0
- package/src/commerce/server/offerAvailability.ts +275 -0
- package/src/commerce/server/orderDraftRpcPayload.ts +39 -0
- package/src/commerce/server/orderFeedbackSubmit.ts +40 -0
- package/src/commerce/server/orderFeedbackTokenCheck.ts +28 -0
- package/src/commerce/server/orderReviewAdminHandlers.ts +43 -0
- package/src/commerce/server/orderReviewHandlers.ts +57 -0
- package/src/commerce/server/orderReviewLifecycle.ts +129 -0
- package/src/commerce/server/orderReviewMedia.ts +170 -0
- package/src/commerce/server/orderReviewRawUploadHandler.ts +300 -0
- package/src/commerce/server/outboxCheckoutExpiredEmailHandler.ts +86 -0
- package/src/commerce/server/outboxCheckoutRecoveryEmailHandler.ts +188 -0
- package/src/commerce/server/outboxDispatchRegistry.ts +269 -0
- package/src/commerce/server/outboxDispatchRegistryComposition.ts +31 -0
- package/src/commerce/server/outboxOrderDraftEmailHandler.ts +162 -0
- package/src/commerce/server/outboxOrderPaidEmailHandler.ts +147 -0
- package/src/commerce/server/outboxOrderPaidFulfillmentHandler.ts +4 -0
- package/src/commerce/server/outboxOrderPaidFulfillmentPorts.ts +3 -0
- package/src/commerce/server/outboxOrderRefundedEmailHandler.ts +58 -0
- package/src/commerce/server/outboxPaymentFailedEmailHandler.ts +99 -0
- package/src/commerce/server/outboxReturnEmailHandlers.ts +92 -0
- package/src/commerce/server/outboxShipmentDeliveredEmailHandler.ts +94 -0
- package/src/commerce/server/outboxShipmentDispatchedEmailHandler.ts +112 -0
- package/src/commerce/server/outboxShipmentExceptionEmailHandler.ts +73 -0
- package/src/commerce/server/referenceCheckoutHandler.ts +87 -0
- package/src/commerce/server/reservationSweepPort.ts +67 -0
- package/src/commerce/server/starterTermsPort.ts +22 -0
- package/src/commerce/server/supabaseCommerceReturnsPort.ts +81 -0
- package/src/composition/accountSupportContribution.ts +28 -0
- package/src/composition/commerceContribution.ts +35 -0
- package/src/composition/index.ts +2 -0
- package/src/fulfillment/index.ts +1 -1
- package/src/fulfillment/paidHandoff.ts +2 -2
- package/src/inventory/bindings.ts +12 -4
- package/src/inventory/index.ts +1 -0
- package/src/inventory/managedStockAvailability.ts +23 -0
- package/src/inventory/postgresStockAvailability.ts +2 -21
- package/src/inventory/stockReadResponse.ts +25 -0
- package/src/pricing/browser/index.ts +6 -0
- package/src/subscriptions/index.ts +3 -2
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { composeOutboxHandlerDescriptors, assertOutboxRegistryDescriptors } from "./outboxDispatchRegistryComposition.js";
|
|
2
|
+
import { createOutboxOrderDraftEmailHandler, outboxOrderDraftEmailDescriptor } from "./outboxOrderDraftEmailHandler.js";
|
|
3
|
+
import { createOutboxCheckoutRecoveryEmailHandler, outboxCheckoutRecoveryEmailDescriptor } from "./outboxCheckoutRecoveryEmailHandler.js";
|
|
4
|
+
import { createOutboxOrderPaidEmailHandler, outboxOrderPaidEmailDescriptor, } from "./outboxOrderPaidEmailHandler.js";
|
|
5
|
+
import { createOutboxPaymentFailedEmailHandler, outboxPaymentFailedEmailDescriptor } from "./outboxPaymentFailedEmailHandler.js";
|
|
6
|
+
import { createOutboxCheckoutExpiredEmailHandler, outboxCheckoutExpiredEmailDescriptor } from "./outboxCheckoutExpiredEmailHandler.js";
|
|
7
|
+
import { createOutboxOrderRefundedEmailHandler, outboxOrderRefundedEmailDescriptor } from "./outboxOrderRefundedEmailHandler.js";
|
|
8
|
+
import { createOutboxShipmentDispatchedEmailHandler, outboxShipmentDispatchedEmailDescriptor } from "./outboxShipmentDispatchedEmailHandler.js";
|
|
9
|
+
import { createOutboxShipmentDeliveredEmailHandler, outboxShipmentDeliveredEmailDescriptor, } from "./outboxShipmentDeliveredEmailHandler.js";
|
|
10
|
+
import { createOutboxShipmentExceptionEmailHandler, outboxShipmentExceptionEmailDescriptor } from "./outboxShipmentExceptionEmailHandler.js";
|
|
11
|
+
import { createOutboxReturnApprovedEmailHandler, outboxReturnApprovedEmailDescriptor, createOutboxReturnRejectedEmailHandler, outboxReturnRejectedEmailDescriptor, } from "./outboxReturnEmailHandlers.js";
|
|
12
|
+
import { createOutboxOrderPaidFulfillmentHandler, outboxOrderPaidFulfillmentDescriptor, } from "./outboxOrderPaidFulfillmentHandler.js";
|
|
13
|
+
import { platformOwnsBuyerEmail, } from "../salesChannelEnvelope.js";
|
|
14
|
+
function readOrderUuid(payload) {
|
|
15
|
+
const value = payload.orderUuid;
|
|
16
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Wraps ONE buyer-facing email handler so a channel that owns buyer
|
|
20
|
+
* communication does not also get ours.
|
|
21
|
+
*
|
|
22
|
+
* WHY THE WRAPPER IS AT THE HANDLER AND NOT AT THE TRIGGER. The checkout email
|
|
23
|
+
* reconciler (`commerce_reconcile_checkout_email_outbox`) back-fills a `commerce.order.paid.email`
|
|
24
|
+
* row for EVERY order that reads `paid` and has none, keyed only on the order
|
|
25
|
+
* id — it does not look at `source_kind`, and outboxDispatchRuntime runs it
|
|
26
|
+
* inline immediately before the dispatch worker in the same invocation. A
|
|
27
|
+
* trigger-level or emitter-level suppression would therefore be undone on the
|
|
28
|
+
* very next reconcile pass, silently, and the buyer would get the email anyway.
|
|
29
|
+
* The dispatcher is the last place that can still decide.
|
|
30
|
+
*
|
|
31
|
+
* Recorded as `processed` rather than `discard` so the event settles once and
|
|
32
|
+
* never retries. `skipped` is one of the DELIVERY_LIFECYCLE_METADATA_KEYS below,
|
|
33
|
+
* so the email-delivery lifecycle trigger reads the suppression as a skip with a
|
|
34
|
+
* reason instead of leaving a delivery hanging — the same shape the
|
|
35
|
+
* carrier-owned delivered notice already uses.
|
|
36
|
+
*/
|
|
37
|
+
function suppressForChannel(handler, reader) {
|
|
38
|
+
if (!reader)
|
|
39
|
+
return handler;
|
|
40
|
+
return {
|
|
41
|
+
eventType: handler.eventType,
|
|
42
|
+
timeoutMs: handler.timeoutMs,
|
|
43
|
+
async handle(row, signal, execution) {
|
|
44
|
+
const orderUuid = readOrderUuid(row.payload);
|
|
45
|
+
// A payload with no usable order id is not a policy question. Hand it to
|
|
46
|
+
// the handler, whose own contract parse produces the right discard rather
|
|
47
|
+
// than this wrapper inventing a second failure mode for the same row.
|
|
48
|
+
if (orderUuid !== null) {
|
|
49
|
+
const policy = await reader.readOrderBuyerCommsPolicy(orderUuid);
|
|
50
|
+
if (!platformOwnsBuyerEmail(policy)) {
|
|
51
|
+
return { kind: "processed", detail: { skipped: "channel_owns_buyer_comms" } };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return handler.handle(row, signal, execution);
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export function describeCoreOutboxHandlers(selection) {
|
|
59
|
+
return [
|
|
60
|
+
...(selection.transactionalEmail ? [
|
|
61
|
+
outboxOrderDraftEmailDescriptor, outboxCheckoutRecoveryEmailDescriptor,
|
|
62
|
+
outboxOrderPaidEmailDescriptor, outboxPaymentFailedEmailDescriptor,
|
|
63
|
+
outboxCheckoutExpiredEmailDescriptor, outboxOrderRefundedEmailDescriptor,
|
|
64
|
+
outboxShipmentDispatchedEmailDescriptor, outboxShipmentDeliveredEmailDescriptor,
|
|
65
|
+
outboxShipmentExceptionEmailDescriptor, outboxReturnApprovedEmailDescriptor,
|
|
66
|
+
outboxReturnRejectedEmailDescriptor,
|
|
67
|
+
] : []),
|
|
68
|
+
...(selection.fulfillmentEnabled ? [outboxOrderPaidFulfillmentDescriptor] : []),
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
export function createOutboxDispatchRegistry(deps) {
|
|
72
|
+
// Applied to the buyer-facing set below. The four email handlers it is NOT
|
|
73
|
+
// applied to are structurally unreachable for a channel order on the ingest
|
|
74
|
+
// path this repository ships, and each is asserted rather than assumed:
|
|
75
|
+
// - order-draft-created: emitted INSIDE `commerce_create_order_draft`.
|
|
76
|
+
// `commerce_create_channel_order` writes the order header directly and
|
|
77
|
+
// emits `channel.order.ingested`, so no draft event ever exists.
|
|
78
|
+
// - checkout-recovery: minted from an expired-checkout recovery token, which
|
|
79
|
+
// only the checkout-expiry path can create.
|
|
80
|
+
// - checkout-expired and payment-failed: both key off a one-time order
|
|
81
|
+
// reaching status `expired`/`failed`, and the ONLY writer of those statuses
|
|
82
|
+
// for a one-time order is `commerce_payment_apply_result`. The ingest saga
|
|
83
|
+
// calls `applySucceeded` and nothing else — the marketplace collected the
|
|
84
|
+
// money before the order existed here, so there is no decline or session to
|
|
85
|
+
// expire. Nothing sweeps a stale `draft` order to `expired` either.
|
|
86
|
+
// This is an argument about the CURRENT ingest path. A later wave that gives a
|
|
87
|
+
// channel order a decline or expiry rail must revisit this list, not assume it.
|
|
88
|
+
//
|
|
89
|
+
// `commerce.order.canceled` is absent from this enumeration because its email
|
|
90
|
+
// handler (outboxOrderCanceledEmailHandler.ts) is registered by NOTHING — the
|
|
91
|
+
// only claimant of that event type is the accounting reversal handler, which
|
|
92
|
+
// arrives through `extraHandlers` and must keep running for a channel order.
|
|
93
|
+
// Wrapping a handler this registry does not compose would be theatre; if that
|
|
94
|
+
// email is ever wired up, it belongs in the wrapped set.
|
|
95
|
+
const suppress = (handler) => suppressForChannel(handler, deps.transactionalEmail?.buyerCommsPolicyReader);
|
|
96
|
+
const handlers = [
|
|
97
|
+
...(deps.transactionalEmail
|
|
98
|
+
? [
|
|
99
|
+
createOutboxOrderDraftEmailHandler({
|
|
100
|
+
runtime: deps.transactionalEmail.runtime,
|
|
101
|
+
emailPort: deps.transactionalEmail.emailPort,
|
|
102
|
+
recipientPort: deps.transactionalEmail.recipientPort,
|
|
103
|
+
lifecyclePort: deps.transactionalEmail.lifecyclePort,
|
|
104
|
+
}),
|
|
105
|
+
createOutboxCheckoutRecoveryEmailHandler({
|
|
106
|
+
runtime: deps.transactionalEmail.runtime,
|
|
107
|
+
emailPort: deps.transactionalEmail.emailPort,
|
|
108
|
+
recipientPort: deps.transactionalEmail.recipientPort,
|
|
109
|
+
lifecyclePort: deps.transactionalEmail.lifecyclePort,
|
|
110
|
+
}),
|
|
111
|
+
suppress(createOutboxOrderPaidEmailHandler({
|
|
112
|
+
runtime: deps.transactionalEmail.runtime,
|
|
113
|
+
emailPort: deps.transactionalEmail.emailPort,
|
|
114
|
+
recipientPort: deps.transactionalEmail.recipientPort,
|
|
115
|
+
linesPort: deps.transactionalEmail.orderPaidLinesPort,
|
|
116
|
+
describeParcel: deps.transactionalEmail.orderPaidParcelNote,
|
|
117
|
+
})),
|
|
118
|
+
createOutboxPaymentFailedEmailHandler({
|
|
119
|
+
runtime: deps.transactionalEmail.runtime,
|
|
120
|
+
emailPort: deps.transactionalEmail.emailPort,
|
|
121
|
+
recipientPort: deps.transactionalEmail.recipientPort,
|
|
122
|
+
lifecyclePort: deps.transactionalEmail.lifecyclePort,
|
|
123
|
+
}),
|
|
124
|
+
createOutboxCheckoutExpiredEmailHandler({
|
|
125
|
+
runtime: deps.transactionalEmail.runtime,
|
|
126
|
+
emailPort: deps.transactionalEmail.emailPort,
|
|
127
|
+
recipientPort: deps.transactionalEmail.recipientPort,
|
|
128
|
+
lifecyclePort: deps.transactionalEmail.lifecyclePort,
|
|
129
|
+
}),
|
|
130
|
+
suppress(createOutboxOrderRefundedEmailHandler({
|
|
131
|
+
runtime: deps.transactionalEmail.runtime,
|
|
132
|
+
emailPort: deps.transactionalEmail.emailPort,
|
|
133
|
+
recipientPort: deps.transactionalEmail.recipientPort,
|
|
134
|
+
})),
|
|
135
|
+
suppress(createOutboxShipmentDispatchedEmailHandler({
|
|
136
|
+
runtime: deps.transactionalEmail.runtime,
|
|
137
|
+
emailPort: deps.transactionalEmail.emailPort,
|
|
138
|
+
recipientPort: deps.transactionalEmail.recipientPort,
|
|
139
|
+
})),
|
|
140
|
+
suppress(createOutboxShipmentDeliveredEmailHandler({
|
|
141
|
+
runtime: deps.transactionalEmail.runtime,
|
|
142
|
+
emailPort: deps.transactionalEmail.emailPort,
|
|
143
|
+
recipientPort: deps.transactionalEmail.recipientPort,
|
|
144
|
+
providerKindReader: deps.transactionalEmail.deliveredProviderKindReader,
|
|
145
|
+
})),
|
|
146
|
+
suppress(createOutboxShipmentExceptionEmailHandler({
|
|
147
|
+
runtime: deps.transactionalEmail.runtime,
|
|
148
|
+
emailPort: deps.transactionalEmail.emailPort,
|
|
149
|
+
recipientPort: deps.transactionalEmail.recipientPort,
|
|
150
|
+
})),
|
|
151
|
+
suppress(createOutboxReturnApprovedEmailHandler({
|
|
152
|
+
runtime: deps.transactionalEmail.runtime,
|
|
153
|
+
emailPort: deps.transactionalEmail.emailPort,
|
|
154
|
+
recipientPort: deps.transactionalEmail.recipientPort,
|
|
155
|
+
})),
|
|
156
|
+
suppress(createOutboxReturnRejectedEmailHandler({
|
|
157
|
+
runtime: deps.transactionalEmail.runtime,
|
|
158
|
+
emailPort: deps.transactionalEmail.emailPort,
|
|
159
|
+
recipientPort: deps.transactionalEmail.recipientPort,
|
|
160
|
+
})),
|
|
161
|
+
]
|
|
162
|
+
: []),
|
|
163
|
+
...(deps.fulfillmentEnabled && deps.fulfillmentPort
|
|
164
|
+
? [
|
|
165
|
+
createOutboxOrderPaidFulfillmentHandler({
|
|
166
|
+
fulfillmentPort: deps.fulfillmentPort,
|
|
167
|
+
riskPort: deps.riskPort,
|
|
168
|
+
isRiskEnabled: () => deps.riskEnabled === true,
|
|
169
|
+
}),
|
|
170
|
+
]
|
|
171
|
+
: []),
|
|
172
|
+
...(deps.extraHandlers ?? []),
|
|
173
|
+
];
|
|
174
|
+
const registry = deps.uniqueRegistry(handlers);
|
|
175
|
+
const expected = deps.expectedDescriptors?.() ?? composeOutboxHandlerDescriptors([
|
|
176
|
+
...describeCoreOutboxHandlers({
|
|
177
|
+
transactionalEmail: Boolean(deps.transactionalEmail),
|
|
178
|
+
fulfillmentEnabled: deps.fulfillmentEnabled && Boolean(deps.fulfillmentPort),
|
|
179
|
+
}),
|
|
180
|
+
...(deps.extraHandlers ?? []).map(({ eventType, timeoutMs }) => ({ eventType, timeoutMs })),
|
|
181
|
+
]);
|
|
182
|
+
assertOutboxRegistryDescriptors(registry, expected);
|
|
183
|
+
return registry;
|
|
184
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { OutboxHandlerDescriptor } from "@openlup/core/outbox";
|
|
2
|
+
import type { OutboxHandlerRegistry } from "../outboxDispatchContracts.js";
|
|
3
|
+
/** Preserve native registration order and the timeout sum of same-event handlers. */
|
|
4
|
+
export declare function composeOutboxHandlerDescriptors(handlers: readonly OutboxHandlerDescriptor[]): OutboxHandlerDescriptor[];
|
|
5
|
+
/** Refuse a different claim surface before a worker can call claimBatch. */
|
|
6
|
+
export declare function assertOutboxRegistryDescriptors(registry: OutboxHandlerRegistry, expected: readonly OutboxHandlerDescriptor[]): void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Preserve native registration order and the timeout sum of same-event handlers. */
|
|
2
|
+
export function composeOutboxHandlerDescriptors(handlers) {
|
|
3
|
+
const descriptors = new Map();
|
|
4
|
+
for (const handler of handlers) {
|
|
5
|
+
const existing = descriptors.get(handler.eventType);
|
|
6
|
+
descriptors.set(handler.eventType, {
|
|
7
|
+
eventType: handler.eventType,
|
|
8
|
+
timeoutMs: (existing?.timeoutMs ?? 0) + handler.timeoutMs,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
return [...descriptors.values()];
|
|
12
|
+
}
|
|
13
|
+
/** Refuse a different claim surface before a worker can call claimBatch. */
|
|
14
|
+
export function assertOutboxRegistryDescriptors(registry, expected) {
|
|
15
|
+
const actual = [...registry.entries()];
|
|
16
|
+
if (actual.length !== expected.length || actual.some(([key, handler], index) => {
|
|
17
|
+
const descriptor = expected[index];
|
|
18
|
+
return key !== descriptor.eventType || handler.eventType !== key
|
|
19
|
+
|| handler.timeoutMs !== descriptor.timeoutMs
|
|
20
|
+
|| !Number.isFinite(handler.timeoutMs) || handler.timeoutMs <= 0;
|
|
21
|
+
}))
|
|
22
|
+
throw new Error("outbox_registry_descriptor_mismatch");
|
|
23
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CommerceEmailRuntime } from "./emailRuntime.js";
|
|
2
|
+
import type { OutboxHandler } from "../outboxDispatchContracts.js";
|
|
3
|
+
import { OUTBOX_ORDER_CONFIRMATION_TEMPLATE_SLUG, type OrderPaymentLifecyclePort, type OrderRecipientPort, type TransactionalEmailPort } from "../outboxOrderDraftEmailPorts.js";
|
|
4
|
+
export { OUTBOX_ORDER_CONFIRMATION_TEMPLATE_SLUG };
|
|
5
|
+
export declare const outboxOrderDraftEmailDescriptor: Readonly<{
|
|
6
|
+
eventType: "commerce.order_draft.created";
|
|
7
|
+
timeoutMs: 10000;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function createOutboxOrderDraftEmailHandler<Locale extends string>(deps: {
|
|
10
|
+
runtime: Pick<CommerceEmailRuntime<Locale>, "formatMoney" | "genericItemLabel" | "mapSendOutcome" | "parseOutboxPayload" | "resolveLocale">;
|
|
11
|
+
emailPort: TransactionalEmailPort<Locale>;
|
|
12
|
+
recipientPort: OrderRecipientPort;
|
|
13
|
+
lifecyclePort: OrderPaymentLifecyclePort;
|
|
14
|
+
}): OutboxHandler;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { COMMERCE_ORDER_DRAFT_CREATED_EVENT_TYPE } from "../outboxEventSchemas.js";
|
|
3
|
+
import { OUTBOX_ORDER_CONFIRMATION_TEMPLATE_SLUG, } from "../outboxOrderDraftEmailPorts.js";
|
|
4
|
+
import { buildItems } from "../orderEmailLines.js";
|
|
5
|
+
import { shouldSkipOrderDraftConfirmation } from "../orderEmailEligibility.js";
|
|
6
|
+
export { OUTBOX_ORDER_CONFIRMATION_TEMPLATE_SLUG };
|
|
7
|
+
const HANDLER_TIMEOUT_MS = 10_000;
|
|
8
|
+
export const outboxOrderDraftEmailDescriptor = Object.freeze({
|
|
9
|
+
eventType: COMMERCE_ORDER_DRAFT_CREATED_EVENT_TYPE, timeoutMs: HANDLER_TIMEOUT_MS,
|
|
10
|
+
});
|
|
11
|
+
// Frozen minimal parse (challenge R-m5): validate ONLY the fields this handler
|
|
12
|
+
// consumes, with schemas owned HERE — never the live quote/order-draft zod
|
|
13
|
+
// schemas. A producer-side schema deploy must not retro-DLQ in-flight events.
|
|
14
|
+
// Everything except orderUuid/orderId is optional-tolerant: malformed lines or
|
|
15
|
+
// totals degrade the email content, they never fail the event.
|
|
16
|
+
const payloadSubsetSchema = z
|
|
17
|
+
.object({
|
|
18
|
+
orderUuid: z.guid(),
|
|
19
|
+
orderId: z.string().min(1),
|
|
20
|
+
orderDraftSnapshot: z.unknown().optional(),
|
|
21
|
+
})
|
|
22
|
+
.passthrough();
|
|
23
|
+
const moneySubsetSchema = z
|
|
24
|
+
.object({
|
|
25
|
+
amountMinor: z.number().int().nonnegative(),
|
|
26
|
+
currency: z.string().trim().min(1),
|
|
27
|
+
})
|
|
28
|
+
.passthrough();
|
|
29
|
+
const lineSubsetSchema = z
|
|
30
|
+
.object({
|
|
31
|
+
quantity: z.number().int().positive(),
|
|
32
|
+
productSlug: z.string().trim().min(1).optional(),
|
|
33
|
+
sku: z.string().trim().min(1).optional(),
|
|
34
|
+
lineSubtotalGross: moneySubsetSchema.optional(),
|
|
35
|
+
})
|
|
36
|
+
.passthrough();
|
|
37
|
+
const snapshotSubsetSchema = z
|
|
38
|
+
.object({
|
|
39
|
+
lines: z.array(z.unknown()).optional(),
|
|
40
|
+
totals: z
|
|
41
|
+
.object({
|
|
42
|
+
subtotalGross: z.unknown().optional(),
|
|
43
|
+
discountTotalGross: z.unknown().optional(),
|
|
44
|
+
totalGross: z.unknown().optional(),
|
|
45
|
+
})
|
|
46
|
+
.passthrough()
|
|
47
|
+
.optional(),
|
|
48
|
+
})
|
|
49
|
+
.passthrough();
|
|
50
|
+
function extractLines(snapshot) {
|
|
51
|
+
const parsed = snapshotSubsetSchema.safeParse(snapshot);
|
|
52
|
+
if (!parsed.success || parsed.data.lines === undefined)
|
|
53
|
+
return [];
|
|
54
|
+
const lines = [];
|
|
55
|
+
for (const candidate of parsed.data.lines) {
|
|
56
|
+
const line = lineSubsetSchema.safeParse(candidate);
|
|
57
|
+
if (!line.success)
|
|
58
|
+
continue;
|
|
59
|
+
if (line.data.productSlug === undefined && line.data.sku === undefined)
|
|
60
|
+
continue;
|
|
61
|
+
lines.push({
|
|
62
|
+
label: null,
|
|
63
|
+
quantity: line.data.quantity,
|
|
64
|
+
lineSubtotalMinor: line.data.lineSubtotalGross?.amountMinor ?? null,
|
|
65
|
+
currency: line.data.lineSubtotalGross?.currency ?? null,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return lines;
|
|
69
|
+
}
|
|
70
|
+
function buildTotals(snapshot, runtime) {
|
|
71
|
+
const parsed = snapshotSubsetSchema.safeParse(snapshot);
|
|
72
|
+
if (!parsed.success || parsed.data.totals === undefined)
|
|
73
|
+
return null;
|
|
74
|
+
const total = moneySubsetSchema.safeParse(parsed.data.totals.totalGross);
|
|
75
|
+
if (!total.success)
|
|
76
|
+
return null;
|
|
77
|
+
const subtotal = moneySubsetSchema.safeParse(parsed.data.totals.subtotalGross);
|
|
78
|
+
const discount = moneySubsetSchema.safeParse(parsed.data.totals.discountTotalGross);
|
|
79
|
+
const currency = total.data.currency;
|
|
80
|
+
return {
|
|
81
|
+
// Omit the subtotal row when it cannot be parsed — do NOT fall back to the
|
|
82
|
+
// grand total, which would render "Subtotal = Total" alongside a separate
|
|
83
|
+
// discount line that no longer reconciles.
|
|
84
|
+
subtotalLabel: subtotal.success
|
|
85
|
+
? runtime.formatMoney(subtotal.data.amountMinor, subtotal.data.currency)
|
|
86
|
+
: null,
|
|
87
|
+
discountLabel: discount.success && discount.data.amountMinor > 0
|
|
88
|
+
? `-${runtime.formatMoney(discount.data.amountMinor, discount.data.currency)}`
|
|
89
|
+
: null,
|
|
90
|
+
totalLabel: runtime.formatMoney(total.data.amountMinor, currency),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export function createOutboxOrderDraftEmailHandler(deps) {
|
|
94
|
+
return {
|
|
95
|
+
...outboxOrderDraftEmailDescriptor,
|
|
96
|
+
async handle(row, signal) {
|
|
97
|
+
const parsed = deps.runtime.parseOutboxPayload(payloadSubsetSchema, row.payload);
|
|
98
|
+
if (parsed.ok === false) {
|
|
99
|
+
return parsed.outcome;
|
|
100
|
+
}
|
|
101
|
+
const lifecycle = await deps.lifecyclePort.read(parsed.data.orderUuid, signal);
|
|
102
|
+
const skipReason = shouldSkipOrderDraftConfirmation(lifecycle);
|
|
103
|
+
if (skipReason) {
|
|
104
|
+
return { kind: "processed", detail: { skipped: skipReason } };
|
|
105
|
+
}
|
|
106
|
+
const recipient = await deps.recipientPort.resolve(parsed.data.orderUuid, signal);
|
|
107
|
+
if (recipient === null) {
|
|
108
|
+
return { kind: "processed", detail: { skipped: "recipient_unresolved" } };
|
|
109
|
+
}
|
|
110
|
+
const alreadySent = await deps.emailPort.findExistingSend(OUTBOX_ORDER_CONFIRMATION_TEMPLATE_SLUG, row.id);
|
|
111
|
+
if (alreadySent) {
|
|
112
|
+
return { kind: "processed", detail: { dedupe: "email_already_sent" } };
|
|
113
|
+
}
|
|
114
|
+
const lines = extractLines(parsed.data.orderDraftSnapshot);
|
|
115
|
+
const locale = deps.runtime.resolveLocale(recipient.country ?? null);
|
|
116
|
+
const outcome = await deps.emailPort.sendOrderConfirmation({
|
|
117
|
+
to: recipient.email,
|
|
118
|
+
firstName: recipient.firstName,
|
|
119
|
+
contextName: recipient.contextName ?? null,
|
|
120
|
+
orderId: parsed.data.orderId,
|
|
121
|
+
outboxEventId: row.id,
|
|
122
|
+
items: buildItems(lines, locale, deps.runtime),
|
|
123
|
+
totals: buildTotals(parsed.data.orderDraftSnapshot, deps.runtime),
|
|
124
|
+
locale,
|
|
125
|
+
signal,
|
|
126
|
+
});
|
|
127
|
+
return deps.runtime.mapSendOutcome(outcome);
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CommerceEmailRuntime } from "./emailRuntime.js";
|
|
2
|
+
import type { OutboxHandler } from "../outboxDispatchContracts.js";
|
|
3
|
+
import { OUTBOX_ORDER_PAID_TEMPLATE_SLUG, type OrderPaidLinesPort, type OrderRecipientPort, type TransactionalEmailPort } from "../outboxOrderDraftEmailPorts.js";
|
|
4
|
+
export { OUTBOX_ORDER_PAID_TEMPLATE_SLUG };
|
|
5
|
+
export declare const outboxOrderPaidEmailDescriptor: Readonly<{
|
|
6
|
+
eventType: "commerce.order.paid.email";
|
|
7
|
+
timeoutMs: 10000;
|
|
8
|
+
}>;
|
|
9
|
+
/**
|
|
10
|
+
* An adopter's note about the paid order's parcel, already localized, or null
|
|
11
|
+
* for none. Best-effort and inside this handler's timeout: a failure is logged
|
|
12
|
+
* and the receipt is sent without the note.
|
|
13
|
+
*/
|
|
14
|
+
export type OrderPaidParcelNoteReader<Locale extends string = string> = (orderUuid: string, locale: Locale, signal: AbortSignal) => Promise<string | null>;
|
|
15
|
+
export declare function createOutboxOrderPaidEmailHandler<Locale extends string>(deps: {
|
|
16
|
+
runtime: Pick<CommerceEmailRuntime<Locale>, "formatMoney" | "genericItemLabel" | "mapSendOutcome" | "parseOutboxPayload" | "presentPaidOrder" | "resolveLocale">;
|
|
17
|
+
emailPort: TransactionalEmailPort<Locale>;
|
|
18
|
+
recipientPort: OrderRecipientPort;
|
|
19
|
+
linesPort: OrderPaidLinesPort;
|
|
20
|
+
describeParcel?: OrderPaidParcelNoteReader<Locale>;
|
|
21
|
+
}): OutboxHandler;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { COMMERCE_ORDER_PAID_EMAIL_EVENT_TYPE } from "../outboxEventSchemas.js";
|
|
3
|
+
import { OUTBOX_ORDER_PAID_TEMPLATE_SLUG, } from "../outboxOrderDraftEmailPorts.js";
|
|
4
|
+
import { buildItems } from "../orderEmailLines.js";
|
|
5
|
+
export { OUTBOX_ORDER_PAID_TEMPLATE_SLUG };
|
|
6
|
+
const HANDLER_TIMEOUT_MS = 10_000;
|
|
7
|
+
export const outboxOrderPaidEmailDescriptor = Object.freeze({
|
|
8
|
+
eventType: COMMERCE_ORDER_PAID_EMAIL_EVENT_TYPE, timeoutMs: HANDLER_TIMEOUT_MS,
|
|
9
|
+
});
|
|
10
|
+
// Frozen minimal parse (mirror the order-draft handler): validate ONLY what this
|
|
11
|
+
// handler consumes; a producer schema change must never retro-DLQ in-flight rows.
|
|
12
|
+
const payloadSubsetSchema = z
|
|
13
|
+
.object({
|
|
14
|
+
orderUuid: z.guid(),
|
|
15
|
+
orderId: z.string().min(1),
|
|
16
|
+
mode: z.string().min(1).optional(),
|
|
17
|
+
})
|
|
18
|
+
.passthrough();
|
|
19
|
+
function totalsFrom(data, runtime) {
|
|
20
|
+
return {
|
|
21
|
+
subtotalLabel: runtime.formatMoney(data.subtotalMinor, data.currency),
|
|
22
|
+
discountLabel: data.discountMinor > 0 ? `−${runtime.formatMoney(data.discountMinor, data.currency)}` : null,
|
|
23
|
+
totalLabel: runtime.formatMoney(data.totalMinor, data.currency),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function createOutboxOrderPaidEmailHandler(deps) {
|
|
27
|
+
return {
|
|
28
|
+
...outboxOrderPaidEmailDescriptor,
|
|
29
|
+
async handle(row, signal) {
|
|
30
|
+
const parsed = deps.runtime.parseOutboxPayload(payloadSubsetSchema, row.payload);
|
|
31
|
+
if (parsed.ok === false) {
|
|
32
|
+
return parsed.outcome;
|
|
33
|
+
}
|
|
34
|
+
// Dedupe FIRST (cheap, recipient-independent): an already-sent event must not
|
|
35
|
+
// burn the recipient + lines reads (4 queries) on every reprocess/retry/preview
|
|
36
|
+
// drain — those passes were pure waste on the dupe path.
|
|
37
|
+
const alreadySent = await deps.emailPort.findExistingSend(OUTBOX_ORDER_PAID_TEMPLATE_SLUG, row.id);
|
|
38
|
+
if (alreadySent) {
|
|
39
|
+
return { kind: "processed", detail: { dedupe: "email_already_sent" } };
|
|
40
|
+
}
|
|
41
|
+
const recipient = await deps.recipientPort.resolve(parsed.data.orderUuid, signal);
|
|
42
|
+
if (recipient === null) {
|
|
43
|
+
return { kind: "processed", detail: { skipped: "recipient_unresolved" } };
|
|
44
|
+
}
|
|
45
|
+
// Items + totals from the DB. A genuine read error throws → worker retries.
|
|
46
|
+
// A missing order row means the paid order is not yet readable (replication
|
|
47
|
+
// lag): retry rather than send a contentless "receipt" with no items/totals.
|
|
48
|
+
const data = await deps.linesPort.read(parsed.data.orderUuid, signal);
|
|
49
|
+
if (data === null) {
|
|
50
|
+
return { kind: "retry", reason: "order_paid_data_unavailable" };
|
|
51
|
+
}
|
|
52
|
+
const presentation = deps.runtime.presentPaidOrder(data);
|
|
53
|
+
const rawLines = (data.lines ?? []).map((line) => ({
|
|
54
|
+
label: line.label,
|
|
55
|
+
quantity: line.quantity,
|
|
56
|
+
lineSubtotalMinor: presentation ? null : line.lineTotalMinor,
|
|
57
|
+
currency: data.currency,
|
|
58
|
+
}));
|
|
59
|
+
const locale = deps.runtime.resolveLocale(recipient.country ?? null);
|
|
60
|
+
const parcelNote = await readParcelNote(deps.describeParcel, parsed.data.orderUuid, locale, signal, row.id);
|
|
61
|
+
const outcome = await deps.emailPort.sendOrderPaidConfirmation({
|
|
62
|
+
to: recipient.email,
|
|
63
|
+
firstName: recipient.firstName,
|
|
64
|
+
contextName: recipient.contextName ?? null,
|
|
65
|
+
orderId: parsed.data.orderId,
|
|
66
|
+
mode: parsed.data.mode ?? "one_time",
|
|
67
|
+
outboxEventId: row.id,
|
|
68
|
+
items: buildItems(rawLines, locale, deps.runtime),
|
|
69
|
+
totals: presentation ?? totalsFrom(data, deps.runtime),
|
|
70
|
+
...(parcelNote ? { parcelNote } : {}),
|
|
71
|
+
locale,
|
|
72
|
+
signal,
|
|
73
|
+
});
|
|
74
|
+
return deps.runtime.mapSendOutcome(outcome);
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Asks the composed reader, if any, for the receipt's parcel note. A missing
|
|
80
|
+
* reader, an empty answer or a failure all mean no note: a failure is logged
|
|
81
|
+
* with the event id only, and the receipt is sent without the note.
|
|
82
|
+
*/
|
|
83
|
+
async function readParcelNote(describeParcel, orderUuid, locale, signal, eventId) {
|
|
84
|
+
if (!describeParcel)
|
|
85
|
+
return null;
|
|
86
|
+
try {
|
|
87
|
+
return (await describeParcel(orderUuid, locale, signal)) || null;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
console.warn("[outbox-dispatch] order_paid_parcel_note_unavailable", eventId);
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { createOutboxOrderPaidFulfillmentHandler } from "../../fulfillment/index.js";
|
|
2
|
+
export { createOutboxOrderPaidFulfillmentHandler, outboxOrderPaidFulfillmentDescriptor } from "../../fulfillment/index.js";
|
|
3
|
+
export type OrderPaidRiskAssessmentPort = NonNullable<Parameters<typeof createOutboxOrderPaidFulfillmentHandler>[0]["riskPort"]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createOutboxOrderPaidFulfillmentHandler, outboxOrderPaidFulfillmentDescriptor } from "../../fulfillment/index.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { createOutboxOrderPaidFulfillmentHandler } from "../../fulfillment/index.js";
|
|
2
|
+
export type OrderPaidFulfillmentPort = Parameters<typeof createOutboxOrderPaidFulfillmentHandler>[0]["fulfillmentPort"];
|
|
3
|
+
export type OrderPaidFulfillmentResult = Awaited<ReturnType<OrderPaidFulfillmentPort["ensureFulfilledFromPaidOrder"]>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CommerceEmailRuntime } from "./emailRuntime.js";
|
|
2
|
+
import type { OutboxHandler } from "../outboxDispatchContracts.js";
|
|
3
|
+
import { OUTBOX_ORDER_REFUNDED_TEMPLATE_SLUG, type OrderRecipientPort, type TransactionalEmailPort } from "../outboxOrderDraftEmailPorts.js";
|
|
4
|
+
export { OUTBOX_ORDER_REFUNDED_TEMPLATE_SLUG };
|
|
5
|
+
export declare const outboxOrderRefundedEmailDescriptor: Readonly<{
|
|
6
|
+
eventType: "commerce.order.refunded";
|
|
7
|
+
timeoutMs: 10000;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function createOutboxOrderRefundedEmailHandler<Locale extends string>(deps: {
|
|
10
|
+
runtime: Pick<CommerceEmailRuntime<Locale>, "createTransactionalEmailHandler" | "formatMoney" | "resolveLocale">;
|
|
11
|
+
emailPort: TransactionalEmailPort<Locale>;
|
|
12
|
+
recipientPort: OrderRecipientPort;
|
|
13
|
+
}): OutboxHandler;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { COMMERCE_ORDER_REFUNDED_EVENT_TYPE } from "../outboxEventSchemas.js";
|
|
3
|
+
import { OUTBOX_ORDER_REFUNDED_TEMPLATE_SLUG, } from "../outboxOrderDraftEmailPorts.js";
|
|
4
|
+
export { OUTBOX_ORDER_REFUNDED_TEMPLATE_SLUG };
|
|
5
|
+
const HANDLER_TIMEOUT_MS = 10_000;
|
|
6
|
+
export const outboxOrderRefundedEmailDescriptor = Object.freeze({
|
|
7
|
+
eventType: COMMERCE_ORDER_REFUNDED_EVENT_TYPE, timeoutMs: HANDLER_TIMEOUT_MS,
|
|
8
|
+
});
|
|
9
|
+
const payloadSubsetSchema = z
|
|
10
|
+
.object({
|
|
11
|
+
orderUuid: z.guid(),
|
|
12
|
+
orderId: z.string().min(1),
|
|
13
|
+
refundCents: z.number().int().nonnegative().optional(),
|
|
14
|
+
refundEvidenceVersion: z.string().optional(),
|
|
15
|
+
currency: z.string().trim().min(1).optional(),
|
|
16
|
+
})
|
|
17
|
+
.passthrough();
|
|
18
|
+
export function createOutboxOrderRefundedEmailHandler(deps) {
|
|
19
|
+
return deps.runtime.createTransactionalEmailHandler({
|
|
20
|
+
...outboxOrderRefundedEmailDescriptor,
|
|
21
|
+
templateSlug: OUTBOX_ORDER_REFUNDED_TEMPLATE_SLUG,
|
|
22
|
+
schema: payloadSubsetSchema,
|
|
23
|
+
resolveKey: (payload) => payload.orderUuid,
|
|
24
|
+
recipientPort: deps.recipientPort,
|
|
25
|
+
findExistingSend: (slug, id) => deps.emailPort.findExistingSend(slug, id),
|
|
26
|
+
send: ({ payload, recipient, row, signal }) => {
|
|
27
|
+
const amountCents = payload.refundEvidenceVersion === "provider-refund.v2" ? payload.refundCents : undefined;
|
|
28
|
+
const amountLabel = amountCents !== undefined && payload.currency !== undefined
|
|
29
|
+
? deps.runtime.formatMoney(amountCents, payload.currency)
|
|
30
|
+
: null;
|
|
31
|
+
return deps.emailPort.sendOrderRefundedNotice({
|
|
32
|
+
to: recipient.email,
|
|
33
|
+
firstName: recipient.firstName,
|
|
34
|
+
orderId: payload.orderId,
|
|
35
|
+
amountLabel,
|
|
36
|
+
outboxEventId: row.id,
|
|
37
|
+
locale: deps.runtime.resolveLocale(recipient.country ?? null),
|
|
38
|
+
signal,
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CommerceEmailRuntime } from "./emailRuntime.js";
|
|
2
|
+
import type { OutboxHandler } from "../outboxDispatchContracts.js";
|
|
3
|
+
import { OUTBOX_PAYMENT_FAILED_TEMPLATE_SLUG, type OrderPaymentLifecyclePort, type OrderRecipientPort, type TransactionalEmailPort } from "../outboxOrderDraftEmailPorts.js";
|
|
4
|
+
export { OUTBOX_PAYMENT_FAILED_TEMPLATE_SLUG };
|
|
5
|
+
export declare const outboxPaymentFailedEmailDescriptor: Readonly<{
|
|
6
|
+
eventType: "commerce.payment.failed";
|
|
7
|
+
timeoutMs: 10000;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function createOutboxPaymentFailedEmailHandler<Locale extends string>(deps: {
|
|
10
|
+
runtime: Pick<CommerceEmailRuntime<Locale>, "formatMoney" | "mapSendOutcome" | "parseOutboxPayload" | "resolveLocale">;
|
|
11
|
+
emailPort: TransactionalEmailPort<Locale>;
|
|
12
|
+
recipientPort: OrderRecipientPort;
|
|
13
|
+
lifecyclePort: OrderPaymentLifecyclePort;
|
|
14
|
+
}): OutboxHandler;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { COMMERCE_PAYMENT_FAILED_EVENT_TYPE } from "../outboxEventSchemas.js";
|
|
3
|
+
import { OUTBOX_PAYMENT_FAILED_TEMPLATE_SLUG, } from "../outboxOrderDraftEmailPorts.js";
|
|
4
|
+
import { shouldSkipPaymentFailedNotice } from "../orderEmailEligibility.js";
|
|
5
|
+
export { OUTBOX_PAYMENT_FAILED_TEMPLATE_SLUG };
|
|
6
|
+
const HANDLER_TIMEOUT_MS = 10_000;
|
|
7
|
+
export const outboxPaymentFailedEmailDescriptor = Object.freeze({
|
|
8
|
+
eventType: COMMERCE_PAYMENT_FAILED_EVENT_TYPE, timeoutMs: HANDLER_TIMEOUT_MS,
|
|
9
|
+
});
|
|
10
|
+
// Frozen minimal parse: only orderUuid/orderId are required; the amount fields
|
|
11
|
+
// degrade the copy (no amount line) but never fail the event.
|
|
12
|
+
const payloadSubsetSchema = z
|
|
13
|
+
.object({
|
|
14
|
+
orderUuid: z.guid(),
|
|
15
|
+
orderId: z.string().min(1),
|
|
16
|
+
recoveryToken: z.string().trim().min(1),
|
|
17
|
+
mode: z.string().optional(),
|
|
18
|
+
totalCents: z.number().int().nonnegative().optional(),
|
|
19
|
+
currency: z.string().trim().min(1).optional(),
|
|
20
|
+
})
|
|
21
|
+
.passthrough();
|
|
22
|
+
export function createOutboxPaymentFailedEmailHandler(deps) {
|
|
23
|
+
return {
|
|
24
|
+
...outboxPaymentFailedEmailDescriptor,
|
|
25
|
+
async handle(row, signal, execution) {
|
|
26
|
+
const parsed = deps.runtime.parseOutboxPayload(payloadSubsetSchema, row.payload);
|
|
27
|
+
if (parsed.ok === false) {
|
|
28
|
+
return parsed.outcome;
|
|
29
|
+
}
|
|
30
|
+
execution?.setPhase("lifecycle");
|
|
31
|
+
const lifecycle = await deps.lifecyclePort.read(parsed.data.orderUuid, signal);
|
|
32
|
+
const skipReason = shouldSkipPaymentFailedNotice(lifecycle);
|
|
33
|
+
if (skipReason) {
|
|
34
|
+
return { kind: "processed", detail: { skipped: skipReason } };
|
|
35
|
+
}
|
|
36
|
+
execution?.setPhase("recipient");
|
|
37
|
+
const recipient = await deps.recipientPort.resolve(parsed.data.orderUuid, signal);
|
|
38
|
+
if (recipient === null) {
|
|
39
|
+
return { kind: "processed", detail: { skipped: "recipient_unresolved" } };
|
|
40
|
+
}
|
|
41
|
+
execution?.setPhase("dedupe");
|
|
42
|
+
const alreadySent = await deps.emailPort.findExistingSend(OUTBOX_PAYMENT_FAILED_TEMPLATE_SLUG, row.id);
|
|
43
|
+
if (alreadySent) {
|
|
44
|
+
return { kind: "processed", detail: { dedupe: "email_already_sent" } };
|
|
45
|
+
}
|
|
46
|
+
const payload = parsed.data;
|
|
47
|
+
const amountLabel = payload.totalCents !== undefined && payload.currency !== undefined
|
|
48
|
+
? deps.runtime.formatMoney(payload.totalCents, payload.currency)
|
|
49
|
+
: null;
|
|
50
|
+
execution?.setPhase("email_send");
|
|
51
|
+
const outcome = await deps.emailPort.sendPaymentFailedNotice({
|
|
52
|
+
to: recipient.email,
|
|
53
|
+
firstName: recipient.firstName,
|
|
54
|
+
orderId: payload.orderId,
|
|
55
|
+
amountLabel,
|
|
56
|
+
recoveryToken: payload.recoveryToken,
|
|
57
|
+
mode: payload.mode ?? "one_time",
|
|
58
|
+
outboxEventId: row.id,
|
|
59
|
+
locale: deps.runtime.resolveLocale(recipient.country ?? null),
|
|
60
|
+
signal,
|
|
61
|
+
});
|
|
62
|
+
return deps.runtime.mapSendOutcome(outcome);
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|