Newer
Older
gn-synapse / app / settings_store.py
"""Слой поверх .env: эффективная настройка = env-дефолт + оверрайд из app_settings.

Без кэша — чтения редкие (на приём/ingest/expire), один SELECT по PK, а свежесть
для владельца важнее; Redis-инвалидацию добавим, если появится нагрузка.
"""

from sqlalchemy.orm import Session

from app.config import get_settings
from app.models import AppSetting
from app.settings_registry import EDITABLE, SettingDef


def default_of(defn: SettingDef) -> str | None:
    """Дефолт из .env; None — ключа в Settings нет (его задают только через UI)."""
    return getattr(get_settings(), defn.key, None)


def get_setting_row(db: Session, key: str) -> str | None:
    """Необработанное значение из БД (None — оверрайда нет)."""
    row = db.get(AppSetting, key)
    return row.value if row is not None else None


def get_setting(db: Session, key: str) -> str | bool:
    """Эффективное значение, коэрсия по типу реестра: строка или bool."""
    defn = EDITABLE[key]
    raw = get_setting_row(db, key)
    raw = default_of(defn) if raw is None else raw
    if defn.kind == "int":
        return int(raw) if raw is not None else 0
    if defn.kind == "bool":
        return raw in ("true", "1")
    return raw or ""


def set_setting(db: Session, key: str, value: str | None) -> None:
    """Upsert; value=None — удалить оверрайд (вернётся дефолт .env)."""
    if value is None:
        row = db.get(AppSetting, key)
        if row is not None:
            db.delete(row)
        return
    row = db.get(AppSetting, key)
    if row is None:
        db.add(AppSetting(key=key, value=value))
    else:
        row.value = value