Persist an explicit timezone choice (timezone_configured)
The admin settings screen auto-set the browser zone whenever it loaded an empty timezone, guarded only by a per-mount ref. After an admin cleared the timezone (empty = API-host-local), the next open re-fetched "" and auto-set the browser zone again, so the empty choice could not persist. Add a twelfth settings field, timezone_configured (strict bool, default false), carried by the core settings table, the stored JSON document and the admin GET/PATCH. The screen now auto-sets only when the timezone is empty AND timezone_configured is false, patching the flag with the detected zone; saving the timezone field (including clearing it) also sends timezone_configured: true. Detection returning nothing sets nothing. Task: a0e7649c-58b0-4aa3-91b5-cf426e334a76 (release review TZ-001) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+12
-7
@@ -165,12 +165,13 @@ integration's Home-Assistant config-entry options remain a temporary,
|
||||
SEPARATE source until Feature 18 wires the client to the API — the two
|
||||
are deliberately not unified here:
|
||||
|
||||
- ``GET /settings`` returns the current effective settings: all eleven
|
||||
- ``GET /settings`` returns the current effective settings: all twelve
|
||||
documented fields (the rolling horizon, the day rollover time, the
|
||||
notify target, the three notification times, the four enable
|
||||
toggles and the ``timezone`` — the IANA household zone the
|
||||
household-local dates derive from, empty meaning host local) — the
|
||||
defaults on a fresh database.
|
||||
toggles, the ``timezone`` — the IANA household zone the
|
||||
household-local dates derive from, empty meaning host local — and
|
||||
``timezone_configured``, whether the admin explicitly chose that
|
||||
zone) — the defaults on a fresh database.
|
||||
- ``PATCH /settings`` updates ONLY the supplied fields: the body is a
|
||||
JSON object of settings field names to new values, passed STRAIGHT
|
||||
to :func:`nestquest_core.settings_store.update_settings` — the
|
||||
@@ -905,7 +906,7 @@ class AdminSettingsResponse(BaseModel):
|
||||
"""The effective settings as the admin plane serializes them.
|
||||
|
||||
Mirrors the core :class:`~nestquest_core.settings.NestQuestSettings`
|
||||
— all ELEVEN documented fields, resolved (every absent stored field
|
||||
— all TWELVE documented fields, resolved (every absent stored field
|
||||
already fell back to its default in the core). The same shape both
|
||||
the GET and the PATCH route answer with.
|
||||
"""
|
||||
@@ -923,6 +924,9 @@ class AdminSettingsResponse(BaseModel):
|
||||
#: The household IANA time zone the API reads its clock in; ``""``
|
||||
#: means the API host's local time.
|
||||
timezone: str
|
||||
#: Whether the admin explicitly chose ``timezone`` (even ``""``);
|
||||
#: ``False`` lets the admin UI auto-set the browser's zone once.
|
||||
timezone_configured: bool
|
||||
|
||||
|
||||
class AdminMissedSweepResponse(BaseModel):
|
||||
@@ -2179,7 +2183,7 @@ def _settings_response(
|
||||
"""Serialize one core NestQuestSettings into the documented payload.
|
||||
|
||||
Explicit field-by-field (not ``dataclasses.asdict``) so the payload
|
||||
stays pinned to the eleven documented fields even if the core
|
||||
stays pinned to the twelve documented fields even if the core
|
||||
dataclass later grows another one.
|
||||
"""
|
||||
return AdminSettingsResponse(
|
||||
@@ -2194,6 +2198,7 @@ def _settings_response(
|
||||
end_of_day_report_enabled=settings.end_of_day_report_enabled,
|
||||
celebration_enabled=settings.celebration_enabled,
|
||||
timezone=settings.timezone,
|
||||
timezone_configured=settings.timezone_configured,
|
||||
)
|
||||
|
||||
|
||||
@@ -2291,7 +2296,7 @@ async def admin_history_csv(
|
||||
response_model=AdminSettingsResponse,
|
||||
)
|
||||
async def admin_get_settings(request: Request) -> AdminSettingsResponse:
|
||||
"""Return the current effective settings (all eleven documented fields).
|
||||
"""Return the current effective settings (all twelve documented fields).
|
||||
|
||||
Requires a valid admin JWT (the router's shared
|
||||
:func:`~api.auth.require_admin` dependency — the ONE check; this
|
||||
|
||||
Reference in New Issue
Block a user