From 96c94fae570b2be13421f9b03819d58a0ed3f34b Mon Sep 17 00:00:00 2001
From: ValueOn AG
Date: Tue, 24 Mar 2026 14:17:18 +0100
Subject: [PATCH] unified data - step 1
---
.../workspace/interfaceFeatureWorkspace.py | 1 -
.../workspace/routeFeatureWorkspace.py | 131 ------------------
2 files changed, 132 deletions(-)
diff --git a/modules/features/workspace/interfaceFeatureWorkspace.py b/modules/features/workspace/interfaceFeatureWorkspace.py
index 56016ba2..525ac62e 100644
--- a/modules/features/workspace/interfaceFeatureWorkspace.py
+++ b/modules/features/workspace/interfaceFeatureWorkspace.py
@@ -14,7 +14,6 @@ from modules.features.workspace.datamodelFeatureWorkspace import WorkspaceUserSe
from modules.interfaces.interfaceRbac import getRecordsetWithRBAC
from modules.security.rbac import RbacClass
from modules.shared.configuration import APP_CONFIG
-from modules.shared.timeUtils import getUtcTimestamp
logger = logging.getLogger(__name__)
diff --git a/modules/features/workspace/routeFeatureWorkspace.py b/modules/features/workspace/routeFeatureWorkspace.py
index 6b8c529b..1828cba6 100644
--- a/modules/features/workspace/routeFeatureWorkspace.py
+++ b/modules/features/workspace/routeFeatureWorkspace.py
@@ -1582,137 +1582,6 @@ async def synthesizeVoice(
return JSONResponse({"audio": None, "note": "TTS via browser Speech Synthesis API recommended"})
-# =========================================================================
-# Voice Settings Endpoints
-# =========================================================================
-
-@router.get("/{instanceId}/settings/voice")
-@limiter.limit("120/minute")
-async def getVoiceSettings(
- request: Request,
- instanceId: str = Path(...),
- context: RequestContext = Depends(getRequestContext),
-):
- """Load voice settings for the current user and instance."""
- _validateInstanceAccess(instanceId, context)
- wsInterface = _getWorkspaceInterface(context, instanceId)
- userId = str(context.user.id)
- try:
- vs = wsInterface.getVoiceSettings(userId)
- if not vs:
- logger.info(f"GET voice settings: not found for user={userId}, creating defaults")
- vs = wsInterface.getOrCreateVoiceSettings(userId)
- result = vs.model_dump() if vs else {}
- mapKeys = list(result.get("ttsVoiceMap", {}).keys()) if result else []
- logger.info(f"GET voice settings for user={userId}: ttsVoiceMap languages={mapKeys}")
- return JSONResponse(result)
- except Exception as e:
- logger.error(f"Failed to load voice settings for user={userId}: {e}", exc_info=True)
- return JSONResponse({"ttsVoiceMap": {}}, status_code=200)
-
-
-@router.put("/{instanceId}/settings/voice")
-@limiter.limit("120/minute")
-async def updateVoiceSettings(
- request: Request,
- instanceId: str = Path(...),
- body: dict = Body(...),
- context: RequestContext = Depends(getRequestContext),
-):
- """Update voice settings for the current user and instance."""
- _validateInstanceAccess(instanceId, context)
- wsInterface = _getWorkspaceInterface(context, instanceId)
- userId = str(context.user.id)
-
- try:
- logger.info(f"PUT voice settings for user={userId}, instance={instanceId}, body keys={list(body.keys())}")
- vs = wsInterface.getVoiceSettings(userId)
- if not vs:
- logger.info(f"No existing voice settings, creating new for user={userId}")
- createData = {
- "userId": userId,
- "mandateId": str(context.mandateId) if context.mandateId else "",
- "featureInstanceId": instanceId,
- }
- createData.update(body)
- created = wsInterface.createVoiceSettings(createData)
- logger.info(f"Created voice settings for user={userId}, ttsVoiceMap keys={list((created or {}).get('ttsVoiceMap', {}).keys())}")
- return JSONResponse(created)
-
- updateData = {k: v for k, v in body.items() if k not in ("id", "userId", "mandateId", "featureInstanceId", "creationDate")}
- logger.info(f"Updating voice settings for user={userId}, update keys={list(updateData.keys())}")
- updated = wsInterface.updateVoiceSettings(userId, updateData)
- logger.info(f"Updated voice settings for user={userId}, ttsVoiceMap keys={list((updated or {}).get('ttsVoiceMap', {}).keys())}")
- return JSONResponse(updated)
- except Exception as e:
- logger.error(f"Failed to update voice settings for user={userId}: {e}", exc_info=True)
- return JSONResponse({"error": str(e)}, status_code=500)
-
-
-@router.get("/{instanceId}/voice/languages")
-@limiter.limit("120/minute")
-async def getVoiceLanguages(
- request: Request,
- instanceId: str = Path(...),
- context: RequestContext = Depends(getRequestContext),
-):
- """Return available TTS languages."""
- mandateId, _ = _validateInstanceAccess(instanceId, context)
- from modules.interfaces.interfaceVoiceObjects import getVoiceInterface
- voiceInterface = getVoiceInterface(context.user, mandateId)
- languagesResult = await voiceInterface.getAvailableLanguages()
- languageList = languagesResult.get("languages", []) if isinstance(languagesResult, dict) else languagesResult
- return JSONResponse({"languages": languageList})
-
-
-@router.get("/{instanceId}/voice/voices")
-@limiter.limit("120/minute")
-async def getVoiceVoices(
- request: Request,
- instanceId: str = Path(...),
- language: str = Query("de-DE"),
- context: RequestContext = Depends(getRequestContext),
-):
- """Return available TTS voices for a given language."""
- mandateId, _ = _validateInstanceAccess(instanceId, context)
- from modules.interfaces.interfaceVoiceObjects import getVoiceInterface
- voiceInterface = getVoiceInterface(context.user, mandateId)
- voicesResult = await voiceInterface.getAvailableVoices(language)
- voiceList = voicesResult.get("voices", []) if isinstance(voicesResult, dict) else voicesResult
- return JSONResponse({"voices": voiceList})
-
-
-@router.post("/{instanceId}/voice/test")
-@limiter.limit("30/minute")
-async def testVoice(
- request: Request,
- instanceId: str = Path(...),
- body: dict = Body(...),
- context: RequestContext = Depends(getRequestContext),
-):
- """Test a specific voice with a sample text."""
- import base64
- mandateId, _ = _validateInstanceAccess(instanceId, context)
- text = body.get("text", "Hallo, das ist ein Stimmtest.")
- language = body.get("language", "de-DE")
- voiceId = body.get("voiceId")
-
- from modules.interfaces.interfaceVoiceObjects import getVoiceInterface
- voiceInterface = getVoiceInterface(context.user, mandateId)
-
- try:
- result = await voiceInterface.textToSpeech(text=text, languageCode=language, voiceName=voiceId)
- if result and isinstance(result, dict):
- audioContent = result.get("audioContent")
- if audioContent:
- audioB64 = base64.b64encode(
- audioContent if isinstance(audioContent, bytes) else audioContent.encode()
- ).decode()
- return JSONResponse({"success": True, "audio": audioB64, "format": "mp3", "text": text})
- return JSONResponse({"success": False, "error": "TTS returned no audio"})
- except Exception as e:
- logger.error(f"Voice test failed: {e}")
- raise HTTPException(status_code=500, detail=f"TTS test failed: {str(e)}")
# =============================================================================