openreplay/backend/pkg/analytics/api/card-handlers.go
2024-12-18 11:02:44 +01:00

296 lines
9.1 KiB
Go

package api
import (
"encoding/json"
"fmt"
"net/http"
"openreplay/backend/pkg/analytics/api/models"
"openreplay/backend/pkg/server/api"
"openreplay/backend/pkg/server/user"
"strconv"
"time"
"github.com/go-playground/validator/v10"
)
func (e *handlersImpl) createCard(w http.ResponseWriter, r *http.Request) {
startTime := time.Now()
bodySize := 0
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 := &models.CardCreateRequest{}
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
}
validate := validator.New()
err = validate.Struct(req)
if err != nil {
e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusBadRequest, err, startTime, r.URL.Path, bodySize)
return
}
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
}
currentUser := r.Context().Value("userData").(*user.User)
resp, err := e.service.CreateCard(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)
}
// getCard
func (e *handlersImpl) getCard(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
}
id, err := getIDFromRequest(r, "id")
if err != nil {
e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusBadRequest, err, startTime, r.URL.Path, bodySize)
return
}
resp, err := e.service.GetCardWithSeries(projectID, id)
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)
}
func (e *handlersImpl) getCards(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
}
//currentUser := r.Context().Value("userData").(*user.User)
resp, err := e.service.GetCards(projectID)
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)
}
func (e *handlersImpl) getCardsPaginated(w http.ResponseWriter, r *http.Request) {
startTime := time.Now()
bodySize := 0
// Extract projectID from request
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
}
// Parse query parameters
query := r.URL.Query()
// Filters
filters := models.CardListFilter{
Filters: make(map[string]interface{}),
}
if name := query.Get("name"); name != "" {
filters.Filters["name"] = name
}
if metricType := query.Get("metric_type"); metricType != "" {
filters.Filters["metric_type"] = metricType
}
if dashboardIDs := query["dashboard_ids"]; len(dashboardIDs) > 0 {
// Parse dashboard_ids into []int
var ids []int
for _, id := range dashboardIDs {
if val, err := strconv.Atoi(id); err == nil {
ids = append(ids, val)
}
}
filters.Filters["dashboard_ids"] = ids
}
// Sorting
sort := models.CardListSort{
Field: query.Get("sort_field"),
Order: query.Get("sort_order"),
}
if sort.Field == "" {
sort.Field = "created_at" // Default sort field
}
if sort.Order == "" {
sort.Order = "desc" // Default sort order
}
// Pagination
limit := 10 // Default limit
page := 1 // Default page number
if val := query.Get("limit"); val != "" {
if l, err := strconv.Atoi(val); err == nil && l > 0 {
limit = l
}
}
if val := query.Get("page"); val != "" {
if p, err := strconv.Atoi(val); err == nil && p > 0 {
page = p
}
}
offset := (page - 1) * limit
// Validate inputs
if err := models.ValidateStruct(filters); err != nil {
e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusBadRequest, fmt.Errorf("invalid filters: %w", err), startTime, r.URL.Path, bodySize)
return
}
if err := models.ValidateStruct(sort); err != nil {
e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusBadRequest, fmt.Errorf("invalid sort: %w", err), startTime, r.URL.Path, bodySize)
return
}
// Call the service
resp, err := e.service.GetCardsPaginated(projectID, filters, sort, limit, offset)
if err != nil {
e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusInternalServerError, err, startTime, r.URL.Path, bodySize)
return
}
// Respond with JSON
e.responser.ResponseWithJSON(e.log, r.Context(), w, resp, startTime, r.URL.Path, bodySize)
}
func (e *handlersImpl) updateCard(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
}
cardId, err := getIDFromRequest(r, "id")
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 := &models.CardUpdateRequest{}
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
}
validate := validator.New()
err = validate.Struct(req)
if 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.service.UpdateCard(projectID, int64(cardId), 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)
}
func (e *handlersImpl) deleteCard(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
}
cardId, err := getIDFromRequest(r, "id")
if 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)
err = e.service.DeleteCard(projectID, int64(cardId), currentUser.ID)
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, nil, startTime, r.URL.Path, bodySize)
}
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 := &models.GetCardChartDataRequest{}
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
}
validate := validator.New()
err = validate.Struct(req)
if 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.service.GetCardChartData(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)
}