CREATE table IF NOT EXISTS accounts( id SERIAL PRIMARY KEY, accountnum VARCHAR UNIQUE NOT NULL, accountname VARCHAR UNIQUE NOT NULL, REFERENCES organizations(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS organizations( id SERIAL PRIMARY KEY, orgname VARCHAR(50) UNIQUE NOT NULL ) CREATE TABLE IF NOT EXISTS transactions( id SERIAL PRIMARY KEY, datetime DATE NOT NULL, description VARCHAR NOT NULL, amount REAL NOT NULL, accountid INT NOT NULL REFERENCES accounts(id) ON DELETE SET NULL, orgid INT NOT NULL REFERENCES organizations(id) ON DELETE SET NULL ) CREATE TABLE IF NOT EXISTS snapshots( id SERIAL PRIMARY KEY, datetime DATE NOT NULL, accountid INT NOT NULL REFERENCES accounts(id) ON DELETE SET NULL, balance REAL NOT NULL, orgid INT NOT NULL REFERENCES organizations(id) ON DELETE SET NULL ) CREATE TABLE IF NOT EXISTS syncs( id SERIAL PRIMARY KEY, datetime DATE NOT NULL, accountid INT NOT NULL REFERENCES accounts(id) ON DELETE SET NULL, orgid INT NOT NULL REFERENCES organizations(id) ON DELETE SET NULL ) CREATE TABLE IF NOT EXISTS vendors( id SERIAL PRIMARY KEY, vendorname VARCHAR NOT NULL, orgid INT NOT NULL REFERENCES organizations(id) ON DELETE SET NULL ) CREATE TABLE IF NOT EXISTS rawtransactions( id SERIAL PRIMARY KEY, data JSONB NOT NULL, received_at TIMESTAMPTZ NOT NULL DEFAULT now(), source VARCHAR(100), accountid INT REFERENCES accounts(id) ON DELETE SET NULL, orgid INT REFERENCES organizations(id) ON DELETE SET NULL, raw_sha256 CHAR(64) UNIQUE, processed BOOLEAN NOT NULL DEFAULT FALSE ); CREATE INDEX IF NOT EXISTS rawtransactions_data_idx ON rawtransactions USING GIN (data); CREATE INDEX IF NOT EXISTS rawtransactions_received_at_idx ON rawtransactions (received_at); CREATE INDEX IF NOT EXISTS rawtransactions_account_org_idx ON rawtransactions (orgid, accountid);