Asma-yaseen's picture
feat: Deploy all advanced endpoints - Phase 2 complete
80df84c
Raw
History Blame Contribute Delete
2.54 kB
"""
Bulk Operations API (US6).
Task: US6 - Batch task updates and deletions
Spec: specs/features/task-crud.md
"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlmodel import Session, select, col
from typing import List, Optional
from pydantic import BaseModel, Field
from models import Task
from db import get_session
from middleware.auth import verify_token
router = APIRouter(prefix="/api", tags=["bulk"])
class BulkUpdate(BaseModel):
"""Request model for bulk updates."""
task_ids: List[int] = Field(..., min_length=1)
completed: Optional[bool] = None
priority: Optional[str] = None
delete: bool = Field(default=False)
@router.post("/{user_id}/tasks/bulk")
async def bulk_task_operations(
user_id: str,
data: BulkUpdate,
session: Session = Depends(get_session),
authenticated_user_id: str = Depends(verify_token)
):
"""
Perform bulk operations on tasks (US6).
Args:
user_id: User ID from URL path
data: Bulk operation data (IDs and fields to update)
session: Database session
authenticated_user_id: User ID from JWT token
Returns:
Summary of the operation
Raises:
HTTPException: 403 if user_id doesn't match authenticated user
"""
# Verify user_id matches authenticated user
if user_id != authenticated_user_id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Cannot perform operations on other users' tasks"
)
# Fetch tasks belonging to the user
query = select(Task).where(
Task.user_id == user_id,
col(Task.id).in_(data.task_ids)
)
tasks = session.exec(query).all()
found_ids = {t.id for t in tasks}
missing_ids = [tid for tid in data.task_ids if tid not in found_ids]
if data.delete:
# Delete operation
for task in tasks:
session.delete(task)
action = "deleted"
else:
# Update operation
for task in tasks:
if data.completed is not None:
task.completed = data.completed
if data.priority is not None:
task.priority = data.priority
session.add(task)
action = "updated"
session.commit()
return {
"message": f"Successfully {action} {len(tasks)} tasks",
"count": len(tasks),
"missing_ids": missing_ids if missing_ids else None
}