package handlers import ( "encoding/json" "net/http" "strconv" "github.com/rede5/gohorsejobs/backend/internal/services" ) // MetricsHandler handles job metrics endpoints type MetricsHandler struct { Service *services.MetricsService } // NewMetricsHandler creates a new metrics handler func NewMetricsHandler(service *services.MetricsService) *MetricsHandler { return &MetricsHandler{Service: service} } // GetJobMetrics godoc // @Summary Get job metrics // @Description Get analytics data for a job including views, applications, and conversion rate // @Tags Metrics // @Accept json // @Produce json // @Param id path int true "Job ID" // @Success 200 {object} models.JobMetrics // @Failure 400 {string} string "Bad Request" // @Failure 404 {string} string "Not Found" // @Router /api/v1/jobs/{id}/metrics [get] func (h *MetricsHandler) GetJobMetrics(w http.ResponseWriter, r *http.Request) { idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { http.Error(w, "Invalid job ID", http.StatusBadRequest) return } metrics, err := h.Service.GetJobMetrics(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(metrics) } // RecordJobView godoc // @Summary Record a job view // @Description Record that a user viewed a job (called internally or by frontend) // @Tags Metrics // @Accept json // @Produce json // @Param id path int true "Job ID" // @Success 204 "No Content" // @Failure 400 {string} string "Bad Request" // @Failure 500 {string} string "Internal Server Error" // @Router /api/v1/jobs/{id}/view [post] func (h *MetricsHandler) RecordJobView(w http.ResponseWriter, r *http.Request) { idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { http.Error(w, "Invalid job ID", http.StatusBadRequest) return } // Get user ID from context if authenticated var userID *int if uid := r.Context().Value("user_id"); uid != nil { if id, ok := uid.(int); ok { userID = &id } } // Get IP and User-Agent for analytics ip := r.Header.Get("X-Forwarded-For") if ip == "" { ip = r.RemoteAddr } userAgent := r.Header.Get("User-Agent") err = h.Service.RecordView(id, userID, &ip, &userAgent) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusNoContent) }