Ship a new app version with broader analytics, restructured dashboards, and a server-rendered risk map. Frontend: - Add Overview, Demographic, Disease, and Environmental Health analysis pages - Add AnomalyMarkers, CalendarHeatmap, and MetricHeatmapTable components - Rebuild Alerts map onto server-rendered raster risk tiles; expand Monitoring, Trend, and District Comparison views - Extend API client, stores, and TypeScript types Backend: - Add environment router (pollutants, lag correlations) - Add risk_raster util serving XYZ 100m risk tiles - Expand cases endpoints (demographics, seasonality, diagnoses) and insights; harden auth and file-based loaders Data & tooling: - Add processed outpatient/inpatient/combined case parquet (LFS) - Add nested CLAUDE.md guides, pyrightconfig, and test updates
1.7 KiB
1.7 KiB
Routers — API Endpoints
Pattern
Each router file defines one APIRouter(prefix=..., tags=[...]) with typed endpoints.
from fastapi import APIRouter
from models import SomeResponse
router = APIRouter(prefix="/api/domain", tags=["domain"])
@router.get("/endpoint", response_model=SomeResponse)
async def get_something(...):
...
Conventions
- Return Pydantic models (
response_model=), never raw dicts - Use
Annotated[Type, Query(...)]/Path(...)for request params - Spatial queries use
scipy.spatial.KDTreefor nearest-neighbor lookups - GeoJSON parsing is delegated to
utils/geojson.py - Risk level mapping is in
utils/risk.py— userisk_value_to_level()not inline thresholds - Large repeated queries use
@lru_cache(fromfunctools) - Date helpers from
utils/date_helpers.py— alwaysget_latest_date(), never guess
File Map
| File | Domain |
|---|---|
risk.py |
Risk maps, grid detail, history (largest router, ~42 file reads) |
alerts.py |
Alert feed, stats |
cases.py |
Medical case queries (age, disease, district filters) |
analysis.py |
Trend analysis, statistics |
grid.py |
Grid metadata, elevation, population |
reports.py |
Report generation, export |
insights.py |
AI-generated insights |
chat.py |
Chatbot endpoint |
geocoded.py |
Geocoded case data |
Anti-Patterns
- Don't use sync I/O in
async def— useasync with db.get_connection()for DB - Don't catch bare
Exception— use specific HTTPException or let it propagate to middleware - Don't return raw GeoJSON dicts without Pydantic validation
- Don't inline risk thresholds — use
utils/risk.risk_value_to_level()