Skip to content

Commit a34fcfa

Browse files
authored
fix(): Remove redundant indexes to resolve schema warnings (medusajs#13736)
Fixes medusajs#13735 ### What This Pull Request introduces new database migrations to remove multiple redundant indexes across several core modules, including product, cart, order, customer, and inventory. ### Why As detailed in issue medusajs#13735, a fresh Medusa installation produces numerous "Duplicate Index" warnings. These legacy indexes add unnecessary write overhead and provide no performance benefit. This PR cleans up the schema to resolve these warnings and improve database health. ### How I have added one new, reversible migration file for each of the five affected modules: - `@medusajs/product` - `@medusajs/cart` - `@medusajs/order` - `@medusajs/customer` - `@medusajs/inventory` Each migration's `up()` method safely drops the older, redundant index, and its `down()` method re-creates it, ensuring the change is fully reversible and non-destructive. ### Testing I have tested these migrations by following the local development workflow outlined in the `CONTRIBUTING.md` guide. 1. **Setup:** * Cloned my forked Medusa repository locally . * Created a separate, fresh test project using `npx create-medusa-app@latest my-medusa-store`. * The test project's PostgreSQL database, which already contained the schema with the duplicate indexes. 2. **Linking Local Source Code:** * In the test project's `package.json`, I modified all `@medusajs/*` dependencies and resolutions to point to the local packages in my forked repository (e.g., `"@medusajs/product": "file:../medusa/packages/modules/product"`). * From the test project's directory, I ran `yarn install` to link the local, modified Medusa source code into its `node_modules`. 3. **Build & Migration:** * Inside my forked Medusa repository, I ran `yarn build` to compile the new TypeScript migration files. * From the root of the **test project**, I then executed the migration command: `npx medusa migration run`. 4. **Verification:** * The command successfully identified and ran only the new migration files I had created. * I also confirmed via direct SQL queries that the old, redundant indexes were correctly dropped from all affected tables (`product_collection`, `customer_group`, etc.).
1 parent 0d83918 commit a34fcfa

18 files changed

+501
-352
lines changed

.changeset/poor-llamas-march.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@medusajs/cart": patch
3+
"@medusajs/customer": patch
4+
"@medusajs/inventory": patch
5+
"@medusajs/order": patch
6+
"@medusajs/product": patch
7+
---
8+
9+
fix(): Remove redundant indexes from product, cart, order, customer, and inventory modules to improve database schema health.

packages/modules/cart/src/migrations/.snapshot-medusa-cart.json

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -895,15 +895,6 @@
895895
"unique": false,
896896
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_cart_line_item_deleted_at\" ON \"cart_line_item\" (deleted_at) WHERE deleted_at IS NULL"
897897
},
898-
{
899-
"keyName": "IDX_line_item_cart_id",
900-
"columnNames": [],
901-
"composite": false,
902-
"constraint": false,
903-
"primary": false,
904-
"unique": false,
905-
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_line_item_cart_id\" ON \"cart_line_item\" (cart_id) WHERE deleted_at IS NULL"
906-
},
907898
{
908899
"keyName": "IDX_line_item_variant_id",
909900
"columnNames": [],
@@ -1116,15 +1107,6 @@
11161107
"unique": false,
11171108
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_line_item_adjustment_promotion_id\" ON \"cart_line_item_adjustment\" (promotion_id) WHERE deleted_at IS NULL AND promotion_id IS NOT NULL"
11181109
},
1119-
{
1120-
"keyName": "IDX_adjustment_item_id",
1121-
"columnNames": [],
1122-
"composite": false,
1123-
"constraint": false,
1124-
"primary": false,
1125-
"unique": false,
1126-
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_adjustment_item_id\" ON \"cart_line_item_adjustment\" (item_id) WHERE deleted_at IS NULL"
1127-
},
11281110
{
11291111
"keyName": "cart_line_item_adjustment_pkey",
11301112
"columnNames": [
@@ -1297,15 +1279,6 @@
12971279
"unique": false,
12981280
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_line_item_tax_line_tax_rate_id\" ON \"cart_line_item_tax_line\" (tax_rate_id) WHERE deleted_at IS NULL AND tax_rate_id IS NOT NULL"
12991281
},
1300-
{
1301-
"keyName": "IDX_tax_line_item_id",
1302-
"columnNames": [],
1303-
"composite": false,
1304-
"constraint": false,
1305-
"primary": false,
1306-
"unique": false,
1307-
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_tax_line_item_id\" ON \"cart_line_item_tax_line\" (item_id) WHERE deleted_at IS NULL"
1308-
},
13091282
{
13101283
"keyName": "cart_line_item_tax_line_pkey",
13111284
"columnNames": [
@@ -1482,15 +1455,6 @@
14821455
"unique": false,
14831456
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_cart_shipping_method_deleted_at\" ON \"cart_shipping_method\" (deleted_at) WHERE deleted_at IS NULL"
14841457
},
1485-
{
1486-
"keyName": "IDX_shipping_method_cart_id",
1487-
"columnNames": [],
1488-
"composite": false,
1489-
"constraint": false,
1490-
"primary": false,
1491-
"unique": false,
1492-
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_shipping_method_cart_id\" ON \"cart_shipping_method\" (cart_id) WHERE deleted_at IS NULL"
1493-
},
14941458
{
14951459
"keyName": "IDX_shipping_method_option_id",
14961460
"columnNames": [],
@@ -1681,15 +1645,6 @@
16811645
"unique": false,
16821646
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_shipping_method_adjustment_promotion_id\" ON \"cart_shipping_method_adjustment\" (promotion_id) WHERE deleted_at IS NULL AND promotion_id IS NOT NULL"
16831647
},
1684-
{
1685-
"keyName": "IDX_adjustment_shipping_method_id",
1686-
"columnNames": [],
1687-
"composite": false,
1688-
"constraint": false,
1689-
"primary": false,
1690-
"unique": false,
1691-
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_adjustment_shipping_method_id\" ON \"cart_shipping_method_adjustment\" (shipping_method_id) WHERE deleted_at IS NULL"
1692-
},
16931648
{
16941649
"keyName": "cart_shipping_method_adjustment_pkey",
16951650
"columnNames": [
@@ -1846,15 +1801,6 @@
18461801
"unique": false,
18471802
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_cart_shipping_method_tax_line_deleted_at\" ON \"cart_shipping_method_tax_line\" (deleted_at) WHERE deleted_at IS NULL"
18481803
},
1849-
{
1850-
"keyName": "IDX_tax_line_shipping_method_id",
1851-
"columnNames": [],
1852-
"composite": false,
1853-
"constraint": false,
1854-
"primary": false,
1855-
"unique": false,
1856-
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_tax_line_shipping_method_id\" ON \"cart_shipping_method_tax_line\" (shipping_method_id) WHERE deleted_at IS NULL"
1857-
},
18581804
{
18591805
"keyName": "IDX_shipping_method_tax_line_tax_rate_id",
18601806
"columnNames": [],
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Migration } from '@mikro-orm/migrations';
2+
3+
export class Migration20251017153909 extends Migration {
4+
5+
override async up(): Promise<void> {
6+
this.addSql(`drop index if exists "IDX_line_item_cart_id";`);
7+
8+
this.addSql(`drop index if exists "IDX_adjustment_item_id";`);
9+
10+
this.addSql(`drop index if exists "IDX_tax_line_item_id";`);
11+
12+
this.addSql(`drop index if exists "IDX_shipping_method_cart_id";`);
13+
14+
this.addSql(`drop index if exists "IDX_adjustment_shipping_method_id";`);
15+
16+
this.addSql(`drop index if exists "IDX_tax_line_shipping_method_id";`);
17+
}
18+
19+
override async down(): Promise<void> {
20+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_line_item_cart_id" ON "cart_line_item" (cart_id) WHERE deleted_at IS NULL;`);
21+
22+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_adjustment_item_id" ON "cart_line_item_adjustment" (item_id) WHERE deleted_at IS NULL;`);
23+
24+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_tax_line_item_id" ON "cart_line_item_tax_line" (item_id) WHERE deleted_at IS NULL;`);
25+
26+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_shipping_method_cart_id" ON "cart_shipping_method" (cart_id) WHERE deleted_at IS NULL;`);
27+
28+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_adjustment_shipping_method_id" ON "cart_shipping_method_adjustment" (shipping_method_id) WHERE deleted_at IS NULL;`);
29+
30+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_tax_line_shipping_method_id" ON "cart_shipping_method_tax_line" (shipping_method_id) WHERE deleted_at IS NULL;`);
31+
}
32+
33+
}

packages/modules/cart/src/models/line-item-adjustment.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ const LineItemAdjustment = model
2424
on: ["promotion_id"],
2525
where: "deleted_at IS NULL AND promotion_id IS NOT NULL",
2626
},
27-
{
28-
name: "IDX_adjustment_item_id",
27+
{
28+
name: "IDX_cart_line_item_adjustment_item_id",
2929
on: ["item_id"],
3030
where: "deleted_at IS NULL",
3131
},

packages/modules/cart/src/models/line-item-tax-line.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const LineItemTaxLine = model
2727
where: "deleted_at IS NULL AND tax_rate_id IS NOT NULL",
2828
},
2929
{
30-
name: "IDX_tax_line_item_id",
30+
name: "IDX_cart_line_item_tax_line_item_id",
3131
on: ["item_id"],
3232
where: "deleted_at IS NULL",
3333
},

packages/modules/cart/src/models/line-item.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const LineItem = model
4646
)
4747
.indexes([
4848
{
49-
name: "IDX_line_item_cart_id",
49+
name: "IDX_cart_line_item_cart_id",
5050
on: ["cart_id"],
5151
where: "deleted_at IS NULL",
5252
},

packages/modules/cart/src/models/shipping-method-adjustment.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const ShippingMethodAdjustment = model
2727
where: "deleted_at IS NULL AND promotion_id IS NOT NULL",
2828
},
2929
{
30-
name: "IDX_adjustment_shipping_method_id",
30+
name: "IDX_cart_shipping_method_adjustment_shipping_method_id",
3131
on: ["shipping_method_id"],
3232
where: "deleted_at IS NULL",
3333
},

packages/modules/cart/src/models/shipping-method-tax-line.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const ShippingMethodTaxLine = model
2222
)
2323
.indexes([
2424
{
25-
name: "IDX_tax_line_shipping_method_id",
25+
name: "IDX_cart_shipping_method_tax_line_shipping_method_id",
2626
on: ["shipping_method_id"],
2727
where: "deleted_at IS NULL",
2828
},

packages/modules/cart/src/models/shipping-method.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const ShippingMethod = model
3131
)
3232
.indexes([
3333
{
34-
name: "IDX_shipping_method_cart_id",
34+
name: "IDX_cart_shipping_method_cart_id",
3535
on: ["cart_id"],
3636
where: "deleted_at IS NULL",
3737
},

packages/modules/customer/src/migrations/.snapshot-medusa-customer.json

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
"keyName": "IDX_customer_deleted_at",
129129
"columnNames": [],
130130
"composite": false,
131+
"constraint": false,
131132
"primary": false,
132133
"unique": false,
133134
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_customer_deleted_at\" ON \"customer\" (deleted_at) WHERE deleted_at IS NULL"
@@ -136,6 +137,7 @@
136137
"keyName": "IDX_customer_email_has_account_unique",
137138
"columnNames": [],
138139
"composite": false,
140+
"constraint": false,
139141
"primary": false,
140142
"unique": false,
141143
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_customer_email_has_account_unique\" ON \"customer\" (email, has_account) WHERE deleted_at IS NULL"
@@ -146,12 +148,14 @@
146148
"id"
147149
],
148150
"composite": false,
151+
"constraint": true,
149152
"primary": true,
150153
"unique": true
151154
}
152155
],
153156
"checks": [],
154-
"foreignKeys": {}
157+
"foreignKeys": {},
158+
"nativeEnums": {}
155159
},
156160
{
157161
"columns": {
@@ -341,6 +345,7 @@
341345
"keyName": "IDX_customer_address_customer_id",
342346
"columnNames": [],
343347
"composite": false,
348+
"constraint": false,
344349
"primary": false,
345350
"unique": false,
346351
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_customer_address_customer_id\" ON \"customer_address\" (customer_id) WHERE deleted_at IS NULL"
@@ -349,6 +354,7 @@
349354
"keyName": "IDX_customer_address_deleted_at",
350355
"columnNames": [],
351356
"composite": false,
357+
"constraint": false,
352358
"primary": false,
353359
"unique": false,
354360
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_customer_address_deleted_at\" ON \"customer_address\" (deleted_at) WHERE deleted_at IS NULL"
@@ -357,6 +363,7 @@
357363
"keyName": "IDX_customer_address_unique_customer_billing",
358364
"columnNames": [],
359365
"composite": false,
366+
"constraint": false,
360367
"primary": false,
361368
"unique": false,
362369
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_customer_address_unique_customer_billing\" ON \"customer_address\" (customer_id) WHERE \"is_default_billing\" = true AND deleted_at IS NULL"
@@ -365,6 +372,7 @@
365372
"keyName": "IDX_customer_address_unique_customer_shipping",
366373
"columnNames": [],
367374
"composite": false,
375+
"constraint": false,
368376
"primary": false,
369377
"unique": false,
370378
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_customer_address_unique_customer_shipping\" ON \"customer_address\" (customer_id) WHERE \"is_default_shipping\" = true AND deleted_at IS NULL"
@@ -375,6 +383,7 @@
375383
"id"
376384
],
377385
"composite": false,
386+
"constraint": true,
378387
"primary": true,
379388
"unique": true
380389
}
@@ -394,7 +403,8 @@
394403
"deleteRule": "cascade",
395404
"updateRule": "cascade"
396405
}
397-
}
406+
},
407+
"nativeEnums": {}
398408
},
399409
{
400410
"columns": {
@@ -474,6 +484,7 @@
474484
"keyName": "IDX_customer_group_deleted_at",
475485
"columnNames": [],
476486
"composite": false,
487+
"constraint": false,
477488
"primary": false,
478489
"unique": false,
479490
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_customer_group_deleted_at\" ON \"customer_group\" (deleted_at) WHERE deleted_at IS NULL"
@@ -482,6 +493,7 @@
482493
"keyName": "IDX_customer_group_name_unique",
483494
"columnNames": [],
484495
"composite": false,
496+
"constraint": false,
485497
"primary": false,
486498
"unique": false,
487499
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_customer_group_name_unique\" ON \"customer_group\" (name) WHERE deleted_at IS NULL"
@@ -492,12 +504,14 @@
492504
"id"
493505
],
494506
"composite": false,
507+
"constraint": true,
495508
"primary": true,
496509
"unique": true
497510
}
498511
],
499512
"checks": [],
500-
"foreignKeys": {}
513+
"foreignKeys": {},
514+
"nativeEnums": {}
501515
},
502516
{
503517
"columns": {
@@ -586,6 +600,7 @@
586600
"keyName": "IDX_customer_group_customer_customer_id",
587601
"columnNames": [],
588602
"composite": false,
603+
"constraint": false,
589604
"primary": false,
590605
"unique": false,
591606
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_customer_group_customer_customer_id\" ON \"customer_group_customer\" (customer_id) WHERE deleted_at IS NULL"
@@ -594,6 +609,7 @@
594609
"keyName": "IDX_customer_group_customer_customer_group_id",
595610
"columnNames": [],
596611
"composite": false,
612+
"constraint": false,
597613
"primary": false,
598614
"unique": false,
599615
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_customer_group_customer_customer_group_id\" ON \"customer_group_customer\" (customer_group_id) WHERE deleted_at IS NULL"
@@ -602,6 +618,7 @@
602618
"keyName": "IDX_customer_group_customer_deleted_at",
603619
"columnNames": [],
604620
"composite": false,
621+
"constraint": false,
605622
"primary": false,
606623
"unique": false,
607624
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_customer_group_customer_deleted_at\" ON \"customer_group_customer\" (deleted_at) WHERE deleted_at IS NULL"
@@ -612,12 +629,15 @@
612629
"id"
613630
],
614631
"composite": false,
632+
"constraint": true,
615633
"primary": true,
616634
"unique": true
617635
}
618636
],
619637
"checks": [],
620-
"foreignKeys": {}
638+
"foreignKeys": {},
639+
"nativeEnums": {}
621640
}
622-
]
641+
],
642+
"nativeEnums": {}
623643
}

0 commit comments

Comments
 (0)