From caf83cf78cb6d2dbd1837f6814062dafecbd04fa Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Wed, 26 Feb 2025 18:42:48 +0100 Subject: [PATCH] chore: prevent workflow steps to call modules when not necessary (#11632) **What** Some steps were calling the modules even when nothing was needed which for some operations would create transaction for nothing leading to extra execution time that add up very quickly on cloud network Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com> --- .changeset/good-bulldogs-sparkle.md | 6 +++ .../cart/steps/add-shipping-method-to-cart.ts | 7 +++- .../src/cart/steps/confirm-inventory.ts | 6 ++- .../steps/create-line-item-adjustments.ts | 7 +++- .../src/cart/steps/create-line-items.ts | 2 +- .../cart/steps/create-payment-collection.ts | 4 ++ .../create-shipping-method-adjustments.ts | 7 +++- .../get-actions-to-compute-from-promotions.ts | 9 +++-- .../src/cart/steps/get-line-item-actions.ts | 14 +++++-- .../steps/get-promotion-codes-to-apply.ts | 18 +++++---- .../src/cart/steps/get-variant-price-sets.ts | 15 +++++--- ...pare-adjustments-from-promotion-actions.ts | 13 ++++++- .../steps/remove-line-item-adjustments.ts | 5 +++ .../remove-shipping-method-adjustments.ts | 5 +++ .../src/cart/steps/reserve-inventory.ts | 8 +++- .../src/cart/steps/update-cart-promotions.ts | 37 ++++++++++--------- .../modules/cart/src/services/cart-module.ts | 17 +++++---- 17 files changed, 125 insertions(+), 55 deletions(-) create mode 100644 .changeset/good-bulldogs-sparkle.md diff --git a/.changeset/good-bulldogs-sparkle.md b/.changeset/good-bulldogs-sparkle.md new file mode 100644 index 0000000000..a86deee94a --- /dev/null +++ b/.changeset/good-bulldogs-sparkle.md @@ -0,0 +1,6 @@ +--- +"@medusajs/core-flows": patch +"@medusajs/cart": patch +--- + +chore(): Prevent workflow steps to even call modules when not necessary diff --git a/packages/core/core-flows/src/cart/steps/add-shipping-method-to-cart.ts b/packages/core/core-flows/src/cart/steps/add-shipping-method-to-cart.ts index 2a53c7d6c9..dd4fb9612b 100644 --- a/packages/core/core-flows/src/cart/steps/add-shipping-method-to-cart.ts +++ b/packages/core/core-flows/src/cart/steps/add-shipping-method-to-cart.ts @@ -18,7 +18,7 @@ export interface AddShippingMethodToCartStepInput { export const addShippingMethodToCartStepId = "add-shipping-method-to-cart-step" /** * This step adds shipping methods to a cart. - * + * * @example * const data = addShippingMethodToCartStep({ * shipping_methods: [ @@ -33,8 +33,11 @@ export const addShippingMethodToCartStepId = "add-shipping-method-to-cart-step" export const addShippingMethodToCartStep = createStep( addShippingMethodToCartStepId, async (data: AddShippingMethodToCartStepInput, { container }) => { - const cartService = container.resolve(Modules.CART) + if (!data.shipping_methods?.length) { + return new StepResponse([], []) + } + const cartService = container.resolve(Modules.CART) const methods = await cartService.addShippingMethods(data.shipping_methods) return new StepResponse(methods, methods) diff --git a/packages/core/core-flows/src/cart/steps/confirm-inventory.ts b/packages/core/core-flows/src/cart/steps/confirm-inventory.ts index 6115e4f674..9b21f093f1 100644 --- a/packages/core/core-flows/src/cart/steps/confirm-inventory.ts +++ b/packages/core/core-flows/src/cart/steps/confirm-inventory.ts @@ -43,7 +43,7 @@ export const confirmInventoryStepId = "confirm-inventory-step" /** * This step validates that items in the cart have sufficient inventory quantity. * If an item doesn't have sufficient inventory, an error is thrown. - * + * * @example * confirmInventoryStep({ * items: [ @@ -60,6 +60,10 @@ export const confirmInventoryStepId = "confirm-inventory-step" export const confirmInventoryStep = createStep( confirmInventoryStepId, async (data: ConfirmVariantInventoryStepInput, { container }) => { + if (!data.items?.length) { + return new StepResponse([], []) + } + const inventoryService = container.resolve( Modules.INVENTORY ) diff --git a/packages/core/core-flows/src/cart/steps/create-line-item-adjustments.ts b/packages/core/core-flows/src/cart/steps/create-line-item-adjustments.ts index 3215a793cd..f945863abe 100644 --- a/packages/core/core-flows/src/cart/steps/create-line-item-adjustments.ts +++ b/packages/core/core-flows/src/cart/steps/create-line-item-adjustments.ts @@ -18,7 +18,7 @@ export interface CreateLineItemAdjustmentsCartStepInput { export const createLineItemAdjustmentsStepId = "create-line-item-adjustments" /** * This step creates line item adjustments in a cart, such as when a promotion is applied. - * + * * @example * createLineItemAdjustmentsStep({ * lineItemAdjustmentsToCreate: [ @@ -34,6 +34,11 @@ export const createLineItemAdjustmentsStep = createStep( createLineItemAdjustmentsStepId, async (data: CreateLineItemAdjustmentsCartStepInput, { container }) => { const { lineItemAdjustmentsToCreate = [] } = data + + if (!lineItemAdjustmentsToCreate?.length) { + return new StepResponse([], []) + } + const cartModuleService: ICartModuleService = container.resolve( Modules.CART ) diff --git a/packages/core/core-flows/src/cart/steps/create-line-items.ts b/packages/core/core-flows/src/cart/steps/create-line-items.ts index 2bf7fce857..29072ad1a2 100644 --- a/packages/core/core-flows/src/cart/steps/create-line-items.ts +++ b/packages/core/core-flows/src/cart/steps/create-line-items.ts @@ -22,7 +22,7 @@ export interface CreateLineItemsCartStepInput { export const createLineItemsStepId = "create-line-items-step" /** * This step creates line item in a cart. - * + * * @example * const data = createLineItemsStep({ * "id": "cart_123", diff --git a/packages/core/core-flows/src/cart/steps/create-payment-collection.ts b/packages/core/core-flows/src/cart/steps/create-payment-collection.ts index f1afe8a447..0fd22ee3ff 100644 --- a/packages/core/core-flows/src/cart/steps/create-payment-collection.ts +++ b/packages/core/core-flows/src/cart/steps/create-payment-collection.ts @@ -33,6 +33,10 @@ export const createPaymentCollectionsStepId = "create-payment-collections" export const createPaymentCollectionsStep = createStep( createPaymentCollectionsStepId, async (data: CreatePaymentCollectionCartStepInput, { container }) => { + if (!data?.length) { + return new StepResponse([], []) + } + const service = container.resolve(Modules.PAYMENT) const created = await service.createPaymentCollections(data) diff --git a/packages/core/core-flows/src/cart/steps/create-shipping-method-adjustments.ts b/packages/core/core-flows/src/cart/steps/create-shipping-method-adjustments.ts index a62d476e76..d75987e2e2 100644 --- a/packages/core/core-flows/src/cart/steps/create-shipping-method-adjustments.ts +++ b/packages/core/core-flows/src/cart/steps/create-shipping-method-adjustments.ts @@ -19,7 +19,7 @@ export const createShippingMethodAdjustmentsStepId = "create-shipping-method-adjustments" /** * This step creates shipping method adjustments for a cart. - * + * * @example * const data = createShippingMethodAdjustmentsStep({ * "shippingMethodAdjustmentsToCreate": [{ @@ -33,6 +33,11 @@ export const createShippingMethodAdjustmentsStep = createStep( createShippingMethodAdjustmentsStepId, async (data: CreateShippingMethodAdjustmentsStepInput, { container }) => { const { shippingMethodAdjustmentsToCreate = [] } = data + + if (!shippingMethodAdjustmentsToCreate?.length) { + return new StepResponse(void 0, []) + } + const cartModuleService: ICartModuleService = container.resolve( Modules.CART ) diff --git a/packages/core/core-flows/src/cart/steps/get-actions-to-compute-from-promotions.ts b/packages/core/core-flows/src/cart/steps/get-actions-to-compute-from-promotions.ts index f4f12164b5..927f9ee069 100644 --- a/packages/core/core-flows/src/cart/steps/get-actions-to-compute-from-promotions.ts +++ b/packages/core/core-flows/src/cart/steps/get-actions-to-compute-from-promotions.ts @@ -21,13 +21,13 @@ export const getActionsToComputeFromPromotionsStepId = /** * This step retrieves the actions to compute based on the promotions * applied on a cart. - * + * * :::tip - * + * * You can use the {@link retrieveCartStep} to retrieve a cart's details. - * + * * ::: - * + * * @example * const data = getActionsToComputeFromPromotionsStep({ * // retrieve the details of the cart from another workflow @@ -40,6 +40,7 @@ export const getActionsToComputeFromPromotionsStep = createStep( getActionsToComputeFromPromotionsStepId, async (data: GetActionsToComputeFromPromotionsStepInput, { container }) => { const { cart, promotionCodesToApply = [] } = data + const promotionService = container.resolve( Modules.PROMOTION ) diff --git a/packages/core/core-flows/src/cart/steps/get-line-item-actions.ts b/packages/core/core-flows/src/cart/steps/get-line-item-actions.ts index 70afe46369..807de541ca 100644 --- a/packages/core/core-flows/src/cart/steps/get-line-item-actions.ts +++ b/packages/core/core-flows/src/cart/steps/get-line-item-actions.ts @@ -41,7 +41,7 @@ export const getLineItemActionsStepId = "get-line-item-actions-step" /** * This step returns lists of cart line items to create or update based on the * provided input. - * + * * @example * const data = getLineItemActionsStep({ * "id": "cart_123", @@ -56,11 +56,16 @@ export const getLineItemActionsStepId = "get-line-item-actions-step" export const getLineItemActionsStep = createStep( getLineItemActionsStepId, async (data: GetLineItemActionsStepInput, { container }) => { + if (!data.items.length) { + return new StepResponse({ itemsToCreate: [], itemsToUpdate: [] }, null) + } + const cartModule = container.resolve(Modules.CART) + const variantIds = data.items.map((d) => d.variant_id!) const existingVariantItems = await cartModule.listLineItems({ cart_id: data.id, - variant_id: data.items.map((d) => d.variant_id!), + variant_id: variantIds, }) const variantItemMap = new Map( @@ -99,7 +104,8 @@ export const getLineItemActionsStep = createStep( } return new StepResponse( - { itemsToCreate, itemsToUpdate } as GetLineItemActionsStepOutput - , null) + { itemsToCreate, itemsToUpdate } as GetLineItemActionsStepOutput, + null + ) } ) diff --git a/packages/core/core-flows/src/cart/steps/get-promotion-codes-to-apply.ts b/packages/core/core-flows/src/cart/steps/get-promotion-codes-to-apply.ts index ea35110f3f..4de4ab53fb 100644 --- a/packages/core/core-flows/src/cart/steps/get-promotion-codes-to-apply.ts +++ b/packages/core/core-flows/src/cart/steps/get-promotion-codes-to-apply.ts @@ -34,7 +34,7 @@ export interface GetPromotionCodesToApplyStepInput { /** * The promotion codes to apply on the cart. - * + * * @example ["PRO10", "SHIPFREE", "NEWYEAR20"] */ export type GetPromotionCodesToApplyStepOutput = string[] @@ -42,7 +42,7 @@ export type GetPromotionCodesToApplyStepOutput = string[] export const getPromotionCodesToApplyId = "get-promotion-codes-to-apply" /** * This step retrieves the promotion codes to apply on a cart. - * + * * @example * const data = getPromotionCodesToApply( * { @@ -84,12 +84,14 @@ export const getPromotionCodesToApply = createStep( }) const promotionCodesToApply: Set = new Set( - ( - await promotionService.listPromotions( - { code: adjustmentCodes }, - { select: ["code"] } - ) - ).map((p) => p.code!) + adjustmentCodes.length + ? ( + await promotionService.listPromotions( + { code: adjustmentCodes }, + { select: ["code"] } + ) + ).map((p) => p.code!) + : [] ) if (action === PromotionActions.ADD) { diff --git a/packages/core/core-flows/src/cart/steps/get-variant-price-sets.ts b/packages/core/core-flows/src/cart/steps/get-variant-price-sets.ts index 74ef6a0c8a..0ab7680453 100644 --- a/packages/core/core-flows/src/cart/steps/get-variant-price-sets.ts +++ b/packages/core/core-flows/src/cart/steps/get-variant-price-sets.ts @@ -1,4 +1,7 @@ -import { CalculatedPriceSet, IPricingModuleService } from "@medusajs/framework/types" +import { + CalculatedPriceSet, + IPricingModuleService, +} from "@medusajs/framework/types" import { MedusaError, Modules } from "@medusajs/framework/utils" import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk" @@ -12,7 +15,7 @@ export interface GetVariantPriceSetsStepInput { variantIds: string[] /** * The context to use when calculating the price sets. - * + * * Learn more in [this documentation](https://docs.medusajs.com/resources/commerce-modules/product/guides/price#retrieve-calculated-price-for-a-context). */ context?: Record @@ -28,18 +31,18 @@ export interface GetVariantPriceSetsStepOutput { export const getVariantPriceSetsStepId = "get-variant-price-sets" /** * This step retrieves the calculated price sets of the specified variants. - * + * * @example * To retrieve a variant's price sets: - * + * * ```ts * const data = getVariantPriceSetsStep({ * variantIds: ["variant_123"], * }) * ``` - * + * * To retrieve the calculated price sets of a variant: - * + * * ```ts * const data = getVariantPriceSetsStep({ * variantIds: ["variant_123"], diff --git a/packages/core/core-flows/src/cart/steps/prepare-adjustments-from-promotion-actions.ts b/packages/core/core-flows/src/cart/steps/prepare-adjustments-from-promotion-actions.ts index 72404ff6ab..a4832c2a38 100644 --- a/packages/core/core-flows/src/cart/steps/prepare-adjustments-from-promotion-actions.ts +++ b/packages/core/core-flows/src/cart/steps/prepare-adjustments-from-promotion-actions.ts @@ -85,7 +85,7 @@ export const prepareAdjustmentsFromPromotionActionsStepId = /** * This step prepares the line item or shipping method adjustments using * actions computed by the Promotion Module. - * + * * @example * const data = prepareAdjustmentsFromPromotionActionsStep({ * "actions": [{ @@ -107,6 +107,17 @@ export const prepareAdjustmentsFromPromotionActionsStep = createStep( ) const { actions = [] } = data + + if (!actions.length) { + return new StepResponse({ + lineItemAdjustmentsToCreate: [], + lineItemAdjustmentIdsToRemove: [], + shippingMethodAdjustmentsToCreate: [], + shippingMethodAdjustmentIdsToRemove: [], + computedPromotionCodes: [], + } as PrepareAdjustmentsFromPromotionActionsStepOutput) + } + const promotions = await promotionModuleService.listPromotions( { code: actions.map((a) => a.code) }, { select: ["id", "code"] } diff --git a/packages/core/core-flows/src/cart/steps/remove-line-item-adjustments.ts b/packages/core/core-flows/src/cart/steps/remove-line-item-adjustments.ts index cbab15bf71..8d9dc54b40 100644 --- a/packages/core/core-flows/src/cart/steps/remove-line-item-adjustments.ts +++ b/packages/core/core-flows/src/cart/steps/remove-line-item-adjustments.ts @@ -20,6 +20,11 @@ export const removeLineItemAdjustmentsStep = createStep( removeLineItemAdjustmentsStepId, async (data: RemoveLineItemAdjustmentsStepInput, { container }) => { const { lineItemAdjustmentIdsToRemove = [] } = data + + if (!lineItemAdjustmentIdsToRemove?.length) { + return new StepResponse(void 0, []) + } + const cartModuleService: ICartModuleService = container.resolve( Modules.CART ) diff --git a/packages/core/core-flows/src/cart/steps/remove-shipping-method-adjustments.ts b/packages/core/core-flows/src/cart/steps/remove-shipping-method-adjustments.ts index 6d7cd3a74f..1f6a7886d1 100644 --- a/packages/core/core-flows/src/cart/steps/remove-shipping-method-adjustments.ts +++ b/packages/core/core-flows/src/cart/steps/remove-shipping-method-adjustments.ts @@ -21,6 +21,11 @@ export const removeShippingMethodAdjustmentsStep = createStep( removeShippingMethodAdjustmentsStepId, async (data: RemoveShippingMethodAdjustmentsStepInput, { container }) => { const { shippingMethodAdjustmentIdsToRemove = [] } = data + + if (!shippingMethodAdjustmentIdsToRemove?.length) { + return new StepResponse(void 0, []) + } + const cartModuleService: ICartModuleService = container.resolve( Modules.CART ) diff --git a/packages/core/core-flows/src/cart/steps/reserve-inventory.ts b/packages/core/core-flows/src/cart/steps/reserve-inventory.ts index 42756502d6..6448a9aaca 100644 --- a/packages/core/core-flows/src/cart/steps/reserve-inventory.ts +++ b/packages/core/core-flows/src/cart/steps/reserve-inventory.ts @@ -61,8 +61,14 @@ export const reserveInventoryStepId = "reserve-inventory-step" export const reserveInventoryStep = createStep( reserveInventoryStepId, async (data: ReserveVariantInventoryStepInput, { container }) => { - const inventoryService = container.resolve(Modules.INVENTORY) + if (!data.items.length) { + return new StepResponse([], { + reservations: [], + inventoryItemIds: [], + }) + } + const inventoryService = container.resolve(Modules.INVENTORY) const locking = container.resolve(Modules.LOCKING) const inventoryItemIds: string[] = [] diff --git a/packages/core/core-flows/src/cart/steps/update-cart-promotions.ts b/packages/core/core-flows/src/cart/steps/update-cart-promotions.ts index 205c4a7201..068d9423b5 100644 --- a/packages/core/core-flows/src/cart/steps/update-cart-promotions.ts +++ b/packages/core/core-flows/src/cart/steps/update-cart-promotions.ts @@ -35,6 +35,7 @@ export const updateCartPromotionsStep = createStep( updateCartPromotionsStepId, async (data: UpdateCartPromotionStepInput, { container }) => { const { promo_codes = [], id, action = PromotionActions.ADD } = data + const remoteLink = container.resolve(ContainerRegistrationKeys.LINK) const remoteQuery = container.resolve( ContainerRegistrationKeys.REMOTE_QUERY @@ -55,29 +56,31 @@ export const updateCartPromotionsStep = createStep( existingCartPromotionLinks.map((link) => [link.promotion_id, link]) ) - const promotions = await promotionService.listPromotions( - { code: promo_codes }, - { select: ["id"] } - ) - const linksToCreate: any[] = [] const linksToDismiss: any[] = [] - for (const promotion of promotions) { - const linkObject = { - [Modules.CART]: { cart_id: id }, - [Modules.PROMOTION]: { promotion_id: promotion.id }, - } + if (promo_codes?.length) { + const promotions = await promotionService.listPromotions( + { code: promo_codes }, + { select: ["id"] } + ) - if ([PromotionActions.ADD, PromotionActions.REPLACE].includes(action)) { - linksToCreate.push(linkObject) - } + for (const promotion of promotions) { + const linkObject = { + [Modules.CART]: { cart_id: id }, + [Modules.PROMOTION]: { promotion_id: promotion.id }, + } - if (action === PromotionActions.REMOVE) { - const link = promotionLinkMap.get(promotion.id) + if ([PromotionActions.ADD, PromotionActions.REPLACE].includes(action)) { + linksToCreate.push(linkObject) + } - if (link) { - linksToDismiss.push(linkObject) + if (action === PromotionActions.REMOVE) { + const link = promotionLinkMap.get(promotion.id) + + if (link) { + linksToDismiss.push(linkObject) + } } } } diff --git a/packages/modules/cart/src/services/cart-module.ts b/packages/modules/cart/src/services/cart-module.ts index 40777d8b28..95a042ea6b 100644 --- a/packages/modules/cart/src/services/cart-module.ts +++ b/packages/modules/cart/src/services/cart-module.ts @@ -1083,10 +1083,9 @@ export default class CartModuleService ) } - const result = await this.lineItemTaxLineService_.upsert( - taxLines, - sharedContext - ) + const result = taxLines.length + ? await this.lineItemTaxLineService_.upsert(taxLines, sharedContext) + : [] return await this.baseRepository_.serialize( result, @@ -1201,10 +1200,12 @@ export default class CartModuleService ) } - const result = await this.shippingMethodTaxLineService_.upsert( - taxLines as UpdateShippingMethodTaxLineDTO[], - sharedContext - ) + const result = taxLines.length + ? await this.shippingMethodTaxLineService_.upsert( + taxLines as UpdateShippingMethodTaxLineDTO[], + sharedContext + ) + : [] return await this.baseRepository_.serialize< CartTypes.ShippingMethodTaxLineDTO[]