feat: add discoverable rig catalog

This commit is contained in:
ik
2026-09-21 19:43:17 +07:00
parent 5c1a7ffa01
commit b4585cee7e
5 changed files with 58 additions and 8 deletions
+28 -4
View File
@@ -6,7 +6,7 @@ from sqlalchemy.orm import selectinload
from ..dependencies import Db
from ..models import Bait, CatchReport, Fish, ModerationStatus, Rig, Spot, TackleItem, Waterbody
from ..schemas import BaitOut, FishOut, PaginatedTackleItemOut, RigOut, TackleItemOut, WaterbodyOut
from ..schemas import BaitOut, FishOut, PaginatedRigOut, PaginatedTackleItemOut, RigOut, RigSummaryOut, TackleItemOut, WaterbodyOut
router = APIRouter()
@@ -34,6 +34,12 @@ def _item_missing_fields(item: TackleItem) -> list[str]:
) if value is None]
def _rig_missing_fields(rig: Rig) -> list[str]:
return [field for field, value in (
("source_url", rig.source_url), ("source_checked_at", rig.source_checked_at),
) if value is None]
@router.get("/api/v1/tackle/items", response_model=PaginatedTackleItemOut)
def tackle_items(
db: Db,
@@ -69,14 +75,32 @@ def tackle_item(item_id: UUID, db: Db) -> TackleItemOut:
return TackleItemOut.model_validate(item).model_copy(update={"missing_fields": _item_missing_fields(item)})
@router.get("/api/v1/tackle/rigs", response_model=PaginatedRigOut)
def tackle_rigs(
db: Db,
limit: int = Query(48, ge=1, le=100),
offset: int = Query(0, ge=0),
) -> PaginatedRigOut:
query = select(Rig).options(selectinload(Rig.components))
total = db.scalar(select(func.count(Rig.id))) or 0
rigs = list(db.scalars(query.order_by(Rig.name, Rig.id).offset(offset).limit(limit)))
return PaginatedRigOut(
items=[RigSummaryOut(
id=rig.id, name=rig.name, source_system=rig.source_system,
source_external_id=rig.source_external_id, source_url=rig.source_url,
source_checked_at=rig.source_checked_at, missing_fields=_rig_missing_fields(rig),
component_count=len(rig.components),
) for rig in rigs],
total=total, limit=limit, offset=offset,
)
@router.get("/api/v1/tackle/rigs/{rig_id}", response_model=RigOut)
def rig_detail(rig_id: UUID, db: Db) -> RigOut:
rig = db.scalar(select(Rig).options(selectinload(Rig.components)).where(Rig.id == rig_id))
if rig is None:
raise HTTPException(status_code=404, detail="rig not found")
missing = [field for field, value in (
("source_url", rig.source_url), ("source_checked_at", rig.source_checked_at),
) if value is None]
missing = _rig_missing_fields(rig)
return RigOut(
id=rig.id, name=rig.name, source_system=rig.source_system,
source_external_id=rig.source_external_id, source_url=rig.source_url,