add promo stats activation with time duration

This commit is contained in:
Pavel 2024-04-25 13:57:26 +03:00
parent e175593b3b
commit c7a8e3b6e9
5 changed files with 108 additions and 9 deletions

16
docs/proto/promo.proto Normal file

@ -0,0 +1,16 @@
syntax = "proto3";
package codeword;
message Time {
int64 from = 1;
int64 to = 2;
}
service PromoCodeService {
rpc GetAllPromoActivations(Time) returns (PromoActivationResp);
}
message PromoActivationResp {
map<string, repeated string> response = 1;
}

@ -210,3 +210,19 @@ func (p *PromoCodeController) GetStats(c *fiber.Ctx) error {
}
return c.Status(fiber.StatusOK).JSON(promoStats)
}
func (p *PromoCodeController) GetAllPromoActivations(c *fiber.Ctx) error {
var req models.Time
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"})
}
result, err := p.promoCodeService.GetAllPromoActivations(c.Context(), &req)
if err != nil {
p.logger.Error("Failed getting all promo activations", zap.Error(err))
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error: " + err.Error()})
}
return c.Status(fiber.StatusOK).JSON(result)
}

@ -10,7 +10,6 @@ func (p *PromoCodeController) Register(router fiber.Router) {
router.Delete("/:promocodeID", p.Delete)
router.Post("/fastlink", p.CreateFastLink)
router.Post("/stats", p.GetStats)
}
func (p *PromoCodeController) Name() string {

@ -77,3 +77,60 @@ func (r *StatsRepository) GetStatistics(ctx context.Context, promoCodeID string)
return promoCodeStats, nil
}
func (r *StatsRepository) GetAllPromoActivations(ctx context.Context, req *models.Time) (map[string][]string, error) {
pipeline := []bson.M{
{
"$project": bson.M{
"_id": 1,
"usageArray": bson.M{"$objectToArray": "$usageMap"},
},
},
{
"$unwind": "$usageArray",
},
{
"$unwind": "$usageArray.v",
},
{
"$match": bson.M{
"usageArray.v.time": bson.M{
"$gte": req.From,
"$lte": req.To,
},
},
},
{
"$group": bson.M{
"_id": "$_id",
"users": bson.M{"$push": bson.M{
"UserID": "$usageArray.v.userID",
}},
},
},
}
cursor, err := r.mdb.Aggregate(ctx, pipeline)
if err != nil {
return nil, err
}
result := make(map[string][]string)
for cursor.Next(ctx) {
var data struct {
ID string `bson:"_id"`
Users []struct {
UserID string `bson:"UserID"`
} `bson:"users"`
}
err := cursor.Decode(&data)
if err != nil {
return nil, err
}
for _, user := range data.Users {
result[data.ID] = append(result[data.ID], user.UserID)
}
}
return result, nil
}

@ -28,6 +28,7 @@ type PromoCodeRepository interface {
type PromoStatsRepository interface {
UpdateStatistics(ctx context.Context, req *models.ActivateReq, promoCode *models.PromoCode, userID string) error
GetStatistics(ctx context.Context, promoCodeID string) (models.PromoCodeStats, error)
GetAllPromoActivations(ctx context.Context, req *models.Time) (map[string][]string, error)
}
type PromoDeps struct {
@ -268,3 +269,13 @@ func (s *PromoCodeService) GetStats(ctx context.Context, req models.PromoStatReq
return resp, nil
}
func (s *PromoCodeService) GetAllPromoActivations(ctx context.Context, req *models.Time) (map[string][]string, error) {
result, err := s.statsRepo.GetAllPromoActivations(ctx, req)
if err != nil {
s.logger.Error("error getting all promo activations data", zap.Error(err))
return nil, err
}
return result, nil
}