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
48 lines
1.7 KiB
Markdown
48 lines
1.7 KiB
Markdown
# Routers — API Endpoints
|
|
|
|
## Pattern
|
|
|
|
Each router file defines one `APIRouter(prefix=..., tags=[...])` with typed endpoints.
|
|
|
|
```python
|
|
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.KDTree` for nearest-neighbor lookups
|
|
- GeoJSON parsing is delegated to `utils/geojson.py`
|
|
- Risk level mapping is in `utils/risk.py` — use `risk_value_to_level()` not inline thresholds
|
|
- Large repeated queries use `@lru_cache` (from `functools`)
|
|
- Date helpers from `utils/date_helpers.py` — always `get_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` — use `async 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()`
|