-- YakPanel 2026 Identity Core additions CREATE TABLE IF NOT EXISTS api_tokens ( id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, name varchar(80) NOT NULL, token_hash varchar(255) NOT NULL UNIQUE, scopes jsonb NOT NULL DEFAULT '[]'::jsonb, expires_at timestamptz NULL, last_used_at timestamptz NULL, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS sessions ( id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, refresh_token_hash varchar(255) NOT NULL UNIQUE, ip inet NULL, user_agent text NULL, expires_at timestamptz NOT NULL, revoked_at timestamptz NULL, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS mfa_factors ( id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, factor_type varchar(24) NOT NULL, secret_encrypted text NOT NULL, recovery_codes_encrypted text NULL, verified_at timestamptz NULL, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_api_tokens_tenant_user ON api_tokens (tenant_id, user_id); CREATE INDEX IF NOT EXISTS idx_sessions_tenant_user ON sessions (tenant_id, user_id);