From c149d6a743cbd9e80d583fbb0ec91b0d14ee6a46 Mon Sep 17 00:00:00 2001 From: pasha1coil Date: Wed, 22 Nov 2023 20:31:17 +0300 Subject: [PATCH] update issue 3 --- .../controller/rest/history/history.go | 24 +++++++++ internal/interface/repository/history.go | 50 +++++++++++++++++++ internal/interface/swagger/api.go | 5 ++ internal/service/history/history.go | 34 +++++++++++++ 4 files changed, 113 insertions(+) diff --git a/internal/interface/controller/rest/history/history.go b/internal/interface/controller/rest/history/history.go index f5347d7..d44cf40 100644 --- a/internal/interface/controller/rest/history/history.go +++ b/internal/interface/controller/rest/history/history.go @@ -16,6 +16,7 @@ import ( type historyService interface { GetHistoryList(context.Context, *dto.GetHistories) (*models.PaginationResponse[models.History], errors.Error) + GetRecentTariffs(context.Context, string) ([]string, errors.Error) //new } type Deps struct { @@ -69,3 +70,26 @@ func (receiver *Controller) GetHistoryList(ctx echo.Context, params swagger.GetH return ctx.JSON(http.StatusOK, histories) } + +// TODO:tests +func (receiver *Controller) GetRecentTariffs(ctx echo.Context) error { + userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string) + if !ok { + receiver.logger.Error("failed to convert jwt payload to string on of ") + return errors.HTTP(ctx, errors.New( + fmt.Errorf("failed to convert jwt payload to string: %s", userID), + errors.ErrInvalidArgs, + )) + } + + tariffs, err := receiver.historyService.GetRecentTariffs(ctx.Request().Context(), userID) + if err != nil { + receiver.logger.Error("failed to get recent tariffs on of ", + zap.String("userId", userID), + zap.Error(err), + ) + return errors.HTTP(ctx, err) + } + + return ctx.JSON(http.StatusOK, tariffs) +} diff --git a/internal/interface/repository/history.go b/internal/interface/repository/history.go index 1abd6f6..073aacb 100644 --- a/internal/interface/repository/history.go +++ b/internal/interface/repository/history.go @@ -3,7 +3,9 @@ package repository import ( "context" "fmt" + "go.mongodb.org/mongo-driver/bson" "log" + "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/fields" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" @@ -107,3 +109,51 @@ func (receiver *HistoryRepository) CountAll(ctx context.Context, dto *dto.GetHis return count, nil } + +// TODO:tests +// GetRecentTariffs method for processing a user request with data aggregation with a limit of 100 sorted in descending order +func (receiver *HistoryRepository) GetRecentTariffs(ctx context.Context, userID string) ([]string, errors.Error) { + var result []struct { + ID string `bson:"tariffID"` + } + filter := bson.D{ + {fields.History.UserID, userID}, + {fields.History.IsDeleted, false}, + } + pipeline := mongo.Pipeline{ + {{"$match", filter}}, + {{"$unwind", "$rawDetails"}}, + {{"$match", bson.D{{"rawDetails.Key", "tariffs"}}}}, + {{"$unwind", "$rawDetails.Value"}}, + {{"$group", bson.D{{"_id", "$rawDetails.Value.Key.id"}}}}, + {{"$sort", bson.D{{"createdAt", -1}}}}, // -1 specifies descending order + {{"$limit", 100}}, + } + cursor, err := receiver.mongoDB.Aggregate(ctx, pipeline) + if err != nil { + receiver.logger.Error("failed to get recent tariffs on of ", + zap.String("userId", userID), + zap.Error(err), + ) + return nil, errors.New( + fmt.Errorf("failed to get recent tariffs on of : %w", err), + errors.ErrInternalError, + ) + } + + if err := cursor.All(ctx, &result); err != nil { + receiver.logger.Error("failed to decode recent tariffs on of ", + zap.String("userId", userID), + zap.Error(err), + ) + return nil, errors.New( + fmt.Errorf("failed to decode recent tariffs on of : %w", err), + errors.ErrInternalError, + ) + } + tariffs := make([]string, len(result)) + for i, item := range result { + tariffs[i] = item.ID + } + return tariffs, nil +} diff --git a/internal/interface/swagger/api.go b/internal/interface/swagger/api.go index 3784d8c..9ae85af 100644 --- a/internal/interface/swagger/api.go +++ b/internal/interface/swagger/api.go @@ -35,6 +35,7 @@ type walletController interface { type historyController interface { GetHistoryList(ctx echo.Context, params GetHistoryParams) error + GetRecentTariffs(ctx echo.Context) error } type Deps struct { @@ -147,6 +148,10 @@ func (receiver *API) GetHistory(ctx echo.Context, params GetHistoryParams) error return receiver.historyController.GetHistoryList(ctx, params) } +func (receiver *API) GetRecentTariffs(ctx echo.Context) error { + return receiver.historyController.GetRecentTariffs(ctx) +} + // Wallet func (receiver *API) RequestMoney(ctx echo.Context) error { diff --git a/internal/service/history/history.go b/internal/service/history/history.go index 4894d30..013732b 100644 --- a/internal/service/history/history.go +++ b/internal/service/history/history.go @@ -16,6 +16,7 @@ type historyRepository interface { CountAll(context.Context, *dto.GetHistories) (int64, errors.Error) FindMany(context.Context, *dto.GetHistories) ([]models.History, errors.Error) Insert(context.Context, *models.History) (*models.History, errors.Error) + GetRecentTariffs(context.Context, string) ([]string, errors.Error) //new } type Deps struct { @@ -90,3 +91,36 @@ func (receiver *Service) CreateHistory(ctx context.Context, history *models.Hist return createdHistory, nil } + +// TODO:tests +func (receiver *Service) GetRecentTariffs(ctx context.Context, userID string) ([]string, errors.Error) { + // Validation of input data + if userID == "" { + receiver.logger.Error("user id is missing in of ") + return nil, errors.New( + fmt.Errorf("user id is missing: %w", errors.ErrInvalidArgs), + errors.ErrInvalidArgs, + ) + } + + tariffs, err := receiver.repository.GetRecentTariffs(ctx, userID) + if err != nil { + receiver.logger.Error( + "failed to get recent tariffs in of ", + zap.String("userId", userID), + zap.Error(err), + ) + return nil, err + } + + // Processing the received response, optional + if len(tariffs) == 0 { + receiver.logger.Info( + "no recent tariffs found for user in of ", + zap.String("userId", userID), + ) + // если слайс тарифов пуст является ли это ошибкой, возвращать ошибку или пустой слайс? + } + + return tariffs, nil +}