From f4d1fd4de105a5df996af5c55d0e5ff29138231b Mon Sep 17 00:00:00 2001 From: Lars Date: Thu, 26 Mar 2026 08:20:18 +0100 Subject: [PATCH] feat: add activity_detail placeholder for detailed activity logs - New placeholder: {{activity_detail}} returns formatted activity log - Shows last 20 activities with date, type, duration, kcal, HR - Makes activity analysis prompts work properly Co-Authored-By: Claude Opus 4.6 --- backend/placeholder_resolver.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/backend/placeholder_resolver.py b/backend/placeholder_resolver.py index 6d4d409..e9359c3 100644 --- a/backend/placeholder_resolver.py +++ b/backend/placeholder_resolver.py @@ -128,6 +128,35 @@ def calculate_age(dob: Optional[str]) -> str: return "unbekannt" +def get_activity_detail(profile_id: str, days: int = 14) -> str: + """Get detailed activity log for analysis.""" + with get_db() as conn: + cur = get_cursor(conn) + cutoff = (datetime.now() - timedelta(days=days)).strftime('%Y-%m-%d') + cur.execute( + """SELECT date, activity_type, duration_min, kcal_active, hr_avg + FROM activity_log + WHERE profile_id=%s AND date >= %s + ORDER BY date DESC + LIMIT 50""", + (profile_id, cutoff) + ) + rows = [r2d(r) for r in cur.fetchall()] + + if not rows: + return f"Keine Aktivitäten in den letzten {days} Tagen" + + # Format as readable list + lines = [] + for r in rows: + hr_str = f" HF={r['hr_avg']}" if r.get('hr_avg') else "" + lines.append( + f"{r['date']}: {r['activity_type']} ({r['duration_min']}min, {r.get('kcal_active', 0)}kcal{hr_str})" + ) + + return '\n'.join(lines[:20]) # Max 20 entries to avoid token bloat + + def get_trainingstyp_verteilung(profile_id: str, days: int = 14) -> str: """Get training type distribution.""" with get_db() as conn: @@ -174,6 +203,7 @@ PLACEHOLDER_MAP: Dict[str, Callable[[str], str]] = { # Training '{{activity_summary}}': get_activity_summary, + '{{activity_detail}}': get_activity_detail, '{{trainingstyp_verteilung}}': get_trainingstyp_verteilung, # Zeitraum