feat: search official records
CI / backend-and-migrations (push) Waiting to run
CI / astro-build (push) Waiting to run
CI / dependency-audit (push) Waiting to run
CI / compose-e2e (push) Waiting to run

This commit is contained in:
ik
2026-09-21 20:21:12 +07:00
parent f711b9ac0b
commit 55e5810e65
2 changed files with 12 additions and 4 deletions
+9 -2
View File
@@ -1,13 +1,14 @@
from datetime import datetime, timedelta, timezone
from fastapi import APIRouter, Query
from sqlalchemy import func, select
from fastapi import APIRouter, HTTPException, Query
from sqlalchemy import func, or_, select
from sqlalchemy.orm import joinedload
from ..config import settings
from ..dependencies import Db
from ..models import (
CatchReport,
Bait,
CommunityImportRun,
DataSource,
ExternalObservation,
@@ -117,9 +118,12 @@ def records(
fish: str | None = None,
waterbody: str | None = None,
category: str | None = None,
q: str | None = None,
limit: int = Query(50, ge=1, le=100),
offset: int = Query(0, ge=0),
) -> PaginatedOfficialRecordOut:
if q is not None and len(q) > 100:
raise HTTPException(status_code=422, detail="record search query is too long")
query = select(CatchReport).options(
joinedload(CatchReport.fish),
joinedload(CatchReport.waterbody),
@@ -131,6 +135,9 @@ def records(
query = query.join(CatchReport.waterbody).where(Waterbody.slug == waterbody)
if category:
query = query.where(CatchReport.raw_payload["category"].as_string() == category)
if q and q.strip():
needle = f"%{q.strip()}%"
query = query.outerjoin(Bait, CatchReport.bait_id == Bait.id).where(or_(CatchReport.player_name.ilike(needle), Bait.name.ilike(needle)))
total = db.scalar(
query.with_only_columns(func.count(CatchReport.id), maintain_column_froms=True).order_by(None)
) or 0