internal/handler/workout_wod_handler.go
Rama main · réplica de lectura del repositorio original.
package handler
import (
"encoding/json"
"net/http"
"strconv"
"github.com/go-chi/chi/v5"
"github.com/johnzastrow/actalog/internal/service"
"github.com/johnzastrow/actalog/pkg/middleware"
)
// WorkoutWODHandler handles linking WODs to workout templates
type WorkoutWODHandler struct {
workoutWODService *service.WorkoutWODService
}
// NewWorkoutWODHandler creates a new workout WOD handler
func NewWorkoutWODHandler(workoutWODService *service.WorkoutWODService) *WorkoutWODHandler {
return &WorkoutWODHandler{
workoutWODService: workoutWODService,
}
}
// AddWODToWorkoutRequest represents a request to add a WOD to a workout template
type AddWODToWorkoutRequest struct {
WODID int64 `json:"wod_id"`
OrderIndex int `json:"order_index"`
Division *string `json:"division,omitempty"`
}
// UpdateWorkoutWODRequest represents a request to update a WOD in a workout
type UpdateWorkoutWODRequest struct {
ScoreValue *string `json:"score_value,omitempty"`
Division *string `json:"division,omitempty"`
}
// AddWODToWorkout adds a WOD to a workout template
func (h *WorkoutWODHandler) AddWODToWorkout(w http.ResponseWriter, r *http.Request) {
// Extract user ID from JWT token in context
userID, ok := middleware.GetUserID(r.Context())
if !ok {
respondError(w, http.StatusUnauthorized, "Unauthorized")
return
}
// Get workout ID from URL
workoutIDStr := chi.URLParam(r, "workout_id")
workoutID, err := strconv.ParseInt(workoutIDStr, 10, 64)
if err != nil {
respondError(w, http.StatusBadRequest, "Invalid workout ID")
return
}
var req AddWODToWorkoutRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
respondError(w, http.StatusBadRequest, "Invalid request body")
return
}
// Validate required fields
if req.WODID == 0 {
respondError(w, http.StatusBadRequest, "WOD ID is required")
return
}
// Add WOD to workout
workoutWOD, err := h.workoutWODService.AddWODToWorkout(workoutID, req.WODID, userID, req.OrderIndex, req.Division)
if err != nil {
if err == service.ErrUnauthorized {
respondError(w, http.StatusForbidden, "You don't have permission to modify this workout")
} else {
respondError(w, http.StatusInternalServerError, "Failed to add WOD to workout: "+err.Error())
}
return
}
respondJSON(w, http.StatusCreated, workoutWOD)
}
// RemoveWODFromWorkout removes a WOD from a workout template
func (h *WorkoutWODHandler) RemoveWODFromWorkout(w http.ResponseWriter, r *http.Request) {
// Extract user ID from JWT token in context
userID, ok := middleware.GetUserID(r.Context())
if !ok {
respondError(w, http.StatusUnauthorized, "Unauthorized")
return
}
// Get workout WOD ID from URL
workoutWODIDStr := chi.URLParam(r, "workout_wod_id")
workoutWODID, err := strconv.ParseInt(workoutWODIDStr, 10, 64)
if err != nil {
respondError(w, http.StatusBadRequest, "Invalid workout WOD ID")
return
}
// Remove WOD from workout
if err := h.workoutWODService.RemoveWODFromWorkout(workoutWODID, userID); err != nil {
if err == service.ErrUnauthorized {
respondError(w, http.StatusForbidden, "You don't have permission to modify this workout")
} else {
respondError(w, http.StatusInternalServerError, "Failed to remove WOD from workout: "+err.Error())
}
return
}
respondJSON(w, http.StatusOK, map[string]string{"message": "WOD removed from workout successfully"})
}
// UpdateWorkoutWOD updates a WOD in a workout template
func (h *WorkoutWODHandler) UpdateWorkoutWOD(w http.ResponseWriter, r *http.Request) {
// Extract user ID from JWT token in context
userID, ok := middleware.GetUserID(r.Context())
if !ok {
respondError(w, http.StatusUnauthorized, "Unauthorized")
return
}
// Get workout WOD ID from URL
workoutWODIDStr := chi.URLParam(r, "workout_wod_id")
workoutWODID, err := strconv.ParseInt(workoutWODIDStr, 10, 64)
if err != nil {
respondError(w, http.StatusBadRequest, "Invalid workout WOD ID")
return
}
var req UpdateWorkoutWODRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
respondError(w, http.StatusBadRequest, "Invalid request body")
return
}
// Update workout WOD
if err := h.workoutWODService.UpdateWorkoutWOD(workoutWODID, userID, req.ScoreValue, req.Division); err != nil {
if err == service.ErrUnauthorized {
respondError(w, http.StatusForbidden, "You don't have permission to modify this workout")
} else {
respondError(w, http.StatusInternalServerError, "Failed to update workout WOD: "+err.Error())
}
return
}
respondJSON(w, http.StatusOK, map[string]string{"message": "Workout WOD updated successfully"})
}
// ToggleWODPR toggles the PR flag on a WOD in a workout
func (h *WorkoutWODHandler) ToggleWODPR(w http.ResponseWriter, r *http.Request) {
// Extract user ID from JWT token in context
userID, ok := middleware.GetUserID(r.Context())
if !ok {
respondError(w, http.StatusUnauthorized, "Unauthorized")
return
}
// Get workout WOD ID from URL
workoutWODIDStr := chi.URLParam(r, "workout_wod_id")
workoutWODID, err := strconv.ParseInt(workoutWODIDStr, 10, 64)
if err != nil {
respondError(w, http.StatusBadRequest, "Invalid workout WOD ID")
return
}
// Toggle PR flag
if err := h.workoutWODService.ToggleWODPR(workoutWODID, userID); err != nil {
if err == service.ErrUnauthorized {
respondError(w, http.StatusForbidden, "You don't have permission to modify this workout")
} else {
respondError(w, http.StatusInternalServerError, "Failed to toggle WOD PR: "+err.Error())
}
return
}
respondJSON(w, http.StatusOK, map[string]string{"message": "WOD PR flag toggled successfully"})
}
// ListWODsForWorkout retrieves all WODs for a workout template
func (h *WorkoutWODHandler) ListWODsForWorkout(w http.ResponseWriter, r *http.Request) {
// Get workout ID from URL
workoutIDStr := chi.URLParam(r, "workout_id")
workoutID, err := strconv.ParseInt(workoutIDStr, 10, 64)
if err != nil {
respondError(w, http.StatusBadRequest, "Invalid workout ID")
return
}
wods, err := h.workoutWODService.ListWODsForWorkout(workoutID)
if err != nil {
respondError(w, http.StatusInternalServerError, "Failed to retrieve WODs for workout")
return
}
respondJSON(w, http.StatusOK, map[string]interface{}{
"wods": wods,
})
}