add base logic for promo created
This commit is contained in:
parent
95559a0fda
commit
f3df811c9b
@ -1,8 +1,8 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
promocontroller "codeword/internal/controller/promocode"
|
||||
reccontroller "codeword/internal/controller/recovery"
|
||||
"codeword/internal/controller/promocode"
|
||||
"codeword/internal/controller/recovery"
|
||||
"codeword/internal/initialize"
|
||||
"codeword/internal/repository"
|
||||
httpserver "codeword/internal/server/http"
|
||||
@ -26,9 +26,9 @@ func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
|
||||
rdb, err := initialize.Redis(ctx, cfg)
|
||||
encrypt := initialize.Encrypt(cfg)
|
||||
|
||||
promoCodeRepo := repository.NewPromoCodeRepository(mdb.Collection("promoCodes"))
|
||||
codewordRepo := repository.NewCodewordRepository(repository.Deps{Rdb: rdb, Mdb: mdb.Collection("codeword")})
|
||||
userRepo := repository.NewUserRepository(repository.Deps{Rdb: nil, Mdb: mdb.Collection("users")})
|
||||
promoCodeRepo := repository.NewPromoCodeRepository(mdb.Collection("promocodes"))
|
||||
|
||||
recoveryEmailSender := initialize.RecoveryEmailSender(cfg, logger)
|
||||
authClient := initialize.AuthClient(cfg, logger)
|
||||
@ -46,8 +46,8 @@ func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
|
||||
PromoCodeRepo: promoCodeRepo,
|
||||
})
|
||||
|
||||
recoveryController := reccontroller.NewRecoveryController(logger, recoveryService, cfg.DefaultRedirectionURL)
|
||||
promoCodeController := promocontroller.NewPromoCodeController(logger, promoService)
|
||||
recoveryController := recovery.NewRecoveryController(logger, recoveryService, cfg.DefaultRedirectionURL)
|
||||
promoCodeController := promocode.NewPromoCodeController(logger, promoService)
|
||||
|
||||
recoveryWC := recovery_worker.NewRecoveryWC(recovery_worker.Deps{
|
||||
Logger: logger,
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
package controller
|
||||
package promocode
|
||||
|
||||
import (
|
||||
"codeword/internal/models"
|
||||
"codeword/internal/repository"
|
||||
"codeword/internal/services"
|
||||
"errors"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
@ -28,6 +30,11 @@ func (p *PromoCodeController) CreatePromoCode(c *fiber.Ctx) error {
|
||||
createdPromoCode, err := p.promoCodeService.CreatePromoCode(c.Context(), &reqCreatePromoCode)
|
||||
if err != nil {
|
||||
p.logger.Error("Failed to create promocode", zap.Error(err))
|
||||
|
||||
if errors.Is(err, repository.ErrDuplicateCodeword) {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Duplicate Codeword"})
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package controller
|
||||
package recovery
|
||||
|
||||
import (
|
||||
"codeword/internal/models"
|
||||
|
||||
@ -1,28 +1,31 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PromoCode struct {
|
||||
ID string `json:"id"`
|
||||
Codeword string `json:"codeword"` // то, что будет вводить пользователь, чтобы получить плюшки
|
||||
Description string `json:"description"` // описание, необходимое менеджеру в админке
|
||||
Greetings string `json:"greetings"` // текст, выдаваемый пользователю в ответ на активацию промокода
|
||||
DueTo int64 `json:"dueTo"` // таймштамп времени окончания работы активации промокода
|
||||
ActivationCount int64 `json:"activationCount"` // предел количества активаций промокода
|
||||
ID primitive.ObjectID `json:"id" bson:"_id"`
|
||||
Codeword string `json:"codeword" bson:"codeword"` // то, что будет вводить пользователь, чтобы получить плюшки
|
||||
Description string `json:"description" bson:"description"` // описание, необходимое менеджеру в админке
|
||||
Greetings string `json:"greetings" bson:"greetings"` // текст, выдаваемый пользователю в ответ на активацию промокода
|
||||
DueTo int64 `json:"dueTo" bson:"dueTo"` // таймштамп времени окончания работы активации промокода
|
||||
ActivationCount int64 `json:"activationCount" bson:"activationCount"` // предел количества активаций промокода
|
||||
Bonus struct {
|
||||
Privilege struct {
|
||||
PrivilegeID string `json:"privilegeID"` // айдишник привилегии, которая будет выдаваться
|
||||
Amount uint64 `json:"amount"` // количество
|
||||
} `json:"privilege"`
|
||||
PrivilegeID string `json:"privilegeID" bson:"privilegeID"` // айдишник привилегии, которая будет выдаваться
|
||||
Amount uint64 `json:"amount" bson:"amount"` // количество
|
||||
} `json:"privilege" bson:"privilege"`
|
||||
Discount struct {
|
||||
Layer int `json:"layer"` // 1|2
|
||||
Factor float64 `json:"factor"` // процент скидки, вернее множитель, при котором достигается этот процент скидки
|
||||
Target string `json:"target"` // PrivilegeID или ServiceKey в зависимости от слоя
|
||||
Threshold int64 `json:"threshold"` // граничное значение, при пересечении которого применяется эта скидка
|
||||
} `json:"discount"`
|
||||
} `json:"bonus"`
|
||||
Outdated bool `json:"outdated"`
|
||||
OffLimit bool `json:"offLimit"`
|
||||
Delete bool `json:"delete"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Layer int `json:"layer" bson:"layer"` // 1|2
|
||||
Factor float64 `json:"factor" bson:"factor"` // процент скидки, вернее множитель, при котором достигается этот процент скидки
|
||||
Target string `json:"target" bson:"target"` // PrivilegeID или ServiceKey в зависимости от слоя
|
||||
Threshold int64 `json:"threshold" bson:"threshold"` // граничное значение, при пересечении которого применяется эта скидка
|
||||
} `json:"discount" bson:"discount"`
|
||||
} `json:"bonus" bson:"bonus"`
|
||||
Outdated bool `json:"outdated" bson:"outdated"`
|
||||
OffLimit bool `json:"offLimit" bson:"offLimit"`
|
||||
Delete bool `json:"delete" bson:"delete"`
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
}
|
||||
|
||||
@ -3,23 +3,52 @@ package repository
|
||||
import (
|
||||
"codeword/internal/models"
|
||||
"context"
|
||||
"errors"
|
||||
"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"
|
||||
)
|
||||
|
||||
var ErrDuplicateCodeword = errors.New("duplicate codeword")
|
||||
|
||||
type PromoCodeRepository struct {
|
||||
mdb *mongo.Collection
|
||||
}
|
||||
|
||||
func NewPromoCodeRepository(mdb *mongo.Collection) *PromoCodeRepository {
|
||||
indexModel := mongo.IndexModel{
|
||||
Keys: bson.D{
|
||||
{"codeword", 1},
|
||||
{"delete", 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true).SetPartialFilterExpression(bson.M{"delete": false}),
|
||||
}
|
||||
_, err := mdb.Indexes().CreateOne(context.Background(), indexModel)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &PromoCodeRepository{mdb: mdb}
|
||||
}
|
||||
|
||||
func (r *PromoCodeRepository) CreatePromoCode(ctx context.Context, promoCode *models.PromoCode) (*models.PromoCode, error) {
|
||||
func (r *PromoCodeRepository) CreatePromo(ctx context.Context, promoCode *models.PromoCode) (*models.PromoCode, error) {
|
||||
promoCode.CreatedAt = time.Now()
|
||||
promoCode.ID = primitive.NewObjectID()
|
||||
|
||||
_, err := r.mdb.InsertOne(ctx, promoCode)
|
||||
if err != nil {
|
||||
if writeErr, ok := err.(mongo.WriteException); ok {
|
||||
for _, writeError := range writeErr.WriteErrors {
|
||||
if writeError.Code == 11000 {
|
||||
return nil, ErrDuplicateCodeword
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return promoCode, nil
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
promocontroller "codeword/internal/controller/promocode"
|
||||
reccontroller "codeword/internal/controller/recovery"
|
||||
"codeword/internal/controller/promocode"
|
||||
"codeword/internal/controller/recovery"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
@ -12,14 +12,14 @@ import (
|
||||
|
||||
type ServerConfig struct {
|
||||
Logger *zap.Logger
|
||||
RecoveryController *reccontroller.RecoveryController
|
||||
PromoCodeController *promocontroller.PromoCodeController
|
||||
RecoveryController *recovery.RecoveryController
|
||||
PromoCodeController *promocode.PromoCodeController
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
Logger *zap.Logger
|
||||
RecoveryController *reccontroller.RecoveryController
|
||||
PromoCodeController *promocontroller.PromoCodeController
|
||||
RecoveryController *recovery.RecoveryController
|
||||
PromoCodeController *promocode.PromoCodeController
|
||||
app *fiber.App
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ func NewServer(config ServerConfig) *Server {
|
||||
s := &Server{
|
||||
Logger: config.Logger,
|
||||
RecoveryController: config.RecoveryController,
|
||||
PromoCodeController: config.PromoCodeController,
|
||||
app: app,
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
type PromoCodeRepository interface {
|
||||
CreatePromoCode(ctx context.Context, promoCode *models.PromoCode) (*models.PromoCode, error)
|
||||
CreatePromo(ctx context.Context, promoCode *models.PromoCode) (*models.PromoCode, error)
|
||||
}
|
||||
|
||||
type PromoDeps struct {
|
||||
@ -28,5 +28,11 @@ func NewPromoCodeService(deps PromoDeps) *PromoCodeService {
|
||||
}
|
||||
|
||||
func (s *PromoCodeService) CreatePromoCode(ctx context.Context, req *models.PromoCode) (*models.PromoCode, error) {
|
||||
return nil, nil
|
||||
promoCode, err := s.promoCodeRepo.CreatePromo(ctx, req)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to add promocode in database", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return promoCode, nil
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user