Files
backend/database/migrations/010_category_variations.sql
T
Ali Reza bb59d5e9ba Initial commit: Meshkee CMS API
NestJS backend with Prisma, Docker Compose for Postgres/Redis, and deploy docs for the production VM.
2026-07-21 17:52:36 +03:30

105 lines
4.3 KiB
SQL

-- Category variations & options (product categories only)
-- Variation types: color (predefined palette), size (user-defined), custom (user-defined name + values)
CREATE TYPE variation_type AS ENUM ('color', 'size', 'custom');
CREATE TABLE category_variations (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
business_id BIGINT NOT NULL,
category_id BIGINT NOT NULL,
name VARCHAR(255) NOT NULL,
variation_type variation_type NOT NULL,
sort_order INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT category_variations_business_id_fkey
FOREIGN KEY (business_id) REFERENCES businesses (id) ON DELETE CASCADE,
CONSTRAINT category_variations_category_id_fkey
FOREIGN KEY (category_id) REFERENCES categories (id) ON DELETE CASCADE
);
CREATE UNIQUE INDEX category_variations_one_color_per_category
ON category_variations (category_id) WHERE variation_type = 'color';
CREATE UNIQUE INDEX category_variations_one_size_per_category
ON category_variations (category_id) WHERE variation_type = 'size';
CREATE UNIQUE INDEX category_variations_custom_name_per_category
ON category_variations (category_id, name) WHERE variation_type = 'custom';
CREATE INDEX idx_category_variations_category_id ON category_variations (category_id);
CREATE INDEX idx_category_variations_business_id ON category_variations (business_id);
CREATE TRIGGER category_variations_set_updated_at
BEFORE UPDATE ON category_variations
FOR EACH ROW
EXECUTE FUNCTION set_updated_at();
CREATE TABLE category_variation_options (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
variation_id BIGINT NOT NULL,
label VARCHAR(255) NOT NULL,
value VARCHAR(255) NOT NULL,
color_hex VARCHAR(7),
sort_order INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT category_variation_options_variation_id_fkey
FOREIGN KEY (variation_id) REFERENCES category_variations (id) ON DELETE CASCADE,
CONSTRAINT category_variation_options_unique_value
UNIQUE (variation_id, value)
);
CREATE INDEX idx_category_variation_options_variation_id
ON category_variation_options (variation_id);
-- Product variants (combinations of category variation options)
CREATE TABLE product_variants (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
business_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,
sku VARCHAR(100),
price NUMERIC(12, 2),
compare_at_price NUMERIC(12, 2),
stock_quantity INTEGER,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
sort_order INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT product_variants_business_id_fkey
FOREIGN KEY (business_id) REFERENCES businesses (id) ON DELETE CASCADE,
CONSTRAINT product_variants_product_id_fkey
FOREIGN KEY (product_id) REFERENCES products (id) ON DELETE CASCADE,
CONSTRAINT product_variants_stock_non_negative
CHECK (stock_quantity IS NULL OR stock_quantity >= 0)
);
CREATE INDEX idx_product_variants_product_id ON product_variants (product_id);
CREATE INDEX idx_product_variants_business_id ON product_variants (business_id);
CREATE TRIGGER product_variants_set_updated_at
BEFORE UPDATE ON product_variants
FOR EACH ROW
EXECUTE FUNCTION set_updated_at();
CREATE TABLE product_variant_selections (
variant_id BIGINT NOT NULL,
variation_id BIGINT NOT NULL,
option_id BIGINT NOT NULL,
CONSTRAINT product_variant_selections_pkey PRIMARY KEY (variant_id, variation_id),
CONSTRAINT product_variant_selections_variant_id_fkey
FOREIGN KEY (variant_id) REFERENCES product_variants (id) ON DELETE CASCADE,
CONSTRAINT product_variant_selections_variation_id_fkey
FOREIGN KEY (variation_id) REFERENCES category_variations (id) ON DELETE RESTRICT,
CONSTRAINT product_variant_selections_option_id_fkey
FOREIGN KEY (option_id) REFERENCES category_variation_options (id) ON DELETE RESTRICT,
CONSTRAINT product_variant_selections_unique_option
UNIQUE (variant_id, option_id)
);
CREATE INDEX idx_product_variant_selections_option_id
ON product_variant_selections (option_id);