dashboard-nanobot/backend/services/platform_system_settings_se...

105 lines
4.1 KiB
Python

from typing import Any, Dict, List
from sqlmodel import Session, select
from models.platform import PlatformSetting
from schemas.platform import SystemSettingPayload
from services.platform_settings_core import (
ACTIVITY_EVENT_RETENTION_SETTING_KEY,
PROTECTED_SETTING_KEYS,
SYSTEM_SETTING_DEFINITIONS,
_normalize_setting_key,
_read_setting_value,
_setting_item_from_row,
_upsert_setting_row,
)
REQUIRED_SYSTEM_SETTING_KEYS = tuple(SYSTEM_SETTING_DEFINITIONS.keys())
def validate_required_system_settings(session: Session) -> None:
stmt = select(PlatformSetting.key).where(PlatformSetting.key.in_(REQUIRED_SYSTEM_SETTING_KEYS))
present = {
str(key or "").strip()
for key in session.exec(stmt).all()
if str(key or "").strip()
}
missing = [key for key in REQUIRED_SYSTEM_SETTING_KEYS if key not in present]
if missing:
raise RuntimeError(
"Database seed data is not initialized. "
f"Missing sys_setting keys: {', '.join(missing)}. "
"Run scripts/init-full-db.sh or apply scripts/sql/init-data.sql before starting the backend."
)
def list_system_settings(session: Session, search: str = "") -> List[Dict[str, Any]]:
validate_required_system_settings(session)
stmt = select(PlatformSetting).order_by(PlatformSetting.sort_order.asc(), PlatformSetting.key.asc())
rows = session.exec(stmt).all()
keyword = str(search or "").strip().lower()
items = [_setting_item_from_row(row) for row in rows]
if not keyword:
return items
return [
item
for item in items
if keyword in str(item["key"]).lower()
or keyword in str(item["name"]).lower()
or keyword in str(item["category"]).lower()
or keyword in str(item["description"]).lower()
]
def create_or_update_system_setting(session: Session, payload: SystemSettingPayload) -> Dict[str, Any]:
normalized_key = _normalize_setting_key(payload.key)
definition = SYSTEM_SETTING_DEFINITIONS.get(normalized_key, {})
row = _upsert_setting_row(
session,
payload.key,
name=payload.name or str(definition.get("name") or payload.key),
category=payload.category or str(definition.get("category") or "general"),
description=payload.description or str(definition.get("description") or ""),
value_type=payload.value_type or str(definition.get("value_type") or "json"),
value=payload.value if payload.value is not None else definition.get("value"),
is_public=payload.is_public,
sort_order=payload.sort_order or int(definition.get("sort_order") or 100),
)
if normalized_key == ACTIVITY_EVENT_RETENTION_SETTING_KEY:
from services.platform_activity_service import prune_expired_activity_events
prune_expired_activity_events(session, force=True)
session.commit()
session.refresh(row)
return _setting_item_from_row(row)
def delete_system_setting(session: Session, key: str) -> None:
normalized_key = _normalize_setting_key(key)
if normalized_key in PROTECTED_SETTING_KEYS:
raise ValueError("Core platform settings cannot be deleted")
row = session.get(PlatformSetting, normalized_key)
if row is None:
raise ValueError("Setting not found")
session.delete(row)
session.commit()
def get_activity_event_retention_days(session: Session) -> int:
validate_required_system_settings(session)
row = session.get(PlatformSetting, ACTIVITY_EVENT_RETENTION_SETTING_KEY)
if row is None:
raise RuntimeError(
"Database seed data is not initialized. "
f"Missing sys_setting key: {ACTIVITY_EVENT_RETENTION_SETTING_KEY}. "
"Run scripts/init-full-db.sh or apply scripts/sql/init-data.sql before starting the backend."
)
try:
value = int(_read_setting_value(row))
except Exception as exc:
raise RuntimeError(
f"sys_setting value is invalid for key: {ACTIVITY_EVENT_RETENTION_SETTING_KEY}. "
"Fix the row manually or reapply scripts/sql/init-data.sql."
) from exc
return max(1, min(3650, value))