Update carousels, card hover, and IranBay branding.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-10-04 13:21:10 +03:30
co-authored by Cursor
commit d5cf76ee30
43 changed files with 7337 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
MIGRATIONS_DIR="$ROOT_DIR/database/migrations"
CONTAINER="${POSTGRES_CONTAINER:-ariyaway-postgres}"
DB_USER="${POSTGRES_USER:-ariyaway}"
DB_NAME="${POSTGRES_DB:-ariyaway}"
"$ROOT_DIR/database/wait-for-postgres.sh"
run_migration() {
local file="$1"
echo "→ Running $(basename "$file")"
docker exec -i "$CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" < "$file"
}
if [[ $# -gt 0 ]]; then
run_migration "$1"
else
for file in "$MIGRATIONS_DIR"/*.sql; do
[[ -f "$file" ]] || continue
run_migration "$file"
done
fi
echo "Done."
@@ -0,0 +1,127 @@
-- AriyaWay marketplace — categories + businesses
-- Content (products, blog, portfolio) stays in Meshkee.
-- This DB only tracks marketplace presence + taxonomy.
CREATE OR REPLACE FUNCTION set_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- ---------------------------------------------------------------------------
-- categories (marketplace taxonomy)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS categories (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
parent_id BIGINT,
slug VARCHAR(100) NOT NULL,
name VARCHAR(255) NOT NULL,
name_fa VARCHAR(255),
icon_url TEXT,
sort_order INT NOT NULL DEFAULT 0,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT categories_slug_unique UNIQUE (slug),
CONSTRAINT categories_slug_format CHECK (slug ~ '^[a-z0-9]+(?:-[a-z0-9]+)*$'),
CONSTRAINT categories_parent_id_fkey
FOREIGN KEY (parent_id) REFERENCES categories (id) ON DELETE SET NULL
);
CREATE INDEX IF NOT EXISTS idx_categories_parent_sort
ON categories (parent_id, sort_order);
CREATE INDEX IF NOT EXISTS idx_categories_is_active
ON categories (is_active)
WHERE is_active = TRUE;
DROP TRIGGER IF EXISTS categories_set_updated_at ON categories;
CREATE TRIGGER categories_set_updated_at
BEFORE UPDATE ON categories
FOR EACH ROW
EXECUTE FUNCTION set_updated_at();
-- ---------------------------------------------------------------------------
-- businesses (marketplace listings linked to Meshkee)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS businesses (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
meshkee_business_id BIGINT NOT NULL,
slug VARCHAR(100) NOT NULL,
status VARCHAR(32) NOT NULL DEFAULT 'draft',
primary_category_id BIGINT,
is_featured BOOLEAN NOT NULL DEFAULT FALSE,
sort_weight INT NOT NULL DEFAULT 0,
website_url TEXT,
-- Cached display fields (filled when linking / syncing from Meshkee)
name VARCHAR(255) NOT NULL,
tagline VARCHAR(500),
description TEXT,
logo_url TEXT,
hero_url TEXT,
province VARCHAR(100),
country VARCHAR(100),
telephone VARCHAR(50),
since_year SMALLINT,
published_at TIMESTAMPTZ,
synced_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT businesses_meshkee_business_id_unique UNIQUE (meshkee_business_id),
CONSTRAINT businesses_slug_unique UNIQUE (slug),
CONSTRAINT businesses_slug_format CHECK (slug ~ '^[a-z0-9]+(?:-[a-z0-9]+)*$'),
CONSTRAINT businesses_status_check CHECK (
status IN ('draft', 'pending_review', 'published', 'hidden', 'rejected')
),
CONSTRAINT businesses_primary_category_id_fkey
FOREIGN KEY (primary_category_id) REFERENCES categories (id) ON DELETE SET NULL
);
CREATE INDEX IF NOT EXISTS idx_businesses_status_featured
ON businesses (status, is_featured, sort_weight DESC);
CREATE INDEX IF NOT EXISTS idx_businesses_primary_category
ON businesses (primary_category_id);
CREATE INDEX IF NOT EXISTS idx_businesses_meshkee_id
ON businesses (meshkee_business_id);
DROP TRIGGER IF EXISTS businesses_set_updated_at ON businesses;
CREATE TRIGGER businesses_set_updated_at
BEFORE UPDATE ON businesses
FOR EACH ROW
EXECUTE FUNCTION set_updated_at();
-- ---------------------------------------------------------------------------
-- business_categories (extra marketplace categories)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS business_categories (
business_id BIGINT NOT NULL,
category_id BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT business_categories_pkey PRIMARY KEY (business_id, category_id),
CONSTRAINT business_categories_business_id_fkey
FOREIGN KEY (business_id) REFERENCES businesses (id) ON DELETE CASCADE,
CONSTRAINT business_categories_category_id_fkey
FOREIGN KEY (category_id) REFERENCES categories (id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_business_categories_category
ON business_categories (category_id);
-- ---------------------------------------------------------------------------
-- Seed top-level marketplace categories (matches website mega menu roots)
-- ---------------------------------------------------------------------------
INSERT INTO categories (slug, name, name_fa, sort_order)
VALUES
('industry', 'Industry', 'صنعت', 1),
('stores', 'Stores', 'فروشگاه‌ها', 2),
('wholesellers', 'Whole sellers', 'عمده‌فروشان', 3),
('services', 'Services', 'خدمات', 4),
('food', 'Food', 'مواد غذایی', 5)
ON CONFLICT (slug) DO NOTHING;
@@ -0,0 +1,320 @@
-- AriyaWay marketplace categories (Stores / Industries / Services) with search tags
ALTER TABLE categories ADD COLUMN IF NOT EXISTS tags TEXT[] NOT NULL DEFAULT '{}';
CREATE INDEX IF NOT EXISTS idx_categories_tags ON categories USING GIN (tags);
UPDATE categories SET is_active = FALSE, updated_at = NOW() WHERE is_active = TRUE;
-- Level 1
INSERT INTO categories (parent_id, name, name_fa, slug, sort_order, tags, is_active)
VALUES (NULL, 'Stores', 'فروشگاه‌ها', 'stores', 1, ARRAY['retail', 'shop', 'store', 'stores', 'فروشگاه', 'فروشگاه‌ها', 'مغازه']::text[], TRUE)
ON CONFLICT (slug) DO UPDATE SET
parent_id = EXCLUDED.parent_id,
name = EXCLUDED.name,
name_fa = EXCLUDED.name_fa,
sort_order = EXCLUDED.sort_order,
tags = EXCLUDED.tags,
is_active = TRUE,
updated_at = NOW();
INSERT INTO categories (parent_id, name, name_fa, slug, sort_order, tags, is_active)
VALUES (NULL, 'Industries', 'صنایع', 'industries', 2, ARRAY['industrial', 'industries', 'industry', 'manufacturing', 'صنایع', 'صنعت', 'کارخانه']::text[], TRUE)
ON CONFLICT (slug) DO UPDATE SET
parent_id = EXCLUDED.parent_id,
name = EXCLUDED.name,
name_fa = EXCLUDED.name_fa,
sort_order = EXCLUDED.sort_order,
tags = EXCLUDED.tags,
is_active = TRUE,
updated_at = NOW();
INSERT INTO categories (parent_id, name, name_fa, slug, sort_order, tags, is_active)
VALUES (NULL, 'Services', 'خدمات', 'services', 3, ARRAY['service', 'services', 'خدمات']::text[], TRUE)
ON CONFLICT (slug) DO UPDATE SET
parent_id = EXCLUDED.parent_id,
name = EXCLUDED.name,
name_fa = EXCLUDED.name_fa,
sort_order = EXCLUDED.sort_order,
tags = EXCLUDED.tags,
is_active = TRUE,
updated_at = NOW();
-- Level 2
INSERT INTO categories (parent_id, name, name_fa, slug, sort_order, tags, is_active)
SELECT p.id, v.name, v.name_fa, v.slug, v.sort_order, v.tags, TRUE
FROM (VALUES
('stores', 'Fashion & Apparel', 'مد و پوشاک', 'fashion-apparel', 'مد و پوشاک', 1, ARRAY['apparel', 'clothing', 'fashion', 'fashion & apparel', 'fashion apparel', 'مد', 'مد و پوشاک', 'پوشاک']::text[]),
('stores', 'Food & Grocery', 'مواد غذایی و سوپرمارکت', 'food-grocery', 'مواد غذایی و سوپرمارکت', 2, ARRAY['food', 'food & grocery', 'food grocery', 'grocery', 'خواربار', 'مواد غذایی', 'مواد غذایی و سوپرمارکت']::text[]),
('stores', 'Home & Living', 'خانه و زندگی', 'home-living-retail', 'خانه و زندگی', 3, ARRAY['home', 'home & living', 'home living retail', 'living', 'خانه', 'خانه و زندگی', 'لوازم خانگی']::text[]),
('stores', 'Electronics & Tech', 'الکترونیک و فناوری', 'electronics-tech-retail', 'الکترونیک و فناوری', 4, ARRAY['electronics', 'electronics & tech', 'electronics tech retail', 'tech', 'الکترونیک', 'الکترونیک و فناوری', 'دیجیتال']::text[]),
('stores', 'Beauty & Health Retail', 'آرایشی و بهداشتی', 'beauty-health-retail', 'آرایشی و بهداشتی', 5, ARRAY['beauty', 'beauty & health retail', 'beauty health retail', 'health retail', 'آرایشی', 'آرایشی و بهداشتی', 'بهداشتی']::text[]),
('industries', 'Manufacturing', 'تولید و ساخت', 'manufacturing', 'تولید و ساخت', 1, ARRAY['factory', 'manufacturing', 'تولید', 'تولید و ساخت', 'کارخانه']::text[]),
('industries', 'Construction & Building', 'ساختمان و عمران', 'construction-building', 'ساختمان و عمران', 2, ARRAY['building', 'construction', 'construction & building', 'construction building', 'ساختمان', 'ساختمان و عمران', 'عمران']::text[]),
('industries', 'Agriculture & Raw Materials', 'کشاورزی و مواد اولیه', 'agriculture-raw-materials', 'کشاورزی و مواد اولیه', 3, ARRAY['agriculture', 'agriculture & raw materials', 'agriculture raw materials', 'farming', 'کشاورزی', 'کشاورزی و مواد اولیه']::text[]),
('industries', 'Energy & Utilities', 'انرژی و تأسیسات', 'energy-utilities', 'انرژی و تأسیسات', 4, ARRAY['energy', 'energy & utilities', 'energy utilities', 'utilities', 'انرژی', 'انرژی و تأسیسات']::text[]),
('services', 'Professional Services', 'خدمات حرفه‌ای', 'professional-services', 'خدمات حرفه‌ای', 1, ARRAY['professional', 'professional services', 'حرفه ای', 'خدمات حرفه‌ای']::text[]),
('services', 'Technology Services', 'خدمات فناوری', 'technology-services', 'خدمات فناوری', 2, ARRAY['it service', 'tech service', 'technology services', 'خدمات فناوری', 'فناوری']::text[]),
('services', 'Personal & Local Services', 'خدمات محلی و شخصی', 'personal-local-services', 'خدمات محلی و شخصی', 3, ARRAY['local service', 'personal & local services', 'personal local services', 'personal service', 'خدمات محلی', 'خدمات محلی و شخصی']::text[]),
('services', 'Medical', 'پزشکی', 'medical', 'پزشکی', 4, ARRAY['doctor', 'healthcare', 'medical', 'درمان', 'پزشکی']::text[]),
('services', 'Automotive Services', 'خدمات خودرو', 'automotive-services', 'خدمات خودرو', 5, ARRAY['auto service', 'automotive services', 'car service', 'خدمات خودرو', 'خودرو']::text[])
) AS v(parent_slug, name, name_fa, slug, description, sort_order, tags)
JOIN categories p ON p.slug = v.parent_slug
ON CONFLICT (slug) DO UPDATE SET
parent_id = EXCLUDED.parent_id,
name = EXCLUDED.name,
name_fa = EXCLUDED.name_fa,
sort_order = EXCLUDED.sort_order,
tags = EXCLUDED.tags,
is_active = TRUE,
updated_at = NOW();
-- Level 3
INSERT INTO categories (parent_id, name, name_fa, slug, sort_order, tags, is_active)
SELECT p.id, v.name, v.name_fa, v.slug, v.sort_order, v.tags, TRUE
FROM (VALUES
('fashion-apparel', 'Clothing', 'لباس', 'clothing', 'لباس', 1, ARRAY['apparel', 'clothes', 'clothing', 'لباس']::text[]),
('fashion-apparel', 'Shoes & Bags', 'کفش و کیف', 'shoes-bags', 'کفش و کیف', 2, ARRAY['bags', 'footwear', 'shoes', 'shoes & bags', 'shoes bags', 'کفش', 'کفش و کیف', 'کیف']::text[]),
('fashion-apparel', 'Jewelry & Watches', 'جواهرات و ساعت', 'jewelry-watches', 'جواهرات و ساعت', 3, ARRAY['jewellery', 'jewelry', 'jewelry & watches', 'jewelry watches', 'watches', 'جواهر', 'جواهرات و ساعت', 'ساعت']::text[]),
('food-grocery', 'Supermarket & Grocery', 'سوپرمارکت و خواربار', 'supermarket-grocery', 'سوپرمارکت و خواربار', 1, ARRAY['grocery', 'supermarket', 'supermarket & grocery', 'supermarket grocery', 'سوپرمارکت', 'سوپرمارکت و خواربار', 'هایپر']::text[]),
('food-grocery', 'Specialty Food', 'مواد غذایی تخصصی', 'specialty-food', 'مواد غذایی تخصصی', 2, ARRAY['specialty food', 'مواد غذایی تخصصی', 'مواد غذایی خاص']::text[]),
('food-grocery', 'Beverages', 'نوشیدنی', 'beverages-retail', 'نوشیدنی', 3, ARRAY['beverage', 'beverages', 'beverages retail', 'drink', 'نوشیدنی']::text[]),
('home-living-retail', 'Furniture', 'مبلمان', 'furniture', 'مبلمان', 1, ARRAY['furniture', 'مبل', 'مبلمان']::text[]),
('home-living-retail', 'Home Decor', 'دکوراسیون', 'home-decor', 'دکوراسیون', 2, ARRAY['decor', 'decoration', 'home decor', 'دکور', 'دکوراسیون']::text[]),
('home-living-retail', 'Kitchen & Appliances', 'آشپزخانه و لوازم خانگی', 'kitchen-appliances', 'آشپزخانه و لوازم خانگی', 3, ARRAY['appliance', 'kitchen', 'kitchen & appliances', 'kitchen appliances', 'آشپزخانه', 'آشپزخانه و لوازم خانگی', 'لوازم خانگی']::text[]),
('electronics-tech-retail', 'Mobile & Accessories', 'موبایل و لوازم جانبی', 'mobile-accessories', 'موبایل و لوازم جانبی', 1, ARRAY['mobile', 'mobile & accessories', 'mobile accessories', 'phone', 'تلفن', 'موبایل', 'موبایل و لوازم جانبی']::text[]),
('electronics-tech-retail', 'Computers', 'کامپیوتر', 'computers', 'کامپیوتر', 2, ARRAY['computer', 'computers', 'pc', 'رایانه', 'کامپیوتر']::text[]),
('electronics-tech-retail', 'Audio & Visual', 'صوتی و تصویری', 'audio-visual', 'صوتی و تصویری', 3, ARRAY['audio', 'audio & visual', 'audio visual', 'av', 'visual', 'صوتی تصویری', 'صوتی و تصویری']::text[]),
('beauty-health-retail', 'Cosmetics & Personal Care', 'آرایشی و مراقبت شخصی', 'cosmetics-personal-care', 'آرایشی و مراقبت شخصی', 1, ARRAY['cosmetics', 'cosmetics & personal care', 'cosmetics personal care', 'personal care', 'آرایشی', 'آرایشی و مراقبت شخصی']::text[]),
('beauty-health-retail', 'Pharmacy & Wellness', 'داروخانه و سلامت', 'pharmacy-wellness-retail', 'داروخانه و سلامت', 2, ARRAY['pharmacy', 'pharmacy & wellness', 'pharmacy wellness retail', 'wellness', 'داروخانه', 'داروخانه و سلامت', 'سلامت']::text[]),
('manufacturing', 'Textile & Apparel', 'نساجی و پوشاک', 'textile-apparel-mfg', 'نساجی و پوشاک', 1, ARRAY['apparel mfg', 'textile', 'textile & apparel', 'textile apparel mfg', 'نساجی', 'نساجی و پوشاک', 'پوشاک']::text[]),
('manufacturing', 'Food Processing', 'صنایع غذایی', 'food-processing-mfg', 'صنایع غذایی', 2, ARRAY['food factory', 'food processing', 'food processing mfg', 'صنایع غذایی']::text[]),
('manufacturing', 'Metal & Machinery', 'فلز و ماشین‌آلات', 'metal-machinery-mfg', 'فلز و ماشین‌آلات', 3, ARRAY['machinery', 'metal', 'metal & machinery', 'metal machinery mfg', 'فلز', 'فلز و ماشین‌آلات', 'ماشین آلات']::text[]),
('manufacturing', 'Electrical & Cable', 'برق و کابل', 'electrical-cable-mfg', 'برق و کابل', 4, ARRAY['cable', 'electrical', 'electrical & cable', 'electrical cable mfg', 'wire', 'برق و کابل', 'سیم', 'کابل']::text[]),
('manufacturing', 'Automotive Parts', 'قطعات خودرو', 'automotive-parts-mfg', 'قطعات خودرو', 5, ARRAY['auto parts', 'automotive', 'automotive parts', 'automotive parts mfg', 'قطعات خودرو']::text[]),
('manufacturing', 'Chemicals & Materials', 'شیمیایی و مواد', 'chemicals-materials-mfg', 'شیمیایی و مواد', 6, ARRAY['chemical', 'chemicals & materials', 'chemicals materials mfg', 'materials', 'شیمیایی', 'شیمیایی و مواد']::text[]),
('manufacturing', 'Ceramics & Glass', 'سرامیک و شیشه', 'ceramics-glass-mfg', 'سرامیک و شیشه', 7, ARRAY['ceramic', 'ceramics & glass', 'ceramics glass mfg', 'glass', 'سرامیک', 'سرامیک و شیشه', 'شیشه']::text[]),
('manufacturing', 'Pharmaceutical & Health', 'دارویی و سلامت', 'pharma-health-mfg', 'دارویی و سلامت', 8, ARRAY['pharma', 'pharma health mfg', 'pharmaceutical', 'pharmaceutical & health', 'دارویی', 'دارویی و سلامت']::text[]),
('manufacturing', 'Other Factories', 'سایر کارخانه‌ها', 'other-factories', 'سایر کارخانه‌ها', 9, ARRAY['other factories', 'other factory', 'سایر کارخانه', 'سایر کارخانه‌ها']::text[]),
('construction-building', 'Contractors', 'پیمانکاران', 'contractors', 'پیمانکاران', 1, ARRAY['contractor', 'contractors', 'پیمانکار', 'پیمانکاران']::text[]),
('construction-building', 'Building Supplies', 'مصالح ساختمانی', 'building-supplies', 'مصالح ساختمانی', 2, ARRAY['building supplies', 'building supply', 'مصالح', 'مصالح ساختمانی']::text[]),
('agriculture-raw-materials', 'Farming', 'کشاورزی', 'farming', 'کشاورزی', 1, ARRAY['farm', 'farming', 'کشاورز', 'کشاورزی']::text[]),
('agriculture-raw-materials', 'Mining & Extraction', 'معدن و استخراج', 'mining-extraction', 'معدن و استخراج', 2, ARRAY['mining', 'mining & extraction', 'mining extraction', 'معدن', 'معدن و استخراج']::text[]),
('energy-utilities', 'Energy', 'انرژی', 'energy', 'انرژی', 1, ARRAY['energy', 'power', 'انرژی', 'برق']::text[]),
('energy-utilities', 'Industrial Services', 'خدمات صنعتی', 'industrial-services', 'خدمات صنعتی', 2, ARRAY['industrial service', 'industrial services', 'خدمات صنعتی']::text[]),
('professional-services', 'Business Consulting', 'مشاوره کسب‌وکار', 'business-consulting', 'مشاوره کسب‌وکار', 1, ARRAY['business consulting', 'consulting', 'مشاوره', 'مشاوره کسب‌وکار']::text[]),
('professional-services', 'Design & Creative', 'طراحی و خلاقیت', 'design-creative', 'طراحی و خلاقیت', 2, ARRAY['creative', 'design', 'design & creative', 'design creative', 'طراحی', 'طراحی و خلاقیت']::text[]),
('professional-services', 'Education & Training', 'آموزش', 'education-training', 'آموزش', 3, ARRAY['education', 'education & training', 'education training', 'training', 'آموزش']::text[]),
('technology-services', 'Software & IT', 'نرم‌افزار و فناوری اطلاعات', 'software-it', 'نرم‌افزار و فناوری اطلاعات', 1, ARRAY['it', 'software', 'software & it', 'software it', 'نرم افزار', 'نرم‌افزار و فناوری اطلاعات']::text[]),
('technology-services', 'Digital Marketing', 'بازاریابی دیجیتال', 'digital-marketing', 'بازاریابی دیجیتال', 2, ARRAY['digital marketing', 'بازاریابی دیجیتال', 'دیجیتال مارکتینگ']::text[]),
('personal-local-services', 'Beauty & Care', 'زیبایی و مراقبت', 'beauty-care-services', 'زیبایی و مراقبت', 1, ARRAY['beauty & care', 'beauty care services', 'beauty salon', 'آرایشگاه', 'زیبایی و مراقبت']::text[]),
('personal-local-services', 'Home Services', 'خدمات منزل', 'home-services', 'خدمات منزل', 2, ARRAY['home service', 'home services', 'خدمات منزل']::text[]),
('personal-local-services', 'Hospitality', 'پذیرایی و اقامت', 'hospitality', 'پذیرایی و اقامت', 3, ARRAY['hospitality', 'رستوران', 'هتل', 'پذیرایی و اقامت']::text[]),
('medical', 'Doctors & Specialists', 'پزشکان و متخصصان', 'doctors-specialists', 'پزشکان و متخصصان', 1, ARRAY['doctor', 'doctors & specialists', 'doctors specialists', 'specialist', 'متخصص', 'مطب', 'پزشک', 'پزشکان و متخصصان']::text[]),
('medical', 'Clinics & Centers', 'کلینیک‌ها و مراکز', 'clinics-centers', 'کلینیک‌ها و مراکز', 2, ARRAY['center', 'clinic', 'clinics & centers', 'clinics centers', 'مرکز', 'کلینیک', 'کلینیک‌ها و مراکز']::text[]),
('medical', 'Hospitals & Labs', 'بیمارستان و آزمایشگاه', 'hospitals-labs', 'بیمارستان و آزمایشگاه', 3, ARRAY['hospital', 'hospitals & labs', 'hospitals labs', 'lab', 'آزمایشگاه', 'بیمارستان', 'بیمارستان و آزمایشگاه']::text[]),
('medical', 'Care & Support', 'مراقبت و پشتیبانی', 'care-support', 'مراقبت و پشتیبانی', 4, ARRAY['care', 'care & support', 'care support', 'support', 'مراقبت', 'مراقبت و پشتیبانی']::text[]),
('automotive-services', 'Vehicle Sales', 'فروش خودرو', 'vehicle-sales', 'فروش خودرو', 1, ARRAY['car sales', 'vehicle sales', 'فروش خودرو']::text[]),
('automotive-services', 'Repair & Parts', 'تعمیر و قطعات', 'repair-parts', 'تعمیر و قطعات', 2, ARRAY['auto repair', 'repair & parts', 'repair parts', 'تعمیر خودرو', 'تعمیر و قطعات']::text[])
) AS v(parent_slug, name, name_fa, slug, description, sort_order, tags)
JOIN categories p ON p.slug = v.parent_slug
ON CONFLICT (slug) DO UPDATE SET
parent_id = EXCLUDED.parent_id,
name = EXCLUDED.name,
name_fa = EXCLUDED.name_fa,
sort_order = EXCLUDED.sort_order,
tags = EXCLUDED.tags,
is_active = TRUE,
updated_at = NOW();
-- Level 4
INSERT INTO categories (parent_id, name, name_fa, slug, sort_order, tags, is_active)
SELECT p.id, v.name, v.name_fa, v.slug, v.sort_order, v.tags, TRUE
FROM (VALUES
('clothing', 'Women''s Clothing', 'لباس زنانه', 'womens-clothing', 'لباس زنانه', 1, ARRAY['ladies', 'women', 'women''s clothing', 'womens clothing', 'بانوان', 'زنانه', 'لباس زنانه']::text[]),
('clothing', 'Men''s Clothing', 'لباس مردانه', 'mens-clothing', 'لباس مردانه', 2, ARRAY['gents', 'men', 'men''s clothing', 'mens clothing', 'لباس مردانه', 'مردانه']::text[]),
('clothing', 'Kids & Baby', 'کودک و نوزاد', 'kids-baby-clothing', 'کودک و نوزاد', 3, ARRAY['baby', 'children', 'kids', 'kids & baby', 'kids baby clothing', 'بچگانه', 'نوزاد', 'کودک', 'کودک و نوزاد']::text[]),
('clothing', 'Sportswear', 'لباس ورزشی', 'sportswear', 'لباس ورزشی', 4, ARRAY['activewear', 'sport', 'sportswear', 'لباس ورزشی', 'ورزشی']::text[]),
('shoes-bags', 'Shoes', 'کفش', 'shoes', 'کفش', 1, ARRAY['footwear', 'shoes', 'sneakers', 'کفش']::text[]),
('shoes-bags', 'Bags & Luggage', 'کیف و چمدان', 'bags-luggage', 'کیف و چمدان', 2, ARRAY['bag', 'bags & luggage', 'bags luggage', 'luggage', 'suitcase', 'چمدان', 'کیف', 'کیف و چمدان']::text[]),
('shoes-bags', 'Accessories', 'اکسسوری', 'fashion-accessories', 'اکسسوری', 3, ARRAY['accessories', 'accessory', 'belt', 'fashion accessories', 'scarf', 'اکسسوری']::text[]),
('jewelry-watches', 'Jewelry', 'جواهرات', 'jewelry', 'جواهرات', 1, ARRAY['jewellery', 'jewelry', 'necklace', 'ring', 'جواهر', 'جواهرات', 'طلاآلات']::text[]),
('jewelry-watches', 'Watches', 'ساعت', 'watches', 'ساعت', 2, ARRAY['watch', 'watches', 'ساعت', 'ساعت مچی']::text[]),
('jewelry-watches', 'Gold & Silver', 'طلا و نقره', 'gold-silver', 'طلا و نقره', 3, ARRAY['gold', 'gold & silver', 'gold silver', 'silver', 'طلا', 'طلا فروشی', 'طلا و نقره', 'نقره']::text[]),
('supermarket-grocery', 'Supermarket', 'سوپرمارکت', 'supermarket', 'سوپرمارکت', 1, ARRAY['grocery store', 'hypermarket', 'supermarket', 'سوپر', 'سوپرمارکت', 'هایپرمارکت']::text[]),
('supermarket-grocery', 'Convenience Store', 'بقالی', 'convenience-store', 'بقالی', 2, ARRAY['convenience store', 'corner store', 'minimarket', 'بقالی', 'مینی مارکت']::text[]),
('supermarket-grocery', 'Organic & Healthy', 'ارگانیک و سالم', 'organic-healthy', 'ارگانیک و سالم', 3, ARRAY['healthy', 'organic', 'organic & healthy', 'organic healthy', 'ارگانیک', 'ارگانیک و سالم', 'سالم']::text[]),
('specialty-food', 'Bakery & Pastry', 'نانوایی و شیرینی', 'bakery-pastry', 'نانوایی و شیرینی', 1, ARRAY['bakery', 'bakery & pastry', 'bakery pastry', 'pastry', 'شیرینی', 'قنادی', 'نانوایی', 'نانوایی و شیرینی']::text[]),
('specialty-food', 'Nuts & Dried Fruit', 'آجیل و خشکبار', 'nuts-dried-fruit', 'آجیل و خشکبار', 2, ARRAY['dried fruit', 'nuts', 'nuts & dried fruit', 'nuts dried fruit', 'آجیل', 'آجیل و خشکبار', 'خشکبار']::text[]),
('specialty-food', 'Sweets & Confectionery', 'شیرینی و آبنبات', 'sweets-confectionery', 'شیرینی و آبنبات', 3, ARRAY['candy', 'confectionery', 'sweets', 'sweets & confectionery', 'sweets confectionery', 'آبنبات', 'شیرینی', 'شیرینی و آبنبات']::text[]),
('specialty-food', 'Spices & Herbs', 'ادویه و گیاهان دارویی', 'spices-herbs', 'ادویه و گیاهان دارویی', 4, ARRAY['herb', 'saffron', 'spice', 'spices & herbs', 'spices herbs', 'ادویه', 'ادویه و گیاهان دارویی', 'زعفران']::text[]),
('beverages-retail', 'Coffee & Tea', 'قهوه و چای', 'coffee-tea', 'قهوه و چای', 1, ARRAY['coffee', 'coffee & tea', 'coffee tea', 'tea', 'قهوه', 'قهوه و چای', 'چای']::text[]),
('beverages-retail', 'Soft Drinks', 'نوشابه', 'soft-drinks', 'نوشابه', 2, ARRAY['soda', 'soft drink', 'soft drinks', 'نوشابه']::text[]),
('beverages-retail', 'Dairy & Juice', 'لبنیات و آبمیوه', 'dairy-juice', 'لبنیات و آبمیوه', 3, ARRAY['dairy', 'dairy & juice', 'dairy juice', 'juice', 'milk', 'آبمیوه', 'لبنیات', 'لبنیات و آبمیوه']::text[]),
('furniture', 'Home Furniture', 'مبلمان خانگی', 'home-furniture', 'مبلمان خانگی', 1, ARRAY['bedroom', 'home furniture', 'sofa', 'مبلمان خانگی', 'مبلمان منزل']::text[]),
('furniture', 'Office Furniture', 'مبلمان اداری', 'office-furniture', 'مبلمان اداری', 2, ARRAY['desk', 'office chair', 'office furniture', 'اداری', 'مبلمان اداری']::text[]),
('furniture', 'Outdoor Furniture', 'مبلمان فضای باز', 'outdoor-furniture', 'مبلمان فضای باز', 3, ARRAY['garden furniture', 'outdoor furniture', 'فضای باز', 'مبلمان فضای باز']::text[]),
('home-decor', 'Rugs & Carpets', 'فرش و قالی', 'rugs-carpets', 'فرش و قالی', 1, ARRAY['carpet', 'rug', 'rugs & carpets', 'rugs carpets', 'فرش', 'فرش و قالی', 'قالی', 'گلیم']::text[]),
('home-decor', 'Lighting', 'روشنایی', 'lighting', 'روشنایی', 2, ARRAY['lamp', 'light', 'lighting', 'روشنایی', 'لوستر', 'چراغ']::text[]),
('home-decor', 'Decor Accessories', 'لوازم دکوری', 'decor-accessories', 'لوازم دکوری', 3, ARRAY['decor', 'decor accessories', 'ornament', 'دکوری', 'لوازم دکوری']::text[]),
('kitchen-appliances', 'Kitchenware', 'ظروف آشپزخانه', 'kitchenware', 'ظروف آشپزخانه', 1, ARRAY['cookware', 'kitchen tools', 'kitchenware', 'ظروف', 'ظروف آشپزخانه']::text[]),
('kitchen-appliances', 'Small Appliances', 'لوازم کوچک خانگی', 'small-appliances', 'لوازم کوچک خانگی', 2, ARRAY['blender', 'small appliances', 'toaster', 'لوازم کوچک', 'لوازم کوچک خانگی']::text[]),
('kitchen-appliances', 'Large Appliances', 'لوازم بزرگ خانگی', 'large-appliances', 'لوازم بزرگ خانگی', 3, ARRAY['fridge', 'large appliances', 'washer', 'لوازم بزرگ خانگی', 'ماشین لباسشویی', 'یخچال']::text[]),
('mobile-accessories', 'Mobile Phones', 'گوشی موبایل', 'mobile-phones', 'گوشی موبایل', 1, ARRAY['mobile phones', 'phone shop', 'smartphone', 'فروشگاه موبایل', 'گوشی', 'گوشی موبایل']::text[]),
('mobile-accessories', 'Accessories', 'لوازم جانبی موبایل', 'mobile-accessories-store', 'لوازم جانبی موبایل', 2, ARRAY['accessories', 'case', 'charger', 'mobile accessories store', 'لوازم جانبی', 'لوازم جانبی موبایل']::text[]),
('mobile-accessories', 'Wearables', 'گجت پوشیدنی', 'wearables', 'گجت پوشیدنی', 3, ARRAY['smartwatch', 'wearables', 'ساعت هوشمند', 'گجت پوشیدنی']::text[]),
('computers', 'Laptops', 'لپ‌تاپ', 'laptops', 'لپ‌تاپ', 1, ARRAY['laptops', 'notebook', 'لپ تاپ', 'لپتاپ', 'لپ‌تاپ']::text[]),
('computers', 'Desktops & Parts', 'دسکتاپ و قطعات', 'desktops-parts', 'دسکتاپ و قطعات', 2, ARRAY['cpu', 'desktops & parts', 'desktops parts', 'pc parts', 'دسکتاپ و قطعات', 'قطعات کامپیوتر']::text[]),
('computers', 'Peripherals', 'لوازم جانبی کامپیوتر', 'peripherals', 'لوازم جانبی کامپیوتر', 3, ARRAY['keyboard', 'monitor', 'mouse', 'peripherals', 'لوازم جانبی کامپیوتر', 'مانیتور']::text[]),
('audio-visual', 'TVs', 'تلویزیون', 'tvs', 'تلویزیون', 1, ARRAY['television', 'tv store', 'tvs', 'تلویزیون']::text[]),
('audio-visual', 'Audio Systems', 'سیستم صوتی', 'audio-systems', 'سیستم صوتی', 2, ARRAY['audio systems', 'sound', 'speaker', 'اسپیکر', 'سیستم صوتی']::text[]),
('audio-visual', 'Cameras', 'دوربین', 'cameras', 'دوربین', 3, ARRAY['camera', 'cameras', 'photography', 'دوربین', 'دوربین عکاسی']::text[]),
('cosmetics-personal-care', 'Skincare', 'مراقبت پوست', 'skincare', 'مراقبت پوست', 1, ARRAY['cream', 'skin care', 'skincare', 'مراقبت پوست', 'پوست']::text[]),
('cosmetics-personal-care', 'Makeup', 'آرایش', 'makeup', 'آرایش', 2, ARRAY['cosmetic', 'make up', 'makeup', 'آرایش']::text[]),
('cosmetics-personal-care', 'Hair Care', 'مراقبت مو', 'hair-care', 'مراقبت مو', 3, ARRAY['hair', 'hair care', 'shampoo', 'مراقبت مو', 'مو']::text[]),
('pharmacy-wellness-retail', 'Pharmacy', 'داروخانه', 'pharmacy', 'داروخانه', 1, ARRAY['chemist', 'drug store', 'drugstore', 'pharmacy', 'pharmacy store', 'دارو', 'داروخانه', 'شبانه روزی']::text[]),
('pharmacy-wellness-retail', 'Supplements', 'مکمل‌ها', 'supplements', 'مکمل‌ها', 2, ARRAY['supplement', 'supplements', 'vitamin', 'مکمل', 'مکمل‌ها', 'ویتامین']::text[]),
('pharmacy-wellness-retail', 'Medical Supplies', 'لوازم پزشکی', 'medical-supplies-retail', 'لوازم پزشکی', 3, ARRAY['medical supplies', 'medical supplies retail', 'medical supply', 'لوازم پزشکی']::text[]),
('textile-apparel-mfg', 'Garment Factory', 'کارخانه پوشاک', 'garment-factory', 'کارخانه پوشاک', 1, ARRAY['clothing factory', 'garment factory', 'دوخت', 'کارخانه لباس', 'کارخانه پوشاک']::text[]),
('textile-apparel-mfg', 'Fabric & Textile Mill', 'کارخانه پارچه و نساجی', 'fabric-textile-mill', 'کارخانه پارچه و نساجی', 2, ARRAY['fabric & textile mill', 'fabric textile mill', 'textile mill', 'نساجی', 'پارچه', 'کارخانه پارچه و نساجی']::text[]),
('textile-apparel-mfg', 'Knitwear Factory', 'کارخانه تریکو', 'knitwear-factory', 'کارخانه تریکو', 3, ARRAY['knitwear', 'knitwear factory', 'تریکو', 'کارخانه تریکو']::text[]),
('textile-apparel-mfg', 'Leather Goods Factory', 'کارخانه چرم', 'leather-goods-factory', 'کارخانه چرم', 4, ARRAY['leather factory', 'leather goods factory', 'چرم', 'کارخانه چرم']::text[]),
('food-processing-mfg', 'Dairy Factory', 'کارخانه لبنیات', 'dairy-factory', 'کارخانه لبنیات', 1, ARRAY['dairy factory', 'dairy plant', 'لبنیات', 'کارخانه لبنیات']::text[]),
('food-processing-mfg', 'Meat Processing Plant', 'کارخانه فرآوری گوشت', 'meat-processing-plant', 'کارخانه فرآوری گوشت', 2, ARRAY['meat factory', 'meat processing plant', 'کارخانه فرآوری گوشت', 'گوشت']::text[]),
('food-processing-mfg', 'Nuts & Dry Goods Factory', 'کارخانه آجیل و خشکبار', 'nuts-dry-goods-factory', 'کارخانه آجیل و خشکبار', 3, ARRAY['nuts & dry goods factory', 'nuts dry goods factory', 'nuts factory', 'آجیل', 'کارخانه آجیل و خشکبار']::text[]),
('food-processing-mfg', 'Beverage Factory', 'کارخانه نوشیدنی', 'beverage-factory', 'کارخانه نوشیدنی', 4, ARRAY['beverage factory', 'drink factory', 'نوشیدنی', 'کارخانه نوشیدنی']::text[]),
('food-processing-mfg', 'Flour Mill', 'آسیاب آرد', 'flour-mill', 'آسیاب آرد', 5, ARRAY['flour', 'flour mill', 'mill', 'آرد', 'آسیاب آرد']::text[]),
('food-processing-mfg', 'Canning Factory', 'کارخانه کنسرو', 'canning-factory', 'کارخانه کنسرو', 6, ARRAY['cannery', 'canning factory', 'کارخانه کنسرو', 'کنسرو']::text[]),
('metal-machinery-mfg', 'Metal Fabrication Plant', 'کارخانه ساخت فلزی', 'metal-fabrication-plant', 'کارخانه ساخت فلزی', 1, ARRAY['fabrication', 'metal fabrication plant', 'ورق کاری', 'کارخانه ساخت فلزی']::text[]),
('metal-machinery-mfg', 'Machinery Factory', 'کارخانه ماشین‌آلات', 'machinery-factory', 'کارخانه ماشین‌آلات', 2, ARRAY['machine factory', 'machinery factory', 'ماشین سازی', 'کارخانه ماشین‌آلات']::text[]),
('metal-machinery-mfg', 'Tools Factory', 'کارخانه ابزار', 'tools-factory', 'کارخانه ابزار', 3, ARRAY['tool factory', 'tools factory', 'ابزار', 'کارخانه ابزار']::text[]),
('metal-machinery-mfg', 'Foundry', 'ریخته‌گری', 'foundry', 'ریخته‌گری', 4, ARRAY['casting', 'foundry', 'ریخته گری', 'ریخته‌گری']::text[]),
('electrical-cable-mfg', 'Cable Factory', 'کارخانه کابل', 'cable-factory', 'کارخانه کابل', 1, ARRAY['cable factory', 'cable manufacturer', 'سیم و کابل', 'کابل سازی', 'کارخانه کابل']::text[]),
('electrical-cable-mfg', 'Wire Factory', 'کارخانه سیم', 'wire-factory', 'کارخانه سیم', 2, ARRAY['wire factory', 'wire manufacturer', 'سیم سازی', 'کارخانه سیم']::text[]),
('electrical-cable-mfg', 'Electrical Equipment Factory', 'کارخانه تجهیزات برقی', 'electrical-equipment-factory', 'کارخانه تجهیزات برقی', 3, ARRAY['electrical equipment factory', 'electrical factory', 'تجهیزات برقی', 'کارخانه تجهیزات برقی']::text[]),
('electrical-cable-mfg', 'Transformer Factory', 'کارخانه ترانسفورماتور', 'transformer-factory', 'کارخانه ترانسفورماتور', 4, ARRAY['transformer', 'transformer factory', 'ترانسفورماتور', 'کارخانه ترانسفورماتور']::text[]),
('automotive-parts-mfg', 'Auto Parts Factory', 'کارخانه قطعات خودرو', 'auto-parts-factory', 'کارخانه قطعات خودرو', 1, ARRAY['auto parts factory', 'car parts factory', 'قطعه سازی خودرو', 'کارخانه قطعات خودرو']::text[]),
('automotive-parts-mfg', 'Tire Factory', 'کارخانه لاستیک', 'tire-factory', 'کارخانه لاستیک', 2, ARRAY['tire factory', 'tyre', 'لاستیک', 'کارخانه لاستیک']::text[]),
('automotive-parts-mfg', 'Battery Factory', 'کارخانه باتری', 'battery-factory', 'کارخانه باتری', 3, ARRAY['battery factory', 'car battery', 'باتری', 'کارخانه باتری']::text[]),
('automotive-parts-mfg', 'Automotive Electronics Factory', 'کارخانه الکترونیک خودرو', 'automotive-electronics-factory', 'کارخانه الکترونیک خودرو', 4, ARRAY['auto electronics', 'automotive electronics factory', 'الکترونیک خودرو', 'کارخانه الکترونیک خودرو']::text[]),
('chemicals-materials-mfg', 'Chemical Plant', 'کارخانه شیمیایی', 'chemical-plant', 'کارخانه شیمیایی', 1, ARRAY['chemical plant', 'chemicals factory', 'شیمیایی', 'کارخانه شیمیایی']::text[]),
('chemicals-materials-mfg', 'Plastics Factory', 'کارخانه پلاستیک', 'plastics-factory', 'کارخانه پلاستیک', 2, ARRAY['plastic factory', 'plastics factory', 'پلاستیک', 'کارخانه پلاستیک']::text[]),
('chemicals-materials-mfg', 'Paint Factory', 'کارخانه رنگ', 'paint-factory', 'کارخانه رنگ', 3, ARRAY['paint factory', 'paint manufacturer', 'رنگ سازی', 'کارخانه رنگ']::text[]),
('chemicals-materials-mfg', 'Rubber Factory', 'کارخانه لاستیک صنعتی', 'rubber-factory', 'کارخانه لاستیک صنعتی', 4, ARRAY['rubber', 'rubber factory', 'لاستیک صنعتی', 'کارخانه لاستیک صنعتی']::text[]),
('chemicals-materials-mfg', 'Building Materials Factory', 'کارخانه مصالح ساختمانی', 'building-materials-factory', 'کارخانه مصالح ساختمانی', 5, ARRAY['building materials', 'building materials factory', 'مصالح', 'کارخانه مصالح ساختمانی']::text[]),
('ceramics-glass-mfg', 'Ceramic Factory', 'کارخانه سرامیک', 'ceramic-factory', 'کارخانه سرامیک', 1, ARRAY['ceramic factory', 'ceramics plant', 'سرامیک سازی', 'کارخانه سرامیک']::text[]),
('ceramics-glass-mfg', 'Tile Factory', 'کارخانه کاشی', 'tile-factory', 'کارخانه کاشی', 2, ARRAY['tile factory', 'tile manufacturer', 'سرامیک کف', 'کارخانه کاشی', 'کاشی']::text[]),
('ceramics-glass-mfg', 'Porcelain Factory', 'کارخانه چینی', 'porcelain-factory', 'کارخانه چینی', 3, ARRAY['porcelain', 'porcelain factory', 'چینی', 'کارخانه چینی']::text[]),
('ceramics-glass-mfg', 'Glass Factory', 'کارخانه شیشه', 'glass-factory', 'کارخانه شیشه', 4, ARRAY['glass factory', 'glass plant', 'شیشه سازی', 'کارخانه شیشه']::text[]),
('pharma-health-mfg', 'Pharmaceutical Factory', 'کارخانه داروسازی', 'pharmaceutical-factory', 'کارخانه داروسازی', 1, ARRAY['drug factory', 'medicine factory', 'pharmaceutical factory', 'داروسازی', 'کارخانه دارو', 'کارخانه داروسازی']::text[]),
('pharma-health-mfg', 'Cosmetics Factory', 'کارخانه آرایشی', 'cosmetics-factory', 'کارخانه آرایشی', 2, ARRAY['cosmetic manufacturer', 'cosmetics factory', 'آرایشی بهداشتی', 'کارخانه آرایشی']::text[]),
('pharma-health-mfg', 'Medical Devices Factory', 'کارخانه تجهیزات پزشکی', 'medical-devices-factory', 'کارخانه تجهیزات پزشکی', 3, ARRAY['medical devices factory', 'medtech', 'تجهیزات پزشکی', 'کارخانه تجهیزات پزشکی']::text[]),
('pharma-health-mfg', 'Supplement Factory', 'کارخانه مکمل', 'supplement-factory', 'کارخانه مکمل', 4, ARRAY['supplement factory', 'vitamin factory', 'مکمل سازی', 'کارخانه مکمل']::text[]),
('other-factories', 'Packaging Factory', 'کارخانه بسته‌بندی', 'packaging-factory', 'کارخانه بسته‌بندی', 1, ARRAY['packaging', 'packaging factory', 'بسته بندی', 'کارخانه بسته‌بندی']::text[]),
('other-factories', 'Paper & Carton Factory', 'کارخانه کاغذ و کارتن', 'paper-carton-factory', 'کارخانه کاغذ و کارتن', 2, ARRAY['carton', 'paper & carton factory', 'paper carton factory', 'paper mill', 'کارتن', 'کارخانه کاغذ و کارتن', 'کاغذ']::text[]),
('other-factories', 'Furniture Factory', 'کارخانه مبلمان', 'furniture-factory', 'کارخانه مبلمان', 3, ARRAY['furniture factory', 'furniture manufacturer', 'مبلمان سازی', 'کارخانه مبلمان']::text[]),
('other-factories', 'Wood Products Factory', 'کارخانه محصولات چوبی', 'wood-products-factory', 'کارخانه محصولات چوبی', 4, ARRAY['wood factory', 'wood products factory', 'چوب', 'کارخانه محصولات چوبی']::text[]),
('other-factories', 'Printing Factory', 'چاپخانه صنعتی', 'printing-factory', 'چاپخانه صنعتی', 5, ARRAY['printing factory', 'printing plant', 'چاپ', 'چاپخانه صنعتی']::text[]),
('contractors', 'General Contractor', 'پیمانکار عمومی', 'general-contractor', 'پیمانکار عمومی', 1, ARRAY['gc', 'general contractor', 'پیمانکار عمومی', 'پیمانکاری']::text[]),
('contractors', 'Renovation', 'بازسازی', 'renovation', 'بازسازی', 2, ARRAY['remodel', 'renovation', 'بازسازی']::text[]),
('contractors', 'Interior Fit-out', 'طراحی داخلی اجرایی', 'interior-fit-out', 'طراحی داخلی اجرایی', 3, ARRAY['fit out', 'interior fit out', 'interior fit-out', 'دکوراسیون داخلی', 'طراحی داخلی اجرایی']::text[]),
('building-supplies', 'Cement Factory', 'کارخانه سیمان', 'cement-factory', 'کارخانه سیمان', 1, ARRAY['cement factory', 'cement plant', 'سیمان', 'کارخانه سیمان']::text[]),
('building-supplies', 'Steel Plant', 'کارخانه فولاد', 'steel-plant', 'کارخانه فولاد', 2, ARRAY['steel mill', 'steel plant', 'فولاد', 'کارخانه فولاد']::text[]),
('building-supplies', 'Electrical & Plumbing Supply', 'تأسیسات برقی و لوله‌کشی', 'electrical-plumbing-supply', 'تأسیسات برقی و لوله‌کشی', 3, ARRAY['electrical & plumbing supply', 'electrical plumbing supply', 'electrical supply', 'plumbing', 'تأسیسات', 'تأسیسات برقی و لوله‌کشی']::text[]),
('farming', 'Crops', 'زراعت', 'crops', 'زراعت', 1, ARRAY['crop', 'crops', 'farm', 'زراعت']::text[]),
('farming', 'Livestock', 'دامپروری', 'livestock', 'دامپروری', 2, ARRAY['cattle', 'livestock', 'poultry', 'دام', 'دامپروری', 'مرغداری']::text[]),
('farming', 'Greenhouse', 'گلخانه', 'greenhouse', 'گلخانه', 3, ARRAY['greenhouse', 'greenhouse farm', 'گلخانه']::text[]),
('mining-extraction', 'Minerals', 'مواد معدنی', 'minerals', 'مواد معدنی', 1, ARRAY['mineral', 'minerals', 'معدنی', 'مواد معدنی']::text[]),
('mining-extraction', 'Stone & Quarry', 'سنگ و معدن سنگ', 'stone-quarry', 'سنگ و معدن سنگ', 2, ARRAY['quarry', 'stone', 'stone & quarry', 'stone quarry', 'سنگ و معدن سنگ', 'سنگبری']::text[]),
('energy', 'Solar & Renewables', 'خورشیدی و تجدیدپذیر', 'solar-renewables', 'خورشیدی و تجدیدپذیر', 1, ARRAY['renewable', 'solar', 'solar & renewables', 'solar renewables', 'خورشیدی و تجدیدپذیر', 'پنل خورشیدی']::text[]),
('energy', 'Oil & Gas Related', 'نفت و گاز', 'oil-gas-related', 'نفت و گاز', 2, ARRAY['gas', 'oil', 'oil & gas related', 'oil gas related', 'نفت', 'نفت و گاز', 'گاز']::text[]),
('energy', 'Power Equipment', 'تجهیزات برق', 'power-equipment', 'تجهیزات برق', 3, ARRAY['power equipment', 'تجهیزات برق', 'تجهیزات قدرت']::text[]),
('industrial-services', 'Logistics Support', 'پشتیبانی لجستیک', 'logistics-support', 'پشتیبانی لجستیک', 1, ARRAY['logistics', 'logistics support', 'لجستیک', 'پشتیبانی لجستیک']::text[]),
('industrial-services', 'Industrial Maintenance', 'نگهداری صنعتی', 'industrial-maintenance', 'نگهداری صنعتی', 2, ARRAY['industrial maintenance', 'maintenance', 'نگهداری', 'نگهداری صنعتی']::text[]),
('business-consulting', 'Management Consulting', 'مشاوره مدیریت', 'management-consulting', 'مشاوره مدیریت', 1, ARRAY['management consultant', 'management consulting', 'مشاور مدیریت', 'مشاوره مدیریت']::text[]),
('business-consulting', 'Marketing & Branding', 'بازاریابی و برندینگ', 'marketing-branding', 'بازاریابی و برندینگ', 2, ARRAY['branding', 'marketing & branding', 'marketing branding', 'بازاریابی', 'بازاریابی و برندینگ', 'برندینگ']::text[]),
('business-consulting', 'Legal & Accounting', 'حقوقی و حسابداری', 'legal-accounting', 'حقوقی و حسابداری', 3, ARRAY['accountant', 'lawyer', 'legal & accounting', 'legal accounting', 'حسابدار', 'حقوقی و حسابداری', 'وکیل']::text[]),
('design-creative', 'Graphic Design', 'طراحی گرافیک', 'graphic-design', 'طراحی گرافیک', 1, ARRAY['graphic design', 'graphic designer', 'طراحی گرافیک', 'گرافیک']::text[]),
('design-creative', 'Architecture & Interior', 'معماری و داخلی', 'architecture-interior', 'معماری و داخلی', 2, ARRAY['architect', 'architecture & interior', 'architecture interior', 'interior design', 'طراح داخلی', 'معمار', 'معماری و داخلی']::text[]),
('design-creative', 'Photography & Video', 'عکاسی و فیلم', 'photography-video', 'عکاسی و فیلم', 3, ARRAY['photographer', 'photography & video', 'photography video', 'videographer', 'عکاس', 'عکاسی و فیلم', 'فیلمبردار']::text[]),
('education-training', 'Training Centers', 'مراکز آموزشی', 'training-centers', 'مراکز آموزشی', 1, ARRAY['training center', 'training centers', 'آموزشگاه', 'مراکز آموزشی']::text[]),
('education-training', 'Online Courses', 'دوره‌های آنلاین', 'online-courses', 'دوره‌های آنلاین', 2, ARRAY['elearning', 'online course', 'online courses', 'دوره آنلاین', 'دوره‌های آنلاین']::text[]),
('education-training', 'Language Schools', 'آموزشگاه زبان', 'language-schools', 'آموزشگاه زبان', 3, ARRAY['language school', 'language schools', 'آموزشگاه زبان', 'زبان']::text[]),
('software-it', 'Software Development', 'توسعه نرم‌افزار', 'software-development', 'توسعه نرم‌افزار', 1, ARRAY['dev shop', 'software company', 'software development', 'برنامه نویسی', 'توسعه نرم‌افزار']::text[]),
('software-it', 'SaaS & Platforms', 'نرم‌افزار ابری و پلتفرم', 'saas-platforms', 'نرم‌افزار ابری و پلتفرم', 2, ARRAY['platform', 'saas', 'saas & platforms', 'saas platforms', 'ابری', 'نرم‌افزار ابری و پلتفرم']::text[]),
('software-it', 'IT Support', 'پشتیبانی آی‌تی', 'it-support', 'پشتیبانی آی‌تی', 3, ARRAY['helpdesk', 'it support', 'پشتیبانی', 'پشتیبانی آی‌تی']::text[]),
('digital-marketing', 'SEO & Ads', 'سئو و تبلیغات', 'seo-ads', 'سئو و تبلیغات', 1, ARRAY['ads', 'google ads', 'seo', 'seo & ads', 'seo ads', 'سئو', 'سئو و تبلیغات']::text[]),
('digital-marketing', 'Social Media', 'شبکه‌های اجتماعی', 'social-media', 'شبکه‌های اجتماعی', 2, ARRAY['instagram marketing', 'social media', 'سوشال', 'شبکه‌های اجتماعی']::text[]),
('digital-marketing', 'Content Production', 'تولید محتوا', 'content-production', 'تولید محتوا', 3, ARRAY['content', 'content production', 'تولید محتوا', 'محتوا']::text[]),
('beauty-care-services', 'Hair Salon', 'آرایشگاه', 'hair-salon', 'آرایشگاه', 1, ARRAY['barber', 'hair salon', 'hairdresser', 'آرایشگاه', 'آرایشگاه زنانه', 'آرایشگاه مردانه']::text[]),
('beauty-care-services', 'Spa & Wellness', 'اسپا و سلامت', 'spa-wellness', 'اسپا و سلامت', 2, ARRAY['massage', 'spa', 'spa & wellness', 'spa wellness', 'اسپا', 'اسپا و سلامت']::text[]),
('beauty-care-services', 'Clinic Services', 'کلینیک زیبایی', 'clinic-services-beauty', 'کلینیک زیبایی', 3, ARRAY['beauty clinic', 'clinic services', 'clinic services beauty', 'کلینیک زیبایی']::text[]),
('home-services', 'Cleaning', 'نظافت', 'cleaning', 'نظافت', 1, ARRAY['cleaner', 'cleaning', 'شرکت نظافتی', 'نظافت', 'نظافتچی']::text[]),
('home-services', 'Repair & Maintenance', 'تعمیرات', 'repair-maintenance', 'تعمیرات', 2, ARRAY['handyman', 'repair & maintenance', 'repair maintenance', 'تعمیرات', 'تعمیرات منزل']::text[]),
('home-services', 'Moving & Logistics', 'اسباب‌کشی و حمل', 'moving-logistics', 'اسباب‌کشی و حمل', 3, ARRAY['moving', 'moving & logistics', 'moving logistics', 'relocation', 'اسباب کشی', 'اسباب‌کشی و حمل', 'باربری']::text[]),
('hospitality', 'Restaurants & Cafés', 'رستوران و کافه', 'restaurants-cafes', 'رستوران و کافه', 1, ARRAY['cafe', 'restaurant', 'restaurants & cafés', 'restaurants cafes', 'رستوران', 'رستوران و کافه', 'کافه']::text[]),
('hospitality', 'Catering', 'کترینگ', 'catering', 'کترینگ', 2, ARRAY['caterer', 'catering', 'کترینگ']::text[]),
('hospitality', 'Hotels & Stays', 'هتل و اقامتگاه', 'hotels-stays', 'هتل و اقامتگاه', 3, ARRAY['hotel', 'hotels & stays', 'hotels stays', 'اقامتگاه', 'هتل', 'هتل و اقامتگاه']::text[]),
('doctors-specialists', 'General Practitioner', 'پزشک عمومی', 'general-practitioner', 'پزشک عمومی', 1, ARRAY['family doctor', 'general practitioner', 'gp', 'دکتر عمومی', 'پزشک عمومی']::text[]),
('doctors-specialists', 'Internal Medicine', 'داخلی', 'internal-medicine', 'داخلی', 2, ARRAY['internal medicine', 'internist', 'داخلی']::text[]),
('doctors-specialists', 'Cardiology', 'قلب و عروق', 'cardiology', 'قلب و عروق', 3, ARRAY['cardiologist', 'cardiology', 'heart doctor', 'قلب', 'قلب و عروق', 'متخصص قلب']::text[]),
('doctors-specialists', 'ENT (Otolaryngology)', 'گوش و حلق و بینی', 'ent-otolaryngology', 'گوش و حلق و بینی', 4, ARRAY['ear nose throat', 'ent', 'ent (otolaryngology)', 'ent otolaryngology', 'متخصص گوش', 'گوش حلق بینی', 'گوش و حلق و بینی']::text[]),
('doctors-specialists', 'Dermatology', 'پوست', 'dermatology', 'پوست', 5, ARRAY['dermatologist', 'dermatology', 'skin doctor', 'متخصص پوست', 'پوست']::text[]),
('doctors-specialists', 'Ophthalmology', 'چشم', 'ophthalmology', 'چشم', 6, ARRAY['eye doctor', 'ophthalmologist', 'ophthalmology', 'چشم', 'چشم پزشک']::text[]),
('doctors-specialists', 'Orthopedics', 'ارتوپدی', 'orthopedics', 'ارتوپدی', 7, ARRAY['bone doctor', 'orthopedics', 'orthopedist', 'ارتوپد', 'ارتوپدی', 'استخوان']::text[]),
('doctors-specialists', 'Neurology', 'مغز و اعصاب', 'neurology', 'مغز و اعصاب', 8, ARRAY['neurologist', 'neurology', 'مغز اعصاب', 'مغز و اعصاب']::text[]),
('doctors-specialists', 'Neurosurgery', 'جراحی مغز و اعصاب', 'neurosurgery', 'جراحی مغز و اعصاب', 9, ARRAY['neurosurgeon', 'neurosurgery', 'جراح مغز', 'جراحی مغز و اعصاب']::text[]),
('doctors-specialists', 'General Surgery', 'جراحی عمومی', 'general-surgery', 'جراحی عمومی', 10, ARRAY['general surgery', 'surgeon', 'جراح', 'جراحی عمومی']::text[]),
('doctors-specialists', 'Plastic & Aesthetic Surgery', 'جراحی پلاستیک و زیبایی', 'plastic-aesthetic-surgery', 'جراحی پلاستیک و زیبایی', 11, ARRAY['cosmetic surgery', 'plastic & aesthetic surgery', 'plastic aesthetic surgery', 'plastic surgery', 'جراحی زیبایی', 'جراحی پلاستیک و زیبایی', 'پلاستیک']::text[]),
('doctors-specialists', 'Obstetrics & Gynecology', 'زنان و زایمان', 'obstetrics-gynecology', 'زنان و زایمان', 12, ARRAY['gynecologist', 'obgyn', 'obstetrics & gynecology', 'obstetrics gynecology', 'زایمان', 'زنان', 'زنان و زایمان']::text[]),
('doctors-specialists', 'Infertility & IVF', 'ناباروری و IVF', 'infertility-ivf', 'ناباروری و IVF', 13, ARRAY['fertility', 'infertility & ivf', 'infertility ivf', 'ivf', 'ناباروری', 'ناباروری و ivf', 'نازایی']::text[]),
('doctors-specialists', 'Pediatrics', 'اطفال', 'pediatrics', 'اطفال', 14, ARRAY['kids doctor', 'pediatrician', 'pediatrics', 'اطفال', 'کودکان']::text[]),
('doctors-specialists', 'Urology', 'اورولوژی', 'urology', 'اورولوژی', 15, ARRAY['urologist', 'urology', 'اورولوژی']::text[]),
('doctors-specialists', 'Gastroenterology', 'گوارش', 'gastroenterology', 'گوارش', 16, ARRAY['gastro', 'gastroenterology', 'گوارش']::text[]),
('doctors-specialists', 'Endocrinology', 'غدد', 'endocrinology', 'غدد', 17, ARRAY['endocrinologist', 'endocrinology', 'دیابت', 'غدد']::text[]),
('doctors-specialists', 'Pulmonology', 'ریه', 'pulmonology', 'ریه', 18, ARRAY['lung doctor', 'pulmonology', 'تنفسی', 'ریه']::text[]),
('doctors-specialists', 'Nephrology', 'کلیه', 'nephrology', 'کلیه', 19, ARRAY['nephrologist', 'nephrology', 'کلیه']::text[]),
('doctors-specialists', 'Rheumatology', 'روماتولوژی', 'rheumatology', 'روماتولوژی', 20, ARRAY['rheumatologist', 'rheumatology', 'روماتولوژی', 'روماتیسم']::text[]),
('doctors-specialists', 'Hematology & Oncology', 'خون و سرطان', 'hematology-oncology', 'خون و سرطان', 21, ARRAY['cancer', 'hematology & oncology', 'hematology oncology', 'oncologist', 'خون', 'خون و سرطان', 'سرطان']::text[]),
('doctors-specialists', 'Infectious Disease', 'عفونی', 'infectious-disease', 'عفونی', 22, ARRAY['infectious', 'infectious disease', 'عفونی']::text[]),
('doctors-specialists', 'Allergy & Immunology', 'آلرژی و ایمونولوژی', 'allergy-immunology', 'آلرژی و ایمونولوژی', 23, ARRAY['allergy', 'allergy & immunology', 'allergy immunology', 'آلرژی', 'آلرژی و ایمونولوژی']::text[]),
('doctors-specialists', 'Psychiatry', 'روانپزشکی', 'psychiatry', 'روانپزشکی', 24, ARRAY['psychiatrist', 'psychiatry', 'روانپزشک', 'روانپزشکی']::text[]),
('doctors-specialists', 'Psychology', 'روانشناسی', 'psychology', 'روانشناسی', 25, ARRAY['counselor', 'psychologist', 'psychology', 'روانشناس', 'روانشناسی']::text[]),
('doctors-specialists', 'Dentistry', 'دندانپزشکی', 'dentistry', 'دندانپزشکی', 26, ARRAY['dental', 'dentist', 'dentistry', 'دندان', 'دندانپزشک', 'دندانپزشکی']::text[]),
('doctors-specialists', 'Orthodontics', 'ارتودنسی', 'orthodontics', 'ارتودنسی', 27, ARRAY['orthodontics', 'orthodontist', 'ارتودنسی']::text[]),
('doctors-specialists', 'Oral & Maxillofacial Surgery', 'جراحی فک و صورت', 'oral-maxillofacial-surgery', 'جراحی فک و صورت', 28, ARRAY['oral & maxillofacial surgery', 'oral maxillofacial surgery', 'oral surgery', 'جراحی فک', 'جراحی فک و صورت']::text[]),
('doctors-specialists', 'Radiology', 'رادیولوژی', 'radiology', 'رادیولوژی', 29, ARRAY['radiologist', 'radiology', 'رادیولوژی', 'عکسبرداری']::text[]),
('doctors-specialists', 'Nuclear Medicine', 'پزشکی هسته‌ای', 'nuclear-medicine', 'پزشکی هسته‌ای', 30, ARRAY['nuclear medicine', 'پزشکی هسته ای', 'پزشکی هسته‌ای']::text[]),
('doctors-specialists', 'Anesthesiology', 'بیهوشی', 'anesthesiology', 'بیهوشی', 31, ARRAY['anesthesiologist', 'anesthesiology', 'بیهوشی']::text[]),
('doctors-specialists', 'Emergency Medicine', 'اورژانس', 'emergency-medicine', 'اورژانس', 32, ARRAY['emergency doctor', 'emergency medicine', 'اورژانس']::text[]),
('doctors-specialists', 'Physical Medicine & Rehabilitation', 'طب فیزیکی و توانبخشی', 'physical-medicine-rehab', 'طب فیزیکی و توانبخشی', 33, ARRAY['physical medicine & rehabilitation', 'physical medicine rehab', 'pmr', 'rehab', 'توانبخشی', 'طب فیزیکی', 'طب فیزیکی و توانبخشی']::text[]),
('doctors-specialists', 'Traditional Iranian Medicine', 'طب سنتی ایرانی', 'traditional-iranian-medicine', 'طب سنتی ایرانی', 34, ARRAY['persian medicine', 'traditional iranian medicine', 'traditional medicine', 'طب سنتی', 'طب سنتی ایرانی', 'گیاهی']::text[]),
('doctors-specialists', 'Nutrition & Dietetics', 'تغذیه', 'nutrition-dietetics', 'تغذیه', 35, ARRAY['dietitian', 'nutrition & dietetics', 'nutrition dietetics', 'nutritionist', 'تغذیه', 'رژیم']::text[]),
('doctors-specialists', 'Occupational Medicine', 'طب کار', 'occupational-medicine', 'طب کار', 36, ARRAY['occupational health', 'occupational medicine', 'طب کار']::text[]),
('clinics-centers', 'Specialty Clinics', 'کلینیک تخصصی', 'specialty-clinics', 'کلینیک تخصصی', 1, ARRAY['specialty clinic', 'specialty clinics', 'کلینیک تخصصی']::text[]),
('clinics-centers', 'Polyclinics', 'درمانگاه', 'polyclinics', 'درمانگاه', 2, ARRAY['polyclinic', 'polyclinics', 'درمانگاه']::text[]),
('clinics-centers', 'Dental Clinics', 'کلینیک دندانپزشکی', 'dental-clinics', 'کلینیک دندانپزشکی', 3, ARRAY['dental clinic', 'dental clinics', 'کلینیک دندان', 'کلینیک دندانپزشکی']::text[]),
('clinics-centers', 'Aesthetic Clinics', 'کلینیک زیبایی', 'aesthetic-clinics', 'کلینیک زیبایی', 4, ARRAY['aesthetic clinic', 'aesthetic clinics', 'کلینیک زیبایی']::text[]),
('clinics-centers', 'Infertility Centers', 'مراکز ناباروری', 'infertility-centers', 'مراکز ناباروری', 5, ARRAY['infertility centers', 'ivf center', 'مراکز ناباروری', 'مرکز ناباروری']::text[]),
('hospitals-labs', 'Hospitals', 'بیمارستان', 'hospitals', 'بیمارستان', 1, ARRAY['hospital', 'hospitals', 'بیمارستان']::text[]),
('hospitals-labs', 'Diagnostic Labs', 'آزمایشگاه تشخیصی', 'diagnostic-labs', 'آزمایشگاه تشخیصی', 2, ARRAY['diagnostic labs', 'lab', 'laboratory', 'آزمایشگاه', 'آزمایشگاه تشخیصی']::text[]),
('hospitals-labs', 'Imaging Centers', 'مراکز تصویربرداری', 'imaging-centers', 'مراکز تصویربرداری', 3, ARRAY['ct scan', 'imaging centers', 'mri', 'تصویربرداری', 'سونوگرافی', 'مراکز تصویربرداری']::text[]),
('care-support', 'Physiotherapy', 'فیزیوتراپی', 'physiotherapy', 'فیزیوتراپی', 1, ARRAY['physical therapy', 'physio', 'physiotherapy', 'فیزیوتراپی']::text[]),
('care-support', 'Nursing & Home Care', 'پرستاری و مراقبت در منزل', 'nursing-home-care', 'پرستاری و مراقبت در منزل', 2, ARRAY['home care', 'nurse', 'nursing & home care', 'nursing home care', 'مراقبت در منزل', 'پرستاری و مراقبت در منزل']::text[]),
('care-support', 'Midwifery', 'مامایی', 'midwifery', 'مامایی', 3, ARRAY['midwife', 'midwifery', 'ماما', 'مامایی']::text[]),
('care-support', 'Pharmacy Services', 'خدمات داروخانه', 'pharmacy-services', 'خدمات داروخانه', 4, ARRAY['drug store', 'drugstore', 'pharmacy service', 'pharmacy services', 'خدمات داروخانه', 'داروخانه']::text[]),
('vehicle-sales', 'Car Dealership', 'نمایندگی خودرو', 'car-dealership', 'نمایندگی خودرو', 1, ARRAY['car dealer', 'car dealership', 'dealership', 'نمایندگی', 'نمایندگی خودرو']::text[]),
('vehicle-sales', 'Motorcycle Dealer', 'فروش موتورسیکلت', 'motorcycle-dealer', 'فروش موتورسیکلت', 2, ARRAY['bike dealer', 'motorcycle dealer', 'فروش موتورسیکلت', 'موتور']::text[]),
('repair-parts', 'Auto Repair', 'تعمیرگاه خودرو', 'auto-repair', 'تعمیرگاه خودرو', 1, ARRAY['auto repair', 'garage', 'mechanic', 'تعمیرگاه', 'تعمیرگاه خودرو', 'مکانیکی']::text[]),
('repair-parts', 'Auto Parts', 'لوازم یدکی', 'auto-parts', 'لوازم یدکی', 2, ARRAY['auto parts', 'spare parts', 'قطعات', 'لوازم یدکی', 'یدکی']::text[]),
('repair-parts', 'Car Wash & Detailing', 'کارواش و دیتیلینگ', 'car-wash-detailing', 'کارواش و دیتیلینگ', 3, ARRAY['car wash', 'car wash & detailing', 'car wash detailing', 'detailing', 'کارواش', 'کارواش و دیتیلینگ']::text[])
) AS v(parent_slug, name, name_fa, slug, description, sort_order, tags)
JOIN categories p ON p.slug = v.parent_slug
ON CONFLICT (slug) DO UPDATE SET
parent_id = EXCLUDED.parent_id,
name = EXCLUDED.name,
name_fa = EXCLUDED.name_fa,
sort_order = EXCLUDED.sort_order,
tags = EXCLUDED.tags,
is_active = TRUE,
updated_at = NOW();
-- Seeded 237 categories (L1=3, L2=14, L3=43, L4=177)
@@ -0,0 +1,21 @@
-- Add Other catch-all to AriyaWay marketplace categories
ALTER TABLE categories ADD COLUMN IF NOT EXISTS tags TEXT[] NOT NULL DEFAULT '{}';
INSERT INTO categories (parent_id, name, name_fa, slug, sort_order, tags, is_active)
VALUES (
NULL,
'Other',
'سایر',
'other',
99,
ARRAY['other', 'misc', 'miscellaneous', 'uncategorized', 'general', 'سایر', 'متفرقه', 'عمومی']::text[],
TRUE
)
ON CONFLICT (slug) DO UPDATE SET
parent_id = NULL,
name = EXCLUDED.name,
name_fa = EXCLUDED.name_fa,
sort_order = EXCLUDED.sort_order,
tags = EXCLUDED.tags,
is_active = TRUE,
updated_at = NOW();
@@ -0,0 +1,14 @@
-- Slim marketplace businesses: Meshkee owns profile content.
-- AriyaWay keeps listing fields + display name only.
ALTER TABLE businesses
DROP COLUMN IF EXISTS website_url,
DROP COLUMN IF EXISTS tagline,
DROP COLUMN IF EXISTS description,
DROP COLUMN IF EXISTS logo_url,
DROP COLUMN IF EXISTS hero_url,
DROP COLUMN IF EXISTS province,
DROP COLUMN IF EXISTS country,
DROP COLUMN IF EXISTS telephone,
DROP COLUMN IF EXISTS since_year,
DROP COLUMN IF EXISTS synced_at;
@@ -0,0 +1,12 @@
-- Minimum marketplace listing: Meshkee owns name, categories, and profile.
-- AriyaWay/IranBay keeps only listing controls.
ALTER TABLE businesses DROP CONSTRAINT IF EXISTS businesses_primary_category_id_fkey;
DROP TABLE IF EXISTS business_categories;
ALTER TABLE businesses
DROP COLUMN IF EXISTS primary_category_id,
DROP COLUMN IF EXISTS name;
DROP TABLE IF EXISTS categories;
@@ -0,0 +1,10 @@
-- Homepage media config for the public website (slider, banners, categories, about).
CREATE TABLE IF NOT EXISTS website_settings (
key TEXT PRIMARY KEY,
value JSONB NOT NULL DEFAULT '{}'::jsonb,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
COMMENT ON TABLE website_settings IS
'Key/value JSON settings for marketplace website content.';
+31
View File
@@ -0,0 +1,31 @@
-- Website blog posts managed from the superadmin dashboard.
CREATE TABLE IF NOT EXISTS website_blog_categories (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(120) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE UNIQUE INDEX IF NOT EXISTS website_blog_categories_name_unique
ON website_blog_categories (name);
CREATE TABLE IF NOT EXISTS website_blog_posts (
id BIGSERIAL PRIMARY KEY,
title VARCHAR(200) NOT NULL,
abstract TEXT,
main_text_html TEXT,
image_url TEXT,
category_id BIGINT NOT NULL REFERENCES website_blog_categories (id) ON DELETE RESTRICT,
tags TEXT[] NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_website_blog_posts_created_at
ON website_blog_posts (created_at DESC);
CREATE INDEX IF NOT EXISTS idx_website_blog_posts_category_id
ON website_blog_posts (category_id);
COMMENT ON TABLE website_blog_posts IS
'IranBay website blog posts edited from the superadmin dashboard.';
@@ -0,0 +1,21 @@
-- Blog categories can nest under a parent.
ALTER TABLE website_blog_categories
ADD COLUMN IF NOT EXISTS parent_id BIGINT;
DO $$
BEGIN
ALTER TABLE website_blog_categories
ADD CONSTRAINT website_blog_categories_parent_id_fkey
FOREIGN KEY (parent_id) REFERENCES website_blog_categories (id) ON DELETE RESTRICT;
EXCEPTION
WHEN duplicate_object THEN NULL;
END $$;
DROP INDEX IF EXISTS website_blog_categories_name_unique;
CREATE INDEX IF NOT EXISTS idx_website_blog_categories_parent_id
ON website_blog_categories (parent_id);
CREATE UNIQUE INDEX IF NOT EXISTS website_blog_categories_parent_name_unique
ON website_blog_categories (COALESCE(parent_id, 0), lower(name));
@@ -0,0 +1,5 @@
-- Blog categories store the same details shown on the business category form.
ALTER TABLE website_blog_categories
ADD COLUMN IF NOT EXISTS name_fa VARCHAR(120),
ADD COLUMN IF NOT EXISTS description TEXT;
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail
CONTAINER="${POSTGRES_CONTAINER:-ariyaway-postgres}"
DB_USER="${POSTGRES_USER:-ariyaway}"
DB_NAME="${POSTGRES_DB:-ariyaway}"
MAX_ATTEMPTS="${POSTGRES_WAIT_ATTEMPTS:-30}"
for ((i = 1; i <= MAX_ATTEMPTS; i++)); do
if docker exec "$CONTAINER" pg_isready -U "$DB_USER" -d "$DB_NAME" >/dev/null 2>&1; then
echo "Postgres is ready."
exit 0
fi
echo "Waiting for Postgres ($i/$MAX_ATTEMPTS)…"
sleep 1
done
echo "Postgres did not become ready in time." >&2
exit 1