scaffold: schema, compose, contract
This commit is contained in:
148
db/schema.sql
Normal file
148
db/schema.sql
Normal file
@@ -0,0 +1,148 @@
|
||||
-- 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);
|
||||
Reference in New Issue
Block a user