Route Handlers (Vercel Functions): /api/health, /api/estimates (single-source estimate math, ore), /api/catalog, /api/sources (legal sourcing map). sql/001_init.sql = full docs/03 data model (entities + bridge_provenance + platform tables, pgvector). Ready to wire Vercel Postgres. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
138 lines
5.2 KiB
SQL
138 lines
5.2 KiB
SQL
-- 0pt — initial schema (docs/03-data-model.md). Postgres + pgvector.
|
|
-- Amounts in öre (integer). Every fact links to bridge_provenance.
|
|
CREATE EXTENSION IF NOT EXISTS vector;
|
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|
|
|
-- ── Data entities ───────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS dim_source (
|
|
source_id text PRIMARY KEY,
|
|
name text NOT NULL,
|
|
market text,
|
|
access text, -- api | bulk | authorized_web | licensed
|
|
licence text,
|
|
cadence text,
|
|
url text
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS dim_company (
|
|
org_nr text PRIMARY KEY,
|
|
market text NOT NULL,
|
|
lei text,
|
|
name text NOT NULL,
|
|
status text,
|
|
nace text,
|
|
registered_at date,
|
|
address jsonb,
|
|
website text,
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
created_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS fact_financials (
|
|
org_nr text REFERENCES dim_company(org_nr),
|
|
fiscal_year int NOT NULL,
|
|
revenue bigint, result bigint, employees int,
|
|
source_id text REFERENCES dim_source(source_id),
|
|
PRIMARY KEY (org_nr, fiscal_year)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS dim_contact (
|
|
contact_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
org_nr text REFERENCES dim_company(org_nr),
|
|
name text, role text, email text, phone text, linkedin text,
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS dim_ubo (
|
|
ubo_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
org_nr text REFERENCES dim_company(org_nr),
|
|
owner text, share numeric(5,2)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS dim_vehicle (
|
|
vin text PRIMARY KEY,
|
|
market text NOT NULL,
|
|
reg_plate text, make text, model text, year int,
|
|
owner_org text REFERENCES dim_company(org_nr),
|
|
specs jsonb,
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- ── Provenance (the signature) ──────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS bridge_provenance (
|
|
field_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
entity_type text NOT NULL, -- company|contact|vehicle|financials
|
|
entity_key text NOT NULL,
|
|
field_name text NOT NULL,
|
|
source_id text REFERENCES dim_source(source_id),
|
|
freshness date,
|
|
confidence numeric(4,3) NOT NULL,
|
|
level smallint NOT NULL, -- 0 unavailable/licensed,1 single,2 partial,3 corroborated
|
|
agreed_sources int DEFAULT 1,
|
|
UNIQUE (entity_type, entity_key, field_name)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_prov_entity ON bridge_provenance (entity_type, entity_key);
|
|
|
|
-- ── Platform tables ─────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS orgs (
|
|
org_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name text NOT NULL, created_at timestamptz DEFAULT now()
|
|
);
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
user_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
org_id uuid REFERENCES orgs(org_id),
|
|
email text UNIQUE NOT NULL,
|
|
role text NOT NULL DEFAULT 'member',
|
|
created_at timestamptz DEFAULT now()
|
|
);
|
|
CREATE TABLE IF NOT EXISTS orders (
|
|
order_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
org_id uuid REFERENCES orgs(org_id),
|
|
flow text NOT NULL,
|
|
status text NOT NULL DEFAULT 'draft',
|
|
config jsonb NOT NULL,
|
|
total_ore bigint, deposit_ore bigint, balance_ore bigint,
|
|
est_days int, est_confidence numeric(4,3),
|
|
created_at timestamptz DEFAULT now(), updated_at timestamptz DEFAULT now()
|
|
);
|
|
CREATE TABLE IF NOT EXISTS jobs (
|
|
job_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
order_id uuid REFERENCES orders(order_id),
|
|
stage text, pct numeric(5,2) DEFAULT 0, state text DEFAULT 'queued',
|
|
metrics jsonb, started_at timestamptz, finished_at timestamptz
|
|
);
|
|
CREATE TABLE IF NOT EXISTS deliveries (
|
|
delivery_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
order_id uuid REFERENCES orders(order_id),
|
|
formats text[], destinations text[],
|
|
record_count int, avg_confidence numeric(4,3),
|
|
quality_report jsonb, provenance_export_url text, files jsonb,
|
|
created_at timestamptz DEFAULT now()
|
|
);
|
|
CREATE TABLE IF NOT EXISTS subscriptions (
|
|
sub_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
order_id uuid REFERENCES orders(order_id),
|
|
cadence text, webhook_url text, status text DEFAULT 'active', next_run_at timestamptz
|
|
);
|
|
CREATE TABLE IF NOT EXISTS files (
|
|
file_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
org_id uuid REFERENCES orgs(org_id), order_id uuid REFERENCES orders(order_id),
|
|
name text, mime text, bytes bigint, r2_key text, created_at timestamptz DEFAULT now()
|
|
);
|
|
CREATE TABLE IF NOT EXISTS db_grants (
|
|
grant_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
org_id uuid REFERENCES orgs(org_id), order_id uuid REFERENCES orders(order_id),
|
|
conn_encrypted bytea NOT NULL, scope text, expires_at timestamptz, revoked_at timestamptz,
|
|
created_at timestamptz DEFAULT now()
|
|
);
|
|
CREATE TABLE IF NOT EXISTS payments (
|
|
payment_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
order_id uuid REFERENCES orders(order_id),
|
|
kind text, amount_ore bigint, stripe_ref text, status text,
|
|
created_at timestamptz DEFAULT now()
|
|
);
|
|
CREATE TABLE IF NOT EXISTS audit_log (
|
|
id bigserial PRIMARY KEY,
|
|
actor text, action text, target text, meta jsonb, at timestamptz DEFAULT now()
|
|
);
|