"""Key-Value settings store with Redis projection.""" from __future__ import annotations import json from typing import Any from sqlalchemy import JSON, String from sqlalchemy.orm import Mapped, Session, mapped_column from core.db import Base from core.events import event_bus from core.redis_client import redis_client class Setting(Base): __tablename__ = "settings" key: Mapped[str] = mapped_column(String(128), primary_key=True) value: Mapped[dict] = mapped_column(JSON) def get_setting(db: Session, key: str, default: Any = None) -> Any: row = db.get(Setting, key) return row.value.get("v") if row else default def set_setting(db: Session, key: str, value: Any) -> None: row = db.get(Setting, key) if row: row.value = {"v": value} else: row = Setting(key=key, value={"v": value}) db.add(row) db.commit() redis_client.set(f"setting:{key}", json.dumps(value)) event_bus.publish("core.settings_updated", {"key": key, "value": value}, db=db) def get_setting_cached(key: str, default: Any = None) -> Any: raw = redis_client.get(f"setting:{key}") if raw is None: return default return json.loads(raw)