"""Слой поверх .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