Skip to content

Repository files navigation

Sumptus

Sumptus logo

Sumptus — Data Sovereignty. Self-hosted household expense tracking: who paid what, who owes whom, and where the money goes — by category, by month, by label. Built for a family or a shared flat; everything stays on your own machine.

Live demo

A public instance with fictional data (a two-person household with ~2 years of expenses) is hosted for review:

https://sumptus.cloudfr.net

  • No account needed: browse, add and edit freely.
  • The demo is reset every night — nothing you type there is kept, and no real data is ever connected to it.

Features

  • Expenses — date, label, description, amount, category, paid by, paid-from account
  • Label combobox — browse or type-to-filter your own label history (accent-insensitive), and label → category links that preselect the category as you type
  • Splitting — equal split, custom percentage default, or a custom amount per member (validated)
  • Balance — paid vs owed per member, with a simplified "who owes whom" settlement
  • Details — per-category, per-month and per-label breakdowns (label totals by year)
  • Charts — yearly totals, category donut, monthly trend, category × year stacked bars (Chart.js, bundled)
  • List tools — sort on every column, per-column filters (category, payer, amount range, date range)
  • Discreet mode — hides every amount (keeps the charts readable)
  • Settings — members, accounts (joint / personal), categories; inline editing
  • SQLite — zero external dependencies
  • Demo dataset — SEED_DEMO=1 inserts the fictional household on first boot (empty database only)
  • Backup — full JSON export / restore from the Settings page (all-or-nothing import; the desktop build saves through a native dialog), plus a CSV export of the expense list
  • Desktop builds (Windows / macOS) — standalone packages (Sumptus-Windows.zip, Sumptus-macOS.zip, attached to each release): no Python, no Docker, data next to the app

Stack

  • Backend: Python FastAPI + SQLite (stdlib, no ORM)
  • Frontend: vanilla JS + Chart.js (single page, bundled)
  • Deploy: Docker — private LAN compose + Traefik demo compose

Install (dev)

cd backend
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8020

Install (Docker)

Private LAN (no reverse proxy, never exposed to the internet):

cp .env.example .env   # adjust PORT / SEED_DEMO if needed
docker compose -f docker-compose.lan.yml up -d --build
# open http://localhost:8020

Public demo (Traefik + Let's Encrypt; create the DNS record first):

echo "DOMAIN=your-domain.example.com" >> .env
docker compose up -d --build

Desktop builds (Windows / macOS)

Each release ships standalone desktop packages:

  • Sumptus-Windows.zip: unzip anywhere (avoid Program Files), double-click Sumptus.exe — the app opens in its own window.
  • Sumptus-macOS.zip: unzip anywhere, double-click Sumptus.app (first launch: right-click → Open, unsigned build).

In both cases data lives in the data/ folder next to the app (on macOS it falls back to ~/Library/Application Support/Sumptus if that folder is read-only, e.g. launched from a mounted image); backup = copy that folder. Each zip includes user guides in French, English, German and Luxembourgish.

Configuration

Variable Default Description
PORT 8020 HTTP port
DB_PATH /data/sumptus.db SQLite database file (container: /data)
SEED_DEMO 0 1 = insert the fictional demo dataset on first boot (empty database only)

API endpoints

Method Path Description
GET /api/health Liveness + app name + version
GET /api/version Current version
GET/POST /api/members List / create members
PUT/DELETE /api/members/{id} Edit / delete member (delete blocked if expenses exist)
GET/POST /api/accounts List / create accounts (joint or personal)
PUT/DELETE /api/accounts/{id} Edit / delete account
GET/POST /api/categories List / create categories
PUT/DELETE /api/categories/{id} Edit / delete category
GET /api/expenses?month=YYYY-MM&category_id=N List expenses (filtered)
POST /api/expenses Create expense (equal or custom split)
PUT/DELETE /api/expenses/{id} Edit / delete expense
GET /api/balance Balances + net debts
GET /api/stats?month=YYYY-MM Totals, per category, per month
GET /api/stats/analytics Chart datasets (year / category / month)
GET /api/stats/labels Per-label totals and per-year breakdown
GET/PUT /api/settings Default split + dashboard panels
GET/PUT /api/label-categories Label → category links
GET /api/export Full JSON backup (members, accounts, categories, expenses + shares, settings)
POST /api/import Restore a JSON backup (replaces all data, all-or-nothing)
GET /api/export/csv Expense list as CSV (Excel-friendly)

Project structure

backend/
├── app/
│   ├── main.py          # FastAPI app (health/version endpoints, startup seed)
│   ├── db.py            # SQLite schema + connection
│   ├── seed.py          # fictional demo household (SEED_DEMO=1)
│   ├── routes/api.py    # API routes
│   └── static/          # frontend (single page) + brand assets
└── tests/               # pytest suite
desktop/                 # Desktop packages (PyInstaller: Windows + macOS)

License

MIT — see LICENSE.

About

Household expense tracking for families — who paid what, who owes whom, where the money goes. FastAPI + SQLite + vanilla JS + Docker.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages