feat: extend equipment and workout models with service tracking

This commit is contained in:
Blake Ridgway
2026-02-12 10:09:50 -06:00
parent eb9ac1b67a
commit 178ffb3425
37 changed files with 4005 additions and 40 deletions

View File

@@ -0,0 +1,82 @@
package export
import (
"fmt"
"rideaware/internal/user"
"rideaware/internal/workout"
)
type Service struct {
workoutRepo *workout.Repository
userRepo *user.Repository
}
func NewService() *Service {
return &Service{
workoutRepo: workout.NewRepository(),
userRepo: user.NewRepository(),
}
}
func (s *Service) ExportFIT(workoutID, userID uint) ([]byte, string, error) {
w, err := s.workoutRepo.GetWorkoutByID(workoutID, userID)
if err != nil {
return nil, "", fmt.Errorf("workout not found: %w", err)
}
u, err := s.userRepo.GetUserByID(userID)
if err != nil {
return nil, "", fmt.Errorf("user not found: %w", err)
}
ftp := 0
if u.Profile != nil {
ftp = u.Profile.FTP
}
if ftp <= 0 {
return nil, "", fmt.Errorf("FTP must be set in your profile before exporting FIT files")
}
data, err := EncodeFITWorkout(w, ftp)
if err != nil {
return nil, "", err
}
filename := sanitizeFilename(w.Title) + ".fit"
return data, filename, nil
}
func (s *Service) ExportZWO(workoutID, userID uint) ([]byte, string, error) {
w, err := s.workoutRepo.GetWorkoutByID(workoutID, userID)
if err != nil {
return nil, "", fmt.Errorf("workout not found: %w", err)
}
data, err := GenerateZWO(w)
if err != nil {
return nil, "", err
}
filename := sanitizeFilename(w.Title) + ".zwo"
return data, filename, nil
}
func sanitizeFilename(name string) string {
if name == "" {
return "workout"
}
result := make([]byte, 0, len(name))
for _, c := range name {
switch {
case c >= 'a' && c <= 'z', c >= 'A' && c <= 'Z', c >= '0' && c <= '9':
result = append(result, byte(c))
case c == ' ' || c == '-' || c == '_':
result = append(result, '_')
}
}
if len(result) == 0 {
return "workout"
}
return string(result)
}