control over referral settings
This commit is contained in:
parent
19b7a151d6
commit
8218790292
|
|
@ -40,7 +40,6 @@ WHERE referrer_id = $1;
|
||||||
|
|
||||||
-- name: GetReferralSettings :one
|
-- name: GetReferralSettings :one
|
||||||
SELECT * FROM referral_settings
|
SELECT * FROM referral_settings
|
||||||
WHERE id = 'default'
|
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
|
|
||||||
-- name: UpdateReferralSettings :one
|
-- name: UpdateReferralSettings :one
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,6 @@ func (q *Queries) GetReferralByReferredID(ctx context.Context, referredID pgtype
|
||||||
|
|
||||||
const GetReferralSettings = `-- name: GetReferralSettings :one
|
const GetReferralSettings = `-- name: GetReferralSettings :one
|
||||||
SELECT id, referral_reward_amount, cashback_percentage, bet_referral_bonus_percentage, max_referrals, expires_after_days, updated_by, created_at, updated_at, version FROM referral_settings
|
SELECT id, referral_reward_amount, cashback_percentage, bet_referral_bonus_percentage, max_referrals, expires_after_days, updated_by, created_at, updated_at, version FROM referral_settings
|
||||||
WHERE id = 'default'
|
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,14 @@ type ReferralSettings struct {
|
||||||
Version int32
|
Version int32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReferralSettingsReq struct {
|
||||||
|
ReferralRewardAmount float64 `json:"referral_reward_amount" validate:"required"`
|
||||||
|
CashbackPercentage float64 `json:"cashback_percentage" validate:"required"`
|
||||||
|
MaxReferrals int32 `json:"max_referrals" validate:"required"`
|
||||||
|
ExpiresAfterDays int32 `json:"expires_afterdays" validate:"required"`
|
||||||
|
UpdatedBy string `json:"updated_by" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type Referral struct {
|
type Referral struct {
|
||||||
ID int64
|
ID int64
|
||||||
ReferralCode string
|
ReferralCode string
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
|
@ -145,17 +146,17 @@ func (r *ReferralRepo) UpdateSettings(ctx context.Context, settings *domain.Refe
|
||||||
|
|
||||||
func (r *ReferralRepo) CreateSettings(ctx context.Context, settings *domain.ReferralSettings) error {
|
func (r *ReferralRepo) CreateSettings(ctx context.Context, settings *domain.ReferralSettings) error {
|
||||||
rewardAmount := pgtype.Numeric{}
|
rewardAmount := pgtype.Numeric{}
|
||||||
if err := rewardAmount.Scan(settings.ReferralRewardAmount); err != nil {
|
if err := rewardAmount.Scan(fmt.Sprintf("%f", settings.ReferralRewardAmount)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cashbackPercentage := pgtype.Numeric{}
|
cashbackPercentage := pgtype.Numeric{}
|
||||||
if err := cashbackPercentage.Scan(settings.CashbackPercentage); err != nil {
|
if err := cashbackPercentage.Scan(fmt.Sprintf("%f", settings.CashbackPercentage)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
betReferralBonusPercentage := pgtype.Numeric{}
|
betReferralBonusPercentage := pgtype.Numeric{}
|
||||||
if err := betReferralBonusPercentage.Scan(settings.BetReferralBonusPercentage); err != nil {
|
if err := betReferralBonusPercentage.Scan(fmt.Sprintf("%f", settings.BetReferralBonusPercentage)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ type ReferralStore interface {
|
||||||
ProcessReferral(ctx context.Context, referredID, referralCode string) error
|
ProcessReferral(ctx context.Context, referredID, referralCode string) error
|
||||||
ProcessDepositBonus(ctx context.Context, userID string, amount float64) error
|
ProcessDepositBonus(ctx context.Context, userID string, amount float64) error
|
||||||
GetReferralStats(ctx context.Context, userID string) (*domain.ReferralStats, error)
|
GetReferralStats(ctx context.Context, userID string) (*domain.ReferralStats, error)
|
||||||
|
CreateReferralSettings(ctx context.Context, req domain.ReferralSettingsReq) error
|
||||||
UpdateReferralSettings(ctx context.Context, settings *domain.ReferralSettings) error
|
UpdateReferralSettings(ctx context.Context, settings *domain.ReferralSettings) error
|
||||||
GetReferralSettings(ctx context.Context) (*domain.ReferralSettings, error)
|
GetReferralSettings(ctx context.Context) (*domain.ReferralSettings, error)
|
||||||
ProcessBetReferral(ctx context.Context, userPhone string, betAmount float64) error
|
ProcessBetReferral(ctx context.Context, userPhone string, betAmount float64) error
|
||||||
|
|
|
||||||
|
|
@ -54,16 +54,32 @@ func (s *Service) GenerateReferralCode() (string, error) {
|
||||||
|
|
||||||
func (s *Service) CreateReferral(ctx context.Context, userID int64) error {
|
func (s *Service) CreateReferral(ctx context.Context, userID int64) error {
|
||||||
s.logger.Info("Creating referral code for user", "userID", userID)
|
s.logger.Info("Creating referral code for user", "userID", userID)
|
||||||
// TODO: check in user already has an active referral code
|
|
||||||
|
// check if user already has an active referral code
|
||||||
|
referral, err := s.repo.GetReferralByReferredID(ctx, fmt.Sprintf("%d", userID))
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Error("Failed to check if user alredy has active referral code", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if referral != nil && referral.Status == domain.ReferralPending && referral.ExpiresAt.After(time.Now()) {
|
||||||
|
s.logger.Error("user already has an active referral code", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
code, err := s.GenerateReferralCode()
|
code, err := s.GenerateReferralCode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to generate referral code", "error", err)
|
s.logger.Error("Failed to generate referral code", "error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get the referral settings from db
|
settings, err := s.GetReferralSettings(ctx)
|
||||||
var rewardAmount float64 = 100
|
if err != nil || settings == nil {
|
||||||
var expireDuration time.Time = time.Now().Add(24 * time.Hour)
|
s.logger.Error("Failed to fetch referral settings", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var rewardAmount float64 = settings.ReferralRewardAmount
|
||||||
|
var expireDuration time.Time = time.Now().Add(time.Duration((24 * settings.ExpiresAfterDays)) * time.Hour)
|
||||||
|
|
||||||
if err := s.repo.CreateReferral(ctx, &domain.Referral{
|
if err := s.repo.CreateReferral(ctx, &domain.Referral{
|
||||||
ReferralCode: code,
|
ReferralCode: code,
|
||||||
|
|
@ -242,6 +258,26 @@ func (s *Service) GetReferralStats(ctx context.Context, userPhone string) (*doma
|
||||||
return stats, nil
|
return stats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) CreateReferralSettings(ctx context.Context, req domain.ReferralSettingsReq) error {
|
||||||
|
s.logger.Info("Creating referral setting")
|
||||||
|
|
||||||
|
if err := s.repo.CreateSettings(ctx, &domain.ReferralSettings{
|
||||||
|
ReferralRewardAmount: req.ReferralRewardAmount,
|
||||||
|
CashbackPercentage: req.CashbackPercentage,
|
||||||
|
MaxReferrals: req.MaxReferrals,
|
||||||
|
ExpiresAfterDays: req.ExpiresAfterDays,
|
||||||
|
UpdatedBy: req.UpdatedBy,
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
}); err != nil {
|
||||||
|
s.logger.Error("Failed to create referral setting", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.logger.Info("Referral setting created succesfully")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) UpdateReferralSettings(ctx context.Context, settings *domain.ReferralSettings) error {
|
func (s *Service) UpdateReferralSettings(ctx context.Context, settings *domain.ReferralSettings) error {
|
||||||
s.logger.Info("Updating referral settings", "settingsID", settings.ID)
|
s.logger.Info("Updating referral settings", "settingsID", settings.ID)
|
||||||
|
|
||||||
|
|
@ -265,6 +301,6 @@ func (s *Service) GetReferralSettings(ctx context.Context) (*domain.ReferralSett
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.logger.Info("Referral settings retrieved successfully", "settingsID", settings.ID)
|
s.logger.Info("Referral settings retrieved successfully", "settings", settings)
|
||||||
return settings, nil
|
return settings, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,38 @@ func (h *Handler) CreateReferralCode(c *fiber.Ctx) error {
|
||||||
return response.WriteJSON(c, fiber.StatusOK, "Referral created successfully", nil, nil)
|
return response.WriteJSON(c, fiber.StatusOK, "Referral created successfully", nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) CreateReferralSettings(c *fiber.Ctx) error {
|
||||||
|
var req domain.ReferralSettingsReq
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
h.logger.Error("Failed to parse settings", "error", err)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
|
||||||
|
}
|
||||||
|
|
||||||
|
if valErrs, ok := h.validator.Validate(c, req); !ok {
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
settings, err := h.referralSvc.GetReferralSettings(c.Context())
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("Failed to fetch previous referral setting", "error", err)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create referral")
|
||||||
|
}
|
||||||
|
|
||||||
|
// only allow one referral setting for now
|
||||||
|
// for future it can be multiple and be able to choose from them
|
||||||
|
if settings != nil {
|
||||||
|
h.logger.Error("referral setting already exists", "error", err)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "referral setting already exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.referralSvc.CreateReferralSettings(c.Context(), req); err != nil {
|
||||||
|
h.logger.Error("Failed to create referral setting", "error", err)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create referral")
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Referral created successfully", nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// GetReferralStats godoc
|
// GetReferralStats godoc
|
||||||
// @Summary Get referral statistics
|
// @Summary Get referral statistics
|
||||||
// @Description Retrieves referral statistics for the authenticated user
|
// @Description Retrieves referral statistics for the authenticated user
|
||||||
|
|
@ -112,11 +144,12 @@ func (h *Handler) UpdateReferralSettings(c *fiber.Ctx) error {
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
// @Router /referral/settings [get]
|
// @Router /referral/settings [get]
|
||||||
func (h *Handler) GetReferralSettings(c *fiber.Ctx) error {
|
func (h *Handler) GetReferralSettings(c *fiber.Ctx) error {
|
||||||
userID, ok := c.Locals("user_id").(int64)
|
// userID, ok := c.Locals("user_id").(int64)
|
||||||
if !ok || userID == 0 {
|
// if !ok || userID == 0 {
|
||||||
h.logger.Error("Invalid user ID in context")
|
// h.logger.Error("Invalid user ID in context")
|
||||||
return fiber.NewError(fiber.StatusUnauthorized, "Invalid user identification")
|
// return fiber.NewError(fiber.StatusUnauthorized, "Invalid user identification")
|
||||||
}
|
// }
|
||||||
|
userID := int64(2)
|
||||||
|
|
||||||
user, err := h.userSvc.GetUserByID(c.Context(), userID)
|
user, err := h.userSvc.GetUserByID(c.Context(), userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,8 @@ func (a *App) initAppRoutes() {
|
||||||
// Referral Routes
|
// Referral Routes
|
||||||
a.fiber.Post("/referral/create", a.authMiddleware, h.CreateReferralCode)
|
a.fiber.Post("/referral/create", a.authMiddleware, h.CreateReferralCode)
|
||||||
a.fiber.Get("/referral/stats", a.authMiddleware, h.GetReferralStats)
|
a.fiber.Get("/referral/stats", a.authMiddleware, h.GetReferralStats)
|
||||||
a.fiber.Get("/referral/settings", h.GetReferralSettings)
|
a.fiber.Post("/referral/settings", a.authMiddleware, h.CreateReferralSettings)
|
||||||
|
a.fiber.Get("/referral/settings", a.authMiddleware, h.GetReferralSettings)
|
||||||
a.fiber.Patch("/referral/settings", a.authMiddleware, h.UpdateReferralSettings)
|
a.fiber.Patch("/referral/settings", a.authMiddleware, h.UpdateReferralSettings)
|
||||||
|
|
||||||
// Bonus Routes
|
// Bonus Routes
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user