ФУНКЦИИ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: ручное назначение Voice Tasker

This commit is contained in:
DCCONSTRUCTIONS
2026-04-28 11:04:38 +03:00
parent 9243924f78
commit 02d79da6f9
8 changed files with 488 additions and 45 deletions
@@ -227,7 +227,30 @@ def normalize_audio_content_type(content_type):
return content_type.split(";")[0].strip().lower()
def get_voice_task_preflight(workspace, user):
def get_request_project_id(request):
project_id = request.query_params.get("project_id")
if project_id:
return project_id
draft = request.data.get("draft")
if isinstance(draft, dict) and draft.get("project_id"):
return draft.get("project_id")
client_context = request.data.get("client_context")
if not client_context:
return None
try:
parsed_context = json.loads(client_context) if isinstance(client_context, str) else client_context
except (TypeError, json.JSONDecodeError):
return None
if isinstance(parsed_context, dict):
return parsed_context.get("current_project_id")
return None
def get_voice_task_preflight(workspace, user, project_id=None):
ai_settings = WorkspaceAISettings.objects.filter(workspace=workspace).first()
workspace_member = WorkspaceMember.objects.filter(workspace=workspace, member=user, is_active=True).first()
@@ -237,6 +260,8 @@ def get_voice_task_preflight(workspace, user):
"max_audio_duration_seconds": 120,
"accepted_mime_types": VOICE_TASK_ACCEPTED_AUDIO_TYPES,
"access_mode": "all_workspace_members",
"enabled_project_ids": [],
"enabled_member_ids": [],
}
if not ai_settings:
@@ -244,6 +269,8 @@ def get_voice_task_preflight(workspace, user):
response["max_audio_duration_seconds"] = ai_settings.max_audio_duration_seconds
response["access_mode"] = ai_settings.access_mode
response["enabled_project_ids"] = [str(project_id) for project_id in ai_settings.enabled_projects.values_list("id", flat=True)]
response["enabled_member_ids"] = [str(member_id) for member_id in ai_settings.enabled_members.values_list("id", flat=True)]
if not ai_settings.voice_tasker_enabled:
response["reason"] = "disabled"
@@ -263,6 +290,19 @@ def get_voice_task_preflight(workspace, user):
response["reason"] = "role_denied"
return response
if ai_settings.access_mode == WorkspaceAISettings.AccessMode.SELECTED_MEMBERS:
if not ai_settings.enabled_members.filter(id=user.id).exists():
response["reason"] = "scope_denied"
return response
if ai_settings.access_mode == WorkspaceAISettings.AccessMode.SELECTED_PROJECTS:
if not project_id:
response["reason"] = "scope_denied"
return response
if not ai_settings.enabled_projects.filter(id=project_id, workspace=workspace, archived_at__isnull=True).exists():
response["reason"] = "scope_denied"
return response
response["available"] = True
response["reason"] = None
return response
@@ -2332,7 +2372,10 @@ class VoiceTaskPreflightEndpoint(BaseAPIView):
@allow_permission(allowed_roles=[ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
def get(self, request, slug):
workspace = Workspace.objects.get(slug=slug)
return Response(get_voice_task_preflight(workspace, request.user), status=status.HTTP_200_OK)
return Response(
get_voice_task_preflight(workspace, request.user, project_id=get_request_project_id(request)),
status=status.HTTP_200_OK,
)
class VoiceTaskParseEndpoint(BaseAPIView):
@@ -2341,10 +2384,14 @@ class VoiceTaskParseEndpoint(BaseAPIView):
@allow_permission(allowed_roles=[ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
def post(self, request, slug):
workspace = Workspace.objects.get(slug=slug)
preflight = get_voice_task_preflight(workspace, request.user)
preflight = get_voice_task_preflight(workspace, request.user, project_id=get_request_project_id(request))
if not preflight["available"]:
response_status = status.HTTP_403_FORBIDDEN if preflight["reason"] == "role_denied" else status.HTTP_400_BAD_REQUEST
response_status = (
status.HTTP_403_FORBIDDEN
if preflight["reason"] in {"role_denied", "scope_denied"}
else status.HTTP_400_BAD_REQUEST
)
return Response(
{
"ok": False,
@@ -2512,9 +2559,13 @@ class VoiceTaskCommitEndpoint(BaseAPIView):
@allow_permission(allowed_roles=[ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
def post(self, request, slug):
workspace = Workspace.objects.get(slug=slug)
preflight = get_voice_task_preflight(workspace, request.user)
preflight = get_voice_task_preflight(workspace, request.user, project_id=get_request_project_id(request))
if not preflight["available"]:
response_status = status.HTTP_403_FORBIDDEN if preflight["reason"] == "role_denied" else status.HTTP_400_BAD_REQUEST
response_status = (
status.HTTP_403_FORBIDDEN
if preflight["reason"] in {"role_denied", "scope_denied"}
else status.HTTP_400_BAD_REQUEST
)
return Response(
{
"ok": False,