Newer
Older
gnexus-tasks / backend / app / api / settings.py
"""API глобальных настроек (ТЗ: валюта бюджетов и язык UI — общие, выбираются один раз)."""

from typing import cast

from fastapi import APIRouter

from app.dependencies import DbDep, UserDep
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, 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()
    db.commit()
    publish(str(user["user_id"]), "settings.changed")
    return AppSettingsOut(
        currency=_read_value(db, CURRENCY_KEY, CURRENCIES, DEFAULT_CURRENCY),
        language=_read_value(db, LANGUAGE_KEY, LANGUAGES + ("",), DEFAULT_LANGUAGE),
    )