Der Eingangs-Abgleich vergleicht Betrag und Datum mit ein paar Tagen Spielraum – bewusst unscharf, damit eine per Kurzbefehl erfasste Zahlung nicht ein zweites Mal ankommt. Er merkt sich dabei, welchen Eintrag er schon verbraucht hat. Nur ruft der Bankabruf ihn JE ZEILE einzeln auf, und damit begann diese Menge jedes Mal von vorn: Derselbe Eintrag liess sich beliebig oft verbrauchen. Bei Revolut-Aufrundungen – dreimal 1.00 in drei Tagen – kam so nur die erste an, und der Saldo wich ab, ohne dass irgendwo etwas stand. Zwei Aenderungen: - Der Aufrufer kann die Menge jetzt ueber mehrere Aufrufe mitfuehren; der Bankabruf haelt eine je Konto. - Gegen andere BANK-Eintraege wird gar nicht mehr unscharf verglichen. Zwei Umsaetze derselben Quelle sind nie Dubletten voneinander – dort entscheidet die Kennung der Bank, und die ist exakt. Dazu ein Weg zurueck: Ein verschluckter Umsatz hinterliess keinen Eintrag, der naechste Abruf haette ihn also wieder geholt – nur liegt er dann vor dem Fenster des letzten Abrufs. "Aelteres nachholen" gibt es jetzt auch je Konto, wie beim Postfach. Nachgestellt und als Test festgehalten: dreimal 1.00 in drei Tagen, alle drei kommen an, Saldo -3.00. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Certain Finance
Selbstgehostete Finanzverwaltung für Privathaushalte. Budgets, mehrere Konten (EUR und CHF), ein konfigurierbares Dashboard und Import von Kontoauszügen – lauffähig in einem Proxmox-LXC, erreichbar über eine Web-UI hinter dem eigenen Nginx Proxy Manager.
Der interne Codename/Anzeigename steht zentral an einer Stelle (
web/src/brand.js,backend/app/branding.py); der Rest ist generisch.
Stack
- Backend: FastAPI · SQLAlchemy · SQLite · Alembic · argon2 · Server-Sitzungen (Cookie)
- Frontend: React 18 · Vite · reines JSX · react-i18next (DE/EN) · Inline-SVG-Icons
- Betrieb: ein systemd-Dienst (uvicorn) liefert API und gebautes Frontend auf einem Port aus
Entwicklung (lokal)
Backend (Terminal 1):
cd backend
python3 -m venv .venv && . .venv/bin/activate # Python 3.11+
pip install -r requirements.txt
APP_DATA_DIR=./data uvicorn app.main:app --reload --port 8000
Frontend (Terminal 2):
cd web
npm install
npm run dev # http://localhost:5173 (leitet /api an :8000 weiter)
Beim ersten Start wird ein Admin angelegt (Standard admin / changeme, per
APP_ADMIN_USERNAME / APP_ADMIN_PASSWORD änderbar).
Installation im LXC (Proxmox, Debian/Ubuntu)
git clone <repo-url> /opt/certain-finance
cd /opt/certain-finance
sudo ./deploy/install.sh
Danach im Nginx Proxy Manager einen Proxy-Host auf http://<LXC-IP>:<APP_PORT>
anlegen (HTTPS via Let's Encrypt). Updates: sudo ./deploy/update.sh.
Details: docs/ARCHITECTURE.md · Fahrplan: docs/ROADMAP.md