refactor: centralise user timezone as a standalone setting
Browser timezone is now synced to user_settings["user_timezone"] on every login/page load (App.vue). The briefing scheduler and LLM context both read from this single source, falling back to the legacy briefing_config.timezone for existing users during migration. - App.vue: PUT /api/settings with browser IANA timezone on startAppServices - routes/chat.py: fall back to stored user_timezone when not sent in request - briefing_scheduler: read user_timezone setting; briefing_config.timezone kept as fallback only - routes/briefing.py: pass tz_override from user_timezone to live-patched scheduler - Remove timezone field from BriefingConfig interface and all briefing UI Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -56,17 +56,22 @@ async def _get_briefing_enabled_users() -> list[tuple[int, str]]:
|
||||
import json
|
||||
async with async_session() as session:
|
||||
result = await session.execute(
|
||||
select(Setting).where(Setting.key == "briefing_config")
|
||||
select(Setting).where(Setting.key.in_(["briefing_config", "user_timezone"]))
|
||||
)
|
||||
rows = list(result.scalars().all())
|
||||
|
||||
enabled = []
|
||||
by_user: dict[int, dict[str, str]] = {}
|
||||
for row in rows:
|
||||
by_user.setdefault(row.user_id, {})[row.key] = row.value or ""
|
||||
|
||||
enabled = []
|
||||
for user_id, settings in by_user.items():
|
||||
try:
|
||||
config = json.loads(row.value) if row.value else {}
|
||||
config = json.loads(settings.get("briefing_config", "{}") or "{}")
|
||||
if config.get("enabled"):
|
||||
tz = _resolve_timezone(config.get("timezone", "UTC"))
|
||||
enabled.append((row.user_id, tz))
|
||||
tz_str = settings.get("user_timezone") or config.get("timezone", "UTC")
|
||||
tz = _resolve_timezone(tz_str)
|
||||
enabled.append((user_id, tz))
|
||||
except Exception:
|
||||
pass
|
||||
return enabled
|
||||
@@ -105,13 +110,15 @@ def _remove_user_jobs(user_id: int) -> None:
|
||||
|
||||
# ── Public API ────────────────────────────────────────────────────────────────
|
||||
|
||||
def update_user_schedule(user_id: int, config: dict) -> None:
|
||||
def update_user_schedule(user_id: int, config: dict, tz_override: str | None = None) -> None:
|
||||
"""
|
||||
Called when a user saves their briefing config via the settings UI.
|
||||
Live-patches the scheduler — no restart required.
|
||||
tz_override takes priority over any timezone in config.
|
||||
"""
|
||||
if config.get("enabled"):
|
||||
tz = _resolve_timezone(config.get("timezone", "UTC"))
|
||||
tz_str = tz_override or config.get("timezone", "UTC")
|
||||
tz = _resolve_timezone(tz_str)
|
||||
_add_user_jobs(user_id, tz)
|
||||
else:
|
||||
_remove_user_jobs(user_id)
|
||||
|
||||
Reference in New Issue
Block a user