From bd9ecd5e669b0e091d35cb2553705862aaeb0c02 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Tue, 30 Sep 2025 10:01:58 +0300 Subject: [PATCH] docs: updates to custom columns and build guides (#13624) --- www/apps/book/app/learn/build/page.mdx | 59 ++++++- .../configurations/medusa-config/page.mdx | 2 +- .../module-links/custom-columns/page.mdx | 30 +++- www/apps/book/generated/edit-dates.mjs | 6 +- www/apps/book/public/llms-full.txt | 157 +++++++++++++----- 5 files changed, 196 insertions(+), 58 deletions(-) diff --git a/www/apps/book/app/learn/build/page.mdx b/www/apps/book/app/learn/build/page.mdx index 419a593516..7c2ae2bc6d 100644 --- a/www/apps/book/app/learn/build/page.mdx +++ b/www/apps/book/app/learn/build/page.mdx @@ -4,13 +4,13 @@ export const metadata = { # {metadata.title} -In this chapter, you'll learn how to create a production build of your Medusa application to be deployed to a hosting provider. +In this chapter, you'll learn how to create a production build of your Medusa application for deployment to a hosting provider. Next chapters explain how to deploy the Medusa application. ## build Command -The Medusa CLI tool has a [build](!resources!/medusa-cli/commands/build) command which creates a standalone build of the Medusa application that: +The Medusa CLI tool provides a [build](!resources!/medusa-cli/commands/build) command that creates a standalone build of the Medusa application that: - Doesn't rely on the source TypeScript files. - Can be copied to a production server reliably. @@ -25,9 +25,9 @@ npx medusa build ## Build Output -The `build` command creates a `.medusa` directory in the root of your project that contains your build assets. Don't commit this directory to your repository. +The `build` command creates a `.medusa` directory in the root of your project that contains your build assets. Do not commit this directory to your repository. -The `.medusa` directory contains the following directories: +The `.medusa` directory contains the following subdirectories: - `.medusa/server`: Contains the production build of your Medusa application. - `.medusa/server/public/admin`: Contains the production build of the admin dashboard. @@ -46,13 +46,19 @@ npx medusa build --admin-only To start the Medusa application after running the `build` command: -- Change to the `.medusa/server` directory and install the dependencies: + + +You need to run these steps every time you run the `build` command, as the `.medusa` directory is recreated each time. + + + +1. Change to the `.medusa/server` directory and install the dependencies: ```bash npm2yarn cd .medusa/server && npm install ``` -- When running the application locally, make sure to copy the `.env` file from the root project's directory. In production, use system environment variables instead. +2. When running the application locally, make sure to copy the `.env` file from the root project's directory. In production, use system environment variables instead. ```bash title=".medusa/server" cp ../../.env .env.production @@ -64,17 +70,52 @@ When `NODE_ENV=production`, the Medusa application loads the environment variabl -- Set `NODE_ENV` to `production` in the system environment variable, then start the Medusa application from `.medusa/server`: +3. Set `NODE_ENV` to `production` in the system environment variable: ```bash npm2yarn title=".medusa/server" export NODE_ENV=production +``` + +4. Start the Medusa application from `.medusa/server`: + +```bash npm2yarn title=".medusa/server" npm run start ``` +### Authentication Locally in Production Build + +When the Medusa application is started in production (`NODE_ENV=production`) or staging modes, cookie settings are more strict. You can only use cookie authentication if the client application is served from the same domain as the Medusa server, and the domain is not `localhost` or part of the [public suffix list](https://publicsuffix.org/). + +So, if you try to access the Medusa Admin locally in production mode, you won't be able to log in. + +To access the Medusa Admin locally in production mode, set the `projectConfig.cookieOptions` in your `medusa-config.ts` file to be less strict. For example: + +```ts title="medusa-config.ts" +module.exports = defineConfig({ + projectConfig: { + // ... + cookieOptions: { + sameSite: "lax", + secure: false, + } + } +}) +``` + +In this example, you set `sameSite` to `lax` and `secure` to `false`, which allows cookies to be sent over non-secure connections and from different domains. + +Then, rebuild the Medusa application and start it again, as described in the [steps above](#start-built-medusa-application). You can now access the Medusa Admin locally in production mode. + + + +Make sure to remove the `projectConfig.cookieOptions` configuration once you're done testing locally, as it's not secure for production environments. + + + --- ## Deploying Production Build -The next chapter covers how you generally deploy the production build. +The next chapter covers how to deploy the production build. -You can also refer to the [deployment how-to guides](!resources!/deployment) for platform-specific how-to guides. +You can also refer to the [deployment how-to guides](!resources!/deployment) for platform-specific deployment instructions. diff --git a/www/apps/book/app/learn/configurations/medusa-config/page.mdx b/www/apps/book/app/learn/configurations/medusa-config/page.mdx index 0a0deea2b4..dcad539735 100644 --- a/www/apps/book/app/learn/configurations/medusa-config/page.mdx +++ b/www/apps/book/app/learn/configurations/medusa-config/page.mdx @@ -79,7 +79,7 @@ This option is available since Medusa [v2.8.5](https://github.com/medusajs/medus -The `projectConfig.cookieOptions` configuration defines cookie options to be passed to `express-session` when creating the session cookie. This configuration is useful when simulating a production environment locally, where you may need to set options like `secure` or `sameSite`. +The `projectConfig.cookieOptions` configuration defines cookie options to be passed to `express-session` when creating the session cookie. This configuration is useful when simulating a production environment locally, where you may need to set options like `secure` or `sameSite`. Learn more in the [Build chapter](../../build/page.mdx#authentication-locally-in-production-build). #### Example diff --git a/www/apps/book/app/learn/fundamentals/module-links/custom-columns/page.mdx b/www/apps/book/app/learn/fundamentals/module-links/custom-columns/page.mdx index 7c61286fbb..35a0252442 100644 --- a/www/apps/book/app/learn/fundamentals/module-links/custom-columns/page.mdx +++ b/www/apps/book/app/learn/fundamentals/module-links/custom-columns/page.mdx @@ -121,7 +121,35 @@ await link.create({ ## Retrieve Custom Column with Link -To retrieve linked records with their custom columns, use [Query](../query/page.mdx). A module link's definition, exported by a file under `src/links`, has a special `entryPoint` property. Use this property when specifying the `entity` property in Query's `graph` method. +To retrieve linked records with their custom columns, use [Query](../query/page.mdx). This section explores two methods to retrieve a link's custom columns. + +### Method 1: Using Special Link Field + +A data model will have a special field for all its link tables. The field's name is in the `{camel_case_data_model_name}_link` format, where `{camel_case_data_model_name}` is the name of the linked data model in camel case. + +For example: + +export const method1Highlights = [ + ["3", `"post_link.metadata"`, "Retrieve the `metadata` custom column."] +] + +```ts highlights={method1Highlights} +const { data } = await query.graph({ + entity: "product", + fields: ["id", "title", "post_link.metadata", "post.*"], + filters: { + id: "prod_123", + }, +}) +``` + +In this example, you retrieve a product and the `metadata` custom column in the link table between `product` and `post` using the `post_link.metadata` field. + +You can also retrieve all custom columns in the link table using the `post_link.*` field. + +### Method 2: Using Entry Point + +A module link's definition, exported by a file under `src/links`, has a special `entryPoint` property. Use this property when specifying the `entity` property in Query's `graph` method. For example: diff --git a/www/apps/book/generated/edit-dates.mjs b/www/apps/book/generated/edit-dates.mjs index 582d4f9681..65b445e1b3 100644 --- a/www/apps/book/generated/edit-dates.mjs +++ b/www/apps/book/generated/edit-dates.mjs @@ -62,7 +62,7 @@ export const generatedEditDates = { "app/learn/fundamentals/api-routes/errors/page.mdx": "2025-06-19T16:09:08.563Z", "app/learn/fundamentals/admin/constraints/page.mdx": "2025-07-21T08:20:43.223Z", "app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2025-07-23T15:32:18.008Z", - "app/learn/fundamentals/module-links/custom-columns/page.mdx": "2025-03-11T13:29:54.752Z", + "app/learn/fundamentals/module-links/custom-columns/page.mdx": "2025-09-29T16:09:36.116Z", "app/learn/fundamentals/module-links/directions/page.mdx": "2025-03-17T12:52:06.161Z", "app/learn/fundamentals/module-links/page.mdx": "2025-04-17T08:50:17.036Z", "app/learn/fundamentals/module-links/query/page.mdx": "2025-08-15T12:06:30.572Z", @@ -93,7 +93,7 @@ export const generatedEditDates = { "app/learn/fundamentals/data-models/infer-type/page.mdx": "2025-03-18T07:41:01.936Z", "app/learn/fundamentals/custom-cli-scripts/seed-data/page.mdx": "2025-09-15T16:02:51.362Z", "app/learn/fundamentals/environment-variables/page.mdx": "2025-05-26T15:06:07.800Z", - "app/learn/build/page.mdx": "2025-04-25T12:34:33.914Z", + "app/learn/build/page.mdx": "2025-09-30T06:10:46.850Z", "app/learn/deployment/general/page.mdx": "2025-09-01T06:21:43.760Z", "app/learn/fundamentals/workflows/multiple-step-usage/page.mdx": "2025-08-01T14:59:59.501Z", "app/learn/installation/page.mdx": "2025-07-23T14:28:50.404Z", @@ -111,7 +111,7 @@ export const generatedEditDates = { "app/learn/resources/contribution-guidelines/admin-translations/page.mdx": "2025-02-11T16:57:46.726Z", "app/learn/resources/contribution-guidelines/docs/page.mdx": "2025-09-26T13:53:55.070Z", "app/learn/resources/usage/page.mdx": "2025-02-26T13:35:34.824Z", - "app/learn/configurations/medusa-config/page.mdx": "2025-09-02T08:09:21.283Z", + "app/learn/configurations/medusa-config/page.mdx": "2025-09-30T06:04:15.705Z", "app/learn/configurations/ts-aliases/page.mdx": "2025-07-23T15:32:18.008Z", "app/learn/production/worker-mode/page.mdx": "2025-07-18T15:19:45.352Z", "app/learn/fundamentals/module-links/read-only/page.mdx": "2025-08-15T11:52:13.403Z", diff --git a/www/apps/book/public/llms-full.txt b/www/apps/book/public/llms-full.txt index 6f776a46b9..e3c9aa837a 100644 --- a/www/apps/book/public/llms-full.txt +++ b/www/apps/book/public/llms-full.txt @@ -2,13 +2,13 @@ # Build Medusa Application -In this chapter, you'll learn how to create a production build of your Medusa application to be deployed to a hosting provider. +In this chapter, you'll learn how to create a production build of your Medusa application for deployment to a hosting provider. Next chapters explain how to deploy the Medusa application. ## build Command -The Medusa CLI tool has a [build](https://docs.medusajs.com/resources/medusa-cli/commands/build/index.html.md) command which creates a standalone build of the Medusa application that: +The Medusa CLI tool provides a [build](https://docs.medusajs.com/resources/medusa-cli/commands/build/index.html.md) command that creates a standalone build of the Medusa application that: - Doesn't rely on the source TypeScript files. - Can be copied to a production server reliably. @@ -23,9 +23,9 @@ npx medusa build ## Build Output -The `build` command creates a `.medusa` directory in the root of your project that contains your build assets. Don't commit this directory to your repository. +The `build` command creates a `.medusa` directory in the root of your project that contains your build assets. Do not commit this directory to your repository. -The `.medusa` directory contains the following directories: +The `.medusa` directory contains the following subdirectories: - `.medusa/server`: Contains the production build of your Medusa application. - `.medusa/server/public/admin`: Contains the production build of the admin dashboard. @@ -44,13 +44,15 @@ npx medusa build --admin-only To start the Medusa application after running the `build` command: -- Change to the `.medusa/server` directory and install the dependencies: +You need to run these steps every time you run the `build` command, as the `.medusa` directory is recreated each time. + +1. Change to the `.medusa/server` directory and install the dependencies: ```bash npm2yarn cd .medusa/server && npm install ``` -- When running the application locally, make sure to copy the `.env` file from the root project's directory. In production, use system environment variables instead. +2. When running the application locally, make sure to copy the `.env` file from the root project's directory. In production, use system environment variables instead. ```bash title=".medusa/server" cp ../../.env .env.production @@ -58,20 +60,51 @@ cp ../../.env .env.production When `NODE_ENV=production`, the Medusa application loads the environment variables from `.env.production`. Learn more about environment variables in [this guide](https://docs.medusajs.com/learn/fundamentals/environment-variables/index.html.md). -- Set `NODE_ENV` to `production` in the system environment variable, then start the Medusa application from `.medusa/server`: +3. Set `NODE_ENV` to `production` in the system environment variable: ```bash npm2yarn title=".medusa/server" export NODE_ENV=production +``` + +4. Start the Medusa application from `.medusa/server`: + +```bash npm2yarn title=".medusa/server" npm run start ``` +### Authentication Locally in Production Build + +When the Medusa application is started in production (`NODE_ENV=production`) or staging modes, cookie settings are more strict. You can only use cookie authentication if the client application is served from the same domain as the Medusa server, and the domain is not `localhost` or part of the [public suffix list](https://publicsuffix.org/). + +So, if you try to access the Medusa Admin locally in production mode, you won't be able to log in. + +To access the Medusa Admin locally in production mode, set the `projectConfig.cookieOptions` in your `medusa-config.ts` file to be less strict. For example: + +```ts title="medusa-config.ts" +module.exports = defineConfig({ + projectConfig: { + // ... + cookieOptions: { + sameSite: "lax", + secure: false, + } + } +}) +``` + +In this example, you set `sameSite` to `lax` and `secure` to `false`, which allows cookies to be sent over non-secure connections and from different domains. + +Then, rebuild the Medusa application and start it again, as described in the [steps above](#start-built-medusa-application). You can now access the Medusa Admin locally in production mode. + +Make sure to remove the `projectConfig.cookieOptions` configuration once you're done testing locally, as it's not secure for production environments. + *** ## Deploying Production Build -The next chapter covers how you generally deploy the production build. +The next chapter covers how to deploy the production build. -You can also refer to the [deployment how-to guides](https://docs.medusajs.com/resources/deployment/index.html.md) for platform-specific how-to guides. +You can also refer to the [deployment how-to guides](https://docs.medusajs.com/resources/deployment/index.html.md) for platform-specific deployment instructions. # Medusa Application Configuration @@ -145,7 +178,7 @@ The `projectConfig` object contains essential configurations related to the Medu This option is available since Medusa [v2.8.5](https://github.com/medusajs/medusa/releases/tag/v2.8.5). -The `projectConfig.cookieOptions` configuration defines cookie options to be passed to `express-session` when creating the session cookie. This configuration is useful when simulating a production environment locally, where you may need to set options like `secure` or `sameSite`. +The `projectConfig.cookieOptions` configuration defines cookie options to be passed to `express-session` when creating the session cookie. This configuration is useful when simulating a production environment locally, where you may need to set options like `secure` or `sameSite`. Learn more in the [Build chapter](https://docs.medusajs.com/learn/build#authentication-locally-in-production-build/index.html.md). #### Example @@ -13112,7 +13145,31 @@ await link.create({ ## Retrieve Custom Column with Link -To retrieve linked records with their custom columns, use [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query/index.html.md). A module link's definition, exported by a file under `src/links`, has a special `entryPoint` property. Use this property when specifying the `entity` property in Query's `graph` method. +To retrieve linked records with their custom columns, use [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query/index.html.md). This section explores two methods to retrieve a link's custom columns. + +### Method 1: Using Special Link Field + +A data model will have a special field for all its link tables. The field's name is in the `{camel_case_data_model_name}_link` format, where `{camel_case_data_model_name}` is the name of the linked data model in camel case. + +For example: + +```ts highlights={method1Highlights} +const { data } = await query.graph({ + entity: "product", + fields: ["id", "title", "post_link.metadata", "post.*"], + filters: { + id: "prod_123", + }, +}) +``` + +In this example, you retrieve a product and the `metadata` custom column in the link table between `product` and `post` using the `post_link.metadata` field. + +You can also retrieve all custom columns in the link table using the `post_link.*` field. + +### Method 2: Using Entry Point + +A module link's definition, exported by a file under `src/links`, has a special `entryPoint` property. Use this property when specifying the `entity` property in Query's `graph` method. For example: @@ -30131,29 +30188,29 @@ Admin users can then manage the order like any other regular order, including pr # Order Edit -In this document, you'll learn about order edits. +In this guide, you'll learn about order edits. Refer to this [Medusa Admin User Guide](https://docs.medusajs.com/user-guide/orders/edit/index.html.md) to learn how to edit an order's items using the dashboard. ## What is an Order Edit? -A merchant can edit an order to add new items or change the quantity of existing items in the order. +A merchant can edit an order to add new items or change the quantity of existing items. An order edit is represented by the [OrderChange data model](https://docs.medusajs.com/references/order/models/OrderChange/index.html.md). -The `OrderChange` data model is associated with any type of change, including a return or exchange. However, its `change_type` property distinguishes the type of change it's making. +The `OrderChange` data model is associated with any type of change, including returns or exchanges. However, its `change_type` property distinguishes the type of change being made. -In the case of an order edit, the `OrderChange`'s type is `edit`. +For order edits, the `OrderChange`'s `change_type` is `edit`. *** ## Add Items in an Order Edit -When the merchant adds new items to the order in the order edit, the item is added as an [OrderItem](https://docs.medusajs.com/references/order/models/OrderItem/index.html.md). +When a merchant adds new items to an order during editing, the item is added as an [OrderItem](https://docs.medusajs.com/references/order/models/OrderItem/index.html.md). -Also, an `OrderChangeAction` is created. The [OrderChangeAction data model](https://docs.medusajs.com/references/order/models/OrderChangeAction/index.html.md) represents a change made by an `OrderChange`, such as an item added. +Additionally, an `OrderChangeAction` is created. The [OrderChangeAction data model](https://docs.medusajs.com/references/order/models/OrderChangeAction/index.html.md) represents a change made by an `OrderChange`, such as adding an item. -So, when an item is added, an `OrderChangeAction` is created with the type `ITEM_ADD`. In its `details` property, the item's ID, price, and quantity are stored. +When an item is added, an `OrderChangeAction` is created with the type `ITEM_ADD`. Its `details` property stores the item's ID, price, and quantity. *** @@ -30161,7 +30218,7 @@ So, when an item is added, an `OrderChangeAction` is created with the type `ITEM A merchant can update an existing item's quantity or price. -This change is added as an `OrderChangeAction` with the type `ITEM_UPDATE`. In its `details` property, the item's ID, new price, and new quantity are stored. +This change is recorded as an `OrderChangeAction` with the type `ITEM_UPDATE`. Its `details` property stores the item's ID, updated price, and updated quantity. *** @@ -30169,34 +30226,34 @@ This change is added as an `OrderChangeAction` with the type `ITEM_UPDATE`. In i Adding new items to the order requires adding shipping methods for those items. -These shipping methods are represented by the [OrderShippingMethod data model](https://docs.medusajs.com/references/order/models/OrderItem/index.html.md). Also, an `OrderChangeAction` is created with the type `SHIPPING_ADD` +These shipping methods are represented by the [OrderShippingMethod data model](https://docs.medusajs.com/references/order/models/OrderShippingMethod/index.html.md). Also, an `OrderChangeAction` is created with the type `SHIPPING_ADD`. *** ## How Order Edits Impact an Order’s Version -When an order edit is confirmed, the order’s version is incremented. +When an order edit is confirmed, the order’s [version](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/order-versioning/index.html.md) is incremented. *** ## Payments and Refunds for Order Edit Changes -Once the Order Edit is confirmed, any additional payment or refund required can be made on the original order. +Once the order edit is confirmed, any additional payment or refund required can be made on the original order. -This is determined by the comparison between the `OrderSummary` and the order's transactions, as mentioned in [this guide](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/transactions#checking-outstanding-amount/index.html.md). +This is determined by the comparison between the `OrderSummary` and the order's transactions, as mentioned in the [Transactions guide](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/transactions#checking-outstanding-amount/index.html.md). # Order Exchange -In this document, you’ll learn about order exchanges. +In this guide, you’ll learn about order exchanges. Refer to this [Medusa Admin User Guide](https://docs.medusajs.com/user-guide/orders/exchanges/index.html.md) to learn how to manage an order's exchanges using the dashboard. ## What is an Exchange? -An exchange is the replacement of an item that the customer ordered with another. +An exchange is the replacement of an item that the customer ordered with another item. -A merchant creates the exchange, specifying the items to be replaced and the new items to be sent. +A merchant creates the exchange, specifying which items to return and which new items to send. The [OrderExchange data model](https://docs.medusajs.com/references/order/models/OrderExchange/index.html.md) represents an exchange. @@ -30204,11 +30261,11 @@ The [OrderExchange data model](https://docs.medusajs.com/references/order/models ## Returned and New Items -When the exchange is created, a return, represented by the [Return data model](https://docs.medusajs.com/references/order/models/Return/index.html.md), is created to handle receiving the items back from the customer. +When an exchange is created, a return, represented by the [Return data model](https://docs.medusajs.com/references/order/models/Return/index.html.md), is also created to handle receiving the items back from the customer. -Learn more about returns in [this guide](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/return/index.html.md). +Refer to the [Returns guide](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/return/index.html.md) to learn more about returns and how they work. -The [OrderExchangeItem data model](https://docs.medusajs.com/references/order/models/OrderExchangeItem/index.html.md) represents the new items to be sent to the customer. +The [OrderExchangeItem data model](https://docs.medusajs.com/references/order/models/OrderExchangeItem/index.html.md) represents the new items to be sent to the customer. It's associated with the `OrderExchange` data model. *** @@ -30216,27 +30273,27 @@ The [OrderExchangeItem data model](https://docs.medusajs.com/references/order/mo An exchange has shipping methods used to send the new items to the customer. They’re represented by the [OrderShippingMethod data model](https://docs.medusajs.com/references/order/models/OrderShippingMethod/index.html.md). -The shipping methods for the returned items are associated with the exchange's return, as explained in [this guide](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/return#return-shipping-methods/index.html.md). +The shipping methods for the returned items are associated with the exchange's return, as explained in the [Returns guide](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/return#return-shipping-methods/index.html.md). *** ## Exchange Payment -The `Exchange` data model has a `difference_due` property that stores the outstanding amount. +The `OrderExchange` data model has a `difference_due` property that stores the outstanding amount. |Condition|Result| -|---|---|---| -|\`difference\_due \< 0\`|Merchant owes the customer a refund of the | -|\`difference\_due > 0\`|Merchant requires additional payment from the customer of the | +|---|---| +|\`difference\_due \< 0\`|The merchant owes the customer a refund of the | +|\`difference\_due > 0\`|The merchant requires additional payment from the customer of the | |\`difference\_due = 0\`|No payment processing is required.| -Any payment or refund made is stored in the [Transaction data model](https://docs.medusajs.com/references/order/models/OrderTransaction/index.html.md). +Any payments or refunds made are stored in the [OrderTransaction data model](https://docs.medusajs.com/references/order/models/OrderTransaction/index.html.md). *** ## How Exchanges Impact an Order’s Version -When an exchange is confirmed, the order’s version is incremented. +When an exchange is confirmed, the order’s [version](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/order-versioning/index.html.md) is incremented. # Links between Order Module and Other Modules @@ -35795,13 +35852,15 @@ In this example, the cart must have two product variants with the SKU `SHIRT` fo # Campaign -In this document, you'll learn about campaigns. +In this guide, you'll learn what a campaign is and its related concepts. Refer to this [Medusa Admin User Guide](https://docs.medusajs.com/user-guide/promotions/campaigns/index.html.md) to learn how to manage campaigns using the dashboard. ## What is a Campaign? -A [Campaign](https://docs.medusajs.com/references/promotion/models/Campaign/index.html.md) combines promotions under the same conditions, such as start and end dates. +A [Campaign](https://docs.medusajs.com/references/promotion/models/Campaign/index.html.md) combines [promotions](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/promotion/concepts#what-is-a-promotion/index.html.md) under the same conditions, such as start and end dates. + +Campaigns are useful for grouping promotions that share the same time frame or target audience. They're also useful for limiting the usage of promotions. ![A diagram showcasing the relation between the Campaign and Promotion data models](https://res.cloudinary.com/dza7lstvk/image/upload/v1709899225/Medusa%20Resources/campagin-promotion_hh3qsi.jpg) @@ -35809,15 +35868,25 @@ A [Campaign](https://docs.medusajs.com/references/promotion/models/Campaign/inde ## Campaign Limits -Each campaign has a budget represented by the [CampaignBudget data model](https://docs.medusajs.com/references/promotion/models/CampaignBudget/index.html.md). The budget limits how many times the promotion can be used. +Each campaign can have a budget represented by the [CampaignBudget data model](https://docs.medusajs.com/references/promotion/models/CampaignBudget/index.html.md). The budget limits how many times the promotion can be used. There are two types of budgets: -- `spend`: An amount that, when crossed, the promotion becomes unusable. For example, if the amount limit is set to `$100`, and the total amount of usage of this promotion crosses that threshold, the promotion can no longer be applied. -- `usage`: The number of times that a promotion can be used. For example, if the usage limit is set to `10`, the promotion can be used only 10 times by customers. After that, it can no longer be applied. +- `spend`: An amount that, when crossed, the promotion becomes unusable. + - For example, if the amount limit is set to `$100`, and the total amount of usage of this promotion crosses that threshold, the promotion can no longer be applied. +- `usage`: The number of times that a promotion can be used. + - For example, if the usage limit is set to `10`, the promotion can be used only 10 times by customers. After that, it can no longer be applied. ![A diagram showcasing the relation between the Campaign and CampaignBudget data models](https://res.cloudinary.com/dza7lstvk/image/upload/v1709899463/Medusa%20Resources/campagin-budget_rvqlmi.jpg) +### How Budgets Limit Promotion Usage + +When a customer tries to use a promotion, Medusa checks whether the campaign has a budget and if the budget limit has been reached. If so, the promotion cannot be applied. + +For example, if a campaign has a budget of type `usage` with a limit of `10`, and the promotion has already been used 10 times, it cannot be applied anymore and is considered expired. + +However, once a promotion is applied to a cart, it remains valid until the order is completed, even if the budget limit is reached in the meantime. This ensures that customers who have already applied the promotion can still benefit from it during checkout. + # Promotion Concepts @@ -38249,7 +38318,7 @@ Then, the next time the Medusa application starts, it will set the `is_enabled` # Tax Rates and Rules -In this document, you’ll learn about tax rates and rules. +In this guide, you’ll learn about tax rates and rules. Refer to this [Medusa Admin User Guide](https://docs.medusajs.com/user-guide/settings/tax-regions#manage-tax-rate-overrides/index.html.md) to learn how to manage tax rates using the dashboard. @@ -38271,13 +38340,13 @@ Then, when tax rates are retrieved for a taxable item in the child region, both You can create tax rates that override the default for specific conditions or rules. -For example, you can have a default tax rate is 10%, but for products of type “Shirt” is %15. +For example, you can have a default 10% tax rate, but for products of type “Shirt” it is 15%. A tax region can have multiple tax rates, and each tax rate can have multiple tax rules. The [TaxRateRule data model](https://docs.medusajs.com/references/tax/models/TaxRateRule/index.html.md) represents a tax rate’s rule. ![A diagram showcasing the relation between TaxRegion, TaxRate, and TaxRateRule](https://res.cloudinary.com/dza7lstvk/image/upload/v1711462167/Medusa%20Resources/tax-rate-rule_enzbp2.jpg) -These two properties of the data model identify the rule’s target: +The following two properties of the data model identify the rule’s target: - `reference`: the name of the table in the database that this rule points to. For example, `product_type`. - `reference_id`: the ID of the data model’s record that this points to. For example, a product type’s ID.