-- v0.23.0 / roadmap item #29: server-side sign-in state resume.
--
-- Track each authenticated user's last-viewed route + a small bag of
-- "light" component state so that the *next* sign-in can land the user
-- back where they left off, rather than always dropping them on the
-- empty-state home view.
--
-- Storage shape (one row per user — per-user, NOT per-device, per the
-- #29 "safe default"):
--
--   * `user_id` — PRIMARY KEY and FK into users(id) with cascade on
--     delete. INTEGER to match users.id (INTEGER PRIMARY KEY
--     AUTOINCREMENT). A deleted user automatically loses their stored
--     resume state. One row per user means a later sign-in on any
--     device resumes the most-recently-recorded route — the per-user
--     model the roadmap asks for.
--
--   * `last_route` — the frontend pathname the user was last on
--     (e.g. "/rfc/open-human-model"). TEXT, nullable until the first
--     route-change POST lands. NEVER contains draft-buffer contents —
--     it is a route only. See SPEC §6.2 "Sign-in state resume
--     (privacy)".
--
--   * `last_route_state` — a JSON-encoded bag of *light* component
--     state (scroll anchors, open-tab selection, filter chips, etc.).
--     SQLite has no native JSONB; we store JSON as TEXT exactly as the
--     rest of the app stores its JSON blobs (json.dumps / json.loads,
--     cf. permission_events.details, actions.details). Nullable.
--     PRIVACY INVARIANT: this column MUST NOT carry draft-buffer text,
--     PR bodies, comment drafts, or any user-typed content — only
--     ephemeral view state safe to replay. The PUT handler is the
--     enforcement point; the column comment is the contract.
--
--   * `resume_enabled` — the per-user opt-out flag. 1 (default) means
--     "resume me where I left off"; 0 means "always land on home". The
--     PUT handler no-ops the upsert when this is 0, and the read path
--     refuses to hand back a stored route when this is 0. A
--     profile-settings toggle UI to flip this is a follow-up (the
--     column + default-on behavior ship now); see CHANGELOG v0.23.0.
--
--   * `last_updated_at` — TEXT timestamp, app convention
--     `datetime('now')`, matching device_trust.last_seen_at /
--     users.last_seen_at. Refreshed on every successful upsert.
--
-- No new env vars. The debounce interval for the frontend route-change
-- POST is a frontend constant (~1s), not a server knob.

CREATE TABLE user_session_state (
    user_id          INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
    last_route       TEXT,
    last_route_state TEXT,                        -- JSON-encoded light state, nullable
    resume_enabled   INTEGER NOT NULL DEFAULT 1,
    last_updated_at  TEXT NOT NULL DEFAULT (datetime('now'))
);
