diff --git a/cmd/main.go b/cmd/main.go index 29425b3..1019bb5 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -147,7 +147,7 @@ func main() { vitualGameRepo := repository.NewVirtualGameRepository(store) recommendationRepo := repository.NewRecommendationRepository(store) - referalSvc := referralservice.New(referalRepo, *walletSvc, *settingSvc, cfg, logger) + referalSvc := referralservice.New(referalRepo, *walletSvc, *settingSvc, cfg, logger, domain.MongoDBLogger) raffleSvc := raffle.NewService(store) virtualGameSvc := virtualgameservice.New(vitualGameRepo, *walletSvc, store, cfg, logger) aleaService := alea.NewAleaPlayService(vitualGameRepo, *walletSvc, cfg, logger) diff --git a/db/data/001_initial_seed_data.sql b/db/data/001_initial_seed_data.sql index eb64f5c..0441221 100644 --- a/db/data/001_initial_seed_data.sql +++ b/db/data/001_initial_seed_data.sql @@ -83,7 +83,10 @@ VALUES ('sms_provider', 'afro_message'), ('total_winnings_limit', '1000000'), ('amount_for_bet_referral', '1000000'), ('cashback_amount_cap', '1000'), - ('default_winning_limit', '5000000') ON CONFLICT (key) DO NOTHING; + ('default_winning_limit', '5000000'), + ('referral_reward_amount', '10000'), + ('cashback_percentage', '0.2'), + ('default_max_referrals', '15') ON CONFLICT (key) DO NOTHING; -- Users INSERT INTO users ( id, @@ -222,7 +225,7 @@ VALUES ( ), ( 3, - 100000000 , + 100000000, TRUE, TRUE, TRUE, @@ -338,4 +341,5 @@ SET name = EXCLUDED.name, profit_percent = EXCLUDED.profit_percent, is_active = EXCLUDED.is_active, created_at = EXCLUDED.created_at, - updated_at = EXCLUDED.updated_at; \ No newline at end of file + updated_at = EXCLUDED.updated_at; + diff --git a/db/data/003_fix_autoincrement_desync.sql b/db/data/003_fix_autoincrement_desync.sql new file mode 100644 index 0000000..835e10e --- /dev/null +++ b/db/data/003_fix_autoincrement_desync.sql @@ -0,0 +1,31 @@ +-- For each table with an id sequence +SELECT setval( + pg_get_serial_sequence('users', 'id'), + COALESCE(MAX(id), 1) + ) +FROM users; +SELECT setval( + pg_get_serial_sequence('wallets', 'id'), + COALESCE(MAX(id), 1) + ) +FROM wallets; +SELECT setval( + pg_get_serial_sequence('customer_wallets', 'id'), + COALESCE(MAX(id), 1) + ) +FROM customer_wallets; +SELECT setval( + pg_get_serial_sequence('companies', 'id'), + COALESCE(MAX(id), 1) + ) +FROM companies; +SELECT setval( + pg_get_serial_sequence('branches', 'id'), + COALESCE(MAX(id), 1) + ) +FROM branches; +SELECT setval( + pg_get_serial_sequence('supported_operations', 'id'), + COALESCE(MAX(id), 1) + ) +FROM supported_operations; \ No newline at end of file diff --git a/db/migrations/000003_referal.up.sql b/db/migrations/000003_referal.up.sql index c6cbd92..badf443 100644 --- a/db/migrations/000003_referal.up.sql +++ b/db/migrations/000003_referal.up.sql @@ -16,7 +16,6 @@ -- AND cashback_percentage <= 100 -- ) -- ); - CREATE TABLE IF NOT EXISTS referral_codes ( id BIGSERIAL PRIMARY KEY, referral_code VARCHAR(10) NOT NULL UNIQUE, @@ -29,12 +28,10 @@ CREATE TABLE IF NOT EXISTS referral_codes ( updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT reward_amount_positive CHECK (reward_amount >= 0) ); -CREATE INDEX idx_referrals_referrer_id ON referrals (referrer_id); -CREATE INDEX idx_referrals_status ON referrals (status); - +CREATE INDEX idx_referrals_referrer_id ON referral_codes (referrer_id); CREATE TABLE IF NOT EXISTS user_referrals ( id BIGSERIAL PRIMARY KEY, referred_id BIGINT UNIQUE NOT NULL REFERENCES users (id), referral_code_id BIGINT NOT NULL REFERENCES referral_codes (id), created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP -); +); \ No newline at end of file diff --git a/db/query/referal.sql b/db/query/referal.sql index 10e5781..3dbe00e 100644 --- a/db/query/referal.sql +++ b/db/query/referal.sql @@ -30,9 +30,9 @@ SET is_active = $2, WHERE id = $1; -- name: GetReferralStats :one SELECT COUNT(*) AS total_referrals, - SUM(reward_amount) AS total_reward_earned + COALESCE(SUM(reward_amount), 0)::bigint AS total_reward_earned FROM user_referrals - JOIN referral_codes ON referral_codes.id == referral_code_id + JOIN referral_codes ON referral_codes.id = referral_code_id WHERE referrer_id = $1 AND company_id = $2; -- name: GetUserReferral :one @@ -42,10 +42,10 @@ WHERE referred_id = $1; -- name: GetUserReferralsByCode :many SELECT user_referrals.* FROM user_referrals - JOIN referral_codes ON referral_codes.id == referral_code_id + JOIN referral_codes ON referral_codes.id = referral_code_id WHERE referral_code = $1; -- name: GetUserReferralsCount :one SELECT COUNT(*) FROM user_referrals - JOIN referral_codes ON referral_codes.id == referral_code_id + JOIN referral_codes ON referral_codes.id = referral_code_id WHERE referrer_id = $1; \ No newline at end of file diff --git a/gen/db/referal.sql.go b/gen/db/referal.sql.go index 621692d..caaa01a 100644 --- a/gen/db/referal.sql.go +++ b/gen/db/referal.sql.go @@ -136,9 +136,9 @@ func (q *Queries) GetReferralCodeByUser(ctx context.Context, referrerID int64) ( const GetReferralStats = `-- name: GetReferralStats :one SELECT COUNT(*) AS total_referrals, - SUM(reward_amount) AS total_reward_earned + COALESCE(SUM(reward_amount), 0)::bigint AS total_reward_earned FROM user_referrals - JOIN referral_codes ON referral_codes.id == referral_code_id + JOIN referral_codes ON referral_codes.id = referral_code_id WHERE referrer_id = $1 AND company_id = $2 ` @@ -181,7 +181,7 @@ func (q *Queries) GetUserReferral(ctx context.Context, referredID int64) (UserRe const GetUserReferralsByCode = `-- name: GetUserReferralsByCode :many SELECT user_referrals.id, user_referrals.referred_id, user_referrals.referral_code_id, user_referrals.created_at FROM user_referrals - JOIN referral_codes ON referral_codes.id == referral_code_id + JOIN referral_codes ON referral_codes.id = referral_code_id WHERE referral_code = $1 ` @@ -213,7 +213,7 @@ func (q *Queries) GetUserReferralsByCode(ctx context.Context, referralCode strin const GetUserReferralsCount = `-- name: GetUserReferralsCount :one SELECT COUNT(*) FROM user_referrals - JOIN referral_codes ON referral_codes.id == referral_code_id + JOIN referral_codes ON referral_codes.id = referral_code_id WHERE referrer_id = $1 ` diff --git a/internal/domain/referal.go b/internal/domain/referal.go index 5e384f1..bb9e1bb 100644 --- a/internal/domain/referal.go +++ b/internal/domain/referal.go @@ -17,6 +17,17 @@ type ReferralCode struct { UpdatedAt time.Time } +type ReferralCodeRes struct { + ID int64 `json:"id"` + ReferrerID int64 `json:"referrer_id"` + ReferralCode string `json:"referral_code"` + CompanyID int64 `json:"company_id"` + NumberOfReferrals int64 `json:"number_of_referrals"` + RewardAmount float32 `json:"reward_amount"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + type CreateReferralCode struct { ReferrerID int64 ReferralCode string @@ -48,6 +59,11 @@ type ReferralStats struct { TotalRewardEarned Currency } +type ReferralStatsRes struct { + TotalReferrals int64 `json:"total_referrals"` + TotalRewardEarned float32 `json:"total_reward_earned"` +} + // type ReferralSettings struct { // ID int64 // ReferralRewardAmount float64 @@ -78,14 +94,16 @@ func ConvertCreateReferralCode(code CreateReferralCode) dbgen.CreateReferralCode } } -func ConvertDBReferralCode(code dbgen.ReferralCode) ReferralCode { + func ConvertDBReferralCode(code dbgen.ReferralCode) ReferralCode { return ReferralCode{ - ID: code.ID, - ReferrerID: code.ReferrerID, - ReferralCode: code.ReferralCode, - CompanyID: code.CompanyID, - CreatedAt: code.CreatedAt.Time, - UpdatedAt: code.UpdatedAt.Time, + ID: code.ID, + ReferrerID: code.ReferrerID, + ReferralCode: code.ReferralCode, + NumberOfReferrals: code.NumberOfReferrals, + RewardAmount: Currency(code.RewardAmount), + CompanyID: code.CompanyID, + CreatedAt: code.CreatedAt.Time, + UpdatedAt: code.UpdatedAt.Time, } } @@ -132,7 +150,37 @@ func ConvertUpdateReferralCode(referralCode UpdateReferralCode) dbgen.UpdateRefe func ConvertDBReferralStats(stats dbgen.GetReferralStatsRow) ReferralStats { return ReferralStats{ - TotalReferrals: stats.TotalReferrals, + TotalReferrals: stats.TotalReferrals, TotalRewardEarned: Currency(stats.TotalRewardEarned), } } + +func ConvertReferralCodeRes(referral ReferralCode) ReferralCodeRes { + return ReferralCodeRes{ + ID: referral.ID, + ReferrerID: referral.ReferrerID, + ReferralCode: referral.ReferralCode, + CompanyID: referral.CompanyID, + NumberOfReferrals: referral.NumberOfReferrals, + RewardAmount: referral.RewardAmount.Float32(), + CreatedAt: referral.CreatedAt, + UpdatedAt: referral.UpdatedAt, + } +} + +func ConvertReferralCodeResList(referrals []ReferralCode) []ReferralCodeRes { + result := make([]ReferralCodeRes, len(referrals)) + + for i, referral := range referrals { + result[i] = ConvertReferralCodeRes(referral) + } + + return result +} + +func ConvertReferralStatsRes(stats ReferralStats) ReferralStatsRes { + return ReferralStatsRes{ + TotalReferrals: stats.TotalReferrals, + TotalRewardEarned: stats.TotalRewardEarned.Float32(), + } +} diff --git a/internal/services/referal/service.go b/internal/services/referal/service.go index 2dc8a73..eb5b021 100644 --- a/internal/services/referal/service.go +++ b/internal/services/referal/service.go @@ -13,23 +13,26 @@ import ( "github.com/SamuelTariku/FortuneBet-Backend/internal/repository" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/settings" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet" + "go.uber.org/zap" ) type Service struct { - repo repository.ReferralRepository - walletSvc wallet.Service - settingSvc settings.Service - config *config.Config - logger *slog.Logger + repo repository.ReferralRepository + walletSvc wallet.Service + settingSvc settings.Service + config *config.Config + logger *slog.Logger + mongoLogger *zap.Logger } -func New(repo repository.ReferralRepository, walletSvc wallet.Service, settingSvc settings.Service, cfg *config.Config, logger *slog.Logger) *Service { +func New(repo repository.ReferralRepository, walletSvc wallet.Service, settingSvc settings.Service, cfg *config.Config, logger *slog.Logger, mongoLogger *zap.Logger) *Service { return &Service{ - repo: repo, - walletSvc: walletSvc, - settingSvc: settingSvc, - config: cfg, - logger: logger, + repo: repo, + walletSvc: walletSvc, + settingSvc: settingSvc, + config: cfg, + logger: logger, + mongoLogger: mongoLogger, } } @@ -44,38 +47,36 @@ var ( func (s *Service) GenerateReferralCode() (string, error) { b := make([]byte, 8) if _, err := rand.Read(b); err != nil { - s.logger.Error("Failed to generate random bytes for referral code", "error", err) + s.mongoLogger.Error("Failed to generate random bytes for referral code", zap.Error(err)) return "", err } code := base32.StdEncoding.EncodeToString(b)[:10] - s.logger.Debug("Generated referral code", "code", code) + s.mongoLogger.Debug("Generated referral code", zap.String("code", code)) return code, nil } func (s *Service) CreateReferralCode(ctx context.Context, userID int64, companyID int64) (domain.ReferralCode, error) { settingsList, err := s.settingSvc.GetOverrideSettingsList(ctx, companyID) + if err != nil { - s.logger.Error("Failed to fetch settings", "error", err) + s.mongoLogger.Error("Failed to fetch settings", zap.Error(err)) return domain.ReferralCode{}, err } - s.logger.Info("Creating referral code for user", "userID", userID) - // check if user already has an active referral code referralCodes, err := s.repo.GetReferralCodesByUser(ctx, userID) if err != nil { - s.logger.Error("Failed to check if user alredy has active referral code", "error", err) + s.mongoLogger.Error("Failed to check if user already has active referral code", zap.Int64("userID", userID), zap.Error(err)) return domain.ReferralCode{}, err } - if referralCodes != nil { - s.logger.Error("user already has an active referral code", "error", err) + if len(referralCodes) != 0 { + s.mongoLogger.Error("user already has an active referral code", zap.Int64("userID", userID), zap.Any("codes", referralCodes), zap.Error(err)) return domain.ReferralCode{}, ErrUserAlreadyHasReferralCode } code, err := s.GenerateReferralCode() if err != nil { - s.logger.Error("Failed to generate referral code", "error", err) return domain.ReferralCode{}, err } @@ -95,18 +96,20 @@ func (s *Service) CreateReferralCode(ctx context.Context, userID int64, companyI } func (s *Service) ProcessReferral(ctx context.Context, referredID int64, referralCode string, companyID int64) error { - s.logger.Info("Processing referral", "referralCode", referralCode) - + paramLogger := s.mongoLogger.With( + zap.Int64("referredID", referredID), + zap.String("referralCode", referralCode), + zap.Int64("companyID", companyID), + ) referral, err := s.repo.GetReferralCode(ctx, referralCode) - if err != nil { - s.logger.Error("Failed to get referral by code", "referralCode", referralCode, "error", err) + paramLogger.Error("Failed to get referral by code", zap.Error(err)) return err } wallets, err := s.walletSvc.GetCustomerWallet(ctx, referral.ReferrerID) if err != nil { - s.logger.Error("Failed to get referrer wallets", "referrerId", referral.ReferrerID, "error", err) + paramLogger.Error("Failed to get referrer wallets", zap.Error(err)) return err } @@ -115,7 +118,7 @@ func (s *Service) ProcessReferral(ctx context.Context, referredID int64, referra fmt.Sprintf("Added %v to static wallet due to %v referral code being used", referral.RewardAmount, referral.ReferralCode), ) if err != nil { - s.logger.Error("Failed to add referral reward to static wallet", "walletID", wallets.StaticID, "error", err) + paramLogger.Error("Failed to add referral reward to static wallet", zap.Int64("static_wallet_id", wallets.StaticID), zap.Error(err)) return err } @@ -125,35 +128,56 @@ func (s *Service) ProcessReferral(ctx context.Context, referredID int64, referra }) if err != nil { - s.logger.Error("Failed to add referral reward to static wallet", "referredID", referredID, "error", err) + paramLogger.Error("Failed to create user referral", zap.Error(err)) return err } - s.logger.Info("Referral processed successfully", "referralCode", referralCode, "rewardAmount", referral.RewardAmount) + paramLogger.Info("Referral processed successfully", zap.String("rewardAmount", referral.ReferralCode)) return nil } func (s *Service) GetReferralStats(ctx context.Context, userID int64, companyID int64) (domain.ReferralStats, error) { + paramLogger := s.mongoLogger.With(zap.Int64("userID", userID), zap.Int64("companyID", companyID)) + stats, err := s.repo.GetReferralStats(ctx, userID, companyID) if err != nil { - s.logger.Error("Failed to get referral stats", "userID", userID, "error", err) + paramLogger.Error("Failed to get referral stats", zap.Error(err)) return domain.ReferralStats{}, err } - s.logger.Info("Referral stats retrieved successfully", "userID", userID, "totalReferrals", stats.TotalReferrals) return stats, nil } func (s *Service) GetUserReferralCount(ctx context.Context, referrerID int64) (int64, error) { count, err := s.repo.GetUserReferralCount(ctx, referrerID) if err != nil { - s.logger.Error("Failed to get referral count", "userID", referrerID, "error", err) + s.mongoLogger.Error("Failed to get referral count", zap.Int64("referrerID", referrerID), zap.Error(err)) return 0, err } return count, nil } +func (s *Service) GetReferralCodesByUser(ctx context.Context, userID int64) ([]domain.ReferralCode, error) { + return s.repo.GetReferralCodesByUser(ctx, userID) +} + +func (s *Service) GetReferralCode(ctx context.Context, code string) (domain.ReferralCode, error) { + return s.repo.GetReferralCode(ctx, code) +} + +func (s *Service) UpdateReferralCode(ctx context.Context, referral domain.UpdateReferralCode) error { + return s.repo.UpdateReferralCode(ctx, referral) +} + +func (s *Service) GetUserReferral(ctx context.Context, referrerID int64) (domain.UserReferral, error) { + return s.repo.GetUserReferral(ctx, referrerID) +} + +func (s *Service) GetUserReferralsByCode(ctx context.Context, code string) ([]domain.UserReferral, error) { + return s.repo.GetUserReferralsByCode(ctx, code) +} + // func (s *Service) ProcessDepositBonus(ctx context.Context, userID int64, amount float32, companyID int64) error { // settingsList, err := s.settingSvc.GetOverrideSettingsList(ctx, companyID) // if err != nil { diff --git a/internal/services/wallet/wallet.go b/internal/services/wallet/wallet.go index df67111..5865f75 100644 --- a/internal/services/wallet/wallet.go +++ b/internal/services/wallet/wallet.go @@ -26,6 +26,7 @@ func (s *Service) CreateCustomerWallet(ctx context.Context, customerID int64) (d IsBettable: true, IsTransferable: true, UserID: customerID, + Type: domain.RegularWalletType, }) if err != nil { @@ -37,6 +38,7 @@ func (s *Service) CreateCustomerWallet(ctx context.Context, customerID int64) (d IsBettable: true, IsTransferable: true, UserID: customerID, + Type: domain.StaticWalletType, }) if err != nil { diff --git a/internal/web_server/handlers/branch_handler.go b/internal/web_server/handlers/branch_handler.go index 7314ccb..d187b21 100644 --- a/internal/web_server/handlers/branch_handler.go +++ b/internal/web_server/handlers/branch_handler.go @@ -86,6 +86,7 @@ func (h *Handler) CreateBranch(c *fiber.Ctx) error { IsBettable: true, IsTransferable: true, UserID: req.BranchManagerID, + Type: domain.BranchWalletType, }) if err != nil { @@ -254,7 +255,6 @@ func (h *Handler) CreateBranchOperation(c *fiber.Ctx) error { return response.WriteJSON(c, fiber.StatusOK, "Branch Operation Created", nil, nil) } - // GetBranchByID godoc // @Summary Gets branch by id // @Description Gets a single branch by id diff --git a/internal/web_server/handlers/company_handler.go b/internal/web_server/handlers/company_handler.go index 8eb731c..64fd401 100644 --- a/internal/web_server/handlers/company_handler.go +++ b/internal/web_server/handlers/company_handler.go @@ -64,6 +64,7 @@ func (h *Handler) CreateCompany(c *fiber.Ctx) error { IsBettable: true, IsTransferable: true, UserID: req.AdminID, + Type: domain.CompanyWalletType, }) if err != nil { diff --git a/internal/web_server/handlers/referal_handlers.go b/internal/web_server/handlers/referal_handlers.go index 7683466..7ca3856 100644 --- a/internal/web_server/handlers/referal_handlers.go +++ b/internal/web_server/handlers/referal_handlers.go @@ -26,9 +26,9 @@ func (h *Handler) CreateReferralCode(c *fiber.Ctx) error { ) return fiber.NewError(fiber.StatusInternalServerError, "Invalid user identification") } - referralCode, err := h.referralSvc.CreateReferralCode(c.Context(), userID, companyID.Value); + referralCode, err := h.referralSvc.CreateReferralCode(c.Context(), userID, companyID.Value) - if err != nil { + if err != nil { h.mongoLoggerSvc.Error("Failed to create referral", zap.Int64("userID", userID), zap.Int("status_code", fiber.StatusInternalServerError), @@ -39,59 +39,66 @@ func (h *Handler) CreateReferralCode(c *fiber.Ctx) error { } fmt.Printf("Successfully created referral!") - return response.WriteJSON(c, fiber.StatusOK, "Referral created successfully", referralCode, nil) + + res := domain.ConvertReferralCodeRes(referralCode) + + return response.WriteJSON(c, fiber.StatusOK, "Referral created successfully", res, nil) } -// func (h *Handler) GetReferralCode(c *fiber.Ctx) error { -// companyID := c.Locals("company_id").(domain.ValidInt64) -// if !companyID.Valid { -// h.BadRequestLogger().Error("invalid company id") -// return fiber.NewError(fiber.StatusBadRequest, "invalid company id") -// } -// userID, ok := c.Locals("user_id").(int64) -// if !ok || userID == 0 { -// h.mongoLoggerSvc.Error("Invalid user ID in context", -// zap.Int64("userID", userID), -// zap.Int("status_code", fiber.StatusInternalServerError), -// zap.Time("timestamp", time.Now()), -// ) -// return fiber.NewError(fiber.StatusInternalServerError, "Invalid user id") -// } +func (h *Handler) GetReferralCode(c *fiber.Ctx) error { + companyID := c.Locals("company_id").(domain.ValidInt64) + if !companyID.Valid { + h.BadRequestLogger().Error("invalid company id") + return fiber.NewError(fiber.StatusBadRequest, "invalid company id") + } + userID, ok := c.Locals("user_id").(int64) + if !ok || userID == 0 { + h.mongoLoggerSvc.Error("Invalid user ID in context", + zap.Int64("userID", userID), + zap.Int("status_code", fiber.StatusInternalServerError), + zap.Time("timestamp", time.Now()), + ) + return fiber.NewError(fiber.StatusInternalServerError, "Invalid user id") + } -// user, err := h.userSvc.GetUserByID(c.Context(), userID) -// if err != nil { -// h.mongoLoggerSvc.Error("Failed to get user", -// zap.Int64("userID", userID), -// zap.Int("status_code", fiber.StatusInternalServerError), -// zap.Error(err), -// zap.Time("timestamp", time.Now()), -// ) -// return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve user") -// } + user, err := h.userSvc.GetUserByID(c.Context(), userID) + if err != nil { + h.mongoLoggerSvc.Error("Failed to get user", + zap.Int64("userID", userID), + zap.Int("status_code", fiber.StatusInternalServerError), + zap.Error(err), + zap.Time("timestamp", time.Now()), + ) + return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve user") + } -// if !user.CompanyID.Valid || user.CompanyID.Value != companyID.Value { -// h.mongoLoggerSvc.Warn("User attempt to login to different company", -// zap.Int64("userID", userID), -// zap.Int("status_code", fiber.StatusInternalServerError), -// zap.Error(err), -// zap.Time("timestamp", time.Now()), -// ) -// return fiber.NewError(fiber.StatusBadRequest, "Failed to retrieve user") -// } + if !user.CompanyID.Valid || user.CompanyID.Value != companyID.Value { + h.mongoLoggerSvc.Warn("User attempt to login to different company", + zap.Int64("userID", userID), + zap.Int("status_code", fiber.StatusInternalServerError), + zap.Error(err), + zap.Time("timestamp", time.Now()), + ) + return fiber.NewError(fiber.StatusBadRequest, "Failed to retrieve user") + } -// // referrals, err := h.referralSvc.GetReferralStats(c.Context(), user.ID) + referrals, err := h.referralSvc.GetReferralCodesByUser(c.Context(), user.ID) -// if err != nil { -// h.mongoLoggerSvc.Error("Failed to get user referrals", -// zap.Int64("userID", userID), -// zap.Int("status_code", fiber.StatusInternalServerError), -// zap.Error(err), -// zap.Time("timestamp", time.Now()), -// ) -// return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve user referral codes") -// } + if err != nil { + h.mongoLoggerSvc.Error("Failed to get user referrals", + zap.Int64("userID", userID), + zap.Int("status_code", fiber.StatusInternalServerError), + zap.Error(err), + zap.Time("timestamp", time.Now()), + ) + return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve user referral codes") + } -// } + result := domain.ConvertReferralCodeResList(referrals) + + return response.WriteJSON(c, fiber.StatusOK, "Referral Code Fetched Successfully", result, nil) + +} // GetReferralStats godoc // @Summary Get referral statistics @@ -152,107 +159,109 @@ func (h *Handler) GetReferralStats(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve referral stats") } - return response.WriteJSON(c, fiber.StatusOK, "Referral stats retrieved successfully", stats, nil) + res := domain.ConvertReferralStatsRes(stats) + + return response.WriteJSON(c, fiber.StatusOK, "Referral stats retrieved successfully", res, nil) } -// UpdateReferralSettings godoc -// @Summary Update referral settings -// @Description Updates referral settings (admin only) -// @Tags referral -// @Accept json -// @Produce json -// @Param settings body domain.ReferralSettings true "Referral settings" -// @Success 200 {object} response.APIResponse -// @Failure 401 {object} response.APIResponse -// @Failure 403 {object} response.APIResponse -// @Failure 500 {object} response.APIResponse -// @Security Bearer -// @Router /api/v1/referral/settings [put] -func (h *Handler) UpdateReferralSettings(c *fiber.Ctx) error { - userID, ok := c.Locals("user_id").(int64) - if !ok || userID == 0 { - h.logger.Error("Invalid user ID in context") - h.mongoLoggerSvc.Error("Failed to delete user", - zap.Int64("userID", userID), - zap.Int("status_code", fiber.StatusInternalServerError), - zap.Time("timestamp", time.Now()), - ) - return fiber.NewError(fiber.StatusInternalServerError, "Invalid user id") - } +// // UpdateReferralSettings godoc +// // @Summary Update referral settings +// // @Description Updates referral settings (admin only) +// // @Tags referral +// // @Accept json +// // @Produce json +// // @Param settings body domain.ReferralSettings true "Referral settings" +// // @Success 200 {object} response.APIResponse +// // @Failure 401 {object} response.APIResponse +// // @Failure 403 {object} response.APIResponse +// // @Failure 500 {object} response.APIResponse +// // @Security Bearer +// // @Router /api/v1/referral/settings [put] +// func (h *Handler) UpdateReferralSettings(c *fiber.Ctx) error { +// userID, ok := c.Locals("user_id").(int64) +// if !ok || userID == 0 { +// h.logger.Error("Invalid user ID in context") +// h.mongoLoggerSvc.Error("Failed to delete user", +// zap.Int64("userID", userID), +// zap.Int("status_code", fiber.StatusInternalServerError), +// zap.Time("timestamp", time.Now()), +// ) +// return fiber.NewError(fiber.StatusInternalServerError, "Invalid user id") +// } - user, err := h.userSvc.GetUserByID(c.Context(), userID) - if err != nil { - h.mongoLoggerSvc.Error("Failed to get user", - zap.Int64("userID", userID), - zap.Int("status_code", fiber.StatusInternalServerError), - zap.Error(err), - zap.Time("timestamp", time.Now()), - ) - return fiber.NewError(fiber.StatusInternalServerError, err.Error()) - } +// user, err := h.userSvc.GetUserByID(c.Context(), userID) +// if err != nil { +// h.mongoLoggerSvc.Error("Failed to get user", +// zap.Int64("userID", userID), +// zap.Int("status_code", fiber.StatusInternalServerError), +// zap.Error(err), +// zap.Time("timestamp", time.Now()), +// ) +// return fiber.NewError(fiber.StatusInternalServerError, err.Error()) +// } - if user.Role != domain.RoleAdmin { - h.mongoLoggerSvc.Error("Access Forbidden", - zap.Int64("userID", userID), - zap.Int("status_code", fiber.StatusForbidden), - zap.Error(err), - zap.Time("timestamp", time.Now()), - ) - return fiber.NewError(fiber.StatusForbidden, "Admin access required") - } +// if user.Role != domain.RoleAdmin { +// h.mongoLoggerSvc.Error("Access Forbidden", +// zap.Int64("userID", userID), +// zap.Int("status_code", fiber.StatusForbidden), +// zap.Error(err), +// zap.Time("timestamp", time.Now()), +// ) +// return fiber.NewError(fiber.StatusForbidden, "Admin access required") +// } - var settings domain.ReferralSettings - if err := c.BodyParser(&settings); err != nil { - h.mongoLoggerSvc.Info("Failed to parse settings", - zap.Int64("userID", userID), - zap.Int("status_code", fiber.StatusBadRequest), - zap.Error(err), - zap.Time("timestamp", time.Now()), - ) - return fiber.NewError(fiber.StatusBadRequest, "Invalid request body") - } +// var settings domain.ReferralSettings +// if err := c.BodyParser(&settings); err != nil { +// h.mongoLoggerSvc.Info("Failed to parse settings", +// zap.Int64("userID", userID), +// zap.Int("status_code", fiber.StatusBadRequest), +// zap.Error(err), +// zap.Time("timestamp", time.Now()), +// ) +// return fiber.NewError(fiber.StatusBadRequest, "Invalid request body") +// } - settings.UpdatedBy = user.PhoneNumber - if err := h.referralSvc.UpdateReferralSettings(c.Context(), &settings); err != nil { - h.mongoLoggerSvc.Error("Failed to update referral settings", - zap.Int64("userID", userID), - zap.Int("status_code", fiber.StatusInternalServerError), - zap.Error(err), - zap.Time("timestamp", time.Now()), - ) - return fiber.NewError(fiber.StatusInternalServerError, err.Error()) - } +// settings.UpdatedBy = user.PhoneNumber +// if err := h.referralSvc.UpdateReferralSettings(c.Context(), &settings); err != nil { +// h.mongoLoggerSvc.Error("Failed to update referral settings", +// zap.Int64("userID", userID), +// zap.Int("status_code", fiber.StatusInternalServerError), +// zap.Error(err), +// zap.Time("timestamp", time.Now()), +// ) +// return fiber.NewError(fiber.StatusInternalServerError, err.Error()) +// } - return response.WriteJSON(c, fiber.StatusOK, "Referral settings updated successfully", nil, nil) -} +// return response.WriteJSON(c, fiber.StatusOK, "Referral settings updated successfully", nil, nil) +// } -// GetReferralSettings godoc -// @Summary Get referral settings -// @Description Retrieves current referral settings (admin only) -// @Tags referral -// @Accept json -// @Produce json -// @Success 200 {object} domain.ReferralSettings -// @Failure 401 {object} response.APIResponse -// @Failure 403 {object} response.APIResponse -// @Failure 500 {object} response.APIResponse -// @Security Bearer -// @Router /api/v1/referral/settings [get] -func (h *Handler) GetReferralSettings(c *fiber.Ctx) error { - // userID, ok := c.Locals("user_id").(int64) - // if !ok || userID == 0 { - // h.logger.Error("Invalid user ID in context") - // return fiber.NewError(fiber.StatusUnauthorized, "Invalid user identification") - // } - settings, err := h.referralSvc.GetReferralSettings(c.Context()) - if err != nil { - h.mongoLoggerSvc.Error("Failed to get referral settings", - zap.Int("status_code", fiber.StatusInternalServerError), - zap.Error(err), - zap.Time("timestamp", time.Now()), - ) - return fiber.NewError(fiber.StatusInternalServerError, err.Error()) - } +// // GetReferralSettings godoc +// // @Summary Get referral settings +// // @Description Retrieves current referral settings (admin only) +// // @Tags referral +// // @Accept json +// // @Produce json +// // @Success 200 {object} domain.ReferralSettings +// // @Failure 401 {object} response.APIResponse +// // @Failure 403 {object} response.APIResponse +// // @Failure 500 {object} response.APIResponse +// // @Security Bearer +// // @Router /api/v1/referral/settings [get] +// func (h *Handler) GetReferralSettings(c *fiber.Ctx) error { +// // userID, ok := c.Locals("user_id").(int64) +// // if !ok || userID == 0 { +// // h.logger.Error("Invalid user ID in context") +// // return fiber.NewError(fiber.StatusUnauthorized, "Invalid user identification") +// // } +// settings, err := h.referralSvc.GetReferralSettings(c.Context()) +// if err != nil { +// h.mongoLoggerSvc.Error("Failed to get referral settings", +// zap.Int("status_code", fiber.StatusInternalServerError), +// zap.Error(err), +// zap.Time("timestamp", time.Now()), +// ) +// return fiber.NewError(fiber.StatusInternalServerError, err.Error()) +// } - return response.WriteJSON(c, fiber.StatusOK, "Referral settings retrieved successfully", settings, nil) -} +// return response.WriteJSON(c, fiber.StatusOK, "Referral settings retrieved successfully", settings, nil) +// } diff --git a/internal/web_server/handlers/user.go b/internal/web_server/handlers/user.go index 81f8223..5c185fc 100644 --- a/internal/web_server/handlers/user.go +++ b/internal/web_server/handlers/user.go @@ -248,7 +248,7 @@ func (h *Handler) RegisterUser(c *fiber.Ctx) error { } if req.ReferralCode != "" { - err = h.referralSvc.ProcessReferral(c.Context(), req.PhoneNumber, req.ReferralCode, companyID.Value) + err = h.referralSvc.ProcessReferral(c.Context(), newUser.ID, req.ReferralCode, companyID.Value) if err != nil { h.mongoLoggerSvc.Error("Failed to process referral during registration", zap.String("phone", req.PhoneNumber), diff --git a/internal/web_server/routes.go b/internal/web_server/routes.go index 21803b5..4a7f4b7 100644 --- a/internal/web_server/routes.go +++ b/internal/web_server/routes.go @@ -189,10 +189,12 @@ func (a *App) initAppRoutes() { // Referral Routes tenant.Post("/referral/create", a.authMiddleware, h.CreateReferralCode) + tenant.Get("/referral/code", a.authMiddleware, h.GetReferralCode) tenant.Get("/referral/stats", a.authMiddleware, h.GetReferralStats) - groupV1.Post("/referral/settings", a.authMiddleware, h.CreateReferralSettings) - groupV1.Get("/referral/settings", a.authMiddleware, h.GetReferralSettings) - groupV1.Patch("/referral/settings", a.authMiddleware, h.UpdateReferralSettings) + + // groupV1.Post("/referral/settings", a.authMiddleware, h.CreateReferralSettings) + // groupV1.Get("/referral/settings", a.authMiddleware, h.GetReferralSettings) + // groupV1.Patch("/referral/settings", a.authMiddleware, h.UpdateReferralSettings) // Raffle Routes a.fiber.Post("/raffle/create", a.authMiddleware, h.CreateRaffle)