medusa-bonuses-plugin
Version:
medusa-bonuses-plugin is a Medusa plugin that adds bonus program to Medusa ecommerce stores.
169 lines • 10.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UpdateBonusSystem1701234567891 = void 0;
class UpdateBonusSystem1701234567891 {
constructor() {
this.name = "UpdateBonusSystem1701234567891";
}
async up(queryRunner) {
// Проверяем, существуют ли таблицы
const bonusAccountExists = await queryRunner.hasTable("bonus_account");
const bonusTransactionExists = await queryRunner.hasTable("bonus_transaction");
const bonusSettingsExists = await queryRunner.hasTable("bonus_settings");
// Если таблицы существуют, удаляем их
if (bonusTransactionExists) {
await queryRunner.query('DROP TABLE IF EXISTS "bonus_transaction" CASCADE');
}
if (bonusAccountExists) {
await queryRunner.query('DROP TABLE IF EXISTS "bonus_account" CASCADE');
}
if (bonusSettingsExists) {
await queryRunner.query('DROP TABLE IF EXISTS "bonus_settings" CASCADE');
}
// Удаляем существующие enum типы если есть
await queryRunner.query('DROP TYPE IF EXISTS "bonus_transaction_type_enum" CASCADE');
await queryRunner.query('DROP TYPE IF EXISTS "order_relation_type_enum" CASCADE');
// Пересоздаем всё заново
// 1. Создаем расширение uuid-ossp если его еще нет
await queryRunner.query('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"');
// 2. Создаем enum типы
await queryRunner.query(`
CREATE TYPE "bonus_transaction_type_enum" AS ENUM (
'order_earning',
'order_spending',
'reservation',
'adjustment',
'expiration'
)
`);
await queryRunner.query(`
CREATE TYPE "order_relation_type_enum" AS ENUM (
'earned_from',
'spent_on'
)
`);
// 3. Создаем таблицу bonus_settings
await queryRunner.query(`
CREATE TABLE "bonus_settings" (
"id" character varying NOT NULL DEFAULT uuid_generate_v4(),
"default_percentage" numeric(5,2) NOT NULL DEFAULT 3,
"metadata" jsonb,
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
"updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
CONSTRAINT "PK_bonus_settings" PRIMARY KEY ("id")
)
`);
// 4. Создаем таблицу bonus_account (БЕЗ поля id!)
await queryRunner.query(`
CREATE TABLE "bonus_account" (
"customer_id" character varying NOT NULL,
"balance" numeric(10,2) NOT NULL DEFAULT 0,
"custom_percentage" numeric(5,2),
"custom_percentage_ends_at" TIMESTAMP WITH TIME ZONE,
"metadata" jsonb,
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
"updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
CONSTRAINT "PK_bonus_account" PRIMARY KEY ("customer_id"),
CONSTRAINT "FK_bonus_account_customer" FOREIGN KEY ("customer_id")
REFERENCES "customer"("id") ON DELETE CASCADE ON UPDATE NO ACTION
)
`);
// 5. Создаем таблицу bonus_transaction
await queryRunner.query(`
CREATE TABLE "bonus_transaction" (
"id" character varying NOT NULL DEFAULT uuid_generate_v4(),
"bonus_account_id" character varying NOT NULL,
"customer_id" character varying NOT NULL,
"amount" numeric(10,2) NOT NULL,
"type" "bonus_transaction_type_enum" NOT NULL,
"order_id" character varying,
"order_relation_type" "order_relation_type_enum",
"order_amount" numeric(10,2),
"earning_percentage" numeric(5,2),
"created_by" character varying,
"note" character varying,
"metadata" jsonb,
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
"updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
CONSTRAINT "PK_bonus_transaction" PRIMARY KEY ("id"),
CONSTRAINT "FK_bonus_transaction_account" FOREIGN KEY ("bonus_account_id")
REFERENCES "bonus_account"("customer_id") ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT "FK_bonus_transaction_customer" FOREIGN KEY ("customer_id")
REFERENCES "customer"("id") ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT "FK_bonus_transaction_order" FOREIGN KEY ("order_id")
REFERENCES "order"("id") ON DELETE SET NULL ON UPDATE NO ACTION
)
`);
// 6. Создаем индексы для оптимизации
await queryRunner.query('CREATE INDEX "IDX_bonus_account_customer_id" ON "bonus_account" ("customer_id")');
await queryRunner.query('CREATE INDEX "IDX_bonus_transaction_customer_id" ON "bonus_transaction" ("customer_id")');
await queryRunner.query('CREATE INDEX "IDX_bonus_transaction_order_id" ON "bonus_transaction" ("order_id")');
await queryRunner.query('CREATE INDEX "IDX_bonus_transaction_type" ON "bonus_transaction" ("type")');
await queryRunner.query('CREATE INDEX "IDX_bonus_transaction_created_at" ON "bonus_transaction" ("created_at")');
// 7. Создаем бонусные счета для существующих пользователей
await queryRunner.query(`
INSERT INTO bonus_account (
customer_id,
balance,
custom_percentage,
custom_percentage_ends_at,
metadata,
created_at,
updated_at
)
SELECT
c.id,
0,
NULL,
NULL,
jsonb_build_object(
'created_by_migration', true,
'customer_email', c.email,
'migration_date', CURRENT_TIMESTAMP,
'has_account', c.has_account
),
NOW(),
NOW()
FROM customer c
WHERE NOT EXISTS (
SELECT 1 FROM bonus_account ba WHERE ba.customer_id = c.id
)
`);
// 8. Создаем дефолтные настройки бонусной системы
await queryRunner.query(`
INSERT INTO bonus_settings (
id,
default_percentage,
metadata,
created_at,
updated_at
)
SELECT
uuid_generate_v4(),
3,
'{"created_by_migration": true}'::jsonb,
NOW(),
NOW()
WHERE NOT EXISTS (
SELECT 1 FROM bonus_settings LIMIT 1
)
`);
}
async down(queryRunner) {
// Удаляем индексы
await queryRunner.query('DROP INDEX IF EXISTS "IDX_bonus_account_customer_id"');
await queryRunner.query('DROP INDEX IF EXISTS "IDX_bonus_transaction_customer_id"');
await queryRunner.query('DROP INDEX IF EXISTS "IDX_bonus_transaction_order_id"');
await queryRunner.query('DROP INDEX IF EXISTS "IDX_bonus_transaction_type"');
await queryRunner.query('DROP INDEX IF EXISTS "IDX_bonus_transaction_created_at"');
// Удаляем таблицы
await queryRunner.query('DROP TABLE IF EXISTS "bonus_transaction" CASCADE');
await queryRunner.query('DROP TABLE IF EXISTS "bonus_account" CASCADE');
await queryRunner.query('DROP TABLE IF EXISTS "bonus_settings" CASCADE');
// Удаляем enum типы
await queryRunner.query('DROP TYPE IF EXISTS "bonus_transaction_type_enum" CASCADE');
await queryRunner.query('DROP TYPE IF EXISTS "order_relation_type_enum" CASCADE');
}
}
exports.UpdateBonusSystem1701234567891 = UpdateBonusSystem1701234567891;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcwMTIzNDU2Nzg5MC1DcmVhdGVCb251c1N5c3RlbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWdyYXRpb25zLzE3MDEyMzQ1Njc4OTAtQ3JlYXRlQm9udXNTeXN0ZW0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsTUFBYSw4QkFBOEI7SUFBM0M7UUFDRSxTQUFJLEdBQUcsZ0NBQWdDLENBQUE7SUErS3pDLENBQUM7SUE3S1EsS0FBSyxDQUFDLEVBQUUsQ0FBQyxXQUF3QjtRQUN0QyxtQ0FBbUM7UUFDbkMsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLFdBQVcsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUE7UUFDdEUsTUFBTSxzQkFBc0IsR0FBRyxNQUFNLFdBQVcsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtRQUM5RSxNQUFNLG1CQUFtQixHQUFHLE1BQU0sV0FBVyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO1FBRXhFLHNDQUFzQztRQUN0QyxJQUFJLHNCQUFzQixFQUFFLENBQUM7WUFDM0IsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUE7UUFDN0UsQ0FBQztRQUNELElBQUksa0JBQWtCLEVBQUUsQ0FBQztZQUN2QixNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQTtRQUN6RSxDQUFDO1FBQ0QsSUFBSSxtQkFBbUIsRUFBRSxDQUFDO1lBQ3hCLE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQywrQ0FBK0MsQ0FBQyxDQUFBO1FBQzFFLENBQUM7UUFFRCwyQ0FBMkM7UUFDM0MsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDLDJEQUEyRCxDQUFDLENBQUE7UUFDcEYsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDLHdEQUF3RCxDQUFDLENBQUE7UUFFakYseUJBQXlCO1FBQ3pCLG1EQUFtRDtRQUNuRCxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUMsNENBQTRDLENBQUMsQ0FBQTtRQUVyRSx1QkFBdUI7UUFDdkIsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDOzs7Ozs7OztLQVF2QixDQUFDLENBQUE7UUFFRixNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7O0tBS3ZCLENBQUMsQ0FBQTtRQUVGLG9DQUFvQztRQUNwQyxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7Ozs7OztLQVN2QixDQUFDLENBQUE7UUFFRixrREFBa0Q7UUFDbEQsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDOzs7Ozs7Ozs7Ozs7O0tBYXZCLENBQUMsQ0FBQTtRQUVGLHVDQUF1QztRQUN2QyxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQXdCdkIsQ0FBQyxDQUFBO1FBRUYscUNBQXFDO1FBQ3JDLE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQyxpRkFBaUYsQ0FBQyxDQUFBO1FBQzFHLE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQyx5RkFBeUYsQ0FBQyxDQUFBO1FBQ2xILE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQyxtRkFBbUYsQ0FBQyxDQUFBO1FBQzVHLE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQywyRUFBMkUsQ0FBQyxDQUFBO1FBQ3BHLE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQyx1RkFBdUYsQ0FBQyxDQUFBO1FBRWhILDJEQUEyRDtRQUMzRCxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQTJCdkIsQ0FBQyxDQUFBO1FBRUYsa0RBQWtEO1FBQ2xELE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7S0FpQnZCLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQXdCO1FBQ3hDLGtCQUFrQjtRQUNsQixNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQTtRQUMvRSxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUMsMERBQTBELENBQUMsQ0FBQTtRQUNuRixNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUMsdURBQXVELENBQUMsQ0FBQTtRQUNoRixNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQTtRQUM1RSxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUMseURBQXlELENBQUMsQ0FBQTtRQUVsRixrQkFBa0I7UUFDbEIsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUE7UUFDM0UsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUE7UUFDdkUsTUFBTSxXQUFXLENBQUMsS0FBSyxDQUFDLCtDQUErQyxDQUFDLENBQUE7UUFFeEUsb0JBQW9CO1FBQ3BCLE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQywyREFBMkQsQ0FBQyxDQUFBO1FBQ3BGLE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQyx3REFBd0QsQ0FBQyxDQUFBO0lBQ25GLENBQUM7Q0FDRjtBQWhMRCx3RUFnTEMifQ==