From f3c91c908a1c8d38eb31c21dbd94d4ad6cea9688 Mon Sep 17 00:00:00 2001 From: Harminder Virk Date: Fri, 6 Dec 2024 17:38:15 +0530 Subject: [PATCH] refactor: migrate store module to DML (#10467) --- .changeset/gold-birds-draw.md | 5 + .../migrations/.snapshot-medusa-store.json | 38 +++++-- .../src/migrations/Migration20241206083313.ts | 13 +++ packages/modules/store/src/models/currency.ts | 88 +++-------------- packages/modules/store/src/models/store.ts | 99 +++---------------- .../src/services/store-module-service.ts | 11 ++- 6 files changed, 79 insertions(+), 175 deletions(-) create mode 100644 .changeset/gold-birds-draw.md create mode 100644 packages/modules/store/src/migrations/Migration20241206083313.ts diff --git a/.changeset/gold-birds-draw.md b/.changeset/gold-birds-draw.md new file mode 100644 index 0000000000..ea21e15d80 --- /dev/null +++ b/.changeset/gold-birds-draw.md @@ -0,0 +1,5 @@ +--- +"@medusajs/store": patch +--- + +refactor: migrate store module to DML diff --git a/packages/modules/store/src/migrations/.snapshot-medusa-store.json b/packages/modules/store/src/migrations/.snapshot-medusa-store.json index a1b4e14977..cd4b7579cf 100644 --- a/packages/modules/store/src/migrations/.snapshot-medusa-store.json +++ b/packages/modules/store/src/migrations/.snapshot-medusa-store.json @@ -1,5 +1,7 @@ { - "namespaces": ["public"], + "namespaces": [ + "public" + ], "name": "public", "tables": [ { @@ -97,15 +99,17 @@ "indexes": [ { "keyName": "IDX_store_deleted_at", - "columnNames": ["deleted_at"], + "columnNames": [], "composite": false, "primary": false, "unique": false, - "expression": "CREATE INDEX IF NOT EXISTS \"IDX_store_deleted_at\" ON \"store\" (deleted_at) WHERE deleted_at IS NOT NULL" + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_store_deleted_at\" ON \"store\" (deleted_at) WHERE deleted_at IS NULL" }, { "keyName": "store_pkey", - "columnNames": ["id"], + "columnNames": [ + "id" + ], "composite": false, "primary": true, "unique": true @@ -190,16 +194,26 @@ "schema": "public", "indexes": [ { - "keyName": "IDX_store_currency_deleted_at", - "columnNames": ["deleted_at"], + "keyName": "IDX_store_currency_store_id", + "columnNames": [], "composite": false, "primary": false, "unique": false, - "expression": "CREATE INDEX IF NOT EXISTS \"IDX_store_currency_deleted_at\" ON \"store_currency\" (deleted_at) WHERE deleted_at IS NOT NULL" + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_store_currency_store_id\" ON \"store_currency\" (store_id) WHERE deleted_at IS NULL" + }, + { + "keyName": "IDX_store_currency_deleted_at", + "columnNames": [], + "composite": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_store_currency_deleted_at\" ON \"store_currency\" (deleted_at) WHERE deleted_at IS NULL" }, { "keyName": "store_currency_pkey", - "columnNames": ["id"], + "columnNames": [ + "id" + ], "composite": false, "primary": true, "unique": true @@ -209,9 +223,13 @@ "foreignKeys": { "store_currency_store_id_foreign": { "constraintName": "store_currency_store_id_foreign", - "columnNames": ["store_id"], + "columnNames": [ + "store_id" + ], "localTableName": "public.store_currency", - "referencedColumnNames": ["id"], + "referencedColumnNames": [ + "id" + ], "referencedTableName": "public.store", "deleteRule": "cascade", "updateRule": "cascade" diff --git a/packages/modules/store/src/migrations/Migration20241206083313.ts b/packages/modules/store/src/migrations/Migration20241206083313.ts new file mode 100644 index 0000000000..de8556efea --- /dev/null +++ b/packages/modules/store/src/migrations/Migration20241206083313.ts @@ -0,0 +1,13 @@ +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20241206083313 extends Migration { + + async up(): Promise { + this.addSql('CREATE INDEX IF NOT EXISTS "IDX_store_currency_store_id" ON "store_currency" (store_id) WHERE deleted_at IS NULL;'); + } + + async down(): Promise { + this.addSql('drop index if exists "IDX_store_currency_store_id";'); + } + +} diff --git a/packages/modules/store/src/models/currency.ts b/packages/modules/store/src/models/currency.ts index e62286f141..ae37ba6092 100644 --- a/packages/modules/store/src/models/currency.ts +++ b/packages/modules/store/src/models/currency.ts @@ -1,81 +1,15 @@ -import { - DALUtils, - Searchable, - createPsqlIndexStatementHelper, - generateEntityId, -} from "@medusajs/framework/utils" - -import { - BeforeCreate, - Entity, - OnInit, - PrimaryKey, - Property, - Filter, - ManyToOne, -} from "@mikro-orm/core" +import { model } from "@medusajs/framework/utils" import Store from "./store" -const StoreCurrencyDeletedAtIndex = createPsqlIndexStatementHelper({ - tableName: "store_currency", - columns: "deleted_at", - where: "deleted_at IS NOT NULL", +const StoreCurrency = model.define("StoreCurrency", { + id: model.id({ prefix: "stocur" }).primaryKey(), + currency_code: model.text().searchable(), + is_default: model.boolean().default(false), + store: model + .belongsTo(() => Store, { + mappedBy: "supported_currencies", + }) + .nullable(), }) -@Entity() -@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) -export default class StoreCurrency { - @PrimaryKey({ columnType: "text" }) - id: string - - @Searchable() - @Property({ columnType: "text" }) - currency_code: string - - @Property({ columnType: "boolean", default: false }) - is_default?: boolean - - @ManyToOne(() => Store, { - columnType: "text", - fieldName: "store_id", - mapToPk: true, - nullable: true, - onDelete: "cascade", - }) - store_id: string | null - - @ManyToOne(() => Store, { - persist: false, - nullable: true, - }) - store: Store | null - - @Property({ - onCreate: () => new Date(), - columnType: "timestamptz", - defaultRaw: "now()", - }) - created_at: Date - - @Property({ - onCreate: () => new Date(), - onUpdate: () => new Date(), - columnType: "timestamptz", - defaultRaw: "now()", - }) - updated_at: Date - - @StoreCurrencyDeletedAtIndex.MikroORMIndex() - @Property({ columnType: "timestamptz", nullable: true }) - deleted_at: Date | null = null - - @BeforeCreate() - onCreate() { - this.id = generateEntityId(this.id, "stocur") - } - - @OnInit() - onInit() { - this.id = generateEntityId(this.id, "stocur") - } -} +export default StoreCurrency diff --git a/packages/modules/store/src/models/store.ts b/packages/modules/store/src/models/store.ts index 86df01dbf3..7a19e130ae 100644 --- a/packages/modules/store/src/models/store.ts +++ b/packages/modules/store/src/models/store.ts @@ -1,89 +1,20 @@ -import { - DALUtils, - Searchable, - createPsqlIndexStatementHelper, - generateEntityId, -} from "@medusajs/framework/utils" - -import { DAL } from "@medusajs/framework/types" - -import { - BeforeCreate, - Entity, - OnInit, - PrimaryKey, - Property, - Filter, - OptionalProps, - OneToMany, - Collection, - Cascade, -} from "@mikro-orm/core" +import { model } from "@medusajs/framework/utils" import StoreCurrency from "./currency" -type StoreOptionalProps = DAL.SoftDeletableModelDateColumns - -const StoreDeletedAtIndex = createPsqlIndexStatementHelper({ - tableName: "store", - columns: "deleted_at", - where: "deleted_at IS NOT NULL", -}) - -@Entity() -@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) -export default class Store { - [OptionalProps]?: StoreOptionalProps - - @PrimaryKey({ columnType: "text" }) - id: string - - @Searchable() - @Property({ columnType: "text", default: "Medusa Store" }) - name: string - - @OneToMany(() => StoreCurrency, (o) => o.store, { - cascade: [Cascade.PERSIST, "soft-remove"] as any, +const Store = model + .define("Store", { + id: model.id({ prefix: "store" }).primaryKey(), + name: model.text().default("Medusa Store").searchable(), + default_sales_channel_id: model.text().nullable(), + default_region_id: model.text().nullable(), + default_location_id: model.text().nullable(), + metadata: model.json().nullable(), + supported_currencies: model.hasMany(() => StoreCurrency, { + mappedBy: "store", + }), }) - supported_currencies = new Collection(this) - - @Property({ columnType: "text", nullable: true }) - default_sales_channel_id: string | null = null - - @Property({ columnType: "text", nullable: true }) - default_region_id: string | null = null - - @Property({ columnType: "text", nullable: true }) - default_location_id: string | null = null - - @Property({ columnType: "jsonb", nullable: true }) - metadata: Record | null = null - - @Property({ - onCreate: () => new Date(), - columnType: "timestamptz", - defaultRaw: "now()", + .cascades({ + delete: ["supported_currencies"], }) - created_at: Date - @Property({ - onCreate: () => new Date(), - onUpdate: () => new Date(), - columnType: "timestamptz", - defaultRaw: "now()", - }) - updated_at: Date - - @StoreDeletedAtIndex.MikroORMIndex() - @Property({ columnType: "timestamptz", nullable: true }) - deleted_at: Date | null = null - - @BeforeCreate() - onCreate() { - this.id = generateEntityId(this.id, "store") - } - - @OnInit() - onInit() { - this.id = generateEntityId(this.id, "store") - } -} +export default Store diff --git a/packages/modules/store/src/services/store-module-service.ts b/packages/modules/store/src/services/store-module-service.ts index 5f8d422ce0..c4654465bf 100644 --- a/packages/modules/store/src/services/store-module-service.ts +++ b/packages/modules/store/src/services/store-module-service.ts @@ -1,6 +1,7 @@ import { Context, DAL, + InferEntityType, InternalModuleDeclaration, IStoreModuleService, ModulesSdkTypes, @@ -34,7 +35,9 @@ export default class StoreModuleService implements IStoreModuleService { protected baseRepository_: DAL.RepositoryService - protected readonly storeService_: ModulesSdkTypes.IMedusaInternalService + protected readonly storeService_: ModulesSdkTypes.IMedusaInternalService< + InferEntityType + > constructor( { baseRepository, storeService }: InjectedDependencies, @@ -73,7 +76,7 @@ export default class StoreModuleService async create_( data: StoreTypes.CreateStoreDTO[], @MedusaContext() sharedContext: Context = {} - ): Promise { + ): Promise[]> { let normalizedInput = StoreModuleService.normalizeInput(data) StoreModuleService.validateCreateRequest(normalizedInput) @@ -107,7 +110,7 @@ export default class StoreModuleService (store): store is StoreTypes.CreateStoreDTO => !store.id ) - const operations: Promise[] = [] + const operations: Promise[]>[] = [] if (forCreate.length) { operations.push(this.create_(forCreate, sharedContext)) @@ -168,7 +171,7 @@ export default class StoreModuleService protected async update_( data: UpdateStoreInput[], @MedusaContext() sharedContext: Context = {} - ): Promise { + ): Promise[]> { const normalizedInput = StoreModuleService.normalizeInput(data) StoreModuleService.validateUpdateRequest(normalizedInput)