"""System settings router. Manages key-value system settings including API provider configuration. Each user has their own private settings. """ 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, User from ..schemas import SettingResponse, SettingUpdate router = APIRouter( prefix="/api/settings", tags=["settings"], ) @router.get("/", response_model=list[SettingResponse]) def list_settings( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get all system settings for the current user.""" settings = ( db.query(SystemSetting) .filter(SystemSetting.user_id == current_user.id) .order_by(SystemSetting.key) .all() ) return settings @router.get("/providers/status") def get_providers_status( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Check which API providers are configured (have API keys set).""" def _has_setting(key: str) -> str | None: # User-specific first setting = ( db.query(SystemSetting) .filter(SystemSetting.key == key, SystemSetting.user_id == current_user.id) .first() ) if not setting: # Global fallback setting = db.query(SystemSetting).filter( SystemSetting.key == key, SystemSetting.user_id == None ).first() if setting and setting.value: return setting.value if isinstance(setting.value, str) else str(setting.value) return None llm_provider = _has_setting("llm_provider") llm_key = _has_setting("llm_api_key") image_provider = _has_setting("image_provider") image_key = _has_setting("image_api_key") voice_provider = _has_setting("voice_provider") voice_key = _has_setting("voice_api_key") 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, SocialAccount.user_id == current_user.id, ) .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), current_user: User = Depends(get_current_user), ): """Get a single setting by key (user-specific).""" setting = ( db.query(SystemSetting) .filter(SystemSetting.key == key, SystemSetting.user_id == current_user.id) .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), current_user: User = Depends(get_current_user), ): """Create or update a setting by key (user-specific).""" setting = ( db.query(SystemSetting) .filter(SystemSetting.key == key, SystemSetting.user_id == current_user.id) .first() ) if setting: setting.value = data.value setting.updated_at = datetime.utcnow() else: setting = SystemSetting(key=key, value=data.value, user_id=current_user.id) 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), current_user: User = Depends(get_current_user), ): """Delete a setting by key (user-specific).""" setting = ( db.query(SystemSetting) .filter(SystemSetting.key == key, SystemSetting.user_id == current_user.id) .first() ) if not setting: raise HTTPException(status_code=404, detail=f"Setting '{key}' not found") db.delete(setting) db.commit()