Skip to content

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

SplitEasy — Expense-Splitting API with Debt Simplification

A backend API for splitting group expenses (like a Splitwise clone), built with FastAPI, MySQL, and JWT authentication, deployed end-to-end on AWS. The core feature isn't just tracking who paid what — it's calculating the minimum number of payments needed to settle an entire group, using a greedy debt-simplification algorithm.

What makes this interesting

Most "expense splitter" tutorials stop at tracking raw balances — who owes what, per expense. SplitEasy goes a step further: given a group with any number of people and any number of expenses, it computes the smallest possible set of payments needed to settle everyone up, rather than leaving users to work out a messy web of who-pays-whom themselves.

Example: in a 5-person trip with two shared expenses, SplitEasy correctly reduces the group's tangled balances down to exactly the payments needed — each person paying only the person who's actually owed money, with the total settlement math verified to the cent.

The project is also deployed as a real, live system — not just code that runs locally. The database lives on AWS RDS, the API runs on an AWS EC2 instance, and the two communicate over a properly configured security group, matching how a real backend service would actually be hosted.

Features

  • User authentication — registration with bcrypt-hashed passwords, JWT-based login, protected routes
  • Groups — create groups, add members by email, list your groups
  • Expenses — add expenses with either an equal split or a fully custom per-person split (validated to ensure custom splits sum to the total)
  • Balance tracking — see each group member's net balance (positive = owed money, negative = owes money)
  • Debt simplification — the core algorithm: computes the minimum-payment settlement plan for a group, regardless of how many expenses or people are involved
  • Cloud deployment — MySQL database on AWS RDS, API hosted on AWS EC2, connected via a dedicated security group

Architecture

main.py          All API endpoints, request handling, and route logic
database.py      SQLAlchemy engine/session setup, connects to MySQL (local or RDS)
models.py        Database table definitions: User, Group, GroupMember, Expense, ExpenseSplit
schemas.py       Pydantic request/response schemas -- defines exactly what each endpoint accepts and returns
auth.py          Password hashing (bcrypt) and JWT token creation/verification
create_tables.py One-time script to create all database tables

How the debt-simplification algorithm works

  1. Calculate net balances. For every expense, the person who paid is credited the full amount; every person included in the split (including the payer) is debited their individual share. The result is a single net number per person: positive if they're owed money overall, negative if they owe money.

  2. Greedily match the biggest creditor with the biggest debtor. Repeatedly find whoever is owed the most and whoever owes the most, and have the debtor pay the creditor as much as possible — either the full amount owed, or the full amount owing, whichever is smaller.

  3. Repeat until everyone is settled. Each round resolves at least one person completely (bringing them to a balance of zero), so the algorithm always terminates, and never produces more payments than strictly necessary.

This means a group with many small, overlapping expenses across many people still gets reduced to a short, clean list of payments — not a tangle of who-owes-whom-for-what.

API endpoints

Method Endpoint Description
POST /users/register Register a new user
POST /users/login Log in, receive a JWT access token
GET /users/me Get your own profile (requires auth)
POST /groups Create a new group
GET /groups List all groups you belong to
GET /groups/{id} Get one group's details and members
POST /groups/{id}/members Add a member to a group by email
POST /groups/{id}/expenses Add an expense (equal or custom split)
GET /groups/{id}/expenses List all expenses in a group
GET /groups/{id}/balances Get each member's net balance
GET /groups/{id}/settle Get the minimum-payment settlement plan

Full interactive documentation (Swagger UI) is auto-generated by FastAPI at /docs.

Running it locally

# set up
python -m venv venv
venv\Scripts\activate        # Windows
pip install -r requirements.txt

# set up a local MySQL database named 'spliteasy', then update
# DATABASE_URL in database.py with your credentials

# create the tables
python create_tables.py

# run the API
uvicorn main:app --reload

Visit http://127.0.0.1:8000/docs for the interactive API documentation.

Deployment

This project is deployed on AWS:

  • Database: AWS RDS (MySQL 8.4, free tier)
  • API server: AWS EC2 (Ubuntu, free tier), running the FastAPI app via Uvicorn
  • Networking: a dedicated security group allows the EC2 instance to reach the RDS database, separate from general public access rules

To deploy your own copy: provision an RDS MySQL instance and an EC2 instance in the same AWS account, copy the project files to the EC2 instance via scp, install dependencies, update database.py with the RDS endpoint, and run:

uvicorn main:app --host 0.0.0.0 --port 8000

What I'd improve with more time

  • Persistent hosting. Currently the API runs via a foreground uvicorn process over SSH; running it as a proper background service (e.g. with systemd or a process manager) would let it survive terminal disconnects and reboots.
  • Environment variables for secrets. The JWT secret key and database credentials are currently hardcoded for simplicity; a production version would load these from environment variables or a secrets manager.
  • Settlement history. Right now /settle calculates a plan but doesn't record when payments are actually made — adding a settlements table would let the app track real repayments over time, not just suggest them.

Tech stack

Python, FastAPI, SQLAlchemy, MySQL, JWT (python-jose), bcrypt (passlib), AWS RDS, AWS EC2.

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages