init base struct for promocode
This commit is contained in:
parent
5015387857
commit
95559a0fda
@ -1,7 +1,8 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
controller "codeword/internal/controller/recovery"
|
promocontroller "codeword/internal/controller/promocode"
|
||||||
|
reccontroller "codeword/internal/controller/recovery"
|
||||||
"codeword/internal/initialize"
|
"codeword/internal/initialize"
|
||||||
"codeword/internal/repository"
|
"codeword/internal/repository"
|
||||||
httpserver "codeword/internal/server/http"
|
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)
|
rdb, err := initialize.Redis(ctx, cfg)
|
||||||
encrypt := initialize.Encrypt(cfg)
|
encrypt := initialize.Encrypt(cfg)
|
||||||
|
|
||||||
codewordRepo := repository.NewCodewordRepository(repository.Deps{Rdb: rdb, Mdb: mdb.Collection("codeword")})
|
codewordRepo := repository.NewCodewordRepository(repository.Deps{Rdb: rdb, Mdb: mdb.Collection("codeword")})
|
||||||
userRepo := repository.NewUserRepository(repository.Deps{Rdb: nil, Mdb: mdb.Collection("users")})
|
userRepo := repository.NewUserRepository(repository.Deps{Rdb: nil, Mdb: mdb.Collection("users")})
|
||||||
|
promoCodeRepo := repository.NewPromoCodeRepository(mdb.Collection("promocodes"))
|
||||||
|
|
||||||
recoveryEmailSender := initialize.RecoveryEmailSender(cfg, logger)
|
recoveryEmailSender := initialize.RecoveryEmailSender(cfg, logger)
|
||||||
authClient := initialize.AuthClient(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,
|
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{
|
recoveryWC := recovery_worker.NewRecoveryWC(recovery_worker.Deps{
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
@ -55,8 +65,9 @@ func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
|
|||||||
go purgeWC.Start(ctx)
|
go purgeWC.Start(ctx)
|
||||||
|
|
||||||
server := httpserver.NewServer(httpserver.ServerConfig{
|
server := httpserver.NewServer(httpserver.ServerConfig{
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
RecoveryController: recoveryController,
|
RecoveryController: recoveryController,
|
||||||
|
PromoCodeController: promoCodeController,
|
||||||
})
|
})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
|||||||
35
internal/controller/promocode/promocode_controller.go
Normal file
35
internal/controller/promocode/promocode_controller.go
Normal file
@ -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
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"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type codewordRepository struct {
|
type CodewordRepository struct {
|
||||||
mdb *mongo.Collection
|
mdb *mongo.Collection
|
||||||
rdb *redis.Client
|
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()
|
newID := primitive.NewObjectID()
|
||||||
signID := deps.Key + newID.Hex()
|
signID := deps.Key + newID.Hex()
|
||||||
record := models.RestoreRequest{
|
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{
|
task := models.RecoveryRecord{
|
||||||
ID: deps.ID,
|
ID: deps.ID,
|
||||||
UserID: deps.UserID,
|
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
|
var restoreRequest models.RestoreRequest
|
||||||
|
|
||||||
filter := bson.M{"sign_id": key}
|
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 {
|
if err := r.mdb.Database().Client().Ping(ctx, readpref.Primary()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
25
internal/repository/promocode_repository.go
Normal file
25
internal/repository/promocode_repository.go
Normal file
@ -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
|
Rdb *redis.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
type userRepository struct {
|
type UserRepository struct {
|
||||||
mdb *mongo.Collection
|
mdb *mongo.Collection
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserRepository(deps Deps) *userRepository {
|
func NewUserRepository(deps Deps) *UserRepository {
|
||||||
|
|
||||||
return &userRepository{mdb: deps.Mdb}
|
return &UserRepository{mdb: deps.Mdb}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ищем пользователя по мейлу в коллекции users
|
// ищем пользователя по мейлу в коллекции 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
|
var user models.User
|
||||||
|
|
||||||
err := r.mdb.FindOne(ctx, bson.M{"email": email}).Decode(&user)
|
err := r.mdb.FindOne(ctx, bson.M{"email": email}).Decode(&user)
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
controller "codeword/internal/controller/recovery"
|
promocontroller "codeword/internal/controller/promocode"
|
||||||
|
reccontroller "codeword/internal/controller/recovery"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
@ -10,14 +11,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ServerConfig struct {
|
type ServerConfig struct {
|
||||||
Logger *zap.Logger
|
Logger *zap.Logger
|
||||||
RecoveryController *controller.RecoveryController
|
RecoveryController *reccontroller.RecoveryController
|
||||||
|
PromoCodeController *promocontroller.PromoCodeController
|
||||||
}
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Logger *zap.Logger
|
Logger *zap.Logger
|
||||||
RecoveryController *controller.RecoveryController
|
RecoveryController *reccontroller.RecoveryController
|
||||||
app *fiber.App
|
PromoCodeController *promocontroller.PromoCodeController
|
||||||
|
app *fiber.App
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(config ServerConfig) *Server {
|
func NewServer(config ServerConfig) *Server {
|
||||||
@ -52,6 +55,8 @@ func (s *Server) registerRoutes() {
|
|||||||
|
|
||||||
s.app.Post("/recover", s.RecoveryController.HandleRecoveryRequest)
|
s.app.Post("/recover", s.RecoveryController.HandleRecoveryRequest)
|
||||||
s.app.Get("/recover/:sign", s.RecoveryController.HandleRecoveryLink)
|
s.app.Get("/recover/:sign", s.RecoveryController.HandleRecoveryLink)
|
||||||
|
|
||||||
|
s.app.Post("/promocode/create", s.PromoCodeController.CreatePromoCode)
|
||||||
//... other
|
//... other
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
32
internal/services/promocode_service.go
Normal file
32
internal/services/promocode_service.go
Normal file
@ -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
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user