init base struct for promocode

This commit is contained in:
Pavel 2024-01-11 19:29:53 +03:00
parent 5015387857
commit 95559a0fda
8 changed files with 157 additions and 21 deletions

@ -1,7 +1,8 @@
package app
import (
controller "codeword/internal/controller/recovery"
promocontroller "codeword/internal/controller/promocode"
reccontroller "codeword/internal/controller/recovery"
"codeword/internal/initialize"
"codeword/internal/repository"
httpserver "codeword/internal/server/http"
@ -24,8 +25,11 @@ func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
rdb, err := initialize.Redis(ctx, cfg)
encrypt := initialize.Encrypt(cfg)
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)
@ -37,7 +41,13 @@ func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
AuthClient: authClient,
})
recoveryController := controller.NewRecoveryController(logger, recoveryService, cfg.DefaultRedirectionURL)
promoService := services.NewPromoCodeService(services.PromoDeps{
Logger: logger,
PromoCodeRepo: promoCodeRepo,
})
recoveryController := reccontroller.NewRecoveryController(logger, recoveryService, cfg.DefaultRedirectionURL)
promoCodeController := promocontroller.NewPromoCodeController(logger, promoService)
recoveryWC := recovery_worker.NewRecoveryWC(recovery_worker.Deps{
Logger: logger,
@ -55,8 +65,9 @@ func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
go purgeWC.Start(ctx)
server := httpserver.NewServer(httpserver.ServerConfig{
Logger: logger,
RecoveryController: recoveryController,
Logger: logger,
RecoveryController: recoveryController,
PromoCodeController: promoCodeController,
})
go func() {

@ -0,0 +1,35 @@
package controller
import (
"codeword/internal/models"
"codeword/internal/services"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
)
type PromoCodeController struct {
logger *zap.Logger
promoCodeService *services.PromoCodeService
}
func NewPromoCodeController(logger *zap.Logger, promoCodeService *services.PromoCodeService) *PromoCodeController {
return &PromoCodeController{
logger: logger,
promoCodeService: promoCodeService,
}
}
func (p *PromoCodeController) CreatePromoCode(c *fiber.Ctx) error {
var reqCreatePromoCode models.PromoCode
if err := c.BodyParser(&reqCreatePromoCode); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"})
}
createdPromoCode, err := p.promoCodeService.CreatePromoCode(c.Context(), &reqCreatePromoCode)
if err != nil {
p.logger.Error("Failed to create promocode", zap.Error(err))
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
return c.Status(fiber.StatusCreated).JSON(createdPromoCode)
}

28
internal/models/bonus.go Normal file

@ -0,0 +1,28 @@
package models
import "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"` // предел количества активаций промокода
Bonus struct {
Privilege struct {
PrivilegeID string `json:"privilegeID"` // айдишник привилегии, которая будет выдаваться
Amount uint64 `json:"amount"` // количество
} `json:"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"`
}

@ -12,18 +12,18 @@ import (
"time"
)
type codewordRepository struct {
type CodewordRepository struct {
mdb *mongo.Collection
rdb *redis.Client
}
func NewCodewordRepository(deps Deps) *codewordRepository {
func NewCodewordRepository(deps Deps) *CodewordRepository {
return &codewordRepository{mdb: deps.Mdb, rdb: deps.Rdb}
return &CodewordRepository{mdb: deps.Mdb, rdb: deps.Rdb}
}
// сохраняем полученные данные о пользователе и подписи в бд
func (r *codewordRepository) StoreRecoveryRecord(ctx context.Context, deps models.StoreRecDeps) (string, error) {
func (r *CodewordRepository) StoreRecoveryRecord(ctx context.Context, deps models.StoreRecDeps) (string, error) {
newID := primitive.NewObjectID()
signID := deps.Key + newID.Hex()
record := models.RestoreRequest{
@ -45,7 +45,7 @@ func (r *codewordRepository) StoreRecoveryRecord(ctx context.Context, deps model
}
// добавляем в очередь данные для отправки на почту в редис
func (r *codewordRepository) InsertToQueue(ctx context.Context, deps models.RecEmailDeps) error {
func (r *CodewordRepository) InsertToQueue(ctx context.Context, deps models.RecEmailDeps) error {
task := models.RecoveryRecord{
ID: deps.ID,
UserID: deps.UserID,
@ -66,7 +66,7 @@ func (r *codewordRepository) InsertToQueue(ctx context.Context, deps models.RecE
}
// получаем данные юзера по подписи
func (r *codewordRepository) GetRecoveryRecord(ctx context.Context, key string) (*models.RestoreRequest, error) {
func (r *CodewordRepository) GetRecoveryRecord(ctx context.Context, key string) (*models.RestoreRequest, error) {
var restoreRequest models.RestoreRequest
filter := bson.M{"sign_id": key}
@ -80,7 +80,7 @@ func (r *codewordRepository) GetRecoveryRecord(ctx context.Context, key string)
}
// пингует в монгу чтобы проверить подключение
func (r *codewordRepository) Ping(ctx context.Context) error {
func (r *CodewordRepository) Ping(ctx context.Context) error {
if err := r.mdb.Database().Client().Ping(ctx, readpref.Primary()); err != nil {
return err
}

@ -0,0 +1,25 @@
package repository
import (
"codeword/internal/models"
"context"
"go.mongodb.org/mongo-driver/mongo"
"time"
)
type PromoCodeRepository struct {
mdb *mongo.Collection
}
func NewPromoCodeRepository(mdb *mongo.Collection) *PromoCodeRepository {
return &PromoCodeRepository{mdb: mdb}
}
func (r *PromoCodeRepository) CreatePromoCode(ctx context.Context, promoCode *models.PromoCode) (*models.PromoCode, error) {
promoCode.CreatedAt = time.Now()
_, err := r.mdb.InsertOne(ctx, promoCode)
if err != nil {
return nil, err
}
return promoCode, nil
}

@ -13,17 +13,17 @@ type Deps struct {
Rdb *redis.Client
}
type userRepository struct {
type UserRepository struct {
mdb *mongo.Collection
}
func NewUserRepository(deps Deps) *userRepository {
func NewUserRepository(deps Deps) *UserRepository {
return &userRepository{mdb: deps.Mdb}
return &UserRepository{mdb: deps.Mdb}
}
// ищем пользователя по мейлу в коллекции users
func (r *userRepository) FindByEmail(ctx context.Context, email string) (*models.User, error) {
func (r *UserRepository) FindByEmail(ctx context.Context, email string) (*models.User, error) {
var user models.User
err := r.mdb.FindOne(ctx, bson.M{"email": email}).Decode(&user)

@ -1,7 +1,8 @@
package http
import (
controller "codeword/internal/controller/recovery"
promocontroller "codeword/internal/controller/promocode"
reccontroller "codeword/internal/controller/recovery"
"context"
"fmt"
"github.com/gofiber/fiber/v2"
@ -10,14 +11,16 @@ import (
)
type ServerConfig struct {
Logger *zap.Logger
RecoveryController *controller.RecoveryController
Logger *zap.Logger
RecoveryController *reccontroller.RecoveryController
PromoCodeController *promocontroller.PromoCodeController
}
type Server struct {
Logger *zap.Logger
RecoveryController *controller.RecoveryController
app *fiber.App
Logger *zap.Logger
RecoveryController *reccontroller.RecoveryController
PromoCodeController *promocontroller.PromoCodeController
app *fiber.App
}
func NewServer(config ServerConfig) *Server {
@ -52,6 +55,8 @@ func (s *Server) registerRoutes() {
s.app.Post("/recover", s.RecoveryController.HandleRecoveryRequest)
s.app.Get("/recover/:sign", s.RecoveryController.HandleRecoveryLink)
s.app.Post("/promocode/create", s.PromoCodeController.CreatePromoCode)
//... other
}

@ -0,0 +1,32 @@
package services
import (
"codeword/internal/models"
"context"
"go.uber.org/zap"
)
type PromoCodeRepository interface {
CreatePromoCode(ctx context.Context, promoCode *models.PromoCode) (*models.PromoCode, error)
}
type PromoDeps struct {
Logger *zap.Logger
PromoCodeRepo PromoCodeRepository
}
type PromoCodeService struct {
logger *zap.Logger
promoCodeRepo PromoCodeRepository
}
func NewPromoCodeService(deps PromoDeps) *PromoCodeService {
return &PromoCodeService{
logger: deps.Logger,
promoCodeRepo: deps.PromoCodeRepo,
}
}
func (s *PromoCodeService) CreatePromoCode(ctx context.Context, req *models.PromoCode) (*models.PromoCode, error) {
return nil, nil
}