from datetime import datetime from typing import Any, List, Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from app import crud from app.api import deps from app.models.user import User from app.schemas.note import Note, NoteCreate, NoteUpdate router = APIRouter() @router.get("/", response_model=List[Note]) def read_notes( db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100, sort_by: str = Query("created_at", description="Field to sort by (created_at, updated_at, title)"), sort_order: str = Query("desc", description="Sort order (asc, desc)"), search: Optional[str] = Query(None, description="Search term for title and content"), archived: Optional[bool] = Query(None, description="Filter by archived status"), collection_id: Optional[int] = Query(None, description="Filter by collection ID"), start_date: Optional[datetime] = Query(None, description="Filter notes created after this date"), end_date: Optional[datetime] = Query(None, description="Filter notes created before this date"), current_user: User = Depends(deps.get_current_active_user), ) -> Any: """ Retrieve notes for the current user with filtering and sorting options. """ # Search by term if search: return crud.search_notes( db=db, owner_id=current_user.id, search_term=search, skip=skip, limit=limit ) # Filter by archived status if archived is not None: if archived: return crud.get_archived_notes( db=db, owner_id=current_user.id, skip=skip, limit=limit ) else: return db.query(crud.Note).filter( crud.Note.owner_id == current_user.id, not crud.Note.is_archived ).offset(skip).limit(limit).all() # Filter by collection if collection_id: return crud.get_multi_by_collection( db=db, owner_id=current_user.id, collection_id=collection_id, skip=skip, limit=limit ) # Filter by date range if start_date and end_date: return crud.get_notes_created_between( db=db, owner_id=current_user.id, start_date=start_date, end_date=end_date, skip=skip, limit=limit ) # Default sorted retrieval return crud.get_multi_by_owner_sorted( db=db, owner_id=current_user.id, skip=skip, limit=limit, sort_by=sort_by, sort_order=sort_order ) @router.post("/", response_model=Note) def create_note( *, db: Session = Depends(deps.get_db), note_in: NoteCreate, current_user: User = Depends(deps.get_current_active_user), ) -> Any: """ Create new note. """ note = crud.create_note(db=db, obj_in=note_in, owner_id=current_user.id) return note @router.put("/{id}", response_model=Note) def update_note( *, db: Session = Depends(deps.get_db), id: int, note_in: NoteUpdate, current_user: User = Depends(deps.get_current_active_user), ) -> Any: """ Update a note. """ note = crud.get_note(db=db, note_id=id) if not note: raise HTTPException(status_code=404, detail="Note not found") if note.owner_id != current_user.id: raise HTTPException(status_code=403, detail="Not enough permissions") note = crud.update_note(db=db, db_obj=note, obj_in=note_in) return note @router.get("/{id}", response_model=Note) def read_note( *, db: Session = Depends(deps.get_db), id: int, current_user: User = Depends(deps.get_current_active_user), ) -> Any: """ Get note by ID. """ note = crud.get_note(db=db, note_id=id) if not note: raise HTTPException(status_code=404, detail="Note not found") if note.owner_id != current_user.id: raise HTTPException(status_code=403, detail="Not enough permissions") return note @router.delete("/{id}", status_code=204, response_model=None) def delete_note( *, db: Session = Depends(deps.get_db), id: int, current_user: User = Depends(deps.get_current_active_user), ) -> Any: """ Delete a note. """ note = crud.get_note(db=db, note_id=id) if not note: raise HTTPException(status_code=404, detail="Note not found") if note.owner_id != current_user.id: raise HTTPException(status_code=403, detail="Not enough permissions") crud.remove_note(db=db, note_id=id, owner_id=current_user.id) return None