add base logic for falstlinks

This commit is contained in:
Pavel 2024-01-14 17:18:36 +03:00
parent 1019fd3f83
commit c583494fe7
8 changed files with 101 additions and 9 deletions

1
go.mod

@ -27,6 +27,7 @@ require (
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.50.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect

2
go.sum

@ -47,6 +47,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=

@ -84,14 +84,15 @@ func (p *PromoCodeController) GetList(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(resp)
}
// todo затестить и обновить в opnapi
func (p *PromoCodeController) Activate(c *fiber.Ctx) error {
var req models.ActivateReq
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"})
}
if req.Codeword == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "codeword is required"})
if req.Codeword == "" && req.FastLink == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "codeword or fastlink is required"})
}
greetings, err := p.promoCodeService.ActivatePromo(c.Context(), &req)
@ -131,3 +132,27 @@ func (p *PromoCodeController) Delete(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusOK)
}
// todo затестить и добавить в opnapi
func (p *PromoCodeController) CreateFastLink(c *fiber.Ctx) error {
// нужно что-то получать из Localstorage например id или codeword
var req struct {
PromoCodeID string `json:"promoCodeID"`
}
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"})
}
fastLink, err := p.promoCodeService.CreateFastLink(c.Context(), req.PromoCodeID)
if err != nil {
p.logger.Error("Failed to create fastlink", zap.Error(err))
if errors.Is(err, repository.ErrPromoCodeNotFound) {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"})
}
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
return c.Status(fiber.StatusCreated).JSON(fiber.Map{"fastlink": fastLink})
}

@ -28,6 +28,7 @@ type PromoCode struct {
OffLimit bool `json:"offLimit" bson:"offLimit"`
Delete bool `json:"delete" bson:"delete"`
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
FastLinks []string `json:"fastLinks" bson:"fastLinks"`
}
type ReqEditPromoCode struct {
@ -59,6 +60,7 @@ type GetPromoCodesListResp struct {
type ActivateReq struct {
Codeword string `json:"codeword"`
FastLink string `json:"fastLink"`
}
type ActivateResp struct {

@ -196,7 +196,10 @@ func (r *PromoCodeRepository) ActivatePromo(ctx context.Context, req *models.Act
var greetings string
transactionErr := mongo.WithSession(ctx, session, func(sc mongo.SessionContext) error {
filter := bson.M{
var filter bson.M
if req.Codeword != "" {
filter = bson.M{
"codeword": req.Codeword,
"delete": false,
"outdated": false,
@ -204,6 +207,19 @@ func (r *PromoCodeRepository) ActivatePromo(ctx context.Context, req *models.Act
"activationCount": bson.M{"$gt": 0},
"dueTo": bson.M{"$gt": time.Now().Unix()},
}
} else if req.FastLink != "" {
filter = bson.M{
"fastLinks": req.FastLink,
"delete": false,
"outdated": false,
"offLimit": false,
"activationCount": bson.M{"$gt": 0},
"dueTo": bson.M{"$gt": time.Now().Unix()},
}
} else {
return errors.New("codeword or xid is required")
}
update := bson.M{
"$inc": bson.M{"activationCount": -1},
}
@ -251,3 +267,19 @@ func (r *PromoCodeRepository) DeletePromoCode(ctx context.Context, promoCodeID s
return nil
}
func (r *PromoCodeRepository) AddFastLink(ctx context.Context, promoCodeID primitive.ObjectID, xid string) error {
filter := bson.M{"_id": promoCodeID, "delete": false}
update := bson.M{"$push": bson.M{"fastLinks": xid}}
result, err := r.mdb.UpdateOne(ctx, filter, update)
if err != nil {
return err
}
if result.MatchedCount == 0 {
return ErrPromoCodeNotFound
}
return nil
}

@ -62,6 +62,7 @@ func (s *Server) registerRoutes() {
s.app.Post("/promocode/getList", s.PromoCodeController.GetList)
s.app.Post("/promocode/activate", s.PromoCodeController.Activate)
s.app.Delete("/promocode/:promocodeID", s.PromoCodeController.Delete)
s.app.Post("/promocode/fastlink", s.PromoCodeController.CreateFastLink)
//... other
}

@ -2,7 +2,9 @@ package services
import (
"codeword/internal/models"
"codeword/internal/utils/genID"
"context"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.uber.org/zap"
)
@ -12,6 +14,8 @@ type PromoCodeRepository interface {
GetPromoCodesList(ctx context.Context, req *models.GetPromoCodesListReq) ([]models.PromoCode, int64, error)
ActivatePromo(ctx context.Context, req *models.ActivateReq) (string, error)
DeletePromoCode(ctx context.Context, promoCodeID string) error
GetPromoCodeByID(ctx context.Context, promoCodeID primitive.ObjectID) (*models.PromoCode, error)
AddFastLink(ctx context.Context, promoCodeID primitive.ObjectID, xid string) error
}
type PromoDeps struct {
@ -80,3 +84,20 @@ func (s *PromoCodeService) DeletePromoCode(ctx context.Context, promoCodeID stri
return nil
}
func (s *PromoCodeService) CreateFastLink(ctx context.Context, promoCodeID string) (string, error) {
xid := genID.GenerateXID()
promoID, err := primitive.ObjectIDFromHex(promoCodeID)
if err != nil {
s.logger.Error("Failed conversion promoCodeID to ObjectID", zap.Error(err))
return "", err
}
err = s.promoCodeRepo.AddFastLink(ctx, promoID, xid)
if err != nil {
s.logger.Error("Failed to add fastlink for promocode by promocode id", zap.Error(err))
return "", err
}
return xid, nil
}

@ -0,0 +1,8 @@
package genID
import "github.com/rs/xid"
func GenerateXID() string {
id := xid.New()
return id.String()
}