package store import ( "fmt" "krafttrainer/internal/model" ) // StatsOverview enthält die Gesamtübersicht. type StatsOverview struct { TotalSessions int `json:"total_sessions"` TotalVolumeKg float64 `json:"total_volume_kg"` SessionsThisWeek int `json:"sessions_this_week"` Exercises []model.ExerciseStats `json:"exercises"` } // GetStatsOverview gibt die Gesamtstatistik eines Nutzers zurück. func (s *Store) GetStatsOverview(userID int64) (*StatsOverview, error) { var overview StatsOverview err := s.db.QueryRow(` SELECT (SELECT COUNT(*) FROM sessions WHERE user_id = ? AND ended_at IS NOT NULL), (SELECT COALESCE(SUM(sl.weight_kg * sl.reps), 0) FROM session_logs sl JOIN sessions s ON s.id = sl.session_id WHERE s.user_id = ?), (SELECT COUNT(*) FROM sessions WHERE user_id = ? AND ended_at IS NOT NULL AND started_at >= date('now', '-7 days')) `, userID, userID, userID).Scan(&overview.TotalSessions, &overview.TotalVolumeKg, &overview.SessionsThisWeek) if err != nil { return nil, fmt.Errorf("Übersicht abfragen: %w", err) } rows, err := s.db.Query(` SELECT sl.exercise_id, sl.exercise_name, MAX(sl.weight_kg) as max_weight_kg, SUM(sl.weight_kg * sl.reps) as total_volume_kg, COUNT(*) as total_sets, MAX(sl.logged_at) as last_trained FROM session_logs sl JOIN sessions s ON s.id = sl.session_id WHERE s.user_id = ? GROUP BY sl.exercise_id ORDER BY last_trained DESC`, userID) if err != nil { return nil, fmt.Errorf("Übungs-Stats abfragen: %w", err) } defer rows.Close() for rows.Next() { var es model.ExerciseStats if err := rows.Scan(&es.ExerciseID, &es.ExerciseName, &es.MaxWeightKg, &es.TotalVolumeKg, &es.TotalSets, &es.LastTrained); err != nil { return nil, fmt.Errorf("Übungs-Stats scannen: %w", err) } overview.Exercises = append(overview.Exercises, es) } if overview.Exercises == nil { overview.Exercises = []model.ExerciseStats{} } return &overview, rows.Err() } // GetExerciseHistory gibt die letzten N Logs einer Übung für einen Nutzer zurück. func (s *Store) GetExerciseHistory(exerciseID, userID int64, limit int) ([]model.SessionLog, error) { rows, err := s.db.Query(` SELECT sl.id, sl.session_id, sl.exercise_id, sl.exercise_name, sl.set_number, sl.weight_kg, sl.reps, sl.note, sl.logged_at FROM session_logs sl JOIN sessions s ON s.id = sl.session_id WHERE sl.exercise_id = ? AND s.user_id = ? ORDER BY sl.logged_at DESC LIMIT ?`, exerciseID, userID, limit, ) if err != nil { return nil, fmt.Errorf("Übungshistorie abfragen: %w", err) } defer rows.Close() var logs []model.SessionLog for rows.Next() { var log model.SessionLog if err := rows.Scan(&log.ID, &log.SessionID, &log.ExerciseID, &log.ExerciseName, &log.SetNumber, &log.WeightKg, &log.Reps, &log.Note, &log.LoggedAt); err != nil { return nil, fmt.Errorf("Log scannen: %w", err) } logs = append(logs, log) } if logs == nil { logs = []model.SessionLog{} } return logs, rows.Err() }