feat: add system settings with model connectivity and encrypted storage

This commit is contained in:
2026-05-08 08:56:52 +08:00
parent e8f3d97d6a
commit adda87a01d
21 changed files with 1888 additions and 291 deletions

View File

@@ -0,0 +1,44 @@
from __future__ import annotations
from typing import Annotated
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from app.api.deps import get_db
from app.schemas.settings import (
ModelConnectivityTestRead,
ModelConnectivityTestRequest,
SettingsRead,
SettingsWrite,
)
from app.services.model_connectivity import probe_model_connectivity
from app.services.settings import SettingsService
router = APIRouter(prefix="/settings")
DbSession = Annotated[Session, Depends(get_db)]
@router.get("", response_model=SettingsRead)
def get_settings(db: DbSession) -> SettingsRead:
return SettingsService(db).get_settings_snapshot()
@router.put("", response_model=SettingsRead)
def update_settings(payload: SettingsWrite, db: DbSession) -> SettingsRead:
try:
return SettingsService(db).save_settings_snapshot(payload)
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
@router.post("/model-connectivity", response_model=ModelConnectivityTestRead)
def test_model_connectivity(payload: ModelConnectivityTestRequest, db: DbSession) -> ModelConnectivityTestRead:
resolved_payload = payload
if not payload.api_key and payload.slot:
stored_api_key = SettingsService(db).load_saved_model_api_key(payload.slot)
if stored_api_key:
resolved_payload = payload.model_copy(update={"api_key": stored_api_key})
return probe_model_connectivity(resolved_payload)

View File

@@ -5,6 +5,7 @@ from app.api.v1.endpoints.bootstrap import router as bootstrap_router
from app.api.v1.endpoints.employees import router as employees_router
from app.api.v1.endpoints.health import router as health_router
from app.api.v1.endpoints.reimbursements import router as reimbursements_router
from app.api.v1.endpoints.settings import router as settings_router
router = APIRouter()
router.include_router(health_router, tags=["health"])
@@ -12,3 +13,4 @@ router.include_router(bootstrap_router, tags=["bootstrap"])
router.include_router(auth_router, tags=["auth"])
router.include_router(employees_router, prefix="/employees", tags=["employees"])
router.include_router(reimbursements_router, prefix="/reimbursements", tags=["reimbursements"])
router.include_router(settings_router, tags=["settings"])