lots of stuff, don't truly remember
This commit is contained in:
133
internal/ai/handler.go
Normal file
133
internal/ai/handler.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package ai
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"rideaware/internal/config"
|
||||
"rideaware/internal/middleware"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
service *Service
|
||||
}
|
||||
|
||||
func NewHandler() *Handler {
|
||||
return &Handler{
|
||||
service: NewService(),
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateRecommendations POST /api/protected/ai/generate
|
||||
func (h *Handler) GenerateRecommendations(w http.ResponseWriter, r *http.Request) {
|
||||
claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims)
|
||||
if claims == nil {
|
||||
respondError(w, http.StatusUnauthorized, "unauthorized")
|
||||
return
|
||||
}
|
||||
|
||||
var req GenerateRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
respondError(w, http.StatusBadRequest, "invalid request body")
|
||||
return
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if err := validateGenerateRequest(req); err != nil {
|
||||
respondError(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("[AI] User %d requesting %d-day plan (focus: %v, intensity: %s)",
|
||||
claims.UserID, req.PlanDuration, req.FocusAreas, req.IntensityLevel)
|
||||
|
||||
// Generate workouts
|
||||
response, err := h.service.GenerateWorkouts(claims.UserID, req)
|
||||
if err != nil {
|
||||
log.Printf("[AI] Generation error for user %d: %v", claims.UserID, err)
|
||||
respondError(w, http.StatusInternalServerError, "failed to generate workouts: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("[AI] Successfully generated %d workouts for user %d (total TSS: %.1f)",
|
||||
len(response.Workouts), claims.UserID, response.TotalTSS)
|
||||
|
||||
respondJSON(w, http.StatusOK, response)
|
||||
}
|
||||
|
||||
// ScheduleRecommendations POST /api/protected/ai/schedule
|
||||
func (h *Handler) ScheduleRecommendations(w http.ResponseWriter, r *http.Request) {
|
||||
claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims)
|
||||
if claims == nil {
|
||||
respondError(w, http.StatusUnauthorized, "unauthorized")
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
RecommendationID uint `json:"recommendation_id"`
|
||||
WorkoutIndices []int `json:"workout_indices"` // Which workouts to schedule
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
respondError(w, http.StatusBadRequest, "invalid request")
|
||||
return
|
||||
}
|
||||
|
||||
if req.RecommendationID == 0 {
|
||||
respondError(w, http.StatusBadRequest, "recommendation_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("[AI] User %d scheduling %d workouts from recommendation %d",
|
||||
claims.UserID, len(req.WorkoutIndices), req.RecommendationID)
|
||||
|
||||
// Schedule selected workouts
|
||||
workouts, err := h.service.ScheduleWorkouts(claims.UserID, req.RecommendationID, req.WorkoutIndices)
|
||||
if err != nil {
|
||||
log.Printf("[AI] Schedule error for user %d: %v", claims.UserID, err)
|
||||
respondError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("[AI] Successfully scheduled %d workouts for user %d", len(workouts), claims.UserID)
|
||||
|
||||
respondJSON(w, http.StatusCreated, map[string]interface{}{
|
||||
"scheduled_count": len(workouts),
|
||||
"workouts": workouts,
|
||||
})
|
||||
}
|
||||
|
||||
// GetRecommendationHistory GET /api/protected/ai/history
|
||||
func (h *Handler) GetRecommendationHistory(w http.ResponseWriter, r *http.Request) {
|
||||
claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims)
|
||||
if claims == nil {
|
||||
respondError(w, http.StatusUnauthorized, "unauthorized")
|
||||
return
|
||||
}
|
||||
|
||||
history, err := h.service.GetUserRecommendations(claims.UserID, 10)
|
||||
if err != nil {
|
||||
log.Printf("[AI] Failed to fetch history for user %d: %v", claims.UserID, err)
|
||||
respondError(w, http.StatusInternalServerError, "failed to fetch history")
|
||||
return
|
||||
}
|
||||
|
||||
// Return empty array instead of null
|
||||
if history == nil {
|
||||
history = []AIRecommendation{}
|
||||
}
|
||||
|
||||
respondJSON(w, http.StatusOK, history)
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
func respondJSON(w http.ResponseWriter, status int, data interface{}) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
json.NewEncoder(w).Encode(data)
|
||||
}
|
||||
|
||||
func respondError(w http.ResponseWriter, status int, message string) {
|
||||
respondJSON(w, status, map[string]string{"error": message})
|
||||
}
|
||||
Reference in New Issue
Block a user