CREATE TABLE IF NOT EXISTS gateway_oidc_sessions ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), session_token_hash bytea NOT NULL UNIQUE, gateway_user_id uuid NOT NULL REFERENCES gateway_users(id) ON DELETE CASCADE, gateway_tenant_id uuid NOT NULL REFERENCES gateway_tenants(id) ON DELETE CASCADE, token_ciphertext bytea NOT NULL, access_token_expires_at timestamptz NOT NULL, last_seen_at timestamptz NOT NULL, idle_expires_at timestamptz NOT NULL, absolute_expires_at timestamptz NOT NULL, refresh_version bigint NOT NULL DEFAULT 1, refresh_lock_id uuid, refresh_lock_until timestamptz, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), CONSTRAINT gateway_oidc_sessions_hash_length CHECK (octet_length(session_token_hash) = 32), CONSTRAINT gateway_oidc_sessions_expiry_order CHECK (idle_expires_at <= absolute_expires_at) ); CREATE INDEX IF NOT EXISTS idx_gateway_oidc_sessions_expiry ON gateway_oidc_sessions(absolute_expires_at, idle_expires_at); CREATE INDEX IF NOT EXISTS idx_gateway_oidc_sessions_user ON gateway_oidc_sessions(gateway_user_id, created_at DESC);