"""Bounded vessel snapshot APIs for viewport-first consumers.""" from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession from app.api.v1.visualization import _parse_bbox, build_vessel_snapshot_response from app.db.session import get_db from app.services.vessel_ais_aggregation import MAX_SNAPSHOT_LIMIT router = APIRouter() @router.get("/snapshot") async def get_vessel_snapshot( bbox: Optional[str] = Query(None, description="Viewport bbox as lon_min,lat_min,lon_max,lat_max"), zoom: int = Query(..., ge=1, le=20, description="Current map zoom level"), type: Optional[str] = Query( None, description="Comma-separated vessel types: cargo,tanker,passenger,fishing,military,other", ), limit: int = Query(1000, ge=1, le=MAX_SNAPSHOT_LIMIT), since_minutes: int = Query(60, ge=1, le=1440), db: AsyncSession = Depends(get_db), ): if not bbox: raise HTTPException(status_code=400, detail="bbox is required") parsed_bbox = _parse_bbox(bbox) if parsed_bbox is None: raise HTTPException(status_code=400, detail="bbox is required") return await build_vessel_snapshot_response( db, bbox=parsed_bbox, zoom=zoom, type_filter=type, limit=limit, since_minutes=since_minutes, )