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 { filter := bson.M{"_id": promoCode.ID, "usageMap." + userID: bson.M{"$exists": true}} count, err := r.mdb.CountDocuments(ctx, filter) if err != nil { return err } if count >= 1 { return ErrPromoCodeAlreadyActivated } var key string if req.FastLink != "" { key = req.FastLink } else { key = req.Codeword } usage := models.Usage{ Key: key, Time: time.Now(), } update := bson.M{ "$inc": bson.M{"usageCount": 1}, "$push": bson.M{ "usageMap." + userID: 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 nil, err } filter := bson.M{"_id": objID} var promoCodeStats models.PromoCodeStats err = r.mdb.FindOne(ctx, filter).Decode(&promoCodeStats) if err != nil { return nil, err } return &promoCodeStats, nil }