- Exercise number (UF#): optional field on exercises, displayed in cards, training, and sets - Import training plan numbers via migration 005 (UPDATE by name) - Exercise images: JPG upload with multi-image support per exercise (migration 006) - Version endpoint (GET /api/v1/version) with ldflags injection in Makefile and Dockerfile - Version displayed on settings page - Session resume: GET /api/v1/sessions/active endpoint, auto-resume on training page load - Block new session while one is active (409 Conflict) - e1RM sparkline chart per exercise during training (Epley formula) - Fix CORS: add X-User-ID to allowed headers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
50 lines
1.4 KiB
Go
Executable File
50 lines
1.4 KiB
Go
Executable File
package model
|
||
|
||
import (
|
||
"errors"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
// Exercise repräsentiert eine Kraftübung.
|
||
type Exercise struct {
|
||
ID int64 `json:"id"`
|
||
Name string `json:"name"`
|
||
Description string `json:"description"`
|
||
MuscleGroup string `json:"muscle_group"`
|
||
WeightStepKg float64 `json:"weight_step_kg"`
|
||
ExerciseNumber *int `json:"exercise_number,omitempty"`
|
||
CreatedAt time.Time `json:"created_at"`
|
||
UpdatedAt time.Time `json:"updated_at"`
|
||
DeletedAt *time.Time `json:"deleted_at,omitempty"`
|
||
}
|
||
|
||
// CreateExerciseRequest enthält die Felder zum Anlegen einer Übung.
|
||
type CreateExerciseRequest struct {
|
||
Name string `json:"name"`
|
||
Description string `json:"description"`
|
||
MuscleGroup string `json:"muscle_group"`
|
||
WeightStepKg *float64 `json:"weight_step_kg"`
|
||
ExerciseNumber *int `json:"exercise_number,omitempty"`
|
||
}
|
||
|
||
// Validate prüft und normalisiert den Request. Setzt Default für WeightStepKg.
|
||
func (r *CreateExerciseRequest) Validate() error {
|
||
r.Name = strings.TrimSpace(r.Name)
|
||
if len(r.Name) == 0 || len(r.Name) > 100 {
|
||
return errors.New("Name muss 1–100 Zeichen lang sein")
|
||
}
|
||
if !ValidMuscleGroup(r.MuscleGroup) {
|
||
return errors.New("Ungültige Muskelgruppe")
|
||
}
|
||
if r.WeightStepKg != nil {
|
||
if *r.WeightStepKg <= 0 {
|
||
return errors.New("Gewichtsschritt muss > 0 sein")
|
||
}
|
||
} else {
|
||
def := 2.5
|
||
r.WeightStepKg = &def
|
||
}
|
||
return nil
|
||
}
|