feat(profile): add ui_preference field (streamlit|vue, default: streamlit)

This commit is contained in:
pyr0ball 2026-03-22 15:55:38 -07:00
parent bd24275455
commit 0acde6d199
3 changed files with 63 additions and 0 deletions

View file

@ -43,6 +43,7 @@ dev_tier_override: null # overrides tier locally (for testing only)
wizard_complete: false wizard_complete: false
wizard_step: 0 wizard_step: 0
dismissed_banners: [] dismissed_banners: []
ui_preference: streamlit # UI preference — "streamlit" (default) or "vue" (Beta: Paid tier)
docs_dir: "~/Documents/JobSearch" docs_dir: "~/Documents/JobSearch"
ollama_models_dir: "~/models/ollama" ollama_models_dir: "~/models/ollama"

View file

@ -29,6 +29,7 @@ _DEFAULTS = {
"wizard_complete": False, "wizard_complete": False,
"wizard_step": 0, "wizard_step": 0,
"dismissed_banners": [], "dismissed_banners": [],
"ui_preference": "streamlit",
"services": { "services": {
"streamlit_port": 8501, "streamlit_port": 8501,
"ollama_host": "localhost", "ollama_host": "localhost",
@ -76,7 +77,37 @@ class UserProfile:
self.wizard_complete: bool = bool(data.get("wizard_complete", False)) self.wizard_complete: bool = bool(data.get("wizard_complete", False))
self.wizard_step: int = int(data.get("wizard_step", 0)) self.wizard_step: int = int(data.get("wizard_step", 0))
self.dismissed_banners: list[str] = list(data.get("dismissed_banners", [])) self.dismissed_banners: list[str] = list(data.get("dismissed_banners", []))
raw_pref = data.get("ui_preference", "streamlit")
self.ui_preference: str = raw_pref if raw_pref in ("streamlit", "vue") else "streamlit"
self._svc = data["services"] self._svc = data["services"]
self._path = path
def save(self) -> None:
"""Save all profile fields back to user.yaml."""
output = {
"name": self.name,
"email": self.email,
"phone": self.phone,
"linkedin": self.linkedin,
"career_summary": self.career_summary,
"candidate_voice": self.candidate_voice,
"nda_companies": self.nda_companies,
"docs_dir": str(self.docs_dir),
"ollama_models_dir": str(self.ollama_models_dir),
"vllm_models_dir": str(self.vllm_models_dir),
"inference_profile": self.inference_profile,
"mission_preferences": self.mission_preferences,
"candidate_accessibility_focus": self.candidate_accessibility_focus,
"candidate_lgbtq_focus": self.candidate_lgbtq_focus,
"tier": self.tier,
"dev_tier_override": self.dev_tier_override,
"wizard_complete": self.wizard_complete,
"wizard_step": self.wizard_step,
"dismissed_banners": self.dismissed_banners,
"ui_preference": self.ui_preference,
"services": self._svc,
}
self._path.write_text(yaml.dump(output, default_flow_style=False))
# ── Service URLs ────────────────────────────────────────────────────────── # ── Service URLs ──────────────────────────────────────────────────────────
def _url(self, host: str, port: int, ssl: bool) -> str: def _url(self, host: str, port: int, ssl: bool) -> str:

View file

@ -106,3 +106,34 @@ def test_effective_tier_no_override(tmp_path):
p.write_text("name: T\nemail: t@t.com\ncareer_summary: x\ntier: paid\n") p.write_text("name: T\nemail: t@t.com\ncareer_summary: x\ntier: paid\n")
u = UserProfile(p) u = UserProfile(p)
assert u.effective_tier == "paid" assert u.effective_tier == "paid"
def test_ui_preference_default(tmp_path):
"""Fresh profile defaults to streamlit."""
p = tmp_path / "user.yaml"
p.write_text("name: Test User\n")
profile = UserProfile(p)
assert profile.ui_preference == "streamlit"
def test_ui_preference_vue(tmp_path):
"""Saved vue preference loads correctly."""
p = tmp_path / "user.yaml"
p.write_text("name: Test\nui_preference: vue\n")
profile = UserProfile(p)
assert profile.ui_preference == "vue"
def test_ui_preference_roundtrip(tmp_path):
"""Saving ui_preference: vue persists and reloads."""
p = tmp_path / "user.yaml"
p.write_text("name: Test\n")
profile = UserProfile(p)
profile.ui_preference = "vue"
profile.save()
reloaded = UserProfile(p)
assert reloaded.ui_preference == "vue"
def test_ui_preference_invalid_falls_back(tmp_path):
"""Unknown value falls back to streamlit."""
p = tmp_path / "user.yaml"
p.write_text("name: Test\nui_preference: newui\n")
profile = UserProfile(p)
assert profile.ui_preference == "streamlit"