-- 0019_oidc.sql
--
-- OIDC bookkeeping. Three independent additions land in one
-- migration to keep the related changes together:
--
--   1. users.auth_source     — 'local' | 'oidc'. Local users get
--                              the default; first OIDC sign-in JITs
--                              a row with auth_source='oidc'.
--   2. users.oidc_subject    — IdP's stable 'sub' claim. Indexed
--                              uniquely (partial; NULLs allowed).
--   3. sessions.id_token     — last id_token for OIDC sessions, used
--                              as id_token_hint on RP-initiated
--                              logout. NULL for local sessions.
--   4. oidc_state            — short-lived state for the OAuth round-
--                              trip (state + PKCE code_verifier).
--                              Swept on the alert engine tick.
--
-- All column-level ALTERs (CLAUDE.md preference; safe under
-- foreign_keys=ON).

ALTER TABLE users ADD COLUMN auth_source TEXT NOT NULL DEFAULT 'local'
  CHECK (auth_source IN ('local', 'oidc'));
ALTER TABLE users ADD COLUMN oidc_subject TEXT;

CREATE UNIQUE INDEX users_oidc_subject ON users(oidc_subject)
  WHERE oidc_subject IS NOT NULL;

ALTER TABLE sessions ADD COLUMN id_token TEXT;

CREATE TABLE oidc_state (
  state_hash    TEXT PRIMARY KEY,    -- sha256(state) hex; raw never persisted
  code_verifier TEXT NOT NULL,
  created_at    TEXT NOT NULL
);
CREATE INDEX oidc_state_created ON oidc_state(created_at);
