142 lines
4.9 KiB
PL/PgSQL
142 lines
4.9 KiB
PL/PgSQL
BEGIN;
|
|
|
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|
|
|
-- Drop legacy/managed tables for clean rebuild
|
|
DROP TABLE IF EXISTS auth_sync_state CASCADE;
|
|
DROP TABLE IF EXISTS user_sites CASCADE;
|
|
DROP TABLE IF EXISTS site_roles CASCADE;
|
|
DROP TABLE IF EXISTS roles CASCADE;
|
|
DROP TABLE IF EXISTS api_clients CASCADE;
|
|
DROP TABLE IF EXISTS sites CASCADE;
|
|
DROP TABLE IF EXISTS companies CASCADE;
|
|
DROP TABLE IF EXISTS systems CASCADE;
|
|
DROP TABLE IF EXISTS users CASCADE;
|
|
|
|
-- legacy tables
|
|
DROP TABLE IF EXISTS permissions CASCADE;
|
|
DROP TABLE IF EXISTS modules CASCADE;
|
|
DROP TABLE IF EXISTS user_scope_permissions CASCADE;
|
|
DROP TABLE IF EXISTS permission_group_permissions CASCADE;
|
|
DROP TABLE IF EXISTS permission_group_members CASCADE;
|
|
DROP TABLE IF EXISTS permission_groups CASCADE;
|
|
|
|
CREATE TABLE users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_sub TEXT NOT NULL UNIQUE,
|
|
provider_user_id VARCHAR(128) UNIQUE,
|
|
username TEXT UNIQUE,
|
|
email TEXT UNIQUE,
|
|
display_name TEXT,
|
|
status VARCHAR(16) NOT NULL DEFAULT 'active',
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE companies (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
company_key TEXT NOT NULL UNIQUE,
|
|
display_name TEXT NOT NULL,
|
|
legal_name TEXT,
|
|
provider_group_id TEXT,
|
|
status VARCHAR(16) NOT NULL DEFAULT 'active',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE sites (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
site_key TEXT NOT NULL UNIQUE,
|
|
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
display_name TEXT NOT NULL,
|
|
domain TEXT,
|
|
provider_group_id TEXT,
|
|
status VARCHAR(16) NOT NULL DEFAULT 'active',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE systems (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
system_key TEXT NOT NULL UNIQUE,
|
|
name TEXT NOT NULL,
|
|
provider_client_id TEXT NOT NULL UNIQUE,
|
|
status VARCHAR(16) NOT NULL DEFAULT 'active',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE roles (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
role_key TEXT NOT NULL UNIQUE,
|
|
system_id UUID NOT NULL REFERENCES systems(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
description TEXT,
|
|
provider_role_name TEXT NOT NULL,
|
|
status VARCHAR(16) NOT NULL DEFAULT 'active',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT uq_roles_system_provider_role_name UNIQUE (system_id, provider_role_name)
|
|
);
|
|
|
|
CREATE TABLE site_roles (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
site_id UUID NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT uq_site_roles_site_role UNIQUE (site_id, role_id)
|
|
);
|
|
|
|
CREATE TABLE user_sites (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
site_id UUID NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT uq_user_sites_user_site UNIQUE (user_id, site_id)
|
|
);
|
|
|
|
CREATE TABLE auth_sync_state (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
entity_type VARCHAR(32) NOT NULL,
|
|
entity_id UUID NOT NULL,
|
|
last_synced_at TIMESTAMPTZ,
|
|
source_version TEXT,
|
|
last_error TEXT,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT uq_auth_sync_state_entity UNIQUE (entity_type, entity_id)
|
|
);
|
|
|
|
CREATE TABLE api_clients (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
client_key TEXT NOT NULL UNIQUE,
|
|
name TEXT NOT NULL,
|
|
status VARCHAR(16) NOT NULL DEFAULT 'active',
|
|
api_key_hash TEXT NOT NULL,
|
|
allowed_origins JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
allowed_ips JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
allowed_paths JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
rate_limit_per_min INTEGER,
|
|
expires_at TIMESTAMPTZ,
|
|
last_used_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_users_user_sub ON users(user_sub);
|
|
CREATE INDEX idx_users_username ON users(username);
|
|
CREATE INDEX idx_users_email ON users(email);
|
|
CREATE INDEX idx_sites_company_id ON sites(company_id);
|
|
CREATE INDEX idx_roles_system_id ON roles(system_id);
|
|
CREATE INDEX idx_site_roles_site_id ON site_roles(site_id);
|
|
CREATE INDEX idx_site_roles_role_id ON site_roles(role_id);
|
|
CREATE INDEX idx_user_sites_user_id ON user_sites(user_id);
|
|
CREATE INDEX idx_user_sites_site_id ON user_sites(site_id);
|
|
CREATE INDEX idx_auth_sync_entity ON auth_sync_state(entity_type, entity_id);
|
|
CREATE INDEX idx_api_clients_status ON api_clients(status);
|
|
CREATE INDEX idx_api_clients_expires_at ON api_clients(expires_at);
|
|
CREATE INDEX idx_systems_system_key ON systems(system_key);
|
|
|
|
COMMIT;
|