-- AZ-531 (Epic AZ-529): refresh-token sessions with rotation + reuse detection.
-- One row per issued refresh token. Rows in the same session family share
-- family_id; rotation marks the previous row as `revoked_reason='rotated'` and
-- inserts a new row in the same family. Reuse detection keys off detecting a
-- second presentation of an already-rotated row.

CREATE TABLE IF NOT EXISTS public.sessions
(
    id                 uuid        PRIMARY KEY,
    user_id            uuid        NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
    refresh_hash       text        NOT NULL,
    family_id          uuid        NOT NULL,
    issued_at          timestamp   NOT NULL DEFAULT now(),
    last_used_at       timestamp   NOT NULL DEFAULT now(),
    expires_at         timestamp   NOT NULL,
    revoked_at         timestamp   NULL,
    revoked_reason     varchar(64) NULL,
    parent_session_id  uuid        NULL REFERENCES public.sessions(id) ON DELETE SET NULL,
    family_started_at  timestamp   NOT NULL DEFAULT now()
);

-- O(1) lookup by the hash carried in the refresh token.
CREATE UNIQUE INDEX IF NOT EXISTS sessions_refresh_hash_idx
    ON public.sessions (refresh_hash);

-- Family-wide revoke (reuse-detection / logout-all) reads only active rows.
CREATE INDEX IF NOT EXISTS sessions_family_active_idx
    ON public.sessions (family_id)
    WHERE revoked_at IS NULL;

GRANT INSERT, SELECT, UPDATE ON public.sessions TO azaion_admin;
GRANT SELECT                  ON public.sessions TO azaion_reader;
