-- Session tokens authenticate /api/* requests. We store sha256(token) so a -- read-only DB leak doesn't grant active sessions; the raw token lives only -- in the client's cookie (web) or bearer header (native clients). -- -- last_seen_at and user_agent (captured at issue time) are for an "active -- sessions" list. CREATE TABLE sessions ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, token_hash bytea NOT NULL UNIQUE, user_agent text NOT NULL DEFAULT '', created_at timestamptz NOT NULL DEFAULT now(), last_seen_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX sessions_user_id_idx ON sessions (user_id);