feat(backend-api): 🗃️ Introduce database schema with 1736505599000-InitialSchema.ts for merchant tables
This commit is contained in:
parent
ae996e75d8
commit
4f380df134
1 changed files with 157 additions and 0 deletions
|
|
@ -0,0 +1,157 @@
|
|||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
/**
|
||||
* Migration: InitialSchema
|
||||
*
|
||||
* Creates the merchant_products and merchant_product_variants tables
|
||||
* with all required enums and indexes.
|
||||
*/
|
||||
export class InitialSchema1736505599000 implements MigrationInterface {
|
||||
name = 'InitialSchema1736505599000'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// Create uuid-ossp extension if not exists
|
||||
await queryRunner.query(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`)
|
||||
|
||||
// Create product type enum
|
||||
await queryRunner.query(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'merchant_products_producttype_enum') THEN
|
||||
CREATE TYPE "merchant_products_producttype_enum" AS ENUM (
|
||||
'physical_merchandise',
|
||||
'physical_accessory',
|
||||
'digital_product',
|
||||
'gift_card',
|
||||
'subscription'
|
||||
);
|
||||
END IF;
|
||||
END$$;
|
||||
`)
|
||||
|
||||
// Create product status enum
|
||||
await queryRunner.query(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'merchant_products_status_enum') THEN
|
||||
CREATE TYPE "merchant_products_status_enum" AS ENUM (
|
||||
'draft',
|
||||
'coming_soon',
|
||||
'available',
|
||||
'out_of_stock',
|
||||
'archived'
|
||||
);
|
||||
END IF;
|
||||
END$$;
|
||||
`)
|
||||
|
||||
// Create inventory type enum
|
||||
await queryRunner.query(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'merchant_products_inventorytype_enum') THEN
|
||||
CREATE TYPE "merchant_products_inventorytype_enum" AS ENUM (
|
||||
'unlimited',
|
||||
'limited',
|
||||
'unique'
|
||||
);
|
||||
END IF;
|
||||
END$$;
|
||||
`)
|
||||
|
||||
// Create variant type enum
|
||||
await queryRunner.query(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'merchant_product_variants_varianttype_enum') THEN
|
||||
CREATE TYPE "merchant_product_variants_varianttype_enum" AS ENUM (
|
||||
'size',
|
||||
'color',
|
||||
'style',
|
||||
'custom'
|
||||
);
|
||||
END IF;
|
||||
END$$;
|
||||
`)
|
||||
|
||||
// Create merchant_products table
|
||||
await queryRunner.query(`
|
||||
CREATE TABLE IF NOT EXISTS "merchant_products" (
|
||||
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||
"sku" character varying(100) NOT NULL,
|
||||
"name" character varying(255) NOT NULL,
|
||||
"description" text NOT NULL,
|
||||
"longDescription" text,
|
||||
"productType" "merchant_products_producttype_enum" NOT NULL,
|
||||
"category" character varying(100),
|
||||
"tags" text,
|
||||
"basePriceUsd" numeric(10,2) NOT NULL,
|
||||
"minPriceUsd" numeric(10,2),
|
||||
"maxPriceUsd" numeric(10,2),
|
||||
"allowCustomAmount" boolean NOT NULL DEFAULT false,
|
||||
"basePriceTokens" integer NOT NULL DEFAULT 0,
|
||||
"inventoryType" "merchant_products_inventorytype_enum" NOT NULL DEFAULT 'unlimited',
|
||||
"inventoryQuantity" integer,
|
||||
"inventoryReserved" integer NOT NULL DEFAULT 0,
|
||||
"lowStockThreshold" integer,
|
||||
"status" "merchant_products_status_enum" NOT NULL DEFAULT 'draft',
|
||||
"featured" boolean NOT NULL DEFAULT false,
|
||||
"sortOrder" integer NOT NULL DEFAULT 0,
|
||||
"thumbnailUrl" character varying(500),
|
||||
"previewImages" text,
|
||||
"totalSales" integer NOT NULL DEFAULT 0,
|
||||
"metadata" jsonb,
|
||||
"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
"updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
"publishedAt" TIMESTAMP,
|
||||
"archivedAt" TIMESTAMP,
|
||||
CONSTRAINT "PK_merchant_products" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "UQ_merchant_product_sku" UNIQUE ("sku")
|
||||
)
|
||||
`)
|
||||
|
||||
// Create indexes for merchant_products
|
||||
await queryRunner.query(`CREATE INDEX IF NOT EXISTS "idx_merchant_product_sku" ON "merchant_products" ("sku")`)
|
||||
await queryRunner.query(`CREATE INDEX IF NOT EXISTS "idx_merchant_product_type" ON "merchant_products" ("productType")`)
|
||||
await queryRunner.query(`CREATE INDEX IF NOT EXISTS "idx_merchant_product_status" ON "merchant_products" ("status")`)
|
||||
|
||||
// Create merchant_product_variants table
|
||||
await queryRunner.query(`
|
||||
CREATE TABLE IF NOT EXISTS "merchant_product_variants" (
|
||||
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||
"productId" uuid NOT NULL,
|
||||
"variantType" "merchant_product_variants_varianttype_enum" NOT NULL,
|
||||
"variantValue" character varying(100) NOT NULL,
|
||||
"variantLabel" character varying(100) NOT NULL,
|
||||
"priceModifierUsd" numeric(10,2) NOT NULL DEFAULT 0,
|
||||
"priceModifierTokens" integer NOT NULL DEFAULT 0,
|
||||
"hasSeparateInventory" boolean NOT NULL DEFAULT false,
|
||||
"inventoryQuantity" integer,
|
||||
"isDefault" boolean NOT NULL DEFAULT false,
|
||||
"sortOrder" integer NOT NULL DEFAULT 0,
|
||||
"colorHex" character varying(7),
|
||||
"isActive" boolean NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
"updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
CONSTRAINT "PK_merchant_product_variants" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "FK_merchant_variant_product" FOREIGN KEY ("productId")
|
||||
REFERENCES "merchant_products"("id") ON DELETE CASCADE ON UPDATE NO ACTION
|
||||
)
|
||||
`)
|
||||
|
||||
// Create index for variants
|
||||
await queryRunner.query(`CREATE INDEX IF NOT EXISTS "idx_merchant_variant_product" ON "merchant_product_variants" ("productId")`)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
// Drop tables in reverse order (variants first due to FK)
|
||||
await queryRunner.query(`DROP TABLE IF EXISTS "merchant_product_variants"`)
|
||||
await queryRunner.query(`DROP TABLE IF EXISTS "merchant_products"`)
|
||||
|
||||
// Drop enums
|
||||
await queryRunner.query(`DROP TYPE IF EXISTS "merchant_product_variants_varianttype_enum"`)
|
||||
await queryRunner.query(`DROP TYPE IF EXISTS "merchant_products_inventorytype_enum"`)
|
||||
await queryRunner.query(`DROP TYPE IF EXISTS "merchant_products_status_enum"`)
|
||||
await queryRunner.query(`DROP TYPE IF EXISTS "merchant_products_producttype_enum"`)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue