No description
  • Python 76.1%
  • HTML 19.1%
  • CSS 4.6%
  • Dockerfile 0.1%
Find a file
2026-09-01 16:59:30 +02:00
static Einnahmen-Filter + Kategorie-Farben + Transaktionen löschen 2026-09-01 15:05:23 +02:00
templates KI-Internet-Anreicherung via DuckDuckGo für Gegenparteien 2026-09-01 16:59:27 +02:00
tests Untrack test fixture 2026-09-01 16:59:30 +02:00
.dockerignore initial commit 2026-06-25 23:11:15 +02:00
.env.example initial commit 2026-06-25 23:11:15 +02:00
.gitignore Remove .secret_key from repo tracking (runtime artifact) 2026-09-01 15:05:32 +02:00
.secret_key KI-Internet-Anreicherung via DuckDuckGo für Gegenparteien 2026-09-01 16:59:27 +02:00
agent.py KI-Internet-Anreicherung via DuckDuckGo für Gegenparteien 2026-09-01 16:59:27 +02:00
app.py KI-Internet-Anreicherung via DuckDuckGo für Gegenparteien 2026-09-01 16:59:27 +02:00
camt_parser.py Refactor: SQLite storage, LLM cache, hardened parser, tests 2026-09-01 10:52:47 +02:00
docker-compose.yml initial commit 2026-06-25 23:11:15 +02:00
Dockerfile initial commit 2026-06-25 23:11:15 +02:00
entrypoint.sh Refactor: SQLite storage, LLM cache, hardened parser, tests 2026-09-01 10:52:47 +02:00
helpers.py KI-Internet-Anreicherung via DuckDuckGo für Gegenparteien 2026-09-01 16:59:27 +02:00
parsers.py Fix auto-mapping for Swiss bank export XLSX (PostFinance style) 2026-09-01 11:39:26 +02:00
pytest.ini Refactor: SQLite storage, LLM cache, hardened parser, tests 2026-09-01 10:52:47 +02:00
README.md KI-Internet-Anreicherung via DuckDuckGo für Gegenparteien 2026-09-01 16:59:27 +02:00
requirements-dev.txt Refactor: SQLite storage, LLM cache, hardened parser, tests 2026-09-01 10:52:47 +02:00
requirements.txt Add CSV and XLSX upload support with auto-detection 2026-09-01 11:12:56 +02:00
storage.py KI-Internet-Anreicherung via DuckDuckGo für Gegenparteien 2026-09-01 16:59:27 +02:00

Ausgaben-Tracker

KI-gestützter Ausgaben-Tracker für Schweizer Bankauszüge im CAMT-Format (.053/.054). Transaktionen werden per lokalem LLM (Ollama) automatisch kategorisiert.

Features

  • Multi-Format-Upload CAMT-XML (.053/.054), CSV oder XLSX. Spalten werden automatisch erkannt (deutsche + englische Header). Falls nicht möglich, Mapping-UI zum manuellen Zuordnen
  • KI-Kategorisierung Lokales LLM via Ollama klassifiziert jede Transaktion (Essen, ÖV, Miete, …)
  • Counterparty-Cache Wiederkehrende Gegenparteien (z.B. SBB, Coop) werden beim zweiten Mal aus dem Cache kategorisiert, ohne LLM-Call
  • Vorschläge verwalten Neue Kategorien vom LLM können akzeptiert, verworfen oder in eine bestehende Kategorie zusammengeführt werden. Bulk-Merge pro Ziel-Kategorie für mehrere Vorschläge gleichzeitig
  • Manuelles Editieren Kategorien jederzeit per Dropdown korrigierbar (Cache wird mit-aktualisiert)
  • Dashboard Ausgaben pro Kategorie und Monat als Balkendiagramm (Chart.js)
  • CSV-Export Alle Transaktionen als CSV herunterladen
  • Konfigurierbar Kategorien, Ollama-Server & Modell über Web-UI editierbar
  • Ollama-Verbindungstest Button in der Config prüft ob der Server erreichbar und das Modell installiert ist
  • Overlap-Warnung Beim Upload wird gewarnt wenn der Zeitraum bereits Transaktionen enthält
  • Multi-Währungs-Warnung Banner wenn Daten verschiedene Währungen enthalten
  • Docker Fertiges Docker-Setup mit docker compose
  • Tests 220 pytest-Tests (Parser, Storage-Concurrency, Agent, Routes, Merge, Suche, Bulk-Edit, Farben, Löschen, DuckDuckGo-Anreicherung)
  • KI-Internet-Anreicherung DuckDuckGo (Instant Answer API) liefert Wikipedia-Beschreibungen zu jeder Gegenpartei (z.B. "Migros" → "Schweizer Detailhandelskette"). Beschreibungen landen im LLM-Prompt für bessere Kategorisierung. Cache in SQLite, kein Ablauf, Rate-Limit 1.2s/Call. Privacy-Hinweis in der Config

Voraussetzungen

  • Ollama läuft auf einem Server (separater LXC oder gleicher Host)
  • Docker für den App-Container
  • Ein Ollama-Modell (z.B. llama3.2, qwen2.5, mistral)

Quickstart

# 1. Projekt klonen
git clone <repo-url> Ausgaben
cd Ausgaben

# 2. .env erstellen & anpassen
cp .env.example .env
# Bearbeite Ollama-URL und Modell:
# OLLAMA_URL=http://<deine-ollama-ip>:11434
# OLLAMA_MODEL=llama3.2

# 3. Starten
docker compose up -d --build

# 4. Öffnen
# http://<server-ip>:5000

Konfiguration

.env (Docker)

Variable Default Beschreibung
PORT 5000 Port, auf dem die App läuft
OLLAMA_URL http://localhost:11434 Ollama-Server-Adresse
OLLAMA_MODEL llama3.2 Zu nutzendes Ollama-Modell
BATCH_SIZE 5 Transaktionen pro LLM-Aufruf (Cache-Hits werden separat gezählt)

Datenbank

Alle Daten (Transaktionen, Kategorien, Vorschläge, Config, Counterparty-Cache) liegen in einer SQLite-DB unter DATA_DIR/ausgaben.db. Im Docker-Container ist das /data/ausgaben.db.

Schema:

  • categories(id, name UNIQUE)
  • transactions(id, date, amount, currency, counterparty, counterparty_iban, reference, type, category_id, category_confidence, category_is_new, updated_at)
  • suggestions(name, count, examples_json)
  • config(key, value)
  • counterparty_cache(counterparty, category_id, confidence, updated_at)

WAL-Modus aktiv → konfliktfreie parallele Reads, atomare Writes. Bei docker compose down bleiben die Daten erhalten. Zurücksetzen: docker compose down -v (löscht das Volume).

Tests

pip install -r requirements-dev.txt
pytest

Workflow

  1. Upload CAMT-XML, CSV oder XLSX per Drag & Drop auf die Startseite hochladen
  2. Parsen Die App extrahiert automatisch alle Transaktionen
    • Bei CSV/XLSX mit unbekannten Headern → Mapping-UI zur manuellen Spalten-Zuordnung
  3. Warnung Falls der Zeitraum bereits Transaktionen enthält, wird gewarnt
  4. Kategorisieren Button KI kategorisieren klicken das LLM klassifiziert (oder Cache-Hit). Neue Kategorien markiert das LLM als is_new
  5. Prüfen Ergebnisse kontrollieren, Kategorien bei Bedarf manuell korrigieren
  6. Speichern Transaktionen speichern sie landen in der SQLite-DB. is_new-Kategorien werden als "pending" gespeichert, nicht auto-erstellt
  7. Auswerten Unter /transactions und /stats Dashboard und Details einsehen
    • Einnahmen-Filter: Default werden nur Ausgaben angezeigt (positiver Betrag = ausgeblendet). Toggle "Einnahmen einblenden" in der Filter-Bar
    • Kategorie-Farben: Jede Kategorie hat eine deterministische Farbe (SHA256-Hash → HSL). Visueller Punkt vor jeder Kategorie, einheitliche Farben in Charts
    • Suche: Volltext-Suche über Gegenpartei, IBAN und Buchungstext (z.B. "Volg" findet alle Volg-Buchungen). Kombinierbar mit Kategorie- und Monats-Filter
    • Bulk-Edit: Mehrere Transaktionen auswählen + gemeinsam zu einer Kategorie zuordnen (Sticky Action-Bar unten)
    • Bulk-Delete: Mehrere Transaktionen auswählen + gemeinsam löschen (mit Bestätigungs-Modal, unwiderruflich)
    • Einzel-Delete: Pro Zeile ×-Button → confirm-Dialog → entfer
    • Neue Kategorie inline: Im Dropdown jeder Zeile "+ Neue Kategorie…" wählen — Name eingeben, fertig
  8. Vorschläge verwalten Unter /suggestions für jede LLM-vorgeschlagene Kategorie:
    • Akzeptieren: neue Kategorie offiziell bestätigen
    • Zusammenführen: in eine bestehende Kategorie überführen (z.B. "Streaming" → "Abos / Streaming"). Alle betroffenen Transaktionen + Counterparty-Cache werden umgezogen
    • Bulk-Merge: pro Ziel-Kategorie mehrere Vorschläge gleichzeitig per Checkbox auswählen und überführen
    • Ablehnen: Vorschlag entfernen (Transaktionen verlieren die Kategorie-Zuordnung)

Architektur

Ausgaben/
├── app.py              # Flask-Web-App (Routes & UI)
├── camt_parser.py      # CAMT.053/.054 XML-Parser (defusedxml)
├── parsers.py          # Multi-Format-Dispatcher (CAMT, CSV, XLSX + Header-Heuristik)
├── agent.py            # LLM-Agent (Ollama /api/chat, Cache, Retry)
├── storage.py          # SQLite-Storage (CRUD, Cache, Concurrency)
├── ausgaben.db         # SQLite-Datenbank (im DATA_DIR)
├── Dockerfile
├── docker-compose.yml
├── .env.example
├── entrypoint.sh
├── requirements.txt
├── requirements-dev.txt
├── pytest.ini
├── tests/              # pytest-Suite (92 Tests)
│   ├── conftest.py
│   ├── test_camt_parser.py
│   ├── test_parsers.py
│   ├── test_storage.py
│   ├── test_agent.py
│   ├── test_app.py
│   └── fixtures/
├── templates/          # Jinja2-Vorlagen
│   ├── base.html
│   ├── index.html
│   ├── categorize.html
│   ├── mapping.html
│   ├── transactions.html
│   ├── suggestions.html
│   ├── stats.html
│   └── config.html
└── static/
    └── style.css

Ohne Docker (Entwicklung)

python3 -m venv venv
source venv/bin/activate
pip install -r requirements-dev.txt
export DATA_DIR=$PWD  # DB im Projektordner
python app.py --port 5000

Ollama-Modell installieren (falls nicht vorhanden)

ollama pull llama3.2        # ~2 GB, schnell
ollama pull qwen2.5:7b      # ~4.5 GB, sehr guter JSON-Output
ollama pull mistral:7b       # ~4.1 GB, solide

Lizenz

MIT