Überartbeitung History - neue Gesamtübersicht #99

Merged
Lars merged 3 commits from develop into main 2026-04-20 14:39:54 +02:00
Showing only changes of commit 45fb506a5e - Show all commits

View File

@ -6,7 +6,7 @@ Ausgelagert aus routers/charts.py (Issue 53 / Layer 1).
from __future__ import annotations from __future__ import annotations
from datetime import datetime, timedelta from datetime import date, datetime, timedelta
from typing import Any, Dict, Optional, Set from typing import Any, Dict, Optional, Set
from db import get_db, get_cursor from db import get_db, get_cursor
@ -333,14 +333,31 @@ def build_sleep_debt_chart_payload(profile_id: str, days: int) -> Dict[str, Any]
}, },
} }
labels = [] labels: list[str] = []
debt_values = [] debt_values: list[float] = []
for r in visible: for r in visible:
rd = r.get("date") rd = r.get("date")
end_d = rd.date() if isinstance(rd, datetime) else rd end_d = rd.date() if isinstance(rd, datetime) else rd
labels.append(end_d.isoformat() if hasattr(end_d, "isoformat") else str(end_d)) if not isinstance(end_d, date):
continue
labels.append(end_d.isoformat())
debt_values.append(sleep_debt_sum_hours_in_window(all_rows, end_d)) debt_values.append(sleep_debt_sum_hours_in_window(all_rows, end_d))
# KPI nutzt immer Fensterende = heute; die Kurve endete bisher am Datum der letzten Schlaf-Zeile
# (z. B. gestern) → anderes 14-Tage-Fenster. Letzter Punkt = exakt KPI-Wert, Datum = heute.
today = datetime.now().date()
if labels and debt_values:
try:
last_d = date.fromisoformat(labels[-1])
except (TypeError, ValueError):
last_d = None
if last_d is not None:
if last_d < today:
labels.append(today.isoformat())
debt_values.append(float(current_debt))
elif last_d == today:
debt_values[-1] = float(current_debt)
return { return {
"chart_type": "line", "chart_type": "line",
"data": { "data": {
@ -360,13 +377,14 @@ def build_sleep_debt_chart_payload(profile_id: str, days: int) -> Dict[str, Any]
"metadata": serialize_dates( "metadata": serialize_dates(
{ {
"confidence": calculate_confidence(len(visible), days, "general"), "confidence": calculate_confidence(len(visible), days, "general"),
"data_points": len(visible), "data_points": len(labels),
"current_debt_hours": round(float(current_debt), 1), "current_debt_hours": round(float(current_debt), 1),
"sleep_debt_target_hours_per_night": SLEEP_DEBT_TARGET_HOURS_DEFAULT, "sleep_debt_target_hours_per_night": SLEEP_DEBT_TARGET_HOURS_DEFAULT,
"rolling_window_days": SLEEP_DEBT_ROLLING_WINDOW_DAYS, "rolling_window_days": SLEEP_DEBT_ROLLING_WINDOW_DAYS,
"note": "Gleiche Formel wie KPI: Summe der nächtlichen Defizite vs. " "note": "Gleiche Formel wie KPI: Summe der nächtlichen Defizite vs. "
f"{SLEEP_DEBT_TARGET_HOURS_DEFAULT} h/Nacht im rollierenden {SLEEP_DEBT_ROLLING_WINDOW_DAYS}-Tage-Fenster " f"{SLEEP_DEBT_TARGET_HOURS_DEFAULT} h/Nacht im rollierenden {SLEEP_DEBT_ROLLING_WINDOW_DAYS}-Tage-Fenster. "
"(jeder Punkt = Fensterende an dem Datum). Ziel aktuell nicht in den Profileinstellungen änderbar.", "Zwischenpunkte: Fensterende = Datum der jeweiligen Schlaf-Zeile; "
"letzter Punkt ist auf «heute» bzw. KPI-Wert gesetzt, damit Kurve und Kachel übereinstimmen.",
} }
), ),
} }