fix(settings): accept numeric values in update payload

Svelte bind:value on <input type="number"> coerces to a JS number, so the
frontend sends {telegram_cache_ttl_hours: 0} after v0.2.4. Pydantic v2
won't auto-coerce int -> str, which produced a 422 on every save that
touched a numeric setting.

- Widen numeric fields to int | str | None in SettingsUpdate.
- Normalize to str before persisting (DB column is text).
This commit is contained in:
2026-04-22 15:44:40 +03:00
parent 93df538819
commit d7d0a5d921
@@ -56,10 +56,14 @@ async def get_setting(session: AsyncSession, key: str) -> str:
class SettingsUpdate(BaseModel):
# Numeric fields declared as int|str so clients can send either form.
# Svelte's bind:value on <input type="number"> coerces to a JS number,
# so the frontend sends ints for these; older/manual clients may send
# strings. We normalize to str before persisting.
external_url: str | None = None
telegram_webhook_secret: str | None = None
telegram_cache_ttl_hours: str | None = None
telegram_asset_cache_max_entries: str | None = None
telegram_cache_ttl_hours: int | str | None = None
telegram_asset_cache_max_entries: int | str | None = None
supported_locales: str | None = None
timezone: str | None = None
@@ -95,11 +99,12 @@ async def update_settings(
value = getattr(body, key, None)
if value is None:
continue
value_str = str(value)
row = await session.get(AppSetting, key)
if row:
row.value = value
row.value = value_str
else:
row = AppSetting(key=key, value=value)
row = AppSetting(key=key, value=value_str)
session.add(row)
await session.commit()