Tahasaif3's picture
Update src/routers/projects.py
e6cc6c2 verified
from fastapi import APIRouter, HTTPException, status, Depends
from sqlmodel import Session, select, and_, func
from typing import List
from uuid import UUID
from datetime import datetime
from ..models.user import User
from ..models.project import Project, ProjectCreate, ProjectUpdate, ProjectRead
from ..models.task import Task
from ..database import get_session_dep
from ..utils.deps import get_current_user
router = APIRouter(prefix="/api/{user_id}/projects", tags=["projects"])
@router.get("/", response_model=List[ProjectRead])
def list_projects(
user_id: UUID,
current_user: User = Depends(get_current_user),
session: Session = Depends(get_session_dep)
):
"""List all projects for the authenticated user."""
# Verify that the user_id in the URL matches the authenticated user
if current_user.id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found"
)
# Build the query with user_id filter
query = select(Project).where(Project.user_id == user_id)
# Apply ordering (newest first)
query = query.order_by(Project.created_at.desc())
projects = session.exec(query).all()
return projects
@router.post("", response_model=ProjectRead, status_code=status.HTTP_201_CREATED)
def create_project(
*,
user_id: UUID,
project_data: ProjectCreate,
current_user: User = Depends(get_current_user),
session: Session = Depends(get_session_dep)
):
"""Create a new project for the authenticated user."""
# Verify that the user_id in the URL matches the authenticated user
if current_user.id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
# Create the project
project = Project(
name=project_data.name,
description=project_data.description,
color=project_data.color,
user_id=user_id
)
session.add(project)
session.commit()
session.refresh(project)
return project
@router.get("/{project_id}", response_model=ProjectRead)
def get_project(
*,
user_id: UUID,
project_id: UUID,
current_user: User = Depends(get_current_user),
session: Session = Depends(get_session_dep)
):
"""Get a specific project by ID for the authenticated user."""
# Verify that the user_id in the URL matches the authenticated user
if current_user.id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found"
)
# Fetch the project
project = session.get(Project, project_id)
# Check if project exists and belongs to the user
if not project or project.user_id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found"
)
return project
@router.put("/{project_id}", response_model=ProjectRead)
def update_project(
*,
user_id: UUID,
project_id: UUID,
project_data: ProjectUpdate,
current_user: User = Depends(get_current_user),
session: Session = Depends(get_session_dep)
):
"""Update an existing project for the authenticated user."""
# Verify that the user_id in the URL matches the authenticated user
if current_user.id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found"
)
# Fetch the project
project = session.get(Project, project_id)
# Check if project exists and belongs to the user
if not project or project.user_id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found"
)
# Update the project
project_data_dict = project_data.dict(exclude_unset=True)
for key, value in project_data_dict.items():
setattr(project, key, value)
session.add(project)
session.commit()
session.refresh(project)
return project
@router.delete("/{project_id}")
def delete_project(
*,
user_id: UUID,
project_id: UUID,
current_user: User = Depends(get_current_user),
session: Session = Depends(get_session_dep)
):
"""Delete a project for the authenticated user."""
# Verify that the user_id in the URL matches the authenticated user
if current_user.id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found"
)
# Fetch the project
project = session.get(Project, project_id)
# Check if project exists and belongs to the user
if not project or project.user_id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found"
)
# Delete the project
session.delete(project)
session.commit()
return {"message": "Project deleted successfully"}
@router.get("/{project_id}/tasks", response_model=List[Task])
def list_project_tasks(
*,
user_id: UUID,
project_id: UUID,
current_user: User = Depends(get_current_user),
session: Session = Depends(get_session_dep)
):
"""List all tasks for a specific project."""
# Verify that the user_id in the URL matches the authenticated user
if current_user.id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found"
)
# Fetch the project
project = session.get(Project, project_id)
# Check if project exists and belongs to the user
if not project or project.user_id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found"
)
# Build the query with project_id filter
query = select(Task).where(Task.project_id == project_id)
# Apply ordering (newest first)
query = query.order_by(Task.created_at.desc())
tasks = session.exec(query).all()
return tasks
@router.get("/{project_id}/progress")
def get_project_progress(
*,
user_id: UUID,
project_id: UUID,
current_user: User = Depends(get_current_user),
session: Session = Depends(get_session_dep)
):
"""Get progress statistics for a specific project."""
# Verify that the user_id in the URL matches the authenticated user
if current_user.id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found"
)
# Fetch the project
project = session.get(Project, project_id)
# Check if project exists and belongs to the user
if not project or project.user_id != user_id:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found"
)
# Get task counts
total_tasks_query = select(func.count()).where(Task.project_id == project_id)
completed_tasks_query = select(func.count()).where(and_(Task.project_id == project_id, Task.completed == True))
total_tasks = session.exec(total_tasks_query).first()
completed_tasks = session.exec(completed_tasks_query).first()
# Calculate progress
progress = 0
if total_tasks > 0:
progress = round((completed_tasks / total_tasks) * 100, 2)
return {
"total_tasks": total_tasks,
"completed_tasks": completed_tasks,
"pending_tasks": total_tasks - completed_tasks,
"progress": progress
}