"""API настроек пользователя (валюта бюджетов и язык UI).
Per-user (ТЗ 1.2): у каждого пользователя свои настройки; строка с PK
(user_id, key). Настройки прежней эпохи (app_settings_global) копируются
в per-user при первом логине (claim) — см. services/users.py.
"""
from typing import cast
from fastapi import APIRouter
from app.dependencies import DbDep, UserIdDep
from app.models import AppSetting
from app.realtime import publish
from app.schemas import CURRENCIES, LANGUAGES, AppSettingsOut, AppSettingsUpdate
router = APIRouter(prefix="/api/settings", tags=["settings"])
CURRENCY_KEY = "currency"
LANGUAGE_KEY = "language"
DEFAULT_CURRENCY = "UAH"
DEFAULT_LANGUAGE = "" # '' = нет переопределения, следуем SSO locale
def _read_value(db: DbDep, user_id: str, key: str, valid: tuple[str, ...], default: str) -> str:
row = cast(AppSetting | None, db.get(AppSetting, (user_id, key)))
if row is not None and row.value in valid:
return row.value
return default
def _upsert(db: DbDep, user_id: str, key: str, value: str) -> None:
row = cast(AppSetting | None, db.get(AppSetting, (user_id, key)))
if row is None:
db.add(AppSetting(user_id=user_id, key=key, value=value))
else:
row.value = value
db.flush()
@router.get("", response_model=AppSettingsOut)
async def get_settings(db: DbDep, user_id: UserIdDep) -> AppSettingsOut:
return AppSettingsOut(
currency=_read_value(db, user_id, CURRENCY_KEY, CURRENCIES, DEFAULT_CURRENCY),
language=_read_value(db, user_id, LANGUAGE_KEY, LANGUAGES + ("",), DEFAULT_LANGUAGE),
)
@router.put("", response_model=AppSettingsOut)
async def update_settings(
schema: AppSettingsUpdate, db: DbDep, user_id: UserIdDep
) -> AppSettingsOut:
# Частичный PUT: обновляем только переданные поля (model_fields_set)
if schema.currency is not None:
_upsert(db, user_id, CURRENCY_KEY, schema.currency)
if schema.language is not None:
_upsert(db, user_id, LANGUAGE_KEY, schema.language)
db.flush()
db.commit()
publish(user_id, "settings.changed")
return AppSettingsOut(
currency=_read_value(db, user_id, CURRENCY_KEY, CURRENCIES, DEFAULT_CURRENCY),
language=_read_value(db, user_id, LANGUAGE_KEY, LANGUAGES + ("",), DEFAULT_LANGUAGE),
)