CliffSafe helps low-income and gig workers understand exactly where a raise or extra hours causes a net loss in total compensation due to lost government benefits — SNAP, Medicaid, childcare subsidies, housing assistance. We run a Monte Carlo simulation to show the probability your income volatility hits that cliff this year, find the income sweet spot that maximizes real take-home, and explain it all in plain English via a Gemini-powered AI advisor.
Built in response to the One Big Beautiful Bill (signed July 4, 2025), which introduced $863B in Medicaid cuts, new work requirements, and more frequent eligibility checks — making the cliff steeper and harder to see coming.
| Layer | Technology |
|---|---|
| Backend | FastAPI + NumPy + Pydantic |
| Frontend | React 18 + Tailwind CSS + Recharts + Framer Motion |
| AI | Google Gemini API (gemini-2.5-flash, streaming SSE) |
- Python 3.10+
- Node 18+
- Google Gemini API key (
GEMINI_API_KEY)
./start.sh- Backend: http://localhost:8000
- Frontend: http://localhost:3000
- API docs: http://localhost:8000/docs
Backend
cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # then add your GEMINI_API_KEY
uvicorn app.main:app --reload --port 8000Frontend
cd frontend
npm install
npm startCopy backend/.env.example to backend/.env and fill in:
GEMINI_API_KEY=your_gemini_api_key_here
Get a free API key at https://aistudio.google.com/apikey
cliffsafe/
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI entry point, CORS
│ │ ├── config.py # Settings / .env loader
│ │ ├── schemas.py # Pydantic request/response models
│ │ ├── routes/
│ │ │ ├── calculator.py # POST /api/calculate
│ │ │ ├── benefits.py # GET /api/benefits/{state}/{household_size}
│ │ │ ├── optimizer.py # POST /api/optimize
│ │ │ ├── monte_carlo.py # POST /api/monte-carlo
│ │ │ └── advisor.py # POST /api/advisor (Gemini streaming SSE)
│ │ └── services/
│ │ ├── cliff_engine.py # Core cliff math + Monte Carlo (NumPy)
│ │ └── benefits_data.py # 2025 FPL thresholds by state/household
│ ├── requirements.txt
│ └── .env.example
├── frontend/
│ ├── public/
│ │ └── index.html
│ ├── src/
│ │ ├── components/
│ │ │ ├── IncomeForm.jsx # Input form
│ │ │ ├── CliffChart.jsx # Hero cliff curve visualization
│ │ │ ├── ResultsPanel.jsx # Cliff analysis results
│ │ │ ├── OptimizerCard.jsx # Income optimization strategies
│ │ │ ├── MonteCarloSection.jsx # Income volatility risk + distribution chart
│ │ │ ├── Loading.jsx # LoadingScreen, ResultsSkeleton, ButtonSpinner
│ │ │ └── AdvisorChat.jsx # Gemini advisor streaming UI
│ │ ├── pages/
│ │ │ ├── Home.jsx
│ │ │ ├── HowItWorks.jsx
│ │ │ ├── Calculator.jsx
│ │ │ └── Results.jsx
│ │ ├── services/
│ │ │ └── api.js # Axios instance + all API calls
│ │ ├── App.jsx
│ │ ├── index.css
│ │ └── index.js
│ └── package.json
├── start.sh
└── README.md
Calculate benefits cliff for a given income scenario. Returns net income curve (70 points, $10k–$80k), cliff points, benefit details, and effective marginal rate.
Body:
{
"gross_income": 28000,
"household_size": 2,
"state": "NC",
"employment_type": "self_employed",
"has_children": true
}Get benefit program thresholds for a state and household size.
Get income optimization strategies to preserve benefits eligibility.
Run 1000 income simulations, return cliff probability and 90% confidence interval.
Body:
{
"gross_income": 28000,
"household_size": 2,
"state": "NC",
"employment_type": "self_employed",
"has_children": true,
"n_simulations": 1000
}Stream a plain-English Gemini summary of the user's cliff situation via Server-Sent Events.
Body:
{
"gross_income": 28000,
"household_size": 2,
"state": "NC",
"employment_type": "self_employed",
"has_children": true,
"cliff_probability": 0.56
}Response: text/event-stream
data: {"text": "Based on your numbers..."}
data: {"text": " here's what you need to know..."}
data: [DONE]
-
/advisorendpoint — empathetic system prompt using user's actual cliff numbers - Error handling + input validation on all routes
- CORS config — allow production frontend URL (Vercel)
- Real cliff math in
cliff_engine.py— 2025 FPL-based thresholds, SNAP phase-out curves - Monte Carlo simulation — 1000 runs, 12-month lognormal income paths, gig vs salaried variance
- Real benefits thresholds by state/household in
benefits_data.py— all 50 states -
/advisorendpoint — Gemini API streaming via SSE - Wire real calc logic into
/calculateroute — net income curve + cliff detection -
POST /api/monte-carloroute -
POST /api/optimize— replaced hardcoded mock with real optimizer wired tocliff_engine.py: scans income curve to find the optimal reportable income (max total compensation), generates sized IRA/401(k)/SEP-IRA/FSA steps with realbenefits_preservedandnet_gaincomputed from actual benefit math, handles self-employed (SEP-IRA) andhas_children(Dependent Care FSA) scenarios
-
CliffChart.jsx— Recharts line chart showing income vs net compensation curve with cliff drop -
AdvisorChat.jsx— SSE streaming UI for Gemini advisor response -
IncomeForm.jsx— form polish, state dropdown, employment type selector -
ResultsPanel.jsx— display cliff points, benefits lost, effective marginal rate -
OptimizerCard.jsx— display optimization steps and net gain - Home page — hero section with tagline and CTA
- Loading states / skeleton UI while waiting on API
- Error state UI if API call fails
- Animated cliff drop on chart (Framer Motion)
- Color coding — green (safe zone) / red (cliff zone) on chart