customer/internal/interface/repository/history.go

160 lines
4.7 KiB
Go
Raw Normal View History

2023-05-23 10:52:27 +00:00
package repository
import (
"context"
"fmt"
2023-11-22 17:31:17 +00:00
"go.mongodb.org/mongo-driver/bson"
2023-05-23 10:52:27 +00:00
"log"
2023-11-22 17:31:17 +00:00
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/fields"
2023-05-23 10:52:27 +00:00
2023-10-16 12:12:12 +00:00
"go.mongodb.org/mongo-driver/bson"
2023-05-23 10:52:27 +00:00
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
2023-05-23 15:24:52 +00:00
"go.mongodb.org/mongo-driver/mongo/options"
2023-05-23 10:52:27 +00:00
"go.uber.org/zap"
2023-09-14 10:02:32 +00:00
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/dto"
2023-05-23 10:52:27 +00:00
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
2023-05-23 15:24:52 +00:00
mongoWrapper "penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/mongo"
2023-05-23 10:52:27 +00:00
)
type HistoryRepositoryDeps struct {
Logger *zap.Logger
MongoDB *mongo.Collection
}
type HistoryRepository struct {
logger *zap.Logger
mongoDB *mongo.Collection
}
2023-06-13 22:51:34 +00:00
func NewHistoryRepository(deps HistoryRepositoryDeps) *HistoryRepository {
2023-05-23 10:52:27 +00:00
if deps.Logger == nil {
log.Panicln("logger is nil on <NewHistoryRepository>")
}
if deps.MongoDB == nil {
log.Panicln("mongodb is nil on <NewHistoryRepository>")
}
return &HistoryRepository{
logger: deps.Logger,
mongoDB: deps.MongoDB,
}
}
func (receiver *HistoryRepository) Insert(ctx context.Context, history *models.History) (*models.History, errors.Error) {
2023-06-15 12:45:38 +00:00
result, err := receiver.mongoDB.InsertOne(ctx, history.Sanitize())
2023-05-23 10:52:27 +00:00
if err != nil {
receiver.logger.Error("failed to insert history on <Insert> of <HistoryRepository>",
zap.Any("history", history),
zap.Error(err),
)
return nil, errors.New(
fmt.Errorf("failed to insert history on <Insert> of <HistoryRepository>: %w", err),
errors.ErrInternalError,
)
}
insertedID := result.InsertedID.(primitive.ObjectID).Hex()
history.ID = insertedID
return history, nil
}
2023-09-14 10:02:32 +00:00
func (receiver *HistoryRepository) FindMany(ctx context.Context, dto *dto.GetHistories) ([]models.History, errors.Error) {
2023-05-23 15:24:52 +00:00
findOptions := options.Find()
2023-09-14 10:02:32 +00:00
findOptions.SetSkip((dto.Pagination.Page - 1) * dto.Pagination.Limit)
findOptions.SetLimit(dto.Pagination.Limit)
2023-10-16 12:12:12 +00:00
findOptions.SetSort(bson.D{{
Key: "createdAt", Value: -1,
}})
2023-05-23 15:24:52 +00:00
histories, err := mongoWrapper.Find[models.History](ctx, &mongoWrapper.RequestSettings{
Driver: receiver.mongoDB,
Options: findOptions,
2023-09-14 10:02:32 +00:00
Filter: dto.BSON(),
2023-05-23 15:24:52 +00:00
})
if err != nil {
receiver.logger.Error("failed to find many histories on <FindMany> of <HistoryRepository>",
2023-09-14 10:02:32 +00:00
zap.Int64("page", dto.Pagination.Page),
zap.Int64("limit", dto.Pagination.Limit),
zap.Int64("skip", (dto.Pagination.Page-1)*dto.Pagination.Limit),
2023-05-23 15:24:52 +00:00
zap.Error(err),
)
return nil, errors.New(
fmt.Errorf("failed to find many histories on <FindMany> of <HistoryRepository>: %w", err),
errors.ErrInternalError,
)
}
return histories, nil
}
2023-09-14 23:01:53 +00:00
func (receiver *HistoryRepository) CountAll(ctx context.Context, dto *dto.GetHistories) (int64, errors.Error) {
count, err := receiver.mongoDB.CountDocuments(ctx, dto.BSON())
2023-05-23 10:52:27 +00:00
if err != nil {
receiver.logger.Error("failed to count all documents on <CountAll> of <HistoryRepository>",
zap.Error(err),
)
return 0, errors.New(
fmt.Errorf("failed to count all documents on <CountAll> of <HistoryRepository>: %w", err),
errors.ErrInternalError,
)
}
return count, nil
}
2023-11-22 17:31:17 +00:00
// 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 <GetRecentTariffs> of <HistoryRepository>",
zap.String("userId", userID),
zap.Error(err),
)
return nil, errors.New(
fmt.Errorf("failed to get recent tariffs on <GetRecentTariffs> of <HistoryRepository>: %w", err),
errors.ErrInternalError,
)
}
if err := cursor.All(ctx, &result); err != nil {
receiver.logger.Error("failed to decode recent tariffs on <GetRecentTariffs> of <HistoryRepository>",
zap.String("userId", userID),
zap.Error(err),
)
return nil, errors.New(
fmt.Errorf("failed to decode recent tariffs on <GetRecentTariffs> of <HistoryRepository>: %w", err),
errors.ErrInternalError,
)
}
tariffs := make([]string, len(result))
for i, item := range result {
tariffs[i] = item.ID
}
return tariffs, nil
}