from __future__ import annotations import uuid from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from cpv3.db.session import get_db from cpv3.infrastructure.auth import get_current_user from cpv3.modules.projects.service import ProjectService from cpv3.modules.project_workspaces.schemas import ( ProjectWorkspaceRead, WorkflowActionRequest, ) from cpv3.modules.project_workspaces.service import ( ProjectWorkspaceRevisionConflictError, ProjectWorkspaceService, ProjectWorkflowValidationError, ) from cpv3.modules.users.models import User router = APIRouter(prefix="/api/projects", tags=["Project Workspaces"]) @router.get("/{project_id}/workspace", response_model=ProjectWorkspaceRead) @router.get( "/{project_id}/workspace/", response_model=ProjectWorkspaceRead, include_in_schema=False, ) async def get_project_workspace( project_id: uuid.UUID, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> ProjectWorkspaceRead: project_service = ProjectService(db) project = await project_service.get_project(project_id) if project is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Не найдено") if not current_user.is_staff and project.owner_id != current_user.id: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Доступ запрещён") workspace_service = ProjectWorkspaceService(db) return await workspace_service.get_workspace(project=project) @router.post("/{project_id}/workflow/actions", response_model=ProjectWorkspaceRead) @router.post( "/{project_id}/workflow/actions/", response_model=ProjectWorkspaceRead, include_in_schema=False, ) async def dispatch_project_workflow_action( project_id: uuid.UUID, body: WorkflowActionRequest, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> ProjectWorkspaceRead: project_service = ProjectService(db) project = await project_service.get_project(project_id) if project is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Не найдено") if not current_user.is_staff and project.owner_id != current_user.id: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Доступ запрещён") workspace_service = ProjectWorkspaceService(db) try: return await workspace_service.apply_action( project=project, requester=current_user, action=body, ) except ProjectWorkspaceRevisionConflictError as exc: raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(exc)) from exc except ProjectWorkflowValidationError as exc: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc