feat: Phase 2 – Budget-Engine + Direktzugriff (http://IP:Port)

Budget:
- Modelle + Migration 0003: budget_template_lines, planned_income_lines,
  budget_periods, budget_period_lines.
- services/budget: Perioden-Grenzen (einstellbarer Starttag, Label nach Endmonat),
  Standard-Vorlage vs. Monats-Override (Snapshot-on-Customize), Soll/Ist inkl.
  budgetierter Sparen-Transfers, geplante Einnahmen (Soll/Ist).
- routers/budgets: Vorlage, geplante Einnahmen (CRUD), Monats-Soll/Ist,
  Monats-Override, Zurücksetzen. pytest: Perioden, Soll/Ist, Override/Reset, Einnahmen.
- Frontend: Budget-Seite (Monat + Standard-Budget), Fortschrittsbalken grün/rot,
  Monats-Navigation, editierbare Soll-Beträge; Sparen-Option im Transfer-Formular.

Deployment-Fix (Nutzer-Anforderung: http://IP:Port muss funktionieren):
- Dienst bindet an APP_BIND_HOST=0.0.0.0 (direkt im LAN erreichbar).
- APP_COOKIE_SECURE=false als Standard (sonst kein Login über reines HTTP);
  für reinen HTTPS-Betrieb umstellbar. Doku + install.sh entsprechend angepasst.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-08-19 19:16:27 +02:00
co-authored by Claude Opus 4.8
parent d692c04cc1
commit 8ed4bf5254
21 changed files with 1352 additions and 22 deletions
+10 -4
View File
@@ -5,15 +5,21 @@
# Ablageort für SQLite-Datenbank und Backups (muss dem Dienst-Benutzer gehören).
APP_DATA_DIR=/var/lib/certain-finance
# Interner Port, auf dem der Dienst lauscht. Der Nginx Proxy Manager leitet
# von außen (HTTPS) hierher weiter. Nur an 127.0.0.1 gebunden (siehe Unit).
# Adresse + Port, auf denen der Dienst lauscht.
# APP_BIND_HOST=0.0.0.0 macht die Web-UI direkt über http://<LXC-IP>:<APP_PORT>
# im LAN erreichbar. Willst du NUR über einen Reverse-Proxy auf DEMSELBEN Host
# zugreifen, setze 127.0.0.1.
APP_BIND_HOST=0.0.0.0
APP_PORT=8071
# Signiert/HMACt Sitzungen. UNBEDINGT zufällig setzen (install.sh macht das).
APP_SESSION_SECRET=change-me-please
# Cookies nur über HTTPS senden. Hinter dem Nginx Proxy Manager: true.
APP_COOKIE_SECURE=true
# Cookies nur über HTTPS senden. Bei direktem HTTP-Zugriff (http://IP:Port) MUSS
# das false sein, sonst speichert der Browser die Sitzung nicht (Login klappt dann
# scheinbar, springt aber sofort zurück). Nur wenn du ausschließlich über HTTPS
# zugreifst (z. B. Nginx Proxy Manager mit erzwungenem SSL), kannst du true setzen.
APP_COOKIE_SECURE=false
# Erster Admin – wird NUR beim allerersten Start angelegt (wenn noch kein Nutzer da ist).
APP_ADMIN_USERNAME=admin