feat: Grafana-Panel Planung nach Kategorie inkl. Kreditraten (A11-T3)

Neue Tabelle planning_monthly (Monatssummen je Kategorie aus wiederkehrenden
Posten, Einmalposten und allen Kreditraten), Service planning_chart mit
refresh_planning_chart (Advisory-Lock, komplette Neuschreibung), GUI-Hooks
in index/planung_page ueber _safe_refresh, neues Barchart-Panel im
Grafana-Dashboard (Panel 5).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-28 19:15:26 +02:00
co-authored by Claude Opus 5.5
parent 979e1c0edc
commit 42b410446d
9 changed files with 273 additions and 0 deletions
+3
View File
@@ -27,6 +27,7 @@ from app.routers.planning import recurring_suggestions as _recurring_suggestions
from app.routers.scenarios import list_scenarios as _list_scenarios
from app.routers.transactions import count_transactions, list_transactions
from app.services.balances import account_balance, total_balance
from app.services.planning_chart import refresh_planning_chart
from app.services.projection_service import refresh_stale_projections
from app.version import get_version
@@ -146,6 +147,7 @@ def _month_starts_desc(session: Session, today: date) -> list[date]:
@router.get("/", dependencies=[Depends(gui_session)])
def index(request: Request, session: Session = Depends(get_session)):
_safe_refresh(session, refresh_stale_projections, date.today())
_safe_refresh(session, refresh_planning_chart, date.today())
accounts = session.execute(select(Account)).scalars().all()
balances = [(a, account_balance(session, a)) for a in accounts]
return templates.TemplateResponse(request, "index.html", {
@@ -323,6 +325,7 @@ def hilfe_page(request: Request):
@router.get("/planung", dependencies=[Depends(gui_session)])
def planung_page(request: Request, session: Session = Depends(get_session)):
_safe_refresh(session, refresh_planning_chart, date.today())
categories = session.execute(select(Category)).scalars().all()
recurring = _list_recurring(session=session)
planned = _list_planned(session=session)