feat: filter external moderation queue
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s

This commit is contained in:
ik
2026-09-12 21:37:10 +07:00
parent 6e18e8e565
commit 8e419c1832
7 changed files with 93 additions and 10 deletions
+24 -3
View File
@@ -15,7 +15,7 @@ import httpx
from fastapi import Depends, FastAPI, File, Header, HTTPException, Query, Request, Response, UploadFile
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from sqlalchemy import func, select
from sqlalchemy import func, or_, select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session, joinedload
@@ -178,7 +178,11 @@ def _external_out(item: ExternalObservation) -> ExternalObservationOut:
def admin_external_observations(
db: Db, _: Annotated[str, Depends(_admin)],
status: Literal["staged", "mapped", "ready", "published", "rejected", "review"] | None = None,
source_system: str | None = None, limit: int = Query(50, ge=1, le=200), offset: int = Query(0, ge=0),
source_system: str | None = None,
completeness: Literal["all", "complete", "incomplete"] = "all",
order: Literal["newest", "oldest"] = "newest",
q: str | None = Query(None, max_length=100),
limit: int = Query(50, ge=1, le=200), offset: int = Query(0, ge=0),
) -> list[ExternalObservationOut]:
query = select(ExternalObservation).options(
joinedload(ExternalObservation.fish), joinedload(ExternalObservation.waterbody),
@@ -189,7 +193,24 @@ def admin_external_observations(
query = query.where(ExternalObservation.status == status)
if source_system:
query = query.where(ExternalObservation.source_system == source_system)
items = db.scalars(query.order_by(ExternalObservation.last_seen_at.desc(), ExternalObservation.id.desc()).offset(offset).limit(limit))
if completeness == "complete":
query = query.where(
ExternalObservation.x.is_not(None), ExternalObservation.y.is_not(None),
ExternalObservation.weight_g.is_not(None),
)
elif completeness == "incomplete":
query = query.where(or_(
ExternalObservation.x.is_(None), ExternalObservation.y.is_(None),
ExternalObservation.weight_g.is_(None),
))
if q and q.strip():
term = q.strip()
query = query.where(or_(
ExternalObservation.fish_name.icontains(term, autoescape=True),
ExternalObservation.waterbody_name.icontains(term, autoescape=True),
))
direction = ExternalObservation.last_seen_at.asc() if order == "oldest" else ExternalObservation.last_seen_at.desc()
items = db.scalars(query.order_by(direction, ExternalObservation.id.desc()).offset(offset).limit(limit))
return [_external_out(item) for item in items]