refactor: migrate store module to DML (#10467)

This commit is contained in:
Harminder Virk
2024-12-06 17:38:15 +05:30
committed by GitHub
parent 7e04091b49
commit f3c91c908a
6 changed files with 79 additions and 175 deletions

View File

@@ -0,0 +1,5 @@
---
"@medusajs/store": patch
---
refactor: migrate store module to DML

View File

@@ -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"

View File

@@ -0,0 +1,13 @@
import { Migration } from '@mikro-orm/migrations';
export class Migration20241206083313 extends Migration {
async up(): Promise<void> {
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<void> {
this.addSql('drop index if exists "IDX_store_currency_store_id";');
}
}

View File

@@ -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

View File

@@ -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<StoreCurrency>(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<string, unknown> | 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

View File

@@ -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<Store>
protected readonly storeService_: ModulesSdkTypes.IMedusaInternalService<
InferEntityType<typeof Store>
>
constructor(
{ baseRepository, storeService }: InjectedDependencies,
@@ -73,7 +76,7 @@ export default class StoreModuleService
async create_(
data: StoreTypes.CreateStoreDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<Store[]> {
): Promise<InferEntityType<typeof Store>[]> {
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<Store[]>[] = []
const operations: Promise<InferEntityType<typeof Store>[]>[] = []
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<Store[]> {
): Promise<InferEntityType<typeof Store>[]> {
const normalizedInput = StoreModuleService.normalizeInput(data)
StoreModuleService.validateUpdateRequest(normalizedInput)