7.9 KiB
CLAUDE.md — Repo ~/bin
Diese Datei richtet sich primär an künftige Claude-Coding-Sessions in diesem Repo, sekundär an Menschen. Architektur/Modul-Übersicht (Mermaid):
docs/ARCHITEKTUR.md. Vor Code-Änderungen dort das Komponenten- und Sequenzdiagramm lesen — jeder dort genannte Name existiert real im Code.
Projektüberblick
Finanzberatungs-Tool (Verzeichnis finance/): FastAPI-App (API + Web-GUI),
Postgres, Grafana-Dashboards. Importiert Kontoauszüge (PDF: VR/HVB/DKB;
CSV: VR/HVB/DKB), verwaltet Buchungen/Kategorien/Fixposten, rechnet
Kredit-Tilgungspläne und Liquiditäts-Szenarien durch. Läuft als Podman-Pod
finance_pod (3 Container) unter systemd --user, siehe
docs/ARCHITEKTUR.md Abschnitt 3 (Deployment). Aktuelle Version:
finance/VERSION (Single Source — siehe dort).
Zugehöriges Repo /home/wlfb/fb ist die Beratungsumgebung (Skills,
Gesprächsleitfäden für die Nutzung des Tools in der Finanzberatung selbst,
eigenes CLAUDE.md) — nicht der Code dieses Tools. Dieses Repo (~/bin)
enthält Quellcode, Deployment- und Betriebsskripte.
Betriebskommandos
Test-Suite (Basis-Erwartung: alle grün, dreistellige Anzahl):
cd finance && .venv/bin/python -m pytest -q
Deploy / Redeploy (baut das Image neu, erstellt Pod+Container neu, generiert systemd-Units, aktiviert den Service, wartet auf Bereitschaft):
./create_pod_finance.sh
Idempotent — erneutes Ausführen rotiert keine Secrets in einer
bestehenden .env (Ausnahme: FB_GUI_PASSWORD_HASH wird bei jedem Lauf mit
FB_PASSWORD synchron gehalten, siehe Passwort-Prozedur unten). Legacy-Pfad
~/bin/finance/.env wird beim ersten Lauf automatisch nach
~/.local/share/finance_pod/.env migriert.
Backup (kalt, kurze Downtime, Zielverzeichnis optional):
./backup_finance_pod.sh [ZIELDIR] # Default: ~/backups
Stoppt pod-finance_pod.service, sichert ~/.local/share/finance_pod
(inkl. .env) via tar czf im podman unshare-Namespace (Postgres-Daten
gehören auf dem Host der subuid-verschobenen Container-UID und sind sonst
unlesbar), startet den Service wieder, prüft Erreichbarkeit
(GET /login → 200) und Archiv-Integrität (.env, postgres-data,
grafana-data, data müssen enthalten sein), setzt chmod 600 (Archiv
enthält Secrets). Bei jedem Fehler läuft der Service danach trotzdem wieder
(EXIT-Trap).
Passwort ändern (GUI + Grafana teilen sich FB_PASSWORD):
- Vorzugsweg (Admin-Seite):
/adminin der GUI aufrufen — ändert altes Passwort gegen Grafana (services/admin.py::change_password), schreibt danach die.envin-place neu. Bestehende Sitzungen bleiben gültig (Session-Secret ändert sich nicht). - Handverfahren:
FB_PASSWORDin~/.local/share/finance_pod/.envvon Hand editieren (Wert single-quoted lassen!) und./create_pod_finance.sherneut ausführen — das Skript leitetFB_GUI_PASSWORD_HASHautomatisch neu ab und synchronisiert Grafana pergrafana cli admin reset-admin-password.
Parser-Werkzeuge (nur lokal, siehe DATENSCHUTZ unten):
cd finance
PYTHONPATH=. .venv/bin/python scripts/parser_audit.py tests/fixtures/dkb_beispiel.pdf
PYTHONPATH=. .venv/bin/python scripts/parser_vs_csv.py <pdf> <csv> [<csv>...]
parser_audit.py zeigt geparste Transaktionen + PDF-Rohtext einer Fixture.
parser_vs_csv.py vergleicht ein PDF-Parser-Ergebnis gegen CSV-Ground-Truth
(Betrag/Datum-Match, Gegenpartei/Verwendungszweck-Ähnlichkeit via
difflib). Beide geben echte Kontodaten auf der Konsole aus.
WICHTIGE REGELN für künftige Sessions
tests/fixtures/* = ECHTE Kontodaten — NIE committen oder zitieren.
finance/tests/fixtures/*.pdf, *.csv und expected_*.json sind reale
Kontoauszüge (via finance/.gitignore vom Repo ausgeschlossen). In Commits,
PR-Beschreibungen, Reports, Ledger-Einträgen oder Chat-Antworten dürfen
weder Dateiinhalte noch daraus abgeleitete Beträge/Namen/IBANs auftauchen.
Ausgaben von parser_audit.py/parser_vs_csv.py sind ausschließlich zur
lokalen Fehlersuche bestimmt, niemals zum Weiterreichen.
Decimal, nicht float. Geldbeträge sind überall decimal.Decimal
(DB-Spaltentyp Numeric(12,2), siehe models/tables.py::MONEY). Keine
float-Arithmetik für Beträge einführen (Rundungsfehler).
Deutsch. GUI-Texte, Fehlermeldungen, Templates, Commit-Messages und Beratungsinhalte sind auf Deutsch. Datumsformat TT.MM.JJJJ.
UX-Regel: Bedienelemente sichtbar, nicht versteckt. Formulare/Buttons
bleiben immer sichtbar und bedienbar; Sperrzustände werden über disabled
ausgedrückt, nicht durch Entfernen des Elements aus dem DOM. Fehler werden
inline auf derselben Seite gemeldet (Beispiel: routers/admin.py gibt bei
Validierungsfehlern dasselbe Template mit error-Kontext zurück statt
umzuleiten oder das Formular verschwinden zu lassen).
Fable-Testagent-Gate (Nutzer-Vorgabe). Jeder Task in einem
Superpowers-Plan (docs/superpowers/plans/*.md) braucht vor dem Commit eine
Abnahme durch den Fable-Testagenten (Faktencheck/Live-Test je nach Task).
Kein Task gilt als abgeschlossen, solange dieses Gate nicht durchlaufen ist
— auch nicht bei scheinbar trivialen Doku-/Config-Änderungen.
Superpowers-Workflow. Pläne liegen unter docs/superpowers/plans/
(ein Plan pro Ausbaustufe, z.B. 2026-07-20-ausbaustufe-4.md), gegliedert
in Tasks mit Checkbox-Tracking. Fortschritt/Entscheidungen/offene Punkte
werden fortlaufend im Ledger .superpowers/sdd/progress.md festgehalten
(ein Eintrag pro abgeschlossenem Task, inkl. Commit-Range und Fable-Befund).
Vor Arbeitsbeginn an einem Task: Plan-Datei UND Ledger lesen — der Ledger
enthält oft bindende Nutzerentscheidungen und Warnungen aus früheren Tasks
(z.B. Migrations-Hinweise), die nicht im Plan selbst stehen.
Versionierung via finance/VERSION. Einzige Versionsquelle (siehe
docs/ARCHITEKTUR.md Abschnitt 4). Speist Image-Tag
(create_pod_finance.sh), GUI-Footer und GET /api/version
(app/version.py::get_version). Bei einem Release: VERSION hochzählen,
bevor create_pod_finance.sh läuft — sonst baut das Skript ein Image mit
altem Tag.
.env unter ~/.local/share/finance_pod/, nicht im Repo-Checkout.
Secrets liegen unter $BIND_DIR/.env (chmod 600), niemals unter
finance/.env (Legacy-Pfad, wird migriert). Alle Werte darin sind
single-quoted zu schreiben (KEY='wert') — create_pod_finance.sh
sourced die Datei per set -a; . "$ENV_FILE"; set +a, und unquoted Werte
mit $ (z.B. der GUI-Passwort-Hash salt$digest) würden dabei fälschlich
shell-expandiert. Der API-Container mountet dieselbe Datei zusätzlich als
Einzeldatei-Bind-Mount nach /data/.env — das folgt dem Host-Inode, die
App muss sie in-place überschreiben (open im Modus r+, flock,
truncate — siehe services/admin.py::_rewrite_env_file), niemals über
Temp-Datei+rename (neuer Inode, vom laufenden Mount nicht mehr gesehen).
Host-seitige sed-Edits in create_pod_finance.sh selbst sind unkritisch,
weil das Skript die Container ohnehin bei jedem Lauf neu erstellt.
Disaster Recovery = BIND_DIR-Backup + Repo + Skript. Für vollständige
Wiederherstellung werden beide gebraucht: ein Backup von
~/.local/share/finance_pod (Secrets + Postgres-/Grafana-Daten, via
backup_finance_pod.sh) UND der Repo-Checkout ~/bin (Code für den
Image-Build, create_pod_finance.sh, finance/grafana/ für die
Provisioning-Mounts). Wiederherstellung: Backup nach
~/.local/share/finance_pod entpacken, dann ./create_pod_finance.sh
erneut ausführen (baut Image, erstellt Pod/Container/systemd-Units neu,
übernimmt vorhandene .env unverändert). Verifiziert in A2-Task 7
(Live-DR-Probe, siehe .superpowers/sdd/progress.md).
Weiterführend
- Architektur (Module, Funktionen, drei Mermaid-Diagramme):
docs/ARCHITEKTUR.md - Pläne:
docs/superpowers/plans/ - Fortschritts-Ledger:
.superpowers/sdd/progress.md - Beratungsumgebung (Nutzung des Tools, Skills):
/home/wlfb/fb(eigenesCLAUDE.mddort)