import json from pathlib import Path import pandas as pd from fastapi import APIRouter, HTTPException router = APIRouter(prefix="/api", tags=["benefits"]) _DATA_DIR = Path(__file__).parent / "data" with (_DATA_DIR / "member_insights.json").open() as f: _MEMBER_INSIGHTS = json.load(f) _SCHEDULE_TEXT = (_DATA_DIR / "schedule_response.txt").read_text(encoding="utf-8").strip() _HISTORICAL = pd.read_csv(_DATA_DIR / "historical_procedures.csv") _AVAILABLE = pd.read_csv(_DATA_DIR / "available_procedures.csv") _OPS = { "equals": lambda s, v: s == v, "ne": lambda s, v: s != v, "contains": lambda s, v: s.astype(str).str.contains(str(v), case=False, na=False), "gt": lambda s, v: s > v, "lt": lambda s, v: s < v, "ge": lambda s, v: s >= v, "le": lambda s, v: s <= v, } def _apply_filters_and_group(df: pd.DataFrame, filters_raw, group_by_raw) -> list[dict]: try: filters = json.loads(filters_raw) if isinstance(filters_raw, str) else (filters_raw or []) group_by = json.loads(group_by_raw) if isinstance(group_by_raw, str) else (group_by_raw or []) except json.JSONDecodeError as exc: raise HTTPException(status_code=400, detail=f"Invalid JSON in filters or group_by: {exc}") result = df.copy() for f in filters: col, op, val = f.get("column"), f.get("operator"), f.get("value") if col not in result.columns: raise HTTPException(status_code=400, detail=f"Unknown column: {col}") if op not in _OPS: raise HTTPException(status_code=400, detail=f"Unsupported operator: {op}") result = result[_OPS[op](result[col], val)] if group_by: missing = [c for c in group_by if c not in result.columns] if missing: raise HTTPException(status_code=400, detail=f"Unknown group_by columns: {missing}") numeric_cols = result.select_dtypes(include="number").columns.tolist() result = result.groupby(group_by)[numeric_cols].mean().reset_index() return result.to_dict(orient="records") @router.get("/member-insights") def member_insights(): return _MEMBER_INSIGHTS @router.get("/schedule") def schedule(): return {"result": _SCHEDULE_TEXT} @router.post("/historical-procedures") def historical_procedures(payload: dict): rows = _apply_filters_and_group( _HISTORICAL, payload.get("filters", "[]"), payload.get("group_by", "[]"), ) return {"result": rows} @router.post("/available-procedures") def available_procedures(payload: dict): rows = _apply_filters_and_group( _AVAILABLE, payload.get("filters", "[]"), payload.get("group_by", "[]"), ) return {"result": rows}