v2.11.0
medusajs/medusav2.11.0Oct 21, 2025by olivermrbl
AI Summary
Introduces a new caching module (in preview), manual refunds, and improved promotion limits. Includes a major breaking change consolidating core dependencies.
Key Highlights
- New caching primitives and Redis provider
- Manual order refunds with refund reasons
- Promotion limits per customer attribute
- New 'once' promotion allocation method
- Bundle core Medusa dependencies into @medusajs/deps
Breaking Changes
- Bundle core Medusa dependencies into @medusajs/deps package
- Updated variants response in GET /store/products (null vs 0)
- Updated refetchEntity and refetchEntities signatures
- Changed File Upload Encoding (binary to base64)
New Features
- Distributed caching
- Manual refunds
- Limit promotion usage per customer
- Once allocation strategy
- Cluster mode for servers and workers
Full Release Notes
<!--

# v2.11.0: Caching primitives, manual refunds, and improved promotion limits
This release introduces new caching primitives, manual refunds, and more advanced promotion limits.
CMS_BREAK -->
## Highlights
### Caching layer
This release adds new caching primitives to Medusa's toolbox.
_1. New caching module, `@medusajs/caching`_
We have added a new caching module in early preview with strong tools to integrate a cache into your Medusa application. The module comprises three key elements:
- Cache service: the main module service with a simple API for interacting with the cache
- Cache provider: the provider service responsible for delegating operations to the configured cache provider
- Cache strategy: the strategy responsible for computing cache keys and invalidation tags
**Cache invalidation**
Knowing when and how to invalidate cache entries is a challenging task. With the new caching module, we have baked this logic directly into the tooling, so you don't have to manage the complexity yourself.
We plan to share a technical deep dive covering the invalidation mechanism in detail, but here's the short version: whenever entries are inserted, the cache strategy computes tags based on the data. Invalidation of these entries relies on internal module events emitted whenever mutational service methods are called, e.g. `service.update({ ... })`. The cache strategy intercepts these events, computes the relevant tags using the event data, and instructs the cache provider to clear all entries associated with those tags.
Read more about this [in our documentation](https://docs.medusajs.com/resources/infrastructure-modules/caching/concepts#automatic-cache-invalidation).
_2. New Redis caching provider, `@medusajs/caching-redis`_
As described above, the new caching module follows our existing provider architecture, allowing different technologies to be used interchangeably without affecting the core application. In this release, we’ve introduced a Redis caching provider, which integrates directly with the caching module and serves as the underlying storage layer for the cached data.
_3. New cache option on Medusa Query_
Finally, to use the cache, we have introduced a new `cache` option in our `query.graph` API:
```ts
const { data } = await query.graph({
entity: "product",
filters: { id: "prod_1234" },
options: { cache: { enable: true } }
})
```
This new option allows you to leverage the full power of the cache without having to think about computing keys and invalidation tags. These are automatically computed when `query.graph` is configured to use the cache.
**Installation**
Since the caching module is still in early preview, you need to enable a feature flag to use it in addition to registering the Redis cache provider in your `medusa-config.ts`. The new packages come pre-installed in the latest version of `@medusajs/medusa`.
```ts
// medusa-config.ts
module.exports = defineConfig({
projectConfig: { ... },
modules: [
{
resolve: "@medusajs/medusa/caching",
options: {
providers: [
{
id: "caching-redis",
resolve: "@medusajs/caching-redis",
options: {
redisUrl: process.env.REDIS_URL,
},
},
],
},
},
],
featureFlags: {
caching: true,
},
});
```
By default, the cache is integrated across several business-critical APIs to boost performance and throughput. This includes all cart-related operations, where we cache the following data:
- Regions
- Promotion codes
- Variant price sets
- Variants
- Shipping options
- Sales channels
- Customers
With caching enabled, we’ve observed performance improvements of up to 70% across these operations. Read our [blog post
for detailed benchmarks](https://medusajs.com/blog/medusa-cache-benchmarks/) across different Medusa versions.
Bear in mind, our new caching tools are in preview, so they should be used with caution.
### Bundle core Medusa dependencies
_Breaking change_
This release restructures the required dependencies of Medusa projects. We are consolidating all non-Medusa dependencies into a new `@medusajs/deps` package, which is installed internally in `@medusajs/medusa`. We are making this change to take control over our core dependencies. This will enable us to add new dependencies and do minor/major upgrades of core dependencies without breaking users' applications.
This is a breaking change, and the following steps are required to use versions 2.11.0 and over:
1. Remove the following packages from dependencies in your `package.json`:
```json
"dependencies": {
"@medusajs/admin-sdk": "2.11.0",
"@medusajs/cli": "2.11.0",
"@medusajs/framework": "2.11.0",
"@medusajs/medusa": "2.11.0",
- "@mikro-orm/core": "6.4.3",
- "@mikro-orm/knex": "6.4.3",
- "@mikro-orm/migrations": "6.4.3",
- "@mikro-orm/postgresql": "6.4.3",
- "awilix": "^8.0.1",
- "pg": "^8.13.0"
},
"devDependencies": {
"@medusajs/test-utils": "2.11.0",
- "@mikro-orm/cli": "6.4.3",
...
```
2. Install dependencies using your preferred package manager
3. Run the included codemod (see section below)
4. Start your application. If you have issues, please open a GitHub Issue and we will help you out as soon as possible
**Codemod**
By side effect, this update also requires you to update explicit imports from these dependencies in your own project. To help you with this, we have included a codemod that automatically replaces imports throughout your codebase.
To use the codemod, create a file `replace-imports.js` in the root of your Medusa application with the following content
<details>
<summary>Codemod</summary>
```js
#!/usr/bin/env node
const fs = require("fs")
const path = require("path")
const { execSync } = require("child_process")
/**
* Script to replace imports and require statements from mikro-orm/{subpath}, awilix, and pg
* to their @medusajs/framework equivalents
*/
// Define the replacement mappings
const replacements = [
// MikroORM imports - replace mikro-orm/{subpath} with @medusajs/framework/mikro-orm/{subpath}
{
pattern: /from\s+['"]@?mikro-orm\/([^'"]+)['"]/g,
// eslint-disable-next-line quotes
replacement: 'from "@medusajs/framework/mikro-orm/$1"',
},
// Awilix imports - replace awilix with @medusajs/framework/awilix
{
pattern: /from\s+['"]awilix['"]/g,
// eslint-disable-next-line quotes
replacement: 'from "@medusajs/framework/awilix"',
},
// PG imports - replace pg with @medusajs/framework/pg
{
pattern: /from\s+['"]pg['"]/g,
// eslint-disable-next-line quotes
replacement: 'from "@medusajs/framework/pg"',
},
// OpenTelemetry imports - replace @opentelemetry/instrumentation-pg, @opentelemetry/resources,
// @opentelemetry/sdk-node, and @opentelemetry/sdk-trace-node with @medusajs/framework/opentelemetry/{subpath}
{
pattern: /from\s+['"]@?opentelemetry\/(instrumentation-pg|resources|sdk-node|sdk-trace-node)['"]/g,
// eslint-disable-next-line quotes
replacement: 'from "@medusajs/framework/opentelemetry/$1"',
},
// MikroORM require statements - replace require('@?mikro-orm/{subpath}') with require('@medusajs/framework/mikro-orm/{subpath}')
{
pattern: /require\s*\(\s*['"]@?mikro-orm\/([^'"]+)['"]\s*\)/g,
// eslint-disable-next-line quotes
replacement: 'require("@medusajs/framework/mikro-orm/$1")',
},
// Awilix require statements - replace require('awilix') with require('@medusajs/framework/awilix')
{
pattern: /require\s*\(\s*['"]awilix['"]\s*\)/g,
// eslint-disable-next-line quotes
replacement: 'require("@medusajs/framework/awilix")',
},
// PG require statements - replace require('pg') with require('@medusajs/framework/pg')
{
pattern: /require\s*\(\s*['"]pg['"]\s*\)/g,
// eslint-disable-next-line quotes
replacement: 'require("@medusajs/framework/pg")',
},
// OpenTelemetry require statements - replace require('@opentelemetry/instrumentation-pg'),
// require('@opentelemetry/resources'), require('@opentelemetry/sdk-node'), and
// require('@opentelemetry/sdk-trace-node') with require('@medusajs/framework/opentelemetry/{subpath}')
{
pattern: /require\s*\(\s*['"]@?opentelemetry\/(instrumentation-pg|resources|sdk-node|sdk-trace-node)['"]\s*\)/g,
// eslint-disable-next-line quotes
replacement: 'require("@medusajs/framework/opentelemetry/$1")',
},
]
function processFile(filePath) {
try {
const content = fs.readFileSync(filePath, "utf8")
let modifiedContent = content
let wasModified = false
replacements.forEach(({ pattern, replacement }) => {
const newContent = modifiedContent.replace(pattern, replacement)
if (newContent !== modifiedContent) {
wasModified = true
modifiedContent = newContent
}
})
if (wasModified) {
fs.writeFileSync(filePath, modifiedContent)
console.log(`✓ Updated: ${filePath}`)
return true
}
return false
} catch (error) {
console.error(`✗ Error processing ${filePath}:`, error.message)
return false
}
}
function getTargetFiles() {
try {
// Get the current script's filename to exclude it from processing
const currentScript = path.basename(__filename)
// Find TypeScript/JavaScript files, excluding common directories that typically don't contain target imports
const findCommand = `find . -name node_modules -prune -o -name .git -prune -o -name dist -prune -o -name build -prune -o -name coverage -prune -o -name "*.ts" -print -o -name "*.js" -print -o -name "*.tsx" -print -o -name "*.jsx" -print`
const files = execSync(findCommand, {
encoding: "utf8",
maxBuffer: 50 * 1024 * 1024, // 50MB buffer
})
.split("\n")
.filter((line) => line.trim())
console.log(files)
const targetFiles = []
let processedCount = 0
console.log(`📄 Scanning ${files.length} files for target imports and require statements...`)
for (const file of files) {
try {
// Skip the current script file
const fileName = path.basename(file)
if (fileName === currentScript) {
processedCount++
continue
}
const content = fs.readFileSync(file, "utf8")
if (
/from\s+['"]@?mikro-orm\//.test(content) ||
/from\s+['"]awilix['"]/.test(content) ||
/from\s+['"]pg['"]/.test(content) ||
/require\s*\(\s*['"]@?mikro-orm\//.test(content) ||
/require\s*\(\s*['"]awilix['"]/.test(content) ||
/require\s*\(\s*['"]pg['"]/.test(content)
) {
targetFiles.push(file.startsWith("./") ? file.slice(2) : file)
}
processedCount++
if (processedCount % 100 === 0) {
process.stdout.write(
`\r📄 Processed ${processedCount}/${files.length} files...`
)
}
} catch (fileError) {
// Skip files that can't be read
continue
}
}
if (processedCount > 0) {
console.log(`\r📄 Processed ${processedCount} files. `)
}
return targetFiles
} catch (error) {
console.error("Error finding target files:", error.message)
return []
}
}
function main() {
console.log("🔄 Finding files with target imports and require statements...")
const targetFiles = getTargetFiles()
if (targetFiles.length === 0) {
console.log("ℹ️ No files found with target imports or require statements.")
return
}
console.log(`📁 Found ${targetFiles.length} files to process`)
let modifiedCount = 0
let errorCount = 0
targetFiles.forEach((filePath) => {
const fullPath = path.resolve(filePath)
if (fs.existsSync(fullPath)) {
if (processFile(fullPath)) {
modifiedCount++
}
} else {
console.warn(`⚠️ File not found: ${filePath}`)
errorCount++
}
})
console.log("\n📊 Summary:")
console.log(` Files processed: ${targetFiles.length}`)
console.log(` Files modified: ${modifiedCount}`)
console.log(` Errors: ${errorCount}`)
if (modifiedCount > 0) {
console.log("\n✅ Import replacement completed successfully!")
console.log("\n💡 Next steps:")
console.log(" 1. Review the changes with: git diff")
console.log(" 2. Run your tests to ensure everything works correctly")
console.log(" 3. Commit the changes if you're satisfied")
} else {
console.log(
"\n✅ No modifications needed - all imports are already correct!"
)
}
}
// Run if called directly
if (require.main === module) {
main()
}
module.exports = { processFile, getTargetFiles, main }
```
</details>
This script scans your project for files that import the removed dependencies, and replaces those imports with their new equivalents from Medusa.
Next, execute the script with the following command:
```sh
node replace-imports.js
```
This will scan your project files, apply the necessary import replacements, and provide a summary of the changes made.
If you still have issues with imports after running the codemod, please create an issue on GitHub, so we can help.
The release of the new Caching Module deprecates the old cache modules:
- `@medusajs/cache`
- `@medusajs/cache-redis`
- `@medusajs/cache-inmemory`
The deprecation happens to move our caching tooling to follow the general provider architecture. These modules will be removed in a future release. We recommend replacing existing usage as soon as possible.
### Manual order refunds
This release adds manual order refunds. It is now possible to issue refunds that are not tied to returned items. Previously, refunds were only possible as part of a return or exchange where items are returned and the difference due was consequently negative. This version introduces full support for ad-hoc refunds with new Refund Reasons.
The key changes are:
- Ad-hoc refunds: issue refunds on orders regardless of the difference due
- Refund Reasons UI: create and manage custom refund reasons to categorize refunds for accounting purposes
- Refund drawer update: The refund drawer on the order details page now includes an option to select a Refund Reason
- Credit lines: when issuing ad-hoc refunds, Medusa creates corresponding credit lines on the order for accurate financial tracking
This feature comes with changes to the database schemas, so you need to run migrations:
```
npx medusa db:migrate
```
### Promotion limits per customer
This release adds support for defining promotion usage limits per customer. Campaign budgets can now track usage based on an attribute (e.g., `customer_id`, `email`) and enforce limits accordingly.
The key changes are:
- New Campaign Budget Type added `USE_BY_ATTRIBUTE` to support per-attribute usage tracking.
- New entity `CampaignBudgetUsage` added: tracks usage counts per attribute.
- Extended `CampaignBudget` entity:
- Added attribute field (e.g. `customer_id`) to define the usage key
- Added `usages` relation expanding `CampaignBudgetUsage`
- `limit` on Campaign Budgets now applies per attribute for `USE_BY_ATTRIBUTE` budgets
Promotion usage is registered in the cart completion flow.
**Admin + API Support:**
Updated admin to support creating and managing customer attribute budgets.
### New _once_ promotion allocation method
This release adds a new `once` allocation strategy to promotions that limits application to a maximum number of items across the entire cart, rather than per line item.
Example cases:
- "Get $10 off, applied to one item only"
- "20% off up to 2 items in your cart"
The behavior is as follows:
- Applies promotion to maximum `max_quantity` items across entire cart
- Always prioritizes lowest-priced eligible items first
- Distributes sequentially across items until quota exhausted
- Requires `max_quantity` field to be set
### Other noteworthy changes
**Updated variants response in `GET /store/products`**
_Breaking change_
When you fetch variants from the Store Products API, we compute inventory based on the locations associated with the specified sales channel. Up until now, we have returned `inventory_quantity: 0` in case the location did not have any inventory levels for the variants. Going forward, we will return `inventory_quantity: null`. Read more [in the PR](https://github.com/medusajs/medusa/pull/13703).
**Updated refetch entity utilities**
_Breaking change_
The utilities `refetchEntity` and `refetchEntities` have had their method signatures changed to improve usability.
**Before**
```js
async refetchEntities(entryPoint: string, idOrFilter: string | object, scope: MedusaContainer, fields: string[], pagination?: MedusaRequest["queryConfig"]["pagination"], withDeleted?: boolean);
async refetchEntity(entryPoint: string, idOrFilter: string | object, scope: MedusaContainer, fields: string[]);
```
**Now**
```js
async refetchEntities({ entity, idOrFilter, scope, fields, pagination, withDeleted, options })
async refetchEntity({ entity, idOrFilter, scope, fields, options })
```
**Updated Locations & Shipping settings page**
We have changed the Locations & Shipping page to use a regular datatable to allow browsing more than 20 locations.
**Changed File Upload Encoding**
_Breaking change_
Prior to this version, files uploaded through `/admin/uploads` were encoded to binary. Now they're encoded to base64. The Local Storage and S3 file providers have been updated to handle this change. Custom file providers must also handle the change in encoding as well. We recommend supporting both upload types, as you can see in the [S3 File Provider](https://github.com/medusajs/medusa/blob/febf3c173342ac8e1e5b81101176dbc32f64cf56/packages/modules/providers/file-s3/src/services/s3-file.ts#L124-L134)
## Features
* Feat(): faster entity serializer by @adrien2p in https://github.com/medusajs/medusa/pull/13564
* feat(js-sdk): allow passing a query parameter to deleteLineItem by @shahednasser in https://github.com/medusajs/medusa/pull/13581
* feat(admin-shared,dashboard,js-sdk,types): refund reasons in dashboard by @willbouch in https://github.com/medusajs/medusa/pull/13575
* feat(dashboard): refactor location list UI to use data table by @fPolic in https://github.com/medusajs/medusa/pull/13571
* feat(dashboard): select refund reason in refund form by @willbouch in https://github.com/medusajs/medusa/pull/13587
* fix(dashboard): improve inventory level location management by @fPolic in https://github.com/medusajs/medusa/pull/13589
* feat(cli): servers and workers in cluster mode by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13601
* feat(core-flows): support ad hoc returns by @willbouch in https://github.com/medusajs/medusa/pull/13598
* feat(payment-stripe): Allow passing shared payment token in Stripe by @shahednasser in https://github.com/medusajs/medusa/pull/13632
* Feat(): distributed caching by @adrien2p in https://github.com/medusajs/medusa/pull/13435
* feat(core-flows,dashboard,js-sdk,promotion,medusa,types,utils): limit promotion usage per customer by @fPolic in https://github.com/medusajs/medusa/pull/13451
* feat: Add allocation method type `ONCE` by @olivermrbl in https://github.com/medusajs/medusa/pull/13700
* feat: Add support for multiple active keys at a time by @sradevski in https://github.com/medusajs/medusa/pull/13754
## Bugs
* fix(auth-emailpass): better handle identity with same email error by @willbouch in https://github.com/medusajs/medusa/pull/13537
* fix(medusa-test-utils): add health endpoint in test server by @willbouch in https://github.com/medusajs/medusa/pull/13546
* fix(types): pluralize settings by @willbouch in https://github.com/medusajs/medusa/pull/13558
* fix(engine): Always create cleaner job by @adrien2p in https://github.com/medusajs/medusa/pull/13557
* fix(types): missing service zone in shipping option by @willbouch in https://github.com/medusajs/medusa/pull/13559
* fix(workflow-engine-redis): use worker connection by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13561
* fix(workflow-engine-redis): module option queueName wrongly used by @adrien2p in https://github.com/medusajs/medusa/pull/13570
* fix(order): save return's location ID from input by @shahednasser in https://github.com/medusajs/medusa/pull/13567
* fix(utils): Query filters API should have nested optional props by @adrien2p in https://github.com/medusajs/medusa/pull/13583
* fix(dashboard, order): set return status on cancel by @fPolic in https://github.com/medusajs/medusa/pull/13578
* fix(dashboard): edit promotion campaign w/wo currrency by @fPolic in https://github.com/medusajs/medusa/pull/13404
* fix(core-flows): skip locking by default on subworkflows by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13594
* fix(dashboard): payment providers select by @fPolic in https://github.com/medusajs/medusa/pull/13592
* fix(medusa): start cluster by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13599
* fix(): Cart workflow price calculation for different items but same variant by @adrien2p in https://github.com/medusajs/medusa/pull/13511
* fix(medusa): cart now returns 404 when not found by @willbouch in https://github.com/medusajs/medusa/pull/13622
* fix(): Pricing preference context loss by @adrien2p in https://github.com/medusajs/medusa/pull/13626
* fix(): Module test runner lifecycle does not shutdown properly by @adrien2p in https://github.com/medusajs/medusa/pull/13628
* fix(): workflow engine migration issue by @adrien2p in https://github.com/medusajs/medusa/pull/13629
* fix(dashboard): create refund form broken when no payment id defined by @willbouch in https://github.com/medusajs/medusa/pull/13631
* fix(medusa): fixes db setup command to not load connection before creating db by @riqwan in https://github.com/medusajs/medusa/pull/13653
* fix(): Fulfillment custom schema error on provider by @adrien2p in https://github.com/medusajs/medusa/pull/13656
* fix(medusa,file-local,file-s3,core-flows): fix csv parsing special characters by @willbouch in https://github.com/medusajs/medusa/pull/13649
* fix(): workflows concurrency by @adrien2p in https://github.com/medusajs/medusa/pull/13645
* fix(): Transform map by @adrien2p in https://github.com/medusajs/medusa/pull/13655
* fix(core-flows): lock draft order workflows by @willbouch in https://github.com/medusajs/medusa/pull/13668
* fix(): caching better identify default provider by @adrien2p in https://github.com/medusajs/medusa/pull/13675
* fix(types): missing rules in prices types by @willbouch in https://github.com/medusajs/medusa/pull/13669
* fix(medusa,utils,types): inventory management nullable by @willbouch in https://github.com/medusajs/medusa/pull/13703
* fix(): Workflow save to db + index integration instability by @adrien2p in https://github.com/medusajs/medusa/pull/13707
* fix(dashboard): nan in tax total by @willbouch in https://github.com/medusajs/medusa/pull/13699
* fix(dashboard): export with filters not working by @willbouch in https://github.com/medusajs/medusa/pull/13711
* fix(core-flows): customer id filter not working in getOrderDetails by @willbouch in https://github.com/medusajs/medusa/pull/13695
* fix(dashboard): campaign UI improvements by @fPolic in https://github.com/medusajs/medusa/pull/13723
* fix(core-flows): fix warning for when usage in updateOrderTaxLinesWorkflow by @shahednasser in https://github.com/medusajs/medusa/pull/13738
* fix(dashboard): campaign budget labels improvements by @fPolic in https://github.com/medusajs/medusa/pull/13740
* chore: Ensure refund doesn't exceed captured amount by @olivermrbl in https://github.com/medusajs/medusa/pull/13744
* fix(utils,core-flows): fix import erasing tags, categories and others by @willbouch in https://github.com/medusajs/medusa/pull/13724
* fix(dashboard): add error message in toaster on product delete by @willbouch in https://github.com/medusajs/medusa/pull/13756
* fix(draft-order): email reset when changing customer by @fPolic in https://github.com/medusajs/medusa/pull/13771
## Documentation
* chore(docs): Generated References (automated) by @github-actions[bot] in https://github.com/medusajs/medusa/pull/13544
* docs: regenerate reference for views changes by @shahednasser in https://github.com/medusajs/medusa/pull/13551
* docs: generate API reference for 2.10.3 by @shahednasser in https://github.com/medusajs/medusa/pull/13548
* docs: disable retrieving Cloud pricing data on preview + other changes by @shahednasser in https://github.com/medusajs/medusa/pull/13552
* chore(): Move peer deps into a single package and re export from framework by @adrien2p in https://github.com/medusajs/medusa/pull/13439
* docs: fix @medusajs/ui version in docs by @shahednasser in https://github.com/medusajs/medusa/pull/13577
* docs: update GitHub link in ticket booking example by @ericwaetke in https://github.com/medusajs/medusa/pull/13582
* docs: create returns from storefront tutorial by @shahednasser in https://github.com/medusajs/medusa/pull/13522
* docs: improve docs contribution guidelines by @shahednasser in https://github.com/medusajs/medusa/pull/13605
* docs: add missing generated files by @shahednasser in https://github.com/medusajs/medusa/pull/13609
* docs: fix pricing page on small devices by @shahednasser in https://github.com/medusajs/medusa/pull/13617
* docs: fix mobile menu not closing when clicking a link by @shahednasser in https://github.com/medusajs/medusa/pull/13618
* docs: fix search not highlighting subheaders by @shahednasser in https://github.com/medusajs/medusa/pull/13619
* docs: general updates and fixes by @shahednasser in https://github.com/medusajs/medusa/pull/13620
* docs: updates to custom columns and build guides by @shahednasser in https://github.com/medusajs/medusa/pull/13624
* docs: general changes to Cloud docs by @shahednasser in https://github.com/medusajs/medusa/pull/13616
* docs: add details about updating index module's data source by @shahednasser in https://github.com/medusajs/medusa/pull/13637
* docs: fix details about maximum quantity for promotions by @shahednasser in https://github.com/medusajs/medusa/pull/13642
* docs: update Cloud sign up link by @shahednasser in https://github.com/medusajs/medusa/pull/13648
* docs: fix typo by @shahednasser in https://github.com/medusajs/medusa/pull/13643
* Updated the cost descriptions.mdx by @MedusaNick in https://github.com/medusajs/medusa/pull/13647
* docs: fix typo in product feed guide by @shahednasser in https://github.com/medusajs/medusa/pull/13658
* docs: setup PostHog by @shahednasser in https://github.com/medusajs/medusa/pull/13659
* docs: document preview limits in Cloud + general updates by @shahednasser in https://github.com/medusajs/medusa/pull/13661
* docs: fix cursor MCP link by @shahednasser in https://github.com/medusajs/medusa/pull/13664
* docs: agentic commerce guide by @shahednasser in https://github.com/medusajs/medusa/pull/13657
* docs: improve troubleshooting guide for pnpm by @shahednasser in https://github.com/medusajs/medusa/pull/13673
* docs: improved analytics and tracking by @shahednasser in https://github.com/medusajs/medusa/pull/13671
* docs: fixes to github solutions componen by @shahednasser in https://github.com/medusajs/medusa/pull/13676
* docs: added refund details related to transactions by @shahednasser in https://github.com/medusajs/medusa/pull/13677
* docs: remove mention of base64 requirement for api keys by @shahednasser in https://github.com/medusajs/medusa/pull/13679
* docs: fix error when translating page by @shahednasser in https://github.com/medusajs/medusa/pull/13681
* docs: add guide on storefront production optimization tips by @shahednasser in https://github.com/medusajs/medusa/pull/13682
* docs: Add note on LF endings for Docker setup by @Mayuresh-1306 in https://github.com/medusajs/medusa/pull/13650
* docs: fix client error in UI docs by @shahednasser in https://github.com/medusajs/medusa/pull/13686
* docs: show badge for Community integrations by @shahednasser in https://github.com/medusajs/medusa/pull/13691
* docs: meilisearch integration tutorial by @shahednasser in https://github.com/medusajs/medusa/pull/13532
* docs: separate Billing + Plans guide and add note for Indian cards by @shahednasser in https://github.com/medusajs/medusa/pull/13710
* docs: add note to tutorials related to types by @shahednasser in https://github.com/medusajs/medusa/pull/13720
* docs: support since, deprecated, and feature flag tags in dml reference by @shahednasser in https://github.com/medusajs/medusa/pull/13741
* docs: improve headings and context in Cloud docs by @shahednasser in https://github.com/medusajs/medusa/pull/13757
* docs: fix limit text length code by @shahednasser in https://github.com/medusajs/medusa/pull/13752
* docs: clarify how to use token in Auth Provider guide by @shahednasser in https://github.com/medusajs/medusa/pull/13759
* docs: clarify relation name for read-only links by @shahednasser in https://github.com/medusajs/medusa/pull/13758
* docs: add troubleshooting for subscribers + scheduled jobs not working by @shahednasser in https://github.com/medusajs/medusa/pull/13762
* docs: improve references loading by @shahednasser in https://github.com/medusajs/medusa/pull/13761
* docs: add troubleshooting section for middleware by @shahednasser in https://github.com/medusajs/medusa/pull/13764
* docs: fix content shift in references by @shahednasser in https://github.com/medusajs/medusa/pull/13765
* docs: add deep thinking to AI assistant by @shahednasser in https://github.com/medusajs/medusa/pull/13770
## Chores
* chore(docs): Updated UI Reference (automated) by @github-actions[bot] in https://github.com/medusajs/medusa/pull/13542
* chore(docs): Update version in documentation (automated) by @github-actions[bot] in https://github.com/medusajs/medusa/pull/13543
* chore: add since and feature flag TSDocs for setting workflows by @shahednasser in https://github.com/medusajs/medusa/pull/13550
* Chore/promo improve further by @adrien2p in https://github.com/medusajs/medusa/pull/13556
* chore(): upgrade mikro orm by @adrien2p in https://github.com/medusajs/medusa/pull/13450
* chore(medusa): remove empty object type for set cart's customer route by @shahednasser in https://github.com/medusajs/medusa/pull/13549
* chore(): remove ssl_mode from url and also use sslmode by @adrien2p in https://github.com/medusajs/medusa/pull/13568
* chore(utils): make upsert with replace more efficient by @adrien2p in https://github.com/medusajs/medusa/pull/13580
* chore(): create default refund reasons by @willbouch in https://github.com/medusajs/medusa/pull/13591
* chore(): Add instrumentation to deps by @adrien2p in https://github.com/medusajs/medusa/pull/13646
* chore(): Caching improvements by @adrien2p in https://github.com/medusajs/medusa/pull/13660
* chore: updated TSDocs of the Caching Module service + provider by @shahednasser in https://github.com/medusajs/medusa/pull/13696
* chore(): Default caching configuration and gracefull redis error handling by @adrien2p in https://github.com/medusajs/medusa/pull/13663
* chore: Temporary patch to bypass changesets issue with too many commits by @olivermrbl in https://github.com/medusajs/medusa/pull/13706
* chore(): Improve caching rollout by @adrien2p in https://github.com/medusajs/medusa/pull/13702
* chore: fixes to Caching Module's TSDocs by @shahednasser in https://github.com/medusajs/medusa/pull/13709
* chore(): add PR template by @willbouch in https://github.com/medusajs/medusa/pull/13721
* chore(): improve cart operations + Mikro orm 6.4.16 by @adrien2p in https://github.com/medusajs/medusa/pull/13712
* chore: added TSDocs to refund reason HTTP type by @shahednasser in https://github.com/medusajs/medusa/pull/13717
* chore: add since tags for latest release by @shahednasser in https://github.com/medusajs/medusa/pull/13739
* chore: general TSDoc updates by @shahednasser in https://github.com/medusajs/medusa/pull/13742
* chore(core-flows): send error on csv parsing error by @willbouch in https://github.com/medusajs/medusa/pull/13749
## Other Changes
* feat: add metadata to shipping options api endpoints by @bqst in https://github.com/medusajs/medusa/pull/13554
* fix(core-flows,types,medusa): pass /store/shipping-options fields to workflow by @leobenzol in https://github.com/medusajs/medusa/pull/13527
* fix(dashboard): add offset and limit to query parameters in useTableConfiguration by @docloulou in https://github.com/medusajs/medusa/pull/13565
* Revert "fix(types): pluralize settings" by @willbouch in https://github.com/medusajs/medusa/pull/13573
* fix(stripe): add StripePromptPayService to Stripe module provider by @techpowerdev in https://github.com/medusajs/medusa/pull/13572
* Fixed premature teardown in medusa-test-runner by @trevster344 in https://github.com/medusajs/medusa/pull/13038
* Revert "fix(types): pluralize words ending in s like status" by @willbouch in https://github.com/medusajs/medusa/pull/13574
* feat(store): add id filtering to store collections endpoint by @bqst in https://github.com/medusajs/medusa/pull/13555
* fix(product): Correctly fetch category descendants by handle by @saoudi-h in https://github.com/medusajs/medusa/pull/13579
* feat(dashboard): support RTL in dashboard by @MEClouds in https://github.com/medusajs/medusa/pull/11252
* fix: Correctly type Float properties by @aldo-roman in https://github.com/medusajs/medusa/pull/13585
* fix(dashboard): copy phone on order customer info by @bqst in https://github.com/medusajs/medusa/pull/13596
* fix(index): preserve existing fields configuration (#13639) by @martinerko in https://github.com/medusajs/medusa/pull/13640
* fix(medusa): plugin:db:generate skip modules with no data models by @leobenzol in https://github.com/medusajs/medusa/pull/13652
* chore(core-flows): only allow published products in addToCartWorkflow by @leobenzol in https://github.com/medusajs/medusa/pull/13182
* fix(inventory): delete reservation item inventory level required quantity by @NicolasGorga in https://github.com/medusajs/medusa/pull/13633
* feat(admin-bundler): forward env vars to plugin admin extensions by @leobenzol in https://github.com/medusajs/medusa/pull/13634
* feat(medusa): include user_metadata in auth routes jwt by @NicolasGorga in https://github.com/medusajs/medusa/pull/13597
* docs(resources): Improve third party login by @NicolasGorga in https://github.com/medusajs/medusa/pull/13606
* docs(): Add local development instructions in CONTRIBUTING.md by @NicolasGorga in https://github.com/medusajs/medusa/pull/13651
* chore(): Downgrade mikro orm (performance regression) by @adrien2p in https://github.com/medusajs/medusa/pull/13680
* fix(core-flows): fix shipping_total showing as 0 in createFulfillment method by @NicolasGorga in https://github.com/medusajs/medusa/pull/13704
* fix(js-sdk): pass headers to auth.refresh() by @NicolasGorga in https://github.com/medusajs/medusa/pull/13690
* fix(dashboard): replace native select Element in CountrySelect & ProvinceSelect with Select(Medusa UI). by @patelaryan0914 in https://github.com/medusajs/medusa/pull/13521
* feat(medusa): export feature flag configs by @NicolasGorga in https://github.com/medusajs/medusa/pull/13714
* feat(medusa,dashboard): Add support for configurable additional columns in entity views by @docloulou in https://github.com/medusajs/medusa/pull/13566
## New Contributors
* @techpowerdev made their first contribution in https://github.com/medusajs/medusa/pull/13572
* @ericwaetke made their first contribution in https://github.com/medusajs/medusa/pull/13582
* @saoudi-h made their first contribution in https://github.com/medusajs/medusa/pull/13579
* @MEClouds made their first contribution in https://github.com/medusajs/medusa/pull/11252
* @Mayuresh-1306 made their first contribution in https://github.com/medusajs/medusa/pull/13650
* @patelaryan0914 made their first contribution in https://github.com/medusajs/medusa/pull/13521
**Full Changelog**: https://github.com/medusajs/medusa/compare/v2.10.3...v2.11.0