bada72f87e
Track each authenticated user's last-viewed route + light view state server-side, and on next sign-in redirect them to that state, falling back to the empty-state home only when there's no recorded state. Backend: - migration 022_user_session_state.sql: one row per user (user_id PK/FK, last_route, last_route_state JSON-as-TEXT, resume_enabled default 1, last_updated_at). - PUT /api/me/last-state (require_user): upserts route + light state; no-ops when resume_enabled=0. Localized in the /me region. - /api/auth/me payload now carries resume_enabled + last_route + decoded last_route_state (no extra round-trip). - test_session_resume_vertical.py: auth-required, upsert/read-back, per-user isolation, resume_enabled=0 disable. Frontend: - lib/useLastState.js: debounced (~1s) route-change PUT for authenticated users; one-time resume redirect on sign-in, gated on identify having fired (preserves #21 Part C identify-then-track). - api.js: putLastState() client call. - App.jsx: import + call the hook; set identifyReady after identify. Header region untouched. Per-user (not per-device); profile-settings opt-out toggle UI deferred (column + default-on behavior ship now). Stored state is route + light view state ONLY, never draft buffers — documented in SPEC §6.8. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>