feat: Add filtering, searching, and sorting to user extractions retrieval

This commit is contained in:
JSC
2025-08-17 01:27:41 +02:00
parent fe15e7a6af
commit 3326e406f8
3 changed files with 65 additions and 6 deletions

View File

@@ -2,7 +2,7 @@
from typing import Annotated
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlmodel.ext.asyncio.session import AsyncSession
from app.core.database import get_db
@@ -91,6 +91,10 @@ async def get_extraction(
async def get_user_extractions(
current_user: Annotated[User, Depends(get_current_active_user_flexible)],
extraction_service: Annotated[ExtractionService, Depends(get_extraction_service)],
search: Annotated[str | None, Query(description="Search in title, URL, or service")] = None,
sort_by: Annotated[str, Query(description="Sort by field")] = "created_at",
sort_order: Annotated[str, Query(description="Sort order (asc/desc)")] = "desc",
status_filter: Annotated[str | None, Query(description="Filter by status")] = None,
) -> dict[str, list[ExtractionInfo]]:
"""Get all extractions for the current user."""
try:
@@ -100,7 +104,13 @@ async def get_user_extractions(
detail="User ID not available",
)
extractions = await extraction_service.get_user_extractions(current_user.id)
extractions = await extraction_service.get_user_extractions(
user_id=current_user.id,
search=search,
sort_by=sort_by,
sort_order=sort_order,
status_filter=status_filter,
)
except Exception as e:
raise HTTPException(

View File

@@ -1,6 +1,6 @@
"""Extraction repository for database operations."""
from sqlalchemy import desc
from sqlalchemy import asc, desc, or_
from sqlmodel import select
from sqlmodel.ext.asyncio.session import AsyncSession
@@ -55,3 +55,39 @@ class ExtractionRepository(BaseRepository[Extraction]):
.order_by(desc(Extraction.created_at)),
)
return list(result.all())
async def get_user_extractions_filtered(
self,
user_id: int,
search: str | None = None,
sort_by: str = "created_at",
sort_order: str = "desc",
status_filter: str | None = None,
) -> list[Extraction]:
"""Get extractions for a user with filtering, search, and sorting."""
query = select(Extraction).where(Extraction.user_id == user_id)
# Apply search filter
if search:
search_pattern = f"%{search}%"
query = query.where(
or_(
Extraction.title.ilike(search_pattern),
Extraction.url.ilike(search_pattern),
Extraction.service.ilike(search_pattern),
)
)
# Apply status filter
if status_filter:
query = query.where(Extraction.status == status_filter)
# Apply sorting
sort_column = getattr(Extraction, sort_by, Extraction.created_at)
if sort_order.lower() == "asc":
query = query.order_by(asc(sort_column))
else:
query = query.order_by(desc(sort_column))
result = await self.session.exec(query)
return list(result.all())

View File

@@ -545,9 +545,22 @@ class ExtractionService:
"updated_at": extraction.updated_at.isoformat(),
}
async def get_user_extractions(self, user_id: int) -> list[ExtractionInfo]:
"""Get all extractions for a user."""
extractions = await self.extraction_repo.get_by_user(user_id)
async def get_user_extractions(
self,
user_id: int,
search: str | None = None,
sort_by: str = "created_at",
sort_order: str = "desc",
status_filter: str | None = None,
) -> list[ExtractionInfo]:
"""Get all extractions for a user with filtering, search, and sorting."""
extractions = await self.extraction_repo.get_user_extractions_filtered(
user_id=user_id,
search=search,
sort_by=sort_by,
sort_order=sort_order,
status_filter=status_filter,
)
return [
{