fix(todos): datetime query params typés FastAPI, ORDER BY déterministe
- Changer due_after/due_before de str | None vers datetime | None pour typage FastAPI - FastAPI parse et valide automatiquement, retourne 422 si format invalide (pas 500) - Supprimer le parsing manuel datetime.fromisoformat() qui levait ValueError brute - Ajouter ORDER BY déterministe: due_date ASC NULLS LAST, created_at DESC évite les réordonnances aléatoires entre requêtes PostgreSQL Tests: 15/15 passent ✓ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -18,8 +18,8 @@ async def list_todos(
|
|||||||
status: str | None = "pending",
|
status: str | None = "pending",
|
||||||
priority: str | None = None,
|
priority: str | None = None,
|
||||||
tag: str | None = None,
|
tag: str | None = None,
|
||||||
due_after: str | None = None,
|
due_after: datetime | None = None,
|
||||||
due_before: str | None = None,
|
due_before: datetime | None = None,
|
||||||
limit: int = 200,
|
limit: int = 200,
|
||||||
session: AsyncSession = Depends(get_session),
|
session: AsyncSession = Depends(get_session),
|
||||||
):
|
):
|
||||||
@@ -33,13 +33,14 @@ async def list_todos(
|
|||||||
if tag:
|
if tag:
|
||||||
conditions.append(TodoItem.tags.contains([tag]))
|
conditions.append(TodoItem.tags.contains([tag]))
|
||||||
if due_after:
|
if due_after:
|
||||||
conditions.append(TodoItem.due_date >= datetime.fromisoformat(due_after))
|
conditions.append(TodoItem.due_date >= due_after)
|
||||||
if due_before:
|
if due_before:
|
||||||
conditions.append(TodoItem.due_date <= datetime.fromisoformat(due_before))
|
conditions.append(TodoItem.due_date <= due_before)
|
||||||
|
|
||||||
stmt = select(TodoItem)
|
stmt = select(TodoItem)
|
||||||
if conditions:
|
if conditions:
|
||||||
stmt = stmt.where(and_(*conditions))
|
stmt = stmt.where(and_(*conditions))
|
||||||
|
stmt = stmt.order_by(TodoItem.due_date.asc().nulls_last(), TodoItem.created_at.desc())
|
||||||
stmt = stmt.limit(limit)
|
stmt = stmt.limit(limit)
|
||||||
result = await session.execute(stmt)
|
result = await session.execute(stmt)
|
||||||
return result.scalars().all()
|
return result.scalars().all()
|
||||||
|
|||||||
Reference in New Issue
Block a user