"""System settings router. Manages key-value system settings including API provider configuration. """ from datetime import datetime from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from ..auth import get_current_user from ..database import get_db from ..models import SystemSetting from ..schemas import SettingResponse, SettingUpdate router = APIRouter( prefix="/api/settings", tags=["settings"], dependencies=[Depends(get_current_user)], ) @router.get("/", response_model=list[SettingResponse]) def list_settings(db: Session = Depends(get_db)): """Get all system settings.""" settings = db.query(SystemSetting).order_by(SystemSetting.key).all() return settings @router.get("/providers/status") def get_providers_status(db: Session = Depends(get_db)): """Check which API providers are configured (have API keys set). Returns a dict indicating configuration status for each provider category. """ # Helper to check if a setting exists and has a truthy value def _has_setting(key: str) -> str | None: setting = db.query(SystemSetting).filter(SystemSetting.key == key).first() if setting and setting.value: return setting.value if isinstance(setting.value, str) else str(setting.value) return None # LLM provider llm_provider = _has_setting("llm_provider") llm_key = _has_setting("llm_api_key") # Image provider image_provider = _has_setting("image_provider") image_key = _has_setting("image_api_key") # Voice provider (future) voice_provider = _has_setting("voice_provider") voice_key = _has_setting("voice_api_key") # Social platforms - check for any active social accounts from ..models import SocialAccount social_platforms = {} for platform in ("facebook", "instagram", "youtube", "tiktok"): has_account = ( db.query(SocialAccount) .filter( SocialAccount.platform == platform, SocialAccount.is_active == True, SocialAccount.access_token != None, ) .first() ) social_platforms[platform] = has_account is not None return { "llm": { "configured": bool(llm_provider and llm_key), "provider": llm_provider, }, "image": { "configured": bool(image_provider and image_key), "provider": image_provider, }, "voice": { "configured": bool(voice_provider and voice_key), "provider": voice_provider, }, "social": social_platforms, } @router.get("/{key}", response_model=SettingResponse) def get_setting(key: str, db: Session = Depends(get_db)): """Get a single setting by key.""" setting = db.query(SystemSetting).filter(SystemSetting.key == key).first() if not setting: raise HTTPException(status_code=404, detail=f"Setting '{key}' not found") return setting @router.put("/{key}", response_model=SettingResponse) def upsert_setting(key: str, data: SettingUpdate, db: Session = Depends(get_db)): """Create or update a setting by key. If the setting exists, update its value. If not, create it. """ setting = db.query(SystemSetting).filter(SystemSetting.key == key).first() if setting: setting.value = data.value setting.updated_at = datetime.utcnow() else: setting = SystemSetting(key=key, value=data.value) db.add(setting) db.commit() db.refresh(setting) return setting @router.delete("/{key}", status_code=204) def delete_setting(key: str, db: Session = Depends(get_db)): """Delete a setting by key.""" setting = db.query(SystemSetting).filter(SystemSetting.key == key).first() if not setting: raise HTTPException(status_code=404, detail=f"Setting '{key}' not found") db.delete(setting) db.commit()