-- Migration: Consolidated Schema for CASPOS -- Purpose: Complete definition of core webshop structures, global rules, and order split support. CREATE TABLE IF NOT EXISTS public.companies ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, street TEXT, zip TEXT, city TEXT, email TEXT, created_at TIMESTAMPTZ DEFAULT now() ); CREATE TABLE IF NOT EXISTS public.users ( id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE, role TEXT NOT NULL DEFAULT 'partner' CHECK (role IN ('partner', 'admin')), company_id UUID REFERENCES public.companies(id) ON DELETE SET NULL, created_at TIMESTAMPTZ DEFAULT now() ); CREATE TABLE IF NOT EXISTS public.end_customers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), partner_id UUID REFERENCES public.companies(id) ON DELETE CASCADE, company_name TEXT, first_name TEXT, last_name TEXT, street TEXT, zip TEXT, city TEXT, email TEXT, bank_iban TEXT, bank_bic TEXT, bank_name TEXT, bank_owner TEXT, is_anonymized BOOLEAN DEFAULT false NOT NULL, created_at TIMESTAMPTZ DEFAULT now() ); CREATE TABLE IF NOT EXISTS public.categories ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, is_required BOOLEAN DEFAULT false NOT NULL, allow_multiple BOOLEAN DEFAULT false NOT NULL, sort_order INTEGER DEFAULT 0 NOT NULL, show_in_branches BOOLEAN DEFAULT true NOT NULL, preselect BOOLEAN DEFAULT false NOT NULL, resets_others BOOLEAN DEFAULT false NOT NULL, created_at TIMESTAMPTZ DEFAULT now() ); CREATE TABLE IF NOT EXISTS public.products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), category_id UUID REFERENCES public.categories(id) ON DELETE RESTRICT, name TEXT NOT NULL, base_price DECIMAL(10,2) DEFAULT 0.00 NOT NULL, tax_rate DECIMAL(5,2) DEFAULT 19.00 NOT NULL, billing_interval TEXT DEFAULT 'monthly' NOT NULL CHECK (billing_interval IN ('one_time', 'monthly')), show_in_branches BOOLEAN DEFAULT true NOT NULL, created_at TIMESTAMPTZ DEFAULT now() ); CREATE TABLE IF NOT EXISTS public.modules ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), product_id UUID REFERENCES public.products(id) ON DELETE CASCADE, category_id UUID REFERENCES public.categories(id) ON DELETE RESTRICT, name TEXT NOT NULL, price DECIMAL(10,2) DEFAULT 0.00 NOT NULL, has_quantity BOOLEAN DEFAULT false NOT NULL, created_at TIMESTAMPTZ DEFAULT now() ); CREATE TABLE IF NOT EXISTS public.global_inclusions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), trigger_product_id UUID NOT NULL REFERENCES public.products(id) ON DELETE CASCADE, included_module_id UUID NOT NULL REFERENCES public.modules(id) ON DELETE CASCADE, created_at TIMESTAMPTZ DEFAULT now(), UNIQUE (trigger_product_id, included_module_id) ); CREATE TABLE IF NOT EXISTS public.global_exclusions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), product_id UUID NOT NULL REFERENCES public.products(id) ON DELETE CASCADE, excluded_product_id UUID REFERENCES public.products(id) ON DELETE CASCADE, excluded_module_id UUID REFERENCES public.modules(id) ON DELETE CASCADE, created_at TIMESTAMPTZ DEFAULT now(), CHECK ( (excluded_product_id IS NOT NULL AND excluded_module_id IS NULL) OR (excluded_product_id IS NULL AND excluded_module_id IS NOT NULL) ) ); CREATE TABLE IF NOT EXISTS public.orders ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES auth.users(id) ON DELETE SET NULL, company_id UUID REFERENCES public.companies(id) ON DELETE RESTRICT, end_customer_id UUID REFERENCES public.end_customers(id) ON DELETE RESTRICT, order_number TEXT NOT NULL UNIQUE, order_hash TEXT, type TEXT NOT NULL CHECK (type IN ('purchase', 'subscription')), payment_method TEXT NOT NULL, total_price DECIMAL(10,2) DEFAULT 0.00 NOT NULL, customer_snapshot JSONB NOT NULL, order_snapshot JSONB NOT NULL, pdf_url TEXT, status TEXT DEFAULT 'pending' NOT NULL CHECK (status IN ('pending', 'active', 'completed', 'cancelled')), created_at TIMESTAMPTZ DEFAULT now() );