From 880f4f1a949a9bb4e33f8cfa23a45ce61662b6eb Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 23 Dec 2024 14:43:12 +0100 Subject: [PATCH] feat(analytics): better naming for cards and dashboards modules --- backend/pkg/analytics/cards/cards.go | 54 +++++-------------- backend/pkg/analytics/cards/handlers.go | 54 +++---------------- backend/pkg/analytics/cards/model.go | 18 ------- .../pkg/analytics/dashboards/dashboards.go | 34 ++++++------ backend/pkg/analytics/dashboards/handlers.go | 20 +++---- 5 files changed, 47 insertions(+), 133 deletions(-) diff --git a/backend/pkg/analytics/cards/cards.go b/backend/pkg/analytics/cards/cards.go index 3e0033ce8..1425a61f0 100644 --- a/backend/pkg/analytics/cards/cards.go +++ b/backend/pkg/analytics/cards/cards.go @@ -14,14 +14,13 @@ import ( ) type Cards interface { - GetCard(projectId int, cardId int) (*CardGetResponse, error) - GetCardWithSeries(projectId int, cardId int) (*CardGetResponse, error) - GetCards(projectId int) (*GetCardsResponse, error) - GetCardsPaginated(projectId int, filters CardListFilter, sort CardListSort, limit int, offset int) (*GetCardsResponsePaginated, error) - CreateCard(projectId int, userId uint64, req *CardCreateRequest) (*CardGetResponse, error) - UpdateCard(projectId int, cardId int64, userId uint64, req *CardUpdateRequest) (*CardGetResponse, error) - DeleteCard(projectId int, cardId int64, userId uint64) error - GetCardChartData(projectId int, userId uint64, req *GetCardChartDataRequest) ([]DataPoint, error) + Create(projectId int, userId uint64, req *CardCreateRequest) (*CardGetResponse, error) + Get(projectId int, cardId int) (*CardGetResponse, error) + GetWithSeries(projectId int, cardId int) (*CardGetResponse, error) + GetAll(projectId int) (*GetCardsResponse, error) + GetAllPaginated(projectId int, filters CardListFilter, sort CardListSort, limit int, offset int) (*GetCardsResponsePaginated, error) + Update(projectId int, cardId int64, userId uint64, req *CardUpdateRequest) (*CardGetResponse, error) + Delete(projectId int, cardId int64, userId uint64) error } type cardsImpl struct { @@ -36,7 +35,7 @@ func New(log logger.Logger, conn pool.Pool) (Cards, error) { }, nil } -func (s *cardsImpl) CreateCard(projectId int, userID uint64, req *CardCreateRequest) (*CardGetResponse, error) { +func (s *cardsImpl) Create(projectId int, userID uint64, req *CardCreateRequest) (*CardGetResponse, error) { if req.MetricValue == nil { req.MetricValue = []string{} } @@ -153,7 +152,7 @@ func (s *cardsImpl) CreateSeries(ctx context.Context, tx pgx.Tx, metricId int64, return seriesList } -func (s *cardsImpl) GetCard(projectId int, cardID int) (*CardGetResponse, error) { +func (s *cardsImpl) Get(projectId int, cardID int) (*CardGetResponse, error) { sql := `SELECT metric_id, project_id, user_id, name, metric_type, view_type, metric_of, metric_value, metric_format, is_public, created_at, edited_at FROM public.metrics @@ -171,7 +170,7 @@ func (s *cardsImpl) GetCard(projectId int, cardID int) (*CardGetResponse, error) return card, nil } -func (s *cardsImpl) GetCardWithSeries(projectId int, cardID int) (*CardGetResponse, error) { +func (s *cardsImpl) GetWithSeries(projectId int, cardID int) (*CardGetResponse, error) { sql := ` SELECT m.metric_id, m.project_id, m.user_id, m.name, m.metric_type, m.view_type, m.metric_of, m.metric_value, m.metric_format, m.is_public, m.created_at, m.edited_at, @@ -210,7 +209,7 @@ func (s *cardsImpl) GetCardWithSeries(projectId int, cardID int) (*CardGetRespon return card, nil } -func (s *cardsImpl) GetCards(projectId int) (*GetCardsResponse, error) { +func (s *cardsImpl) GetAll(projectId int) (*GetCardsResponse, error) { sql := ` SELECT metric_id, project_id, user_id, name, metric_type, view_type, metric_of, metric_value, metric_format, is_public, created_at, edited_at FROM public.metrics @@ -237,7 +236,7 @@ func (s *cardsImpl) GetCards(projectId int) (*GetCardsResponse, error) { return &GetCardsResponse{Cards: cards}, nil } -func (s *cardsImpl) GetCardsPaginated( +func (s *cardsImpl) GetAllPaginated( projectId int, filters CardListFilter, sort CardListSort, @@ -347,7 +346,7 @@ func (s *cardsImpl) GetCardsPaginated( }, nil } -func (s *cardsImpl) UpdateCard(projectId int, cardID int64, userID uint64, req *CardUpdateRequest) (*CardGetResponse, error) { +func (s *cardsImpl) Update(projectId int, cardID int64, userID uint64, req *CardUpdateRequest) (*CardGetResponse, error) { if req.MetricValue == nil { req.MetricValue = []string{} } @@ -415,7 +414,7 @@ func (s *cardsImpl) DeleteCardSeries(cardId int64) error { return nil } -func (s *cardsImpl) DeleteCard(projectId int, cardID int64, userID uint64) error { +func (s *cardsImpl) Delete(projectId int, cardID int64, userID uint64) error { sql := ` UPDATE public.metrics SET deleted_at = now() @@ -427,28 +426,3 @@ func (s *cardsImpl) DeleteCard(projectId int, cardID int64, userID uint64) error } return nil } - -func (s *cardsImpl) GetCardChartData(projectId int, userID uint64, req *GetCardChartDataRequest) ([]DataPoint, error) { - jsonInput := ` - { - "data": [ - { - "timestamp": 1733934939000, - "Series A": 100, - "Series B": 200 - }, - { - "timestamp": 1733935939000, - "Series A": 150, - "Series B": 250 - } - ] - }` - - var resp GetCardChartDataResponse - if err := json.Unmarshal([]byte(jsonInput), &resp); err != nil { - return nil, fmt.Errorf("failed to unmarshal response: %w", err) - } - - return resp.Data, nil -} diff --git a/backend/pkg/analytics/cards/handlers.go b/backend/pkg/analytics/cards/handlers.go index cb9c389b8..13161b8b5 100644 --- a/backend/pkg/analytics/cards/handlers.go +++ b/backend/pkg/analytics/cards/handlers.go @@ -45,8 +45,6 @@ func (e *handlersImpl) GetAll() []*api.Description { {"/v1/analytics/{projectId}/cards/{id}", e.getCard, "GET"}, {"/v1/analytics/{projectId}/cards/{id}", e.updateCard, "PUT"}, {"/v1/analytics/{projectId}/cards/{id}", e.deleteCard, "DELETE"}, - {"/v1/analytics/{projectId}/cards/{id}/chart", e.getCardChartData, "POST"}, - {"/v1/analytics/{projectId}/cards/{id}/try", e.getCardChartData, "POST"}, } } @@ -90,7 +88,7 @@ func (e *handlersImpl) createCard(w http.ResponseWriter, r *http.Request) { } currentUser := r.Context().Value("userData").(*user.User) - resp, err := e.cards.CreateCard(projectID, currentUser.ID, req) + resp, err := e.cards.Create(projectID, currentUser.ID, req) if err != nil { e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusInternalServerError, err, startTime, r.URL.Path, bodySize) return @@ -116,7 +114,7 @@ func (e *handlersImpl) getCard(w http.ResponseWriter, r *http.Request) { return } - resp, err := e.cards.GetCardWithSeries(projectID, id) + resp, err := e.cards.GetWithSeries(projectID, id) if err != nil { e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusInternalServerError, err, startTime, r.URL.Path, bodySize) return @@ -136,7 +134,7 @@ func (e *handlersImpl) getCards(w http.ResponseWriter, r *http.Request) { } //currentUser := r.Context().Value("userData").(*user.User) - resp, err := e.cards.GetCards(projectID) + resp, err := e.cards.GetAll(projectID) if err != nil { e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusInternalServerError, err, startTime, r.URL.Path, bodySize) return @@ -219,7 +217,7 @@ func (e *handlersImpl) getCardsPaginated(w http.ResponseWriter, r *http.Request) } // Call the service - resp, err := e.cards.GetCardsPaginated(projectID, filters, sort, limit, offset) + resp, err := e.cards.GetAllPaginated(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 @@ -266,7 +264,7 @@ func (e *handlersImpl) updateCard(w http.ResponseWriter, r *http.Request) { } currentUser := r.Context().Value("userData").(*user.User) - resp, err := e.cards.UpdateCard(projectID, int64(cardId), currentUser.ID, req) + resp, err := e.cards.Update(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 @@ -292,7 +290,7 @@ func (e *handlersImpl) deleteCard(w http.ResponseWriter, r *http.Request) { } currentUser := r.Context().Value("userData").(*user.User) - err = e.cards.DeleteCard(projectID, int64(cardId), currentUser.ID) + err = e.cards.Delete(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 @@ -300,43 +298,3 @@ func (e *handlersImpl) deleteCard(w http.ResponseWriter, r *http.Request) { 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 := &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.cards.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) -} diff --git a/backend/pkg/analytics/cards/model.go b/backend/pkg/analytics/cards/model.go index 21692a355..5ab4144f0 100644 --- a/backend/pkg/analytics/cards/model.go +++ b/backend/pkg/analytics/cards/model.go @@ -85,24 +85,6 @@ type GetCardsResponsePaginated struct { Total int `json:"total"` } -type DataPoint struct { - Timestamp int64 `json:"timestamp"` - Series map[string]int64 `json:"series"` -} - -type GetCardChartDataRequest struct { - MetricType string `json:"metricType" validate:"required,oneof=timeseries table funnel"` - MetricOf string `json:"metricOf" validate:"required,oneof=session_count user_count"` - ViewType string `json:"viewType" validate:"required,oneof=line_chart table_view"` - MetricFormat string `json:"metricFormat" validate:"required,oneof=default percentage"` - SessionID int64 `json:"sessionId"` - Series []CardSeries `json:"series" validate:"required,dive"` -} - -type GetCardChartDataResponse struct { - Data []DataPoint `json:"data"` -} - /************************************************************ * CardListFilter and Sorter */ diff --git a/backend/pkg/analytics/dashboards/dashboards.go b/backend/pkg/analytics/dashboards/dashboards.go index 95ba863ed..7a4147654 100644 --- a/backend/pkg/analytics/dashboards/dashboards.go +++ b/backend/pkg/analytics/dashboards/dashboards.go @@ -11,14 +11,14 @@ import ( ) type Dashboards interface { - GetDashboard(projectId int, dashboardId int, userId uint64) (*GetDashboardResponse, error) - GetDashboardsPaginated(projectId int, userId uint64, req *GetDashboardsRequest) (*GetDashboardsResponsePaginated, error) - GetDashboards(projectId int, userId uint64) (*GetDashboardsResponse, error) - CreateDashboard(projectId int, userId uint64, req *CreateDashboardRequest) (*GetDashboardResponse, error) - UpdateDashboard(projectId int, dashboardId int, userId uint64, req *UpdateDashboardRequest) (*GetDashboardResponse, error) - DeleteDashboard(projectId int, dashboardId int, userId uint64) error - AddCardsToDashboard(projectId int, dashboardId int, userId uint64, req *AddCardToDashboardRequest) error - DeleteCardFromDashboard(dashboardId int, cardId int) error + Create(projectId int, userId uint64, req *CreateDashboardRequest) (*GetDashboardResponse, error) + Get(projectId int, dashboardId int, userId uint64) (*GetDashboardResponse, error) + GetAll(projectId int, userId uint64) (*GetDashboardsResponse, error) + GetAllPaginated(projectId int, userId uint64, req *GetDashboardsRequest) (*GetDashboardsResponsePaginated, error) + Update(projectId int, dashboardId int, userId uint64, req *UpdateDashboardRequest) (*GetDashboardResponse, error) + Delete(projectId int, dashboardId int, userId uint64) error + AddCards(projectId int, dashboardId int, userId uint64, req *AddCardToDashboardRequest) error + DeleteCard(dashboardId int, cardId int) error } type dashboardsImpl struct { @@ -34,7 +34,7 @@ func New(log logger.Logger, conn pool.Pool) (Dashboards, error) { } // CreateDashboard Create a new dashboard -func (s *dashboardsImpl) CreateDashboard(projectId int, userID uint64, req *CreateDashboardRequest) (*GetDashboardResponse, error) { +func (s *dashboardsImpl) Create(projectId int, userID uint64, req *CreateDashboardRequest) (*GetDashboardResponse, error) { sql := ` INSERT INTO dashboards (project_id, user_id, name, description, is_public, is_pinned) VALUES ($1, $2, $3, $4, $5, $6) @@ -57,7 +57,7 @@ func (s *dashboardsImpl) CreateDashboard(projectId int, userID uint64, req *Crea } // GetDashboard Fetch a specific dashboard by ID -func (s *dashboardsImpl) GetDashboard(projectId int, dashboardID int, userID uint64) (*GetDashboardResponse, error) { +func (s *dashboardsImpl) Get(projectId int, dashboardID int, userID uint64) (*GetDashboardResponse, error) { sql := ` WITH series_agg AS ( SELECT @@ -133,7 +133,7 @@ func (s *dashboardsImpl) GetDashboard(projectId int, dashboardID int, userID uin return dashboard, nil } -func (s *dashboardsImpl) GetDashboards(projectId int, userID uint64) (*GetDashboardsResponse, error) { +func (s *dashboardsImpl) GetAll(projectId int, userID uint64) (*GetDashboardsResponse, error) { sql := ` SELECT d.dashboard_id, d.user_id, d.project_id, d.name, d.description, d.is_public, d.is_pinned, u.email AS owner_email, u.name AS owner_name FROM dashboards d @@ -168,7 +168,7 @@ func (s *dashboardsImpl) GetDashboards(projectId int, userID uint64) (*GetDashbo } // GetDashboardsPaginated Fetch dashboards with pagination -func (s *dashboardsImpl) GetDashboardsPaginated(projectId int, userID uint64, req *GetDashboardsRequest) (*GetDashboardsResponsePaginated, error) { +func (s *dashboardsImpl) GetAllPaginated(projectId int, userID uint64, req *GetDashboardsRequest) (*GetDashboardsResponsePaginated, error) { baseSQL, args := buildBaseQuery(projectId, userID, req) // Count total dashboards @@ -217,7 +217,7 @@ func (s *dashboardsImpl) GetDashboardsPaginated(projectId int, userID uint64, re } // UpdateDashboard Update a dashboard -func (s *dashboardsImpl) UpdateDashboard(projectId int, dashboardID int, userID uint64, req *UpdateDashboardRequest) (*GetDashboardResponse, error) { +func (s *dashboardsImpl) Update(projectId int, dashboardID int, userID uint64, req *UpdateDashboardRequest) (*GetDashboardResponse, error) { sql := ` UPDATE dashboards SET name = $1, description = $2, is_public = $3, is_pinned = $4 @@ -241,7 +241,7 @@ func (s *dashboardsImpl) UpdateDashboard(projectId int, dashboardID int, userID } // DeleteDashboard Soft-delete a dashboard -func (s *dashboardsImpl) DeleteDashboard(projectId int, dashboardID int, userID uint64) error { +func (s *dashboardsImpl) Delete(projectId int, dashboardID int, userID uint64) error { sql := ` UPDATE dashboards SET deleted_at = now() @@ -320,8 +320,8 @@ func (s *dashboardsImpl) CardsExist(projectId int, cardIDs []int) (bool, error) return count == len(cardIDs), nil } -func (s *dashboardsImpl) AddCardsToDashboard(projectId int, dashboardId int, userId uint64, req *AddCardToDashboardRequest) error { - _, err := s.GetDashboard(projectId, dashboardId, userId) +func (s *dashboardsImpl) AddCards(projectId int, dashboardId int, userId uint64, req *AddCardToDashboardRequest) error { + _, err := s.Get(projectId, dashboardId, userId) if err != nil { return fmt.Errorf("failed to get dashboard: %w", err) } @@ -395,7 +395,7 @@ func (s *dashboardsImpl) AddCardsToDashboard(projectId int, dashboardId int, use return nil } -func (s *dashboardsImpl) DeleteCardFromDashboard(dashboardId int, cardId int) error { +func (s *dashboardsImpl) DeleteCard(dashboardId int, cardId int) error { sql := `DELETE FROM public.dashboard_widgets WHERE dashboard_id = $1 AND metric_id = $2` err := s.pgconn.Exec(sql, dashboardId, cardId) if err != nil { diff --git a/backend/pkg/analytics/dashboards/handlers.go b/backend/pkg/analytics/dashboards/handlers.go index f4c3ef573..a37005d00 100644 --- a/backend/pkg/analytics/dashboards/handlers.go +++ b/backend/pkg/analytics/dashboards/handlers.go @@ -90,7 +90,7 @@ func (e *handlersImpl) createDashboard(w http.ResponseWriter, r *http.Request) { } currentUser := r.Context().Value("userData").(*user.User) - resp, err := e.dashboards.CreateDashboard(projectID, currentUser.ID, req) + resp, err := e.dashboards.Create(projectID, currentUser.ID, req) e.responser.ResponseWithJSON(e.log, r.Context(), w, resp, startTime, r.URL.Path, bodySize) } @@ -107,7 +107,7 @@ func (e *handlersImpl) getDashboards(w http.ResponseWriter, r *http.Request) { } u := r.Context().Value("userData").(*user.User) - resp, err := e.dashboards.GetDashboards(projectID, u.ID) + resp, err := e.dashboards.GetAll(projectID, u.ID) if err != nil { e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusInternalServerError, err, startTime, r.URL.Path, bodySize) return @@ -133,7 +133,7 @@ func (e *handlersImpl) getDashboard(w http.ResponseWriter, r *http.Request) { } u := r.Context().Value("userData").(*user.User) - res, err := e.dashboards.GetDashboard(projectID, dashboardID, u.ID) + res, err := e.dashboards.Get(projectID, dashboardID, u.ID) if err != nil { // Map errors to appropriate HTTP status codes if err.Error() == "not_found: dashboard not found" { @@ -173,7 +173,7 @@ func (e *handlersImpl) updateDashboard(w http.ResponseWriter, r *http.Request) { bodySize = len(bodyBytes) u := r.Context().Value("userData").(*user.User) - _, err = e.dashboards.GetDashboard(projectID, dashboardID, u.ID) + _, err = e.dashboards.Get(projectID, dashboardID, u.ID) if err != nil { // Map errors to appropriate HTTP status codes if err.Error() == "not_found: dashboard not found" { @@ -193,7 +193,7 @@ func (e *handlersImpl) updateDashboard(w http.ResponseWriter, r *http.Request) { } currentUser := r.Context().Value("userData").(*user.User) - resp, err := e.dashboards.UpdateDashboard(projectID, dashboardID, currentUser.ID, req) + resp, err := e.dashboards.Update(projectID, dashboardID, currentUser.ID, req) e.responser.ResponseWithJSON(e.log, r.Context(), w, resp, startTime, r.URL.Path, bodySize) } @@ -215,7 +215,7 @@ func (e *handlersImpl) deleteDashboard(w http.ResponseWriter, r *http.Request) { } u := r.Context().Value("userData").(*user.User) - _, err = e.dashboards.GetDashboard(projectID, dashboardID, u.ID) + _, err = e.dashboards.Get(projectID, dashboardID, u.ID) if err != nil { // Map errors to appropriate HTTP status codes if err.Error() == "not_found: dashboard not found" { @@ -228,7 +228,7 @@ func (e *handlersImpl) deleteDashboard(w http.ResponseWriter, r *http.Request) { return } - err = e.dashboards.DeleteDashboard(projectID, dashboardID, u.ID) + err = e.dashboards.Delete(projectID, dashboardID, u.ID) if err != nil { e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusInternalServerError, err, startTime, r.URL.Path, bodySize) return @@ -286,7 +286,7 @@ func (e *handlersImpl) addCardToDashboard(w http.ResponseWriter, r *http.Request return } - err = e.dashboards.AddCardsToDashboard(projectID, dashboardID, u.ID, req) + err = e.dashboards.AddCards(projectID, dashboardID, u.ID, req) if err != nil { if err.Error() == "not_found: dashboard not found" { e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusNotFound, err, startTime, r.URL.Path, bodySize) @@ -325,7 +325,7 @@ func (e *handlersImpl) removeCardFromDashboard(w http.ResponseWriter, r *http.Re } u := r.Context().Value("userData").(*user.User) - _, err = e.dashboards.GetDashboard(projectID, dashboardID, u.ID) + _, err = e.dashboards.Get(projectID, dashboardID, u.ID) if err != nil { if err.Error() == "not_found: dashboard not found" { e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusNotFound, err, startTime, r.URL.Path, bodySize) @@ -336,7 +336,7 @@ func (e *handlersImpl) removeCardFromDashboard(w http.ResponseWriter, r *http.Re } } - err = e.dashboards.DeleteCardFromDashboard(dashboardID, cardID) + err = e.dashboards.DeleteCard(dashboardID, cardID) if err != nil { e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusInternalServerError, err, startTime, r.URL.Path, bodySize) return