- ui_switcher.py: add explicit guard that forces pref=streamlit when
DEMO_MODE=true, before the tier-downgrade check. Demo Vue SPA (#46)
is not yet implemented, so navigating there produced a blank screen.
- app.py: call sync_ui_cookie inside wizard gate block before st.stop()
so that cloud users with ui_preference=vue are redirected correctly
even when the first-run wizard is still active. Previous behaviour
called sync_ui_cookie after pg.run() which was never reached.
- demo/config/user.yaml: reset ui_preference to streamlit (belt-and-
suspenders alongside the code guard).
Closes: demo blank-screen regression reported 2026-03-24.
- Add explanatory comments to all 5 bare except Exception blocks clarifying that UI components must not crash the app
- Refactor sync_ui_cookie() to load UserProfile once instead of up to 3 times in normal path
- Store profile reference and reuse it in tier downgrade protection block
- Replace importlib.reload() pattern in tests with unittest.mock.patch for _DEMO_MODE
- Improves test isolation and eliminates module state contamination across test runs
- All 5 tests pass (100%)
LinkedIn's unauthenticated public profile only exposes name, summary (truncated),
current employer name, and certifications. Past roles, education, and skills are
blurred server-side behind a login wall — not a scraper limitation.
- Update selectors: data-section='summary' (was 'about'), .profile-section-card
for certs, .visible-list for current experience entry
- Strip login-wall noise injected into summary text after 'see more'
- Skip aria-hidden blurred placeholder experience items
- Add info callout in UI directing users to data export zip for full history