package repository import ( "codeword/internal/models" "context" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "time" ) type StatsRepository struct { mdb *mongo.Collection } func NewStatsRepository(deps Deps) *StatsRepository { return &StatsRepository{mdb: deps.Mdb} } func (r *StatsRepository) UpdateStatistics(ctx context.Context, req *models.ActivateReq, promoCode *models.PromoCode, userID string) error { var key string if req.FastLink != "" { key = req.FastLink } else { key = "-" } var promoCodeStats models.PromoCodeStats err := r.mdb.FindOne(ctx, bson.M{"_id": promoCode.ID}).Decode(&promoCodeStats) if err != nil && mongo.ErrNoDocuments == nil { return err } if promoCodeStats.UsageMap != nil { usageList := promoCodeStats.UsageMap[key] for _, usage := range usageList { if usage.UserID == userID { return ErrPromoCodeAlreadyActivated } } } usage := models.Usage{ UserID: userID, Time: uint64(time.Now().Unix()), } update := bson.M{ "$push": bson.M{ "usageMap." + key: usage, }, } opts := options.Update().SetUpsert(true) _, err = r.mdb.UpdateOne(ctx, bson.M{"_id": promoCode.ID}, update, opts) return err } func (r *StatsRepository) GetStatistics(ctx context.Context, promoCodeID string) (models.PromoCodeStats, error) { objID, err := primitive.ObjectIDFromHex(promoCodeID) if err != nil { return models.PromoCodeStats{}, err } filter := bson.M{"_id": objID} var promoCodeStats models.PromoCodeStats err = r.mdb.FindOne(ctx, filter).Decode(&promoCodeStats) if err != nil { return models.PromoCodeStats{}, err } return promoCodeStats, nil }