Files
moneyfy/CHANGELOG.md
T
moneyfyandClaude Opus 5 87bee9b72a build: Docker-Images, Compose-Setup und Gitea-Workflows
- Mehrstufige Dockerfiles je Dienst mit Stufen für Entwicklung und Betrieb,
  beide Images laufen als unprivilegierter Benutzer
- Backend-Entrypoint wartet auf die Datenbank, migriert und seedt nur bei
  leerem Kategoriebaum (neues Flag --if-empty)
- docker-compose.yml mit Netz-Trennung, Healthchecks und benannten Volumes;
  die Datenbank ist ausschließlich im internen Netz erreichbar
- nginx liefert das Bundle aus und reicht /api weiter; index.html ungecacht,
  gehashte Assets ein Jahr
- Gitea-Workflows: ci.yml für Lint, Tests und Bundle-Bau, build.yml für die
  Images nach linux/amd64 ohne Deploy-Schritt
- docs/runner.md und docs/deployment.md, .dockerignore je Dienst

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

8.2 KiB
Raw Blame History

Changelog

Alle nennenswerten Änderungen an diesem Projekt werden hier dokumentiert.

Das Format orientiert sich an Keep a Changelog, die Versionierung folgt Semantic Versioning.

[Unreleased]

Hinzugefügt

  • Projektgerüst mit getrennten Bereichen für Backend, Frontend, Dokumentation und CI.

  • FastAPI-Backend mit Konfiguration über pydantic-settings und einheitlichem Fehlerformat ({"detail": ..., "code": ...}).

  • Vollständiges Datenmodell als SQLAlchemy-2.0-Modelle: Konten, Kategorien, Firmen, Logo-Assets, Recurrences, Preishistorie, Occurrences, Buchungen, Budgets samt Vorlagen, Sparziele, Rücklagen, Benachrichtigungsregeln und -protokoll, Benutzer.

  • Alembic-Setup gegen die Async-Engine samt Erstmigration des kompletten Schemas; der Downgrade entfernt auch die nativen Enum-Typen, sodass Auf- und Abwärtsmigration beliebig oft wiederholbar sind.

  • Idempotenter Seed für den deutschen Standard-Kategoriebaum (35 Kategorien) und die Standard-Benachrichtigungsregeln.

  • Endpunkte GET /api/health und GET /api/version.

  • Testinfrastruktur mit pytest, httpx und transaktionsisolierten Fixtures.

  • .env.example, docker-compose.override.yml.example und Makefile für die lokale Entwicklung.

  • Recurrence-Engine (app/services/recurrence.py) mit vollständiger RFC-5545-Expansion: expand liefert nominale und tatsächliche Zahltage, expand_by_due_date filtert nach dem Zahltag für Kalender und Monatsberichte.

  • Wochenend- und Feiertagsverschiebung über den NRW-Kalender; das nominale Datum bleibt stabiler Schlüssel zur Zuordnung materialisierter Fälligkeiten.

  • Auflösung der Preishistorie je Fälligkeitsdatum, Overlays aus occurrence, Kappung der Serie durch until, Kündigung und Ratenzahl.

  • installments_remaining (Restraten und Restschuld), contract_term und notice_deadline (Mindestlaufzeit, automatische Verlängerung, Kündigungsfrist) sowie annual_burden und monthly_reserve für die Rücklagenbildung.

  • validate_rrule und next_dates als Grundlage für Eingabeprüfung und Vorschau.

  • Authentifizierung mit Argon2id, JWT in httpOnly-Cookies (Access 30 min, Refresh 14 Tage) und echter Token-Rotation über die Tabelle refresh_token; ein erneut eingelöstes Refresh-Token beendet alle Sitzungen.

  • AuthProvider-Protokoll mit lokalem Provider als Vorbereitung für OIDC.

  • Anlage des Administrators beim Erststart mit erzwungenem Passwortwechsel; bis dahin sind alle Fachrouten gesperrt.

  • CRUD für Konten, Kategorien, Firmen, wiederkehrende Posten, Preisversionen, Buchungen, Budgets, Budgetvorlagen und Sparziele.

  • Fälligkeiten-API mit Overlay-Logik: abrufen, bestätigen (auch mit abweichendem Betrag oder Datum), auslassen und zurücksetzen.

  • Kontosalden zum Stichtag aus Eröffnungssaldo, Buchungen und bestätigten Fälligkeiten, inklusive abweichender Konten je Fälligkeit.

  • Monatsübersicht mit Plan-Ist-Vergleich, Aufteilung in fixe und variable Kosten, Rücklagen und Vergleich zum Vormonat.

  • Vollständig annotiertes OpenAPI-Dokument unter /api/docs.

  • Logo-Service mit fünfstufiger Provider-Kette: lokal gevendorte simple-icons (3.459 Marken, rund 2 MB), logo.dev und Brandfetch bei gesetztem Schlüssel, Favicon-Fallback und generierter Buchstaben-Avatar als Garantie.

  • Logo-Cache im Dateisystem, benannt nach dem SHA-256 des Inhalts; Auslieferung ausschließlich über GET /api/logos/{id} mit immutable-Cache-Header und ETag-Unterstützung.

  • Ermittlung der Markenfarbe: bei SVG aus den fill-Attributen, bei Rastergrafiken per k-Means über 64×64 Pixel; dazu eine im HSL-Raum aufgehellte Variante, die gegen den dunklen Hintergrund mindestens 4,5:1 Kontrast erreicht.

  • Auswahldialog-Endpunkte: Kandidatensuche mit Vorauswahl, Übernahme eines Kandidaten, Upload (SVG/PNG/JPEG bis 1 MB) und Zurücksetzen.

  • Die Logosuche läuft nach dem Anlegen einer Firma im Hintergrund; der Aufruf antwortet sofort.

  • make vendor-icons erzeugt den simple-icons-Index neu.

  • Frontend auf React 18, TypeScript, Vite und TailwindCSS mit dunklem Standard- Theme, umschaltbar und im Browser gespeichert.

  • Anmeldung, erzwungener Passwortwechsel und Layout mit Seitenleiste.

  • TanStack-Query-Client mit zentralen Fehler-Toasts und stiller Token-Erneuerung bei abgelaufenem Access-Token.

  • Seiten für wiederkehrende Posten (inklusive Detail-Drawer mit Preishistorie, Ratenfortschritt und Vertragsfristen), Buchungen, Firmen und Einstellungen.

  • Geführter RRULE-Editor mit sechs Vorlagen, Expertenmodus, deutscher Klartextfassung und den nächsten fünf Terminen aus dem preview-Endpunkt.

  • Firmen als Kachelgrid mit Logo, Markenfarbe, Jahreskosten und Vertragszahl; Logo-Auswahldialog mit Vorauswahl, erneuter Suche über eine Domain und Upload.

  • Beträge durchgängig über Intl.NumberFormat('de-DE'); Eingaben akzeptieren deutsche wie englische Schreibweise.

  • Auswertungen: Monatsübersicht, 12-Monats-Forecast, Kategorienaufteilung mit Drilldown, Abo-Übersicht mit Jahreskosten, Jahresvergleich, Cashflow-Kalender, Budget-Ampel und Fortschritt der Sparziele.

  • Alle Berichte bauen auf einer gemeinsamen Bewegungsschicht auf, sodass Monatsübersicht, Forecast und Kalender nachweislich dieselben Zahlen zeigen.

  • Budgetübertrag über Monatsgrenzen und Budgets auf Oberkategorien, die deren Unterkategorien einschließen.

  • GET /api/reports/dashboard bündelt alles, was die Startseite braucht.

  • Export als CSV (Semikolon, Komma als Dezimaltrenner, UTF-8 mit BOM) und XLSX mit typisierten Beträgen und deutschem Zahlenformat für Buchungen, Posten und die Monatsauswertung.

  • Dashboard, Cashflow-Kalender, Budget-, Sparziel- und Auswertungsseite im Frontend; Diagramme mit Recharts.

  • Die Farbpalette der Diagramme wurde gegen die hellen und dunklen Flächen der Anwendung auf Kontrast und Farbfehlsichtigkeit geprüft. Grün/Rot schied als Serienpaar aus (bei Deuteranopie nicht unterscheidbar) und bleibt den Vorzeichen im Text vorbehalten.

  • Benachrichtigungen über SMTP (HTML-Mail mit eingebetteten Firmenlogos) und Apprise, gesteuert über Regeln je Anlass und Kanal.

  • Vier Anlässe: bald fällige Posten, Kündigungsfristen (30, 14 und 7 Tage vor dem Termin), überschrittene Budgets und anstehende Vertragsverlängerungen.

  • APScheduler-Job täglich um 07:00 Europe/Berlin, der zugleich abgelaufene Sitzungen aufräumt; verpasste Läufe werden einmal nachgeholt.

  • Duplikatsschutz über (rule_id, ref_type, ref_id, Zieltag). Maßgeblich ist der Zieltag des Ereignisses, nicht der Versandtag ein zweiter Lauf am selben oder am nächsten Tag erzeugt keine zweite Nachricht. Ein fehlgeschlagener Versand wird beim nächsten Lauf erneut versucht.

  • POST /api/notifications/test verschickt eine Testnachricht über beide Kanäle, POST /api/notifications/run führt einen Lauf sofort aus.

  • Benachrichtigungen sind in den Einstellungen pflegbar, samt Einrichtungsstand der Kanäle und Versandprotokoll.

  • Mehrstufige Dockerfiles für Backend und Frontend, beide mit einer Stufe für die Entwicklung und einer für den Betrieb; beide Images laufen unprivilegiert.

  • Entrypoint des Backends wartet auf die Datenbank, spielt die Migrationen ein und legt die Stammdaten nur beim leeren Kategoriebaum an.

  • docker-compose.yml mit Netz-Trennung (die Datenbank ist ausschließlich intern erreichbar), Healthchecks und benannten Volumes für Datenbank und Logo-Cache.

  • nginx liefert das Bundle aus und reicht /api weiter; index.html bleibt ungecacht, die gehashten Assets ein Jahr.

  • Gitea-Workflows ci.yml (Lint, Tests, Bundle-Bau) und build.yml (Images für linux/amd64 in die Gitea-Registry, ohne Deploy-Schritt).

  • docs/runner.md zur Einrichtung des act_runners samt Fehlersuche und docs/deployment.md zu NPMplus, Aktualisierung und Sicherung.

  • python -m app.scripts.seed --if-empty seedt nur bei leerem Kategoriebaum.

Geändert

  • SECRET_KEY muss mindestens 32 Zeichen lang sein (Vorgabe von HS256); in Produktion wird der Platzhalterwert beim Start abgelehnt.
  • Der Bildtyp eines Uploads wird ausschließlich am Inhalt bestimmt; die vom Aufrufer gemeldete Kopfzeile wird nicht mehr als Nachweis akzeptiert.