moneyfyandClaude Opus 5 8edb69fe6a feat(logos): Provider-Kette, lokaler Cache und Markenfarben
- simple-icons als kompakter Index im Repository (3.459 Marken, 2 MB gzip),
  erzeugt von scripts/vendor_simple_icons.py bzw. `make vendor-icons`
- logo.dev und Brandfetch als optionale Adapter, ohne Schlüssel übersprungen
- Favicon-Fallback und generierter Buchstaben-Avatar als Garantie
- Bei eindeutigem Offline-Treffer unterbleiben Anfragen nach außen komplett
- Cache im Dateisystem nach SHA-256, Auslieferung nur über /api/logos/{id}
  mit immutable-Header und ETag
- Markenfarbe aus SVG-Fills bzw. per k-Means (k=4) über 64x64 Pixel, dazu eine
  aufgehellte Variante mit mindestens 4,5:1 Kontrast auf dunklem Grund
- Kandidatensuche mit Vorauswahl, Auswahl, Upload und Zurücksetzen
- Bildtyp wird nur noch am Inhalt bestimmt, nicht an der gemeldeten Kopfzeile
- 60 neue Tests, insgesamt 208 grün

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014e7t8UpmoVNMtWivY5LiSH
2026-09-09 13:54:21 +02:00

moneyfy

Selbst gehostete Web-Anwendung zur Planung monatlicher Kosten und Einkünfte. Single-User, deutschsprachige Oberfläche, ausgelegt für den Betrieb im Homelab hinter einem Reverse Proxy.

Status: in Entwicklung. Siehe CHANGELOG.md.

Screenshots

Platzhalter werden ergänzt, sobald die Oberfläche steht.

Dashboard Cashflow-Kalender Firmen
folgt folgt folgt

Funktionsumfang

  • Wiederkehrende Zahlungen und Einkünfte über vollständige RFC-5545-RRULEs, inklusive Werktagsverschiebung nach NRW-Feiertagen.
  • Preishistorie je Vertrag, sodass vergangene Monate betragstreu bleiben.
  • Verträge mit Mindestlaufzeit, Kündigungsfrist und automatischer Verlängerung.
  • Ratenzahlungen mit Restschuld- und Restratenberechnung.
  • Rücklagenbildung für nicht-monatliche Posten.
  • Firmenlogos und Markenfarben, lokal zwischengespeichert (siehe unten).
  • Auswertungen: Monatsübersicht, Cashflow-Kalender, 12-Monats-Forecast, Kategorien, Abo-Übersicht, Jahresvergleich, Budgets, Sparziele.
  • Benachrichtigungen per SMTP und Apprise.

Technischer Stack

Bereich Technologie
Backend Python 3.12, FastAPI, SQLAlchemy 2 (async), Alembic, Pydantic v2
Datenbank PostgreSQL 17
Scheduler APScheduler (in-process)
Frontend React 18, TypeScript, Vite, TailwindCSS
Charts Recharts
Tests pytest + httpx, vitest + testing-library

Schnellstart (lokale Entwicklung)

Voraussetzungen: Python 3.12, uv, Node 20+, eine erreichbare PostgreSQL-17-Instanz.

git clone https://git.menzel.center/menzeljonas/moneyfy.git
cd moneyfy
cp .env.example backend/.env      # DATABASE_URL und SECRET_KEY anpassen

make install                      # Backend-Abhängigkeiten in backend/.venv
make migrate                      # Schema anlegen
make seed                         # Kategoriebaum und Standardregeln
make dev                          # http://localhost:8000/api/docs

Nützliche Ziele: make test, make lint, make format, make check.

Konfiguration

Alle Einstellungen kommen aus Umgebungsvariablen; .env.example enthält die vollständige, kommentierte Liste. Die wichtigsten:

Variable Standard Bedeutung
DATABASE_URL PostgreSQL-DSN, postgresql:// wird auf asyncpg umgestellt
SECRET_KEY Signaturschlüssel für JWTs, mind. 32 Zeichen (openssl rand -hex 32)
MONEYFY_ADMIN_USER / MONEYFY_ADMIN_PASSWORD admin / Beim Erststart angelegter Benutzer
TIMEZONE Europe/Berlin Zeitzone der gesamten Anwendung
HOLIDAY_REGION DE-NW Feiertagsregion für Werktagsverschiebungen
LOGO_STORAGE_DIR /data/logos Verzeichnis des Logo-Caches
LOGODEV_API_KEY / BRANDFETCH_API_KEY leer Optionale Logo-Provider, ohne Schlüssel übersprungen
SMTP_* leer Mailversand für Benachrichtigungen
APPRISE_URLS leer Komma-separierte Apprise-Ziele
COOKIE_SECURE true Hinter HTTPS true, für lokales HTTP false
SCHEDULER_ENABLED true Täglicher Benachrichtigungslauf um 07:00

Logos und Markenfarben

Jede Firma bekommt ein Bild. Die Provider-Kette arbeitet der Reihe nach:

  1. simple-icons rund 3.500 Marken, im Repository unter backend/app/assets/simple_icons.json.gz mitgeliefert. Kein Schlüssel, kein Netzzugriff. Neu erzeugen mit make vendor-icons.
  2. logo.dev nur mit LOGODEV_API_KEY.
  3. Brandfetch nur mit BRANDFETCH_API_KEY und hinterlegter Domain.
  4. Favicon über den Google-Dienst, wenn eine Domain bekannt oder aus dem Namen ableitbar ist.
  5. Generierter Avatar Buchstaben-Monogramm mit fester Farbe aus dem Namens-Hash. Schlägt nie fehl.

Findet die Kette einen eindeutigen Treffer im lokalen Katalog, unterbleiben die Anfragen nach außen vollständig die Firmenliste verlässt den Server nicht. Im Auswahldialog (POST /api/merchants/{id}/logo/search) läuft dagegen bewusst die ganze Kette, damit Alternativen zur Wahl stehen.

Ausgewählte Logos landen unter LOGO_STORAGE_DIR, benannt nach ihrem SHA-256-Hash, und werden nur über GET /api/logos/{id} ausgeliefert. Beim Seitenaufruf entsteht dadurch kein Zugriff auf fremde Dienste. Ein Upload oder eine bewusste Auswahl setzt den Status auf manual und wird von der Automatik nie überschrieben.

Projektstruktur

backend/     FastAPI-Anwendung, Modelle, Services, Alembic-Migrationen, Tests
frontend/    React-Oberfläche (Vite)
docs/        Betriebs- und Runner-Dokumentation
.gitea/      Gitea-Actions-Workflows

Lizenz

MIT

S
Description
Selbst gehostete Planung monatlicher Kosten und Einkünfte
Readme MIT
2.5 MiB
Languages
Python 56.4%
TypeScript 41.9%
Dockerfile 0.5%
JavaScript 0.3%
Makefile 0.3%
Other 0.5%