openreplay/backend/pkg/analytics/charts/handlers.go
2025-05-23 17:02:45 +02:00

96 lines
2.7 KiB
Go

package charts
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"time"
"github.com/go-playground/validator/v10"
"github.com/gorilla/mux"
config "openreplay/backend/internal/config/analytics"
"openreplay/backend/pkg/logger"
"openreplay/backend/pkg/server/api"
"openreplay/backend/pkg/server/user"
)
func getIDFromRequest(r *http.Request, key string) (int, error) {
vars := mux.Vars(r)
idStr := vars[key]
if idStr == "" {
return 0, fmt.Errorf("missing %s in request", key)
}
id, err := strconv.Atoi(idStr)
if err != nil {
return 0, fmt.Errorf("invalid %s format", key)
}
return id, nil
}
type handlersImpl struct {
log logger.Logger
responser *api.Responser
jsonSizeLimit int64
charts Charts
validator *validator.Validate
}
func (e *handlersImpl) GetAll() []*api.Description {
return []*api.Description{
{"/v1/analytics/{projectId}/cards/{id}/chart", e.getCardChartData, "POST"}, // for dashboards
{"/v1/analytics/{projectId}/cards/{id}/try", e.getCardChartData, "POST"},
{"/v1/analytics/{projectId}/cards/try", e.getCardChartData, "POST"}, // for cards itself
}
}
func NewHandlers(log logger.Logger, cfg *config.Config, responser *api.Responser, charts Charts, validator *validator.Validate) (api.Handlers, error) {
return &handlersImpl{
log: log,
responser: responser,
jsonSizeLimit: cfg.JsonSizeLimit,
charts: charts,
validator: validator,
}, nil
}
func (e *handlersImpl) getCardChartData(w http.ResponseWriter, r *http.Request) {
startTime := time.Now()
bodySize := 0
projectID, err := getIDFromRequest(r, "projectId")
if err != nil {
e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusBadRequest, err, startTime, r.URL.Path, bodySize)
return
}
bodyBytes, err := api.ReadBody(e.log, w, r, e.jsonSizeLimit)
if err != nil {
e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusRequestEntityTooLarge, err, startTime, r.URL.Path, bodySize)
return
}
bodySize = len(bodyBytes)
req := &MetricPayload{}
if err := json.Unmarshal(bodyBytes, req); err != nil {
e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusBadRequest, err, startTime, r.URL.Path, bodySize)
return
}
if err = e.validator.Struct(req); err != nil {
e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusBadRequest, err, startTime, r.URL.Path, bodySize)
return
}
currentUser := r.Context().Value("userData").(*user.User)
resp, err := e.charts.GetData(projectID, currentUser.ID, req)
if err != nil {
e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusInternalServerError, err, startTime, r.URL.Path, bodySize)
return
}
e.responser.ResponseWithJSON(e.log, r.Context(), w, resp, startTime, r.URL.Path, bodySize)
}