Files
0pt/sql/001_init.sql
T
adminandClaude Opus 4.8 15c65a584c feat(api): Vercel-native platform API + Postgres schema
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>
2026-06-24 17:56:30 +02:00

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()
);