e9d2831850
CI Build & Deploy Pipeline / Build Staging API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging API Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been skipped
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Production API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Staging E2E Tests (push) Has been skipped
CI Build & Deploy Pipeline / Staging API Integration Tests (push) Has been skipped
CI Build & Deploy Pipeline / Deploy Production (push) Has been skipped
CI Build & Deploy Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI Build & Deploy Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI Build & Deploy Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Successful in 1m33s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m30s
CI Build & Deploy Pipeline / Build Production API Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Production Web Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Deploy Production (pull_request) Has been skipped
CI Build & Deploy Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (push) Successful in 3m13s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 3m18s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Failing after 16m16s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 16m20s
CI/CD Pipeline / Integration Tests (push) Successful in 2m30s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m24s
92 lines
3.2 KiB
Python
92 lines
3.2 KiB
Python
from typing import Any
|
|
|
|
from app.auth import AuthenticatedUser, get_current_user
|
|
from app.dependencies import get_project_repository
|
|
from app.schemas.project import (
|
|
CreateProjectRequest,
|
|
ListProjectsResponse,
|
|
ProjectResponse,
|
|
)
|
|
from fastapi import APIRouter, Depends, HTTPException, Response, status
|
|
|
|
from packages.application import (
|
|
CreateProjectCommand,
|
|
CreateProjectUseCase,
|
|
DeleteProjectUseCase,
|
|
GetProjectUseCase,
|
|
ListProjectsUseCase,
|
|
)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
def _to_project_response(item) -> ProjectResponse:
|
|
return ProjectResponse(
|
|
id=item.id,
|
|
owner_user_id=item.owner_user_id,
|
|
name=item.name,
|
|
description=item.description,
|
|
shared_users=item.shared_users,
|
|
)
|
|
|
|
|
|
@router.get("/{project_id}", response_model=ProjectResponse)
|
|
def get_project(
|
|
project_id: str,
|
|
authenticated_user: AuthenticatedUser = Depends(get_current_user),
|
|
project_repository: Any = Depends(get_project_repository),
|
|
) -> ProjectResponse:
|
|
use_case = GetProjectUseCase(project_repository)
|
|
project = use_case.execute(project_id)
|
|
if project is None:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Project not found")
|
|
if not project.can_access(authenticated_user.user.id):
|
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Access denied to project")
|
|
return _to_project_response(project)
|
|
|
|
|
|
@router.get("", response_model=ListProjectsResponse)
|
|
def list_projects(
|
|
authenticated_user: AuthenticatedUser = Depends(get_current_user),
|
|
project_repository: Any = Depends(get_project_repository),
|
|
) -> ListProjectsResponse:
|
|
use_case = ListProjectsUseCase(project_repository)
|
|
projects = use_case.execute(authenticated_user.user.id)
|
|
return ListProjectsResponse(items=[_to_project_response(item) for item in projects])
|
|
|
|
|
|
@router.post("", response_model=ProjectResponse)
|
|
def create_project(
|
|
request: CreateProjectRequest,
|
|
authenticated_user: AuthenticatedUser = Depends(get_current_user),
|
|
project_repository: Any = Depends(get_project_repository),
|
|
) -> ProjectResponse:
|
|
use_case = CreateProjectUseCase(project_repository)
|
|
project = use_case.execute(
|
|
CreateProjectCommand(
|
|
name=request.name,
|
|
description=request.description,
|
|
),
|
|
owner_user_id=authenticated_user.user.id,
|
|
)
|
|
return _to_project_response(project)
|
|
|
|
|
|
@router.delete("/{project_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None, response_class=Response)
|
|
def delete_project(
|
|
project_id: str,
|
|
authenticated_user: AuthenticatedUser = Depends(get_current_user),
|
|
project_repository: Any = Depends(get_project_repository),
|
|
) -> dict:
|
|
use_case = DeleteProjectUseCase(project_repository)
|
|
try:
|
|
deleted = use_case.execute(project_id, authenticated_user.user.id)
|
|
except PermissionError as _e:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="Only the project owner can delete this project",
|
|
) from _e
|
|
if not deleted:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Project not found")
|
|
return # type: ignore[return-value]
|