diff --git a/app/routers/universe.py b/app/routers/universe.py index d8d64ee..ea1d633 100644 --- a/app/routers/universe.py +++ b/app/routers/universe.py @@ -362,10 +362,19 @@ async def analyze_portfolio( except Exception: raise HTTPException(status_code=400, detail="malformed JSON body") - user_lang = ( + # Resolve lang. The frontend sends the live toggle state in + # payload["lang"]; that's what the user is *looking at* right now + # and is the most up-to-date value. user.lang from the DB is the + # persisted preference and is used as a fallback when the frontend + # didn't send anything (older clients, scripts, direct curl). + db_lang = ( principal.user.lang if (principal.user and principal.user.lang) else "en" ) - payload["lang"] = user_lang + incoming = (payload.get("lang") or "").strip().lower() + payload["lang"] = incoming or db_lang + log.info("analyze.lang_resolved", + payload_lang=incoming or None, db_lang=db_lang, + final=payload["lang"]) try: req = portfolio_analysis.parse_request(payload) diff --git a/app/static/js/portfolio.js b/app/static/js/portfolio.js index 767f078..7ab75f5 100644 --- a/app/static/js/portfolio.js +++ b/app/static/js/portfolio.js @@ -469,6 +469,13 @@ } } + // The language toggle's data-lang attribute is the user's LIVE + // pick — newer than user.lang in the DB if the user toggled and + // hit Generate/Regenerate before the toggle-PATCH committed. + // Backend prefers this value if provided (see universe.py). + const langPill = document.getElementById('lang-toggle'); + const userLang = (langPill && langPill.dataset.lang) || 'en'; + try { const r = await fetch('/api/analyze', { method: 'POST', @@ -478,6 +485,7 @@ positions: pie.positions, prices: prices, base_currency: pie.base_currency || 'GBP', + lang: userLang, }), }); const data = await r.json();