-- Token Broker PostgreSQL init script -- 6 tables: api_tokens, refresh_tokens, token_audit_log, clients, providers, token_usage CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE TABLE IF NOT EXISTS api_tokens ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id INTEGER NOT NULL, name TEXT NOT NULL DEFAULT 'default', token_hash TEXT NOT NULL UNIQUE, token_prefix TEXT NOT NULL, scopes TEXT[] DEFAULT '{}', is_active BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), expires_at TIMESTAMPTZ, last_used_at TIMESTAMPTZ, metadata JSONB DEFAULT '{}' ); CREATE TABLE IF NOT EXISTS refresh_tokens ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id INTEGER NOT NULL, token_hash TEXT NOT NULL UNIQUE, token_prefix TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), expires_at TIMESTAMPTZ NOT NULL, revoked BOOLEAN NOT NULL DEFAULT FALSE, revoked_at TIMESTAMPTZ, replaced_by UUID ); CREATE TABLE IF NOT EXISTS token_audit_log ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id INTEGER, action TEXT NOT NULL, token_prefix TEXT, ip_address TEXT, user_agent TEXT, details JSONB DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS clients ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), client_id TEXT NOT NULL UNIQUE, client_secret TEXT NOT NULL, name TEXT NOT NULL, description TEXT DEFAULT '', redirect_uris TEXT[] DEFAULT '{}', scopes TEXT[] DEFAULT '{}', is_active BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS providers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL UNIQUE, provider_type TEXT NOT NULL DEFAULT 'oauth2', issuer_url TEXT, client_id TEXT, client_secret TEXT, scopes TEXT[] DEFAULT '{}', config JSONB DEFAULT '{}', is_active BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS token_usage ( id BIGSERIAL PRIMARY KEY, user_id INTEGER NOT NULL, token_id UUID, action TEXT NOT NULL DEFAULT 'verify', endpoint TEXT, status TEXT NOT NULL DEFAULT 'success', response_time_ms INTEGER, ip_address TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_api_tokens_user_id ON api_tokens(user_id); CREATE INDEX IF NOT EXISTS idx_api_tokens_token_hash ON api_tokens(token_hash); CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user_id ON refresh_tokens(user_id); CREATE INDEX IF NOT EXISTS idx_refresh_tokens_token_hash ON refresh_tokens(token_hash); CREATE INDEX IF NOT EXISTS idx_token_audit_log_user_id ON token_audit_log(user_id); CREATE INDEX IF NOT EXISTS idx_token_audit_log_created_at ON token_audit_log(created_at); CREATE INDEX IF NOT EXISTS idx_clients_client_id ON clients(client_id); CREATE INDEX IF NOT EXISTS idx_providers_name ON providers(name); CREATE INDEX IF NOT EXISTS idx_token_usage_user_id ON token_usage(user_id); CREATE INDEX IF NOT EXISTS idx_token_usage_created_at ON token_usage(created_at); GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO token_broker; GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO token_broker;