Finance Audit – Persönlicher CFO-Bericht
Wandle einen Ordner mit rohen Kontoauszugsdateien in einen Persönlichen CFO-Bericht um: verifizierte Daten plus eine erzählerische Ebene, die beantwortet, Was ist passiert? Warum? Was sollte ich als Nächstes tun?
Präzision an erster Stelle: Beträge werden wörtlich gelesen und mit dem laufenden Saldo abgeglichen – nichts wird erfunden.
Bankenunabhängig. Funktioniert mit jedem Konto- oder Kontenexport, sofern eine Transaktionsliste vorhanden ist. Spalten, Kopfzeilen und Datumsformat (DMY/MDY/YMD) werden pro Datei automatisch erkannt; der Händler-/Gegenpartei-Reiniger ist schienenunabhängig (UPI, POS, ACH, SEPA, Karte, Überweisung, …). Nichts ist fest auf eine bestimmte Bank codiert – du bestätigst die automatisch erkannte Zuordnung und passt die Kategorie-Schlüsselwörter an.
Pipeline (5 Stufen)
ingest -> parse -> categorize (Schleife bis >=99 %) -> analyze -> report (serve + hot reload)
Die Skripte befinden sich in diesem Skill. Führe sie gegen den Prüf-Ordner (audit folder) des Benutzers aus (den Ordner, der die Kontoauszugsdateien enthält). Setze zuerst zwei Variablen:
SKILL="<absoluter Pfad zu diesem Skill-Verzeichnis>" # der Ordner, der diese SKILL.md enthält
ROOT="<absoluter Pfad zum Prüf-Ordner>" # wo die Kontoauszugsdateien sind
Datenschutz – niemals echte Daten committen
Alle Kontoauszugsdateien, Kontostände, Erzählungen und generierten Ausgaben bleiben lokal in ROOT/. Das Skill-Repository liefert nur Vorlagen, Beispielkonfiguration und Dummy-Testdaten (assets/fixtures/sample_analysis.json).
Gitignoriert (niemals pushen): output/ (einschließlich report.html, analysis.json, audit.db), Kontoauszugsdateien und Live-Dateien wie config/mapping.json / Override-Dateien.
Optionale Bezeichnungen in config/mapping.json: account_label oder account_last4 für die Seitenleisten-Fußzeile (Standard: „Primary account"). Geschäftsanzeigename in config/business.json → display_name (Standard: „Business").
Gehe davon aus, dass die Kontoauszugsdateien bereits in ROOT heruntergeladen wurden (PDF / XLSX / XLS / CSV / TXT).
Wähle die Laufzeitumgebung (der Benutzer bevorzugt Node.js):
- Node verwenden, wenn
nodeverfügbar ist UND keine Eingabe eine PDF ist. - Python verwenden, wenn eine Eingabe eine PDF ist (Node-Pfad kann PDF nicht parsen) oder
nodenicht verfügbar ist.
Erkenne und installiere Abhängigkeiten:
# Node-Pfad (bevorzugt)
command -v node && node --version # benötigt Node >= 22 für integriertes SQLite
( cd "$ROOT" && npm install xlsx ) # NUR für .xls/.xlsx; CSV/TXT benötigen nichts
# Python-Pfad (Fallback / erforderlich für PDF)
python3 --version
pip install openpyxl "xlrd==2.0.1" pdfplumber pandas # + pandas für die Analyze-Stufe
Definiere, wie du eine Stufe aufrufst ($STAGE = ingest|parse|categorize|analyze|report):
# Node: node "$SKILL/scripts/node/$STAGE.mjs" --root "$ROOT" [Argumente]
# Python: python3 "$SKILL/scripts/python/$STAGE.py" --root "$ROOT" [Argumente]
Schritt 1 – Ingest & Erkennung
node "$SKILL/scripts/node/ingest.mjs" --root "$ROOT" # oder python3 .../ingest.py --root "$ROOT"
Dies zeigt eine Vorschau jeder Datei an und schreibt config/mapping.json mit einer automatisch erkannten Kopfzeile, Spaltenrollen und einem expliziten date_format. Lies die Vorschau und überprüfe mapping.json – Banken unterscheiden sich. Wenn ein Eintrag einen _date_note hat, war die Datumsreihenfolge mehrdeutig (z. B. 03/04/2024); bestätige date_format mit dem Benutzer. Jeder Dateieintrag benötigt: header_row, data_start_row, date_format (ein strptime-Muster wie %d/%m/%Y oder auto), columns (Rolle → 0-basierter Index) und amount_mode:
debit_credit– separate Spalten für Lastschrift + Gutschrift (am häufigsten)signed– eineamount-Spalte, deren Vorzeichen die Richtung angibtamount_type– eineamount-Spalte plus einetype-Spalte mit DR/CR
Korrigiere falsche Indizes vor dem Parsen.
Schritt 2 – Parsen, normalisieren, deduplizieren, validieren
node "$SKILL/scripts/node/parse.mjs" --root "$ROOT" # oder .../parse.py
Schreibt output/audit.db (SQLite). Die Aufteilung in Soll/Haben wird aus dem signierten Betrag abgeleitet, sodass sie immer mit der Saldenkette übereinstimmt (korrekte Behandlung von Rückerstattungen, die als negative Lastschriften codiert sind). Erzwinge, dass die Integritätsprüfung BESTANDEN hat (oder n/a, wenn keine Saldenspalte vorhanden ist). Wenn sie FEHLSCHLÄGT:
- Überprüfe erneut die Spalten in
mapping.json/data_start_row/date_format. - Lies erneut die Ingest-Standardausgabe-Vorschau (führe Ingest ggf. erneut aus); bestätige, dass du keine Kopf-/Fußzeilen einbezogen hast.
- Ein pro-Datei
chain_issues > 0zeigt auf die genauen Zeilen, die falsch geparst wurden.
Fahre nicht mit der Kategorisierung fort, bis das Parsen abgestimmt ist.
Schritt 3 – Kategorisieren (Schleife, bis >= 99 % nach Wert)
cp "$SKILL/config/categories.example.json" "$ROOT/config/categories.json" # nur beim ersten Durchlauf
# Für ein Geschäfts-/Freelancer-Konto zusätzlich:
cp "$SKILL/config/business.example.json" "$ROOT/config/business.json" # dann bearbeiten
node "$SKILL/scripts/node/categorize.mjs" --root "$ROOT" # oder .../categorize.py
Regelpriorität: overrides.json > business.json > categories.json; höchste priority gewinnt. Die Kategorisierung erfolgt skriptgesteuert; erreiche 99 % wie folgt:
- Führe
categorizeaus. Lies die Abdeckungszusammenfassung undoutput/uncategorized.csv(Händler gruppiert, größter Wert zuerst). - Füge für Händler, deren Identität aus der Erzählung offensichtlich ist, selbst Regeln zu
config/overrides.jsonhinzu (siehe Format unten) – frage nicht nach. - Stelle bei mehrdeutigen Händlern (unklar, wer/was, oder persönlich vs. geschäftlich unklar) eine kurze Frage an den Benutzer und füge dann die Regel hinzu.
- Führe
categorizeerneut aus. Wiederhole, bis die Werteabdeckung ≥ 99 % erreicht ist.
config/overrides.json-Format:
{ "rules": [
{ "keywords": ["ACME", "ACME CORP"], "primary": "Income", "sub": "Acme retainer", "when": "credit" },
{ "keywords": ["BIGRENT"], "primary": "Housing", "sub": "Rent", "is_business": 0 }
] }
Ziele darauf ab, dass jede Transaktion einen primary_cat und sub_cat trägt. Der faktische P2P-Gegenpartei-Fallback kennzeichnet Überweisungen, zählt aber als „überprüfungsbedürftig"; wandle die wichtigen in echte Regeln um.
Schritt 4 – Analysieren (output/analysis.json erstellen)
python3 "$SKILL/scripts/python/analyze.py" --root "$ROOT"
Berechnet Geschäftsjahres-Scheiben, Kategorieberichte, CFO-Erzählung, Einkommensentwicklung, Ausgabenübersicht, Problembereiche und Geschäfts-Nachbesprechung aus output/audit.db. Schreibt output/analysis.json (und optional findings.md lokal – niemals committen).
Erfordert pandas. Passe config/business.json → display_name für den Geschäftsbereich-Label an (Standard: „Business").
Schritt 5 – Bericht generieren (serve + hot reload + automatisch öffnen)
python3 "$SKILL/scripts/python/report.py" --root "$ROOT" --serve
Erstellt output/report.html aus analysis.json + eingebetteten Ledger-Zeilen. Mit --serve wird http://127.0.0.1:8765/ geöffnet und lädt bei Änderungen an der Datenbank/Konfiguration neu (führt Analyse neu aus + rendert neu). Verwende --refresh-analysis, um bei einem einmaligen Build eine erneute Analyse zu erzwingen.
Bericht-UI (output/report.html) – Money.Audit Hybrid-Dashboard
Hülle: abgerundeter App-Rahmen, helle Seitenleiste mit Geschäftsjahresliste + Abschnittsnavigation (Scroll-Spy), volle Breite Hauptspalte. Titel: Was zählt an deinem Geld.
Look: Fraunces Serif + Spline Sans UI; warme Cremefarbe (#f7f6f3), goldener Akzent. Nicht generisches graues SaaS.
Abschnitte (Seitenleiste): Übersicht, Einkommensentwicklung, monatliche Ausgaben, Problembereiche, Geschäfts-Nachbesprechung, Bargeld & Bewegungen, Aktionsplan, Alle Kategorien, Ledger (Suche + Filter).
Daten eingebettet: const ANALYSIS = … und const LEDGER = … – kein externer Abruf. Fußzeile der Seitenleiste zeigt account_label aus dem Mapping (niemals Kontonummern in der Vorlage hartcodieren).
Bewegung: emil-design-eng – :active scale(0.98), Balkenbreiten-Übergänge, reduzierten Bewegungen sicher. Stilrichtlinie: references/ui_style_guide.md.
Vorlage: assets/report_template.html. Dummy-Fixture für die Dokumentation: assets/fixtures/sample_analysis.json.
Wenn du die Bericht-UI änderst: bearbeite die Vorlage + das Stilrichtlinien-Dokument; committe niemals echtes output/report.html. Generiere lokal über analyze → report neu.
Berichtsinhalt
- Übersicht – Gesundheitspunktzahl, Metriken, drei CFO-Zitate.
- Einkommen / Ausgaben / Probleme – Entscheidungsorientierte Abschnitte mit Drill-Down zu Kategorien.
- Geschäftsprüfung – wenn
config/business.jsonvorhanden ist. - Ledger – durchsuchbarer Transaktionsnachweis (erste 350 Übereinstimmungen werden angezeigt).
Flags: --port N, --no-open, --refresh-analysis. Ohne --serve wird output/report.html einmal geschrieben (führt zuerst analyze aus, falls analysis.json fehlt).
Methodik: references/financial_frameworks.md.
Hinweis: Die hybride Money.Audit-UI verwendet den Python-Analyse + Bericht-Pfad. Node report.mjs rendert weiterhin die Legacy-CFO-Vorlage für einfache Prüfungen ohne Analyse.
Layout im Prüf-Ordner
ROOT/
├── <Kontoauszugsdateien> # Eingabe (PDF/XLSX/XLS/CSV/TXT)
├── config/
│ ├── mapping.json # Spaltenzuordnung (nach Ingest überprüfen)
│ ├── categories.json # Kategorieregeln (aus dem Beispiel)
│ ├── business.json # optional: Geschäftseinkommen/-gehälter/-infrastruktur
│ └── overrides.json # deine Bezeichnungen, die während der Schleife hinzugefügt wurden
└── output/
├── audit.db # SQLite-Quelle der Wahrheit
├── analysis.json # Analyse-Stufe (nur lokal – personenbezogene Daten)
├── uncategorized.csv # Überprüfungswarteschlange (wird bei jedem categorize-Durchlauf neu generiert)
└── report.html # Money.Audit-Dashboard (nur lokal – personenbezogene Daten)
Der Skill schreibt nur das Nötigste: bearbeitbare Konfiguration, die SQLite-Datenbank, die den Zustand zwischen den Stufen überträgt, die Überprüfungswarteschlange und den endgültigen Bericht. Zwischenablagen (die Ingest-Vorschau, das Bericht-JSON) werden ausgegeben/eingebettet, nicht als zusätzliche Dateien geschrieben. mapping.json und audit.db müssen auf der Festplatte verbleiben, da jede Stufe als separater Prozess ausgeführt wird.
Hinweise
- Dieselben
mapping.json/config/ SQLite-Schema funktionieren über beide Laufzeiten hinweg; du kannst die Laufzeiten während einer Prüfung wechseln. - Halte rohe Kontoauszugsdateien aus der Versionskontrolle heraus (sie enthalten personenbezogene Daten).
- Für das vollständige Schema, die Validierungsmathematik und die Konfigurationsreferenz siehe reference.md.
- Für Analyserahmen (Sparquote, 50/30/20, Benchmarks, Empfehlungslogik) siehe references/financial_frameworks.md.
Häufige Anfragen, die dieser Skill bearbeitet
- „Prüfe / kategorisiere meine Kontoauszüge und erstelle einen Bericht" – vollständige Pipeline.
- „Wie lautet mein persönlicher CFO-Bericht für das Geschäftsjahr 2024-25?" – verwende den Zeitraumselektor nach dem Bericht.
- „Wie hoch ist meine Sparquote und wie kann ich sie verbessern?" – Zusammenfassung der Führungsebene + Aktionsplan.
- „Wo gebe ich zu viel aus?" – Ausgabenintelligenz + kontrafaktische Analysen.
- „Was sollte ich stoppen/starten/fortsetzen?" – Aktionsplan-Abschnitt.
- „Frage meinen CFO nach Liquiditätslaufzeit / Schulden / Investitionen" – verwende die „Frage deinen CFO"-Eingabeaufforderungen mit deinem Agenten.
- „Verbessere die Bericht-UI / mache sie vollbreit / korrigiere das Layout" – bearbeite
assets/report_template.htmlgemäß references/ui_style_guide.md; generiere lokal mitanalyze → reportneu. Committe niemalsoutput/report.html.