-- Polaris — canonical PostgreSQL schema (single source of truth) -- Database: reseller User: reseller CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- ── SUPPLIERS ────────────────────────────────────────────── CREATE TABLE suppliers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, adapter_type TEXT NOT NULL, -- csv|xml|json|api|affiliate api_endpoint TEXT, account_id TEXT, credentials_enc TEXT, -- encrypted secret ref (never raw) fulfillment_caps JSONB DEFAULT '[]', shipping_regions JSONB DEFAULT '[]', reliability_score NUMERIC(5,2) DEFAULT 50.0, status TEXT NOT NULL DEFAULT 'active', -- active|paused|failed created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now() ); -- ── PRODUCTS ─────────────────────────────────────────────── CREATE TABLE products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), sku TEXT UNIQUE NOT NULL, title TEXT NOT NULL, description TEXT, category TEXT, brand TEXT, manufacturer TEXT, upc_ean_gtin TEXT, images JSONB DEFAULT '[]', dimensions JSONB, -- {length,width,height,unit} weight_grams NUMERIC(10,2), cost NUMERIC(12,2) NOT NULL DEFAULT 0, retail_price NUMERIC(12,2), min_price NUMERIC(12,2), max_price NUMERIC(12,2), status TEXT NOT NULL DEFAULT 'discovered', -- discovered|analyzing|approved|imported|content_generated|price_calculated|quality_check|published|monitored|paused|sold lifecycle JSONB DEFAULT '{}', -- opportunity score etc created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now() ); -- ── SUPPLIER_PRODUCTS ────────────────────────────────────── CREATE TABLE supplier_products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), supplier_id UUID NOT NULL REFERENCES suppliers(id) ON DELETE CASCADE, supplier_sku TEXT NOT NULL, product_id UUID REFERENCES products(id) ON DELETE SET NULL, supplier_cost NUMERIC(12,2) NOT NULL DEFAULT 0, supplier_inventory INTEGER NOT NULL DEFAULT 0, shipping_cost NUMERIC(12,2) DEFAULT 0, shipping_time TEXT, -- e.g. '3-5 days' last_updated TIMESTAMPTZ DEFAULT now(), UNIQUE (supplier_id, supplier_sku) ); -- ── CUSTOMERS ────────────────────────────────────────────── CREATE TABLE customers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email TEXT UNIQUE NOT NULL, name TEXT, shipping_addr JSONB, created_at TIMESTAMPTZ DEFAULT now() ); -- ── ORDERS ───────────────────────────────────────────────── CREATE TABLE orders ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), order_number TEXT UNIQUE NOT NULL, customer_id UUID REFERENCES customers(id), items JSONB NOT NULL, -- [{product_id,qty,unit_price}] retail_total NUMERIC(12,2) NOT NULL DEFAULT 0, supplier_id UUID REFERENCES suppliers(id), supplier_cost NUMERIC(12,2) DEFAULT 0, shipping_cost NUMERIC(12,2) DEFAULT 0, fees NUMERIC(12,2) DEFAULT 0, profit NUMERIC(12,2) DEFAULT 0, status TEXT NOT NULL DEFAULT 'new', -- new|paid|fraud_check|supplier_order|confirmed|shipped|delivered|cancelled|refunded tracking TEXT, carrier TEXT, created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now() ); -- ── PRICE HISTORY ────────────────────────────────────────── CREATE TABLE price_history ( id BIGSERIAL PRIMARY KEY, product_id UUID NOT NULL REFERENCES products(id) ON DELETE CASCADE, price NUMERIC(12,2) NOT NULL, reason TEXT, -- manual|auto|competitor|cost_change created_at TIMESTAMPTZ DEFAULT now() ); -- ── INVENTORY HISTORY ────────────────────────────────────── CREATE TABLE inventory_history ( id BIGSERIAL PRIMARY KEY, supplier_product_id UUID NOT NULL REFERENCES supplier_products(id) ON DELETE CASCADE, inventory INTEGER NOT NULL, created_at TIMESTAMPTZ DEFAULT now() ); -- ── SUPPLIER PERFORMANCE ─────────────────────────────────── CREATE TABLE supplier_performance ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), supplier_id UUID NOT NULL REFERENCES suppliers(id) ON DELETE CASCADE, fulfillment_rate NUMERIC(5,2) DEFAULT 100, avg_shipping_days NUMERIC(6,2), cancellation_rate NUMERIC(5,2) DEFAULT 0, stock_accuracy NUMERIC(5,2) DEFAULT 100, return_rate NUMERIC(5,2) DEFAULT 0, updated_at TIMESTAMPTZ DEFAULT now() ); -- ── PRICE RULES ──────────────────────────────────────────── CREATE TABLE price_rules ( id SERIAL PRIMARY KEY, min_cost NUMERIC(12,2) NOT NULL DEFAULT 0, max_cost NUMERIC(12,2), -- null = no upper bound markup_pct NUMERIC(6,2) NOT NULL, min_margin_pct NUMERIC(6,2) DEFAULT 0, active BOOLEAN DEFAULT true, created_at TIMESTAMPTZ DEFAULT now() ); -- ── AUDIT LOG ────────────────────────────────────────────── CREATE TABLE audit_logs ( id BIGSERIAL PRIMARY KEY, actor TEXT, action TEXT NOT NULL, entity TEXT, entity_id TEXT, detail JSONB, created_at TIMESTAMPTZ DEFAULT now() ); -- seed default price rules (cost -> markup) INSERT INTO price_rules (min_cost, max_cost, markup_pct) VALUES (0, 25, 50.00), (25, 100, 35.00), (100, 500, 25.00), (500, NULL, 15.00); CREATE INDEX idx_supplier_products_product ON supplier_products(product_id); CREATE INDEX idx_orders_status ON orders(status); CREATE INDEX idx_products_status ON products(status); CREATE INDEX idx_price_history_product ON price_history(product_id);