from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select, func from sqlalchemy.ext.asyncio import AsyncSession from app.database import get_db from app.models.user import User from app.models.project import Project from app.schemas.project import ProjectCreate, ProjectUpdate, ProjectResponse, ProjectListResponse from app.services.auth import get_current_user router = APIRouter(prefix="/api/projects", tags=["projects"]) @router.get("", response_model=ProjectListResponse) async def list_projects( skip: int = 0, limit: int = 20, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): result = await db.execute( select(Project) .where(Project.user_id == user.id) .order_by(Project.updated_at.desc()) .offset(skip).limit(limit) ) projects = list(result.scalars().all()) count_result = await db.execute( select(func.count()).select_from(Project).where(Project.user_id == user.id) ) total = count_result.scalar() or 0 return ProjectListResponse(projects=projects, total=total) @router.post("", response_model=ProjectResponse, status_code=201) async def create_project( data: ProjectCreate, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): project = Project(user_id=user.id, **data.model_dump(exclude_none=True)) db.add(project) await db.commit() await db.refresh(project) return project @router.get("/{project_id}", response_model=ProjectResponse) async def get_project( project_id: int, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): result = await db.execute( select(Project).where(Project.id == project_id, Project.user_id == user.id) ) project = result.scalar_one_or_none() if not project: raise HTTPException(status_code=404, detail="Project not found") return project @router.patch("/{project_id}", response_model=ProjectResponse) async def update_project( project_id: int, data: ProjectUpdate, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): result = await db.execute( select(Project).where(Project.id == project_id, Project.user_id == user.id) ) project = result.scalar_one_or_none() if not project: raise HTTPException(status_code=404, detail="Project not found") for key, value in data.model_dump(exclude_none=True).items(): setattr(project, key, value) await db.commit() await db.refresh(project) return project @router.delete("/{project_id}", status_code=204) async def delete_project( project_id: int, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): result = await db.execute( select(Project).where(Project.id == project_id, Project.user_id == user.id) ) project = result.scalar_one_or_none() if not project: raise HTTPException(status_code=404, detail="Project not found") await db.delete(project) await db.commit()