A full-stack personal finance platform for tracking expenses, planning monthly budgets, visualizing spending trends, and forecasting future expenses with machine learning.
ExpenseKeeper combines a React frontend, an Express + MongoDB backend, and a Python FastAPI ML service to deliver end-to-end expense management with predictive analytics.
- Overview
- Architecture
- Core Features
- Tech Stack
- Project Structure
- Getting Started
- Environment Variables
- Run the Application
- API Overview
- Machine Learning Summary
- Development Notes
- Scripts
- Author
ExpenseKeeper is built as a production-style academic project focused on practical personal finance workflows:
- Secure authentication (JWT + OAuth + CAPTCHA)
- Expense CRUD with category/date filtering and analytics
- Monthly budget bucket planning with allocation/spending tracking
- Dashboard and chart-based insights
- ML-powered multi-month category predictions
The application is split into three services:
-
Frontend (
frontend/)- React + Vite single-page application
- Routing, auth context, charts, forms, and responsive UI
-
Backend (
backend/)- Express 5 API with MongoDB (Mongoose)
- JWT auth, Google/Discord OAuth, Turnstile verification, validation, rate limiting, and ML proxy
-
ML Service (
mlModel/)- FastAPI-based inference service with XGBoost model
- Category-level future expense forecasting with guardrails
- JWT login/registration with bcrypt password hashing
- OAuth 2.0 (Google and Discord)
- Cloudflare Turnstile CAPTCHA on login/register
- Redis-backed rate limiting (general + auth-specific)
- Helmet security headers + CORS controls
- Profile fetch/update endpoints (
name,email,password,monthlyBudget,userType) - Separate user metadata endpoint for onboarding flows
- OAuth users handled safely for password management
- Create, list, update, delete expenses
- Category/date/search filtering
- Visual analytics and period summaries
- Monthly bucket allocation workflow
- Budget month summary (allocated, spent, remaining)
- Allocation validation against configured monthly budget limits
- 1-12 month forecasting via XGBoost
- Category-wise prediction outputs
- Budget-aware and user-type-aware modeling
- Smart guardrails for realistic projections
- Frontend: React, Vite, React Router, Recharts, TailwindCSS, DaisyUI, Axios, React Hot Toast, Lucide
- Backend: Node.js, Express 5, MongoDB, Mongoose, JWT, bcrypt, Zod, Axios, Helmet, Morgan
- Security: Cloudflare Turnstile, CORS, Redis + rate-limit middleware
- ML: Python, FastAPI, XGBoost, scikit-learn, pandas, numpy, Optuna
ExpenseKeeper/
├── backend/ # Express API server
│ ├── src/
│ │ ├── config/
│ │ ├── controllers/
│ │ ├── middleware/
│ │ ├── mlServices/
│ │ ├── models/
│ │ ├── routes/
│ │ ├── utils/
│ │ ├── validators/
│ │ └── server.js
│ └── package.json
├── frontend/ # React + Vite application
│ ├── public/
│ ├── src/
│ │ ├── components/
│ │ ├── contexts/
│ │ ├── lib/
│ │ ├── pages/
│ │ ├── styles/
│ │ ├── App.jsx
│ │ └── main.jsx
│ └── package.json
├── mlModel/ # FastAPI + XGBoost service
│ ├── ml_api.py
│ ├── predict_expense.py
│ ├── train_model.py
│ ├── requirements.txt
│ └── expense_forecast_model.json
├── SECURITY.md
└── README.md
- Node.js v16+
- Python v3.9+
- MongoDB (local or Atlas)
- Redis/Upstash Redis (recommended for production-like setup)
cd backend
npm installCreate backend/.env (see full variables below).
cd frontend
npm installCreate frontend/.env (see full variables below).
cd mlModel
python -m venv venv
# Windows
venv\Scripts\activate
# macOS/Linux
# source venv/bin/activate
pip install -r requirements.txtNODE_ENV=development
PORT=5000
MONGODB_URI=your_mongodb_uri
JWT_SECRET=your_jwt_secret
JWT_EXPIRE=7d
ML_API_URL=http://127.0.0.1:8000
CORS_ORIGIN=http://localhost:5173
UPSTASH_REDIS_REST_URL=your_upstash_redis_url
UPSTASH_REDIS_REST_TOKEN=your_upstash_redis_token
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
DISCORD_CLIENT_ID=your_discord_client_id
DISCORD_CLIENT_SECRET=your_discord_client_secret
DISCORD_REDIRECT_URI=http://localhost:5000/api/auth/discord/callback
TURNSTILE_SECRET_KEY=your_turnstile_secret_keyVITE_API_TARGET=http://localhost:5000
VITE_ML_API_URL=http://127.0.0.1:8000
VITE_GOOGLE_CLIENT_ID=your_google_client_id
VITE_DISCORD_CLIENT_ID=your_discord_client_id
VITE_DISCORD_REDIRECT_URI=http://localhost:5173/discord/callback
VITE_TURNSTILE_SITE_KEY=your_turnstile_site_keyRun all three services in separate terminals.
cd backend
npm run devcd frontend
npm run devcd mlModel
uvicorn ml_api:app --reload --host 0.0.0.0 --port 8000- Frontend:
http://localhost:5173 - Backend:
http://localhost:5000 - ML API:
http://127.0.0.1:8000
GET /health- backend service health check
POST /registerPOST /loginPOST /googlePOST /discordGET /discord/callback
GET /profilePATCH /profileDELETE /profile/deletePATCH /meta
GET /POST /PATCH /:idDELETE /:id
GET /monthPUT /monthGET /summary
POST /
- Universal XGBoost regressor trained on multi-profile spending behavior
- Forecast horizon supports multiple future months
- Features include lags, rolling statistics, trend indicators, seasonality, budget context, and user-type signals
- Guardrails cap unrealistic swings for fixed-cost categories and bound variable categories
For model internals and training details, see mlModel/README.md.
- In development, Redis caching for prediction responses is typically disabled to speed iteration.
- Frontend includes backend/ML health checks to handle sleeping deployments with user-facing wait/retry flows.
- Validation is handled with Zod schemas on backend routes.
npm run dev- run with nodemonnpm start- run with Node.js
npm run dev- start Vite dev servernpm run build- production buildnpm run preview- preview production buildnpm run lint- run ESLint
- Sumeet Dutta (with project collaborator Sahil Kumar)
- Repository: ExpenseKeeper
- Live App: https://expense-keeper-two.vercel.app/
For deeper implementation details, refer to:
backend/README.mdfrontend/README.mdmlModel/README.md