Automated Action a00c823bd1 Add search functionality to find todos by title or description
- Add search parameter to get_todos CRUD function
- Add search parameter to main todos endpoint
- Create dedicated /search endpoint for title/description search
- Update README with new search functionality
- Fix datetime import issue in todo_stats function

generated with BackendIM... (backend.im)
2025-05-13 04:20:44 +00:00

124 lines
3.9 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from typing import List, Optional, Dict, Any
from datetime import datetime
from app import crud
from app.models.todo import PriorityEnum as ModelPriorityEnum
from app.schemas.todo import Todo, TodoCreate, TodoUpdate, PriorityEnum
from app.db.base import get_db
router = APIRouter()
@router.get("/", response_model=List[Todo])
def read_todos(
skip: int = 0,
limit: int = 100,
category: Optional[str] = None,
priority: Optional[PriorityEnum] = None,
completed: Optional[bool] = None,
due_before: Optional[datetime] = None,
due_after: Optional[datetime] = None,
search: Optional[str] = None,
sort_by: str = "created_at",
sort_desc: bool = True,
db: Session = Depends(get_db)
):
"""
Get all todos with filtering options:
- Filter by category
- Filter by priority level
- Filter by completion status
- Filter by due date (before/after)
- Search in title and description
- Sort by any field
- Pagination
"""
todos = crud.get_todos(
db=db,
skip=skip,
limit=limit,
category=category,
priority=priority.value if priority else None,
completed=completed,
due_before=due_before,
due_after=due_after,
search=search,
sort_by=sort_by,
sort_desc=sort_desc
)
return todos
@router.post("/", response_model=Todo, status_code=status.HTTP_201_CREATED)
def create_todo(todo: TodoCreate, db: Session = Depends(get_db)):
"""Create a new todo item with extended fields"""
return crud.create_todo(db=db, todo=todo)
@router.get("/search", response_model=List[Todo])
def search_todos(
q: str = Query(..., min_length=1, description="Search query for title or description"),
skip: int = 0,
limit: int = 100,
sort_by: str = "created_at",
sort_desc: bool = True,
db: Session = Depends(get_db)
):
"""
Search todos by title or description content
Returns todos where the title or description contains the search query
"""
todos = crud.get_todos(
db=db,
skip=skip,
limit=limit,
search=q,
sort_by=sort_by,
sort_desc=sort_desc
)
return todos
@router.get("/stats", response_model=Dict[str, Any])
def get_todo_stats(db: Session = Depends(get_db)):
"""Get statistics about todos including:
- Total, completed, and incomplete counts
- Number of overdue tasks
- Number of tasks completed in the last 24 hours
- Number of tasks completed in the last 7 days
- Breakdown by category and priority
"""
return crud.get_todo_stats(db=db)
@router.get("/{todo_id}", response_model=Todo)
def read_todo(todo_id: int, db: Session = Depends(get_db)):
"""Get a specific todo by ID"""
db_todo = crud.get_todo(db, todo_id=todo_id)
if db_todo is None:
raise HTTPException(status_code=404, detail="Todo not found")
return db_todo
@router.put("/{todo_id}", response_model=Todo)
def update_todo(todo_id: int, todo: TodoUpdate, db: Session = Depends(get_db)):
"""Update a todo with new values including category, priority, due date and completion status.
When a todo is marked as completed, the completion_date will be automatically set to the current time
if not explicitly provided. If a todo is marked as not completed, the completion_date will be cleared.
"""
db_todo = crud.update_todo(db=db, todo_id=todo_id, todo=todo)
if db_todo is None:
raise HTTPException(status_code=404, detail="Todo not found")
return db_todo
@router.delete("/{todo_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_todo(todo_id: int, db: Session = Depends(get_db)):
"""Delete a todo by ID"""
success = crud.delete_todo(db=db, todo_id=todo_id)
if not success:
raise HTTPException(status_code=404, detail="Todo not found")
return None