Files
bin/CLAUDE.md
2026-07-20 08:46:00 +02:00

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): /admin in der GUI aufrufen — ändert altes Passwort gegen Grafana (services/admin.py::change_password), schreibt danach die .env in-place neu. Bestehende Sitzungen bleiben gültig (Session-Secret ändert sich nicht).
  • Handverfahren: FB_PASSWORD in ~/.local/share/finance_pod/.env von Hand editieren (Wert single-quoted lassen!) und ./create_pod_finance.sh erneut ausführen — das Skript leitet FB_GUI_PASSWORD_HASH automatisch neu ab und synchronisiert Grafana per grafana 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 (eigenes CLAUDE.md dort)