"""System settings API — read and update runtime-editable settings. Backs the panel settings page. Values persist in the ``system_settings`` table and are read by the backend (e.g. the transcript-retention prune sweep) with a ``roboco.config`` default as the fallback when a key is unset. """ from fastapi import APIRouter, HTTPException, status from roboco.api.deps import DbSession from roboco.api.schemas.settings import ( FeatureFlag, FeatureFlagsResponse, SettingsResponse, SettingUpdate, ) from roboco.services.settings import ( FEATURE_FLAGS, SettingValidationError, feature_flag_effective_values, get_settings_service, ) router = APIRouter() @router.get("", response_model=SettingsResponse) async def list_settings(db: DbSession) -> SettingsResponse: """Return every stored runtime-editable setting.""" return SettingsResponse(settings=await get_settings_service(db).all()) @router.get("/feature-flags", response_model=FeatureFlagsResponse) async def get_feature_flags(db: DbSession) -> FeatureFlagsResponse: """Effective feature-flag values (stored override, else the env default).""" effective = await feature_flag_effective_values(db) return FeatureFlagsResponse( flags=[ FeatureFlag(key=key, label=label, enabled=effective.get(key, False)) for key, label in FEATURE_FLAGS ] ) @router.put("/{key}", response_model=SettingsResponse) async def update_setting( key: str, data: SettingUpdate, db: DbSession ) -> SettingsResponse: """Validate and persist a single setting, returning the full updated map.""" service = get_settings_service(db) try: await service.set(key, data.value) except SettingValidationError as exc: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc) ) from exc # Write route commits explicitly (get_db auto-commit is unreliable). await db.commit() return SettingsResponse(settings=await service.all())