"""API глобальных настроек (ТЗ: валюта бюджетов и язык UI — общие, выбираются один раз)."""
from typing import cast
from fastapi import APIRouter
from app.dependencies import DbDep, UserDep
from app.models import AppSetting
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, key: str, valid: tuple[str, ...], default: str) -> str:
row = cast(AppSetting | None, db.get(AppSetting, key))
if row is not None and row.value in valid:
return row.value
return default
def _upsert(db: DbDep, key: str, value: str) -> None:
row = cast(AppSetting | None, db.get(AppSetting, key))
if row is None:
db.add(AppSetting(key=key, value=value))
else:
row.value = value
db.flush()
@router.get("", response_model=AppSettingsOut)
async def get_settings(db: DbDep, user: UserDep) -> AppSettingsOut:
return AppSettingsOut(
currency=_read_value(db, CURRENCY_KEY, CURRENCIES, DEFAULT_CURRENCY),
language=_read_value(db, LANGUAGE_KEY, LANGUAGES + ("",), DEFAULT_LANGUAGE),
)
@router.put("", response_model=AppSettingsOut)
async def update_settings(schema: AppSettingsUpdate, db: DbDep, user: UserDep) -> AppSettingsOut:
# Частичный PUT: обновляем только переданные поля (model_fields_set)
if schema.currency is not None:
_upsert(db, CURRENCY_KEY, schema.currency)
if schema.language is not None:
_upsert(db, LANGUAGE_KEY, schema.language)
db.flush()
return AppSettingsOut(
currency=_read_value(db, CURRENCY_KEY, CURRENCIES, DEFAULT_CURRENCY),
language=_read_value(db, LANGUAGE_KEY, LANGUAGES + ("",), DEFAULT_LANGUAGE),
)