create table if not exists auth_identities ( id uuid primary key, user_id uuid not null references users(id) on delete cascade, provider text not null, provider_subject text not null, email_at_provider text, created_at timestamptz not null default now(), updated_at timestamptz not null default now(), unique (provider, provider_subject) ); create table if not exists refresh_tokens ( id uuid primary key, user_id uuid not null references users(id) on delete cascade, organization_id uuid references organizations(id) on delete cascade, token_hash text not null unique, expires_at timestamptz not null, revoked_at timestamptz, revoked_reason text, user_agent text, created_ip text, created_at timestamptz not null default now() ); create table if not exists socket_tokens ( id uuid primary key, user_id uuid not null references users(id) on delete cascade, organization_id uuid not null references organizations(id) on delete cascade, token_hash text not null unique, expires_at timestamptz not null, used_at timestamptz, revoked_at timestamptz, created_at timestamptz not null default now() ); create table if not exists session_keys ( id uuid primary key, user_id uuid not null references users(id) on delete cascade, organization_id uuid not null references organizations(id) on delete cascade, key_id text not null unique, wrapped_key bytea, algorithm text not null, created_at timestamptz not null default now(), expires_at timestamptz not null, revoked_at timestamptz ); create table if not exists idempotency_keys ( id uuid primary key, user_id uuid not null references users(id) on delete cascade, organization_id uuid references organizations(id) on delete cascade, key text not null, request_hash text not null, response_status integer, response_body_json jsonb, expires_at timestamptz not null, created_at timestamptz not null default now(), unique (user_id, organization_id, key) ); create index if not exists idx_refresh_tokens_user_id on refresh_tokens (user_id); create index if not exists idx_socket_tokens_user_organization on socket_tokens (user_id, organization_id); create index if not exists idx_session_keys_user_organization on session_keys (user_id, organization_id);