Bound admin list endpoint limits, add status filter to pending-transactions (B-45)

/admin/rounds and /admin/audit-log accepted any limit, including -1 (which
SQLite treats as "no limit"), and /admin/pending-transactions had no limit
at all -- it grows without end. Add Query(default=..., ge=1, le=500) to all
three, plus an optional status filter on pending-transactions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-27 16:10:53 +02:00
co-authored by Claude Sonnet 5
parent a574db0d93
commit 6045c89ed0
4 changed files with 106 additions and 21 deletions
+11 -6
View File
@@ -1,7 +1,7 @@
import json
import secrets
from fastapi import APIRouter, Depends, Header, HTTPException, status
from fastapi import APIRouter, Depends, Header, HTTPException, Query, status
from pydantic import BaseModel, Field, field_validator
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
@@ -242,7 +242,9 @@ class AdminRoundResponse(BaseModel):
@router.get("/rounds", response_model=list[AdminRoundResponse], dependencies=[Depends(require_admin)])
async def list_rounds(session: AsyncSession = Depends(get_session), limit: int = 50) -> list[AdminRoundResponse]:
async def list_rounds(
session: AsyncSession = Depends(get_session), limit: int = Query(default=50, ge=1, le=500)
) -> list[AdminRoundResponse]:
rounds = (await session.scalars(select(Round).order_by(Round.id.desc()).limit(limit))).all()
winner_ids = {r.winner_user_id for r in rounds if r.winner_user_id is not None}
winners = {}
@@ -282,7 +284,7 @@ class AdminAuditLogResponse(BaseModel):
"/audit-log", response_model=list[AdminAuditLogResponse], dependencies=[Depends(require_admin)]
)
async def list_audit_log(
session: AsyncSession = Depends(get_session), limit: int = 200
session: AsyncSession = Depends(get_session), limit: int = Query(default=200, ge=1, le=500)
) -> list[AdminAuditLogResponse]:
entries = (await session.scalars(select(AuditLog).order_by(AuditLog.id.desc()).limit(limit))).all()
return [
@@ -319,10 +321,13 @@ class AdminPendingTransactionResponse(BaseModel):
)
async def list_pending_transactions(
session: AsyncSession = Depends(get_session),
limit: int = Query(default=50, ge=1, le=500),
status_filter: str | None = Query(default=None, alias="status"),
) -> list[AdminPendingTransactionResponse]:
entries = (
await session.scalars(select(PendingTransaction).order_by(PendingTransaction.id.desc()))
).all()
query = select(PendingTransaction).order_by(PendingTransaction.id.desc())
if status_filter is not None:
query = query.where(PendingTransaction.status == status_filter)
entries = (await session.scalars(query.limit(limit))).all()
return [
AdminPendingTransactionResponse(
id=p.id,