Skip to content

Latest commit

 

History

76 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Split Smart

A group expense-splitting backend that solves the part most tutorials skip: minimizing settlement transactions with a real graph algorithm, and modeling money the way production fintech code actually has to.

Python FastAPI Status


Overview

Split Smart lets a group of people track shared expenses and settle up with the minimum number of payments — not naive pairwise "everyone pays everyone" splitting, but an actual debt-simplification algorithm that collapses a group's tangled IOUs into the smallest possible set of transactions.

It's built as a portfolio-grade backend: the kind of service that's expected to run correctly under real usage, not just pass a demo.

Why this exists

Most expense-splitter builds stop at CRUD: create an expense, divide it evenly, done. Two decisions here are deliberately not that:

  • Debt simplification, not naive splitting. If A owes B, B owes C, and C owes A, a naive splitter creates three payments. This project scopes debts into connected components and resolves them with a greedy deque-based matching algorithm, so a tangled group settles in the minimum number of real transactions.
  • Money as Decimal, not float. Floating-point rounding errors in financial calculations are a well-known, entirely avoidable bug class. Every monetary value in this schema is Decimal from the ground up.

Key Features

  • Group and multi-user expense tracking with role-based membership
  • Debt-simplification engine (connected-component scoping + greedy deque matching) that minimizes settlement transactions
  • Financially correct money handling via Decimal throughout — no float-rounding bugs
  • Standardized, spec-compliant error responses (RFC 7807 problem details) instead of ad hoc error shapes
  • Domain-driven folder structure, not a flat everything-in-one-place layout

Tech Stack

Layer Technology
API framework FastAPI
Database PostgreSQL
Caching Redis
Background jobs Celery
Testing pytest
CI GitHub Actions

Architecture

The codebase follows a domain-driven structure rather than the typical flat models/, routes/, schemas/ split — code is grouped by business domain (users, groups, expenses, payments) so each domain owns its models, schemas, and logic together.

Directory structure:
└── aminishereai-split-smart/
    ├── README.md
    ├── features.md
    ├── LICENSE
    ├── pyproject.toml
    ├── requirements.txt
    ├── schemas.md
    ├── uv.lock
    ├── .python-version
    └── app/
        ├── main.py
        ├── core/
        │   ├── __init__.py
        │   ├── configs.py
        │   ├── database.py
        │   ├── lifespan.py
        │   ├── logging.py
        │   └── redis.py
        ├── src/
        │   ├── __init__.py
        │   ├── auth/
        │   │   ├── __init__.py
        │   │   ├── dependencies.py
        │   │   ├── exceptions.py
        │   │   ├── models.py
        │   │   ├── router.py
        │   │   └── services.py
        │   ├── expenses/
        │   │   ├── __init__.py
        │   │   ├── dependencies.py
        │   │   ├── exceptions.py
        │   │   ├── models.py
        │   │   ├── router.py
        │   │   └── services.py
        │   ├── groups/
        │   │   ├── __init__.py
        │   │   ├── dependencies.py
        │   │   ├── exceptions.py
        │   │   ├── models.py
        │   │   ├── router.py
        │   │   └── services.py
        │   └── payments/
        │       ├── __init__.py
        │       ├── dependencies.py
        │       ├── exceptions.py
        │       ├── models.py
        │       ├── router.py
        │       └── services.py
        └── utils/
            └── exceptions/
                ├── __init__.py
                ├── base.py
                ├── problems.py
                └── register.py

Data Model

Six core tables:

Table Purpose
Users Account records
Groups A collection of users sharing expenses
User_Group Membership join table, carries per-user role within a group
Expenses A recorded expense, amount stored as Decimal
Expense_Splits How a given expense is divided across group members
Payments Settlement transactions between users

Error Handling

All errors are returned as RFC 7807 application/problem+json responses — a consistent, standardized shape (type, title, status, detail) instead of one-off error formats per endpoint.

API Overview

(Representative — match to your actual route definitions.)

Method Endpoint Description
POST /groups Create a group
POST /groups/{id}/members Add a member
POST /expenses Record an expense and its splits
GET /groups/{id}/balances Current balances per member
POST /groups/{id}/settle Run debt simplification, return the minimal settlement plan

Getting Started

git clone https://github.com/aminishereai/split-smart.git
cd split-smart

python -m venv venv
source venv/bin/activate    # Windows: venv\Scripts\activate

pip install -r requirements.txt

# Create a .env file with:
# DATABASE_URL=postgresql://user:password@localhost:5432/splitsmart
# REDIS_URL=redis://localhost:6379/0


uvicorn app.main:app --reload

Project Status

This is an active build, not a finished product — shown here honestly rather than dressed up:

Done:

  • Full schema and domain-driven architecture
  • Debt-simplification algorithm
  • RFC 7807 error handling
  • Self-review pass that caught and fixed real bugs (bad queries, unawaited coroutines, misused HTTP exceptions, incorrect status codes)

In progress:

  • Async conversion
  • Redis caching layer
  • pytest test suite
  • Celery background jobs
  • Docker / production deployment setup

License

MIT

About

Expense-splitting backend with a graph-based debt-simplification algorithm and proper Decimal money handling — not naive pairwise splitting. In progress: async, tests, deployment.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages