diff --git a/internal/services/virtualGame/veli/game_orchestration.go b/internal/services/virtualGame/veli/game_orchestration.go index b2187b0..b2ba665 100644 --- a/internal/services/virtualGame/veli/game_orchestration.go +++ b/internal/services/virtualGame/veli/game_orchestration.go @@ -44,16 +44,36 @@ func (s *Service) AddProviders(ctx context.Context, req domain.ProviderRequest) createParams := dbgen.CreateVirtualGameProviderParams{ ProviderID: p.ProviderID, ProviderName: p.ProviderName, - LogoDark: pgtype.Text{String: p.LogoForDark, Valid: true}, - LogoLight: pgtype.Text{String: p.LogoForLight, Valid: true}, + LogoDark: pgtype.Text{String: p.LogoForDark, Valid: p.LogoForDark != ""}, + LogoLight: pgtype.Text{String: p.LogoForLight, Valid: p.LogoForLight != ""}, Enabled: true, } if _, err := s.repo.CreateVirtualGameProvider(ctx, createParams); err != nil { - // Log error but continue with other providers return nil, fmt.Errorf("failed to add provider %s: %w", p.ProviderID, err) } } + // 4. Always add "popok" provider manually + popokParams := dbgen.CreateVirtualGameProviderParams{ + ProviderID: "popok", + ProviderName: "Popok Gaming", + LogoDark: pgtype.Text{String: "/static/logos/popok-dark.png", Valid: true}, // adjust as needed + LogoLight: pgtype.Text{String: "/static/logos/popok-light.png", Valid: true}, // adjust as needed + Enabled: true, + } + + if _, err := s.repo.CreateVirtualGameProvider(ctx, popokParams); err != nil { + return nil, fmt.Errorf("failed to add popok provider: %w", err) + } + + // Optionally also append it to the response for consistency + // res.Items = append(res.Items, domain.VirtualGameProvider{ + // ProviderID: uuid.New().String(), + // ProviderName: "Popok Gaming", + // LogoForDark: "/static/logos/popok-dark.png", + // LogoForLight: "/static/logos/popok-light.png", + // }) + return &res, nil } diff --git a/internal/services/virtualGame/veli/service.go b/internal/services/virtualGame/veli/service.go index c8da008..292f4e9 100644 --- a/internal/services/virtualGame/veli/service.go +++ b/internal/services/virtualGame/veli/service.go @@ -62,39 +62,102 @@ func (s *Service) GetProviders(ctx context.Context, req domain.ProviderRequest) } func (s *Service) GetGames(ctx context.Context, req domain.GameListRequest) ([]domain.GameEntity, error) { - sigParams := map[string]any{ - "brandId": req.BrandID, "providerId": req.ProviderID, + // 1. Check if provider is enabled in DB + provider, err := s.repo.GetVirtualGameProviderByID(ctx, req.ProviderID) + if err != nil { + return nil, fmt.Errorf("failed to check provider %s: %w", req.ProviderID, err) } + + if !provider.Enabled { + // Provider exists but is disabled → return empty list (or error if you prefer) + return nil, fmt.Errorf("provider %s is disabled", req.ProviderID) + } + + // 2. Prepare signature params + sigParams := map[string]any{ + "brandId": req.BrandID, + "providerId": req.ProviderID, + } + + // 3. Call external API var res struct { Items []domain.GameEntity `json:"items"` } - err := s.client.post(ctx, "/game-lists/public/games", req, sigParams, &res) - return res.Items, err + if err := s.client.post(ctx, "/game-lists/public/games", req, sigParams, &res); err != nil { + return nil, fmt.Errorf("failed to fetch games for provider %s: %w", req.ProviderID, err) + } + + return res.Items, nil } func (s *Service) StartGame(ctx context.Context, req domain.GameStartRequest) (*domain.GameStartResponse, error) { - sigParams := map[string]any{ - "sessionId": req.SessionID, "providerId": req.ProviderID, - "gameId": req.GameID, "language": req.Language, "playerId": req.PlayerID, - "currency": req.Currency, "deviceType": req.DeviceType, "country": "US", - "ip": req.IP, "brandId": req.BrandID, + // 1. Check if provider is enabled in DB + provider, err := s.repo.GetVirtualGameProviderByID(ctx, req.ProviderID) + if err != nil { + return nil, fmt.Errorf("failed to check provider %s: %w", req.ProviderID, err) } + + if !provider.Enabled { + // Provider exists but is disabled → return error + return nil, fmt.Errorf("provider %s is disabled", req.ProviderID) + } + + // 2. Prepare signature params + sigParams := map[string]any{ + "sessionId": req.SessionID, + "providerId": req.ProviderID, + "gameId": req.GameID, + "language": req.Language, + "playerId": req.PlayerID, + "currency": req.Currency, + "deviceType": req.DeviceType, + "country": "US", + "ip": req.IP, + "brandId": req.BrandID, + } + + // 3. Call external API var res domain.GameStartResponse - err := s.client.post(ctx, "/unified-api/public/start-game", req, sigParams, &res) - return &res, err + if err := s.client.post(ctx, "/unified-api/public/start-game", req, sigParams, &res); err != nil { + return nil, fmt.Errorf("failed to start game with provider %s: %w", req.ProviderID, err) + } + + return &res, nil } + func (s *Service) StartDemoGame(ctx context.Context, req domain.DemoGameRequest) (*domain.GameStartResponse, error) { - sigParams := map[string]any{ - "providerId": req.ProviderID, "gameId": req.GameID, - "language": req.Language, "deviceType": req.DeviceType, - "ip": req.IP, "brandId": req.BrandID, + // 1. Check if provider is enabled in DB + provider, err := s.repo.GetVirtualGameProviderByID(ctx, req.ProviderID) + if err != nil { + return nil, fmt.Errorf("failed to check provider %s: %w", req.ProviderID, err) } + + if !provider.Enabled { + // Provider exists but is disabled → return error + return nil, fmt.Errorf("provider %s is disabled", req.ProviderID) + } + + // 2. Prepare signature params + sigParams := map[string]any{ + "providerId": req.ProviderID, + "gameId": req.GameID, + "language": req.Language, + "deviceType": req.DeviceType, + "ip": req.IP, + "brandId": req.BrandID, + } + + // 3. Call external API var res domain.GameStartResponse - err := s.client.post(ctx, "/unified-api/public/start-demo-game", req, sigParams, &res) - return &res, err + if err := s.client.post(ctx, "/unified-api/public/start-demo-game", req, sigParams, &res); err != nil { + return nil, fmt.Errorf("failed to start demo game with provider %s: %w", req.ProviderID, err) + } + + return &res, nil } + func (s *Service) GetBalance(ctx context.Context, req domain.BalanceRequest) (*domain.BalanceResponse, error) { // Retrieve player's real balance from wallet Service playerIDInt64, err := strconv.ParseInt(req.PlayerID, 10, 64) diff --git a/internal/web_server/handlers/bet_handler.go b/internal/web_server/handlers/bet_handler.go index a323560..fb59223 100644 --- a/internal/web_server/handlers/bet_handler.go +++ b/internal/web_server/handlers/bet_handler.go @@ -149,7 +149,7 @@ func (h *Handler) CreateBetWithFastCode(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusInternalServerError, "Failed to create bet:"+err.Error()) } - wallet, err := h.walletSvc.GetCustomerWallet(c.Context(), bet.UserID) + wallet, _ := h.walletSvc.GetCustomerWallet(c.Context(), bet.UserID) // amount added for fast code owner can be fetched from settings in db settingList, err := h.settingSvc.GetSettingList(c.Context()) diff --git a/internal/web_server/handlers/veli_games.go b/internal/web_server/handlers/veli_games.go index 8a005e6..0f299f5 100644 --- a/internal/web_server/handlers/veli_games.go +++ b/internal/web_server/handlers/veli_games.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log" + "strings" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/veli" @@ -70,6 +71,7 @@ func (h *Handler) GetGamesByProvider(c *fiber.Ctx) error { }) } + // Default brand if not provided if req.BrandID == "" { req.BrandID = h.Cfg.VeliGames.BrandID } @@ -77,6 +79,16 @@ func (h *Handler) GetGamesByProvider(c *fiber.Ctx) error { res, err := h.veliVirtualGameSvc.GetGames(context.Background(), req) if err != nil { log.Println("GetGames error:", err) + + // Handle provider disabled case specifically + if strings.Contains(err.Error(), "is disabled") { + return c.Status(fiber.StatusForbidden).JSON(domain.ErrorResponse{ + Message: "Provider is disabled", + Error: err.Error(), + }) + } + + // Fallback for other errors return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{ Message: "Failed to retrieve games", Error: err.Error(), @@ -91,6 +103,7 @@ func (h *Handler) GetGamesByProvider(c *fiber.Ctx) error { }) } + // StartGame godoc // @Summary Start a real game session // @Description Starts a real VeliGames session with the given player and game info @@ -119,7 +132,10 @@ func (h *Handler) StartGame(c *fiber.Ctx) error { }) } + // Attach user ID to request req.PlayerID = fmt.Sprintf("%d", userId) + + // Default brand if not provided if req.BrandID == "" { req.BrandID = h.Cfg.VeliGames.BrandID } @@ -127,6 +143,16 @@ func (h *Handler) StartGame(c *fiber.Ctx) error { res, err := h.veliVirtualGameSvc.StartGame(context.Background(), req) if err != nil { log.Println("StartGame error:", err) + + // Handle provider disabled case specifically + if strings.Contains(err.Error(), "is disabled") { + return c.Status(fiber.StatusForbidden).JSON(domain.ErrorResponse{ + Message: "Provider is disabled", + Error: err.Error(), + }) + } + + // Fallback for other errors return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{ Message: "Failed to start game", Error: err.Error(), @@ -141,6 +167,7 @@ func (h *Handler) StartGame(c *fiber.Ctx) error { }) } + // StartDemoGame godoc // @Summary Start a demo game session // @Description Starts a demo session of the specified game (must support demo mode) @@ -161,6 +188,7 @@ func (h *Handler) StartDemoGame(c *fiber.Ctx) error { }) } + // Default brand if not provided if req.BrandID == "" { req.BrandID = h.Cfg.VeliGames.BrandID } @@ -168,6 +196,16 @@ func (h *Handler) StartDemoGame(c *fiber.Ctx) error { res, err := h.veliVirtualGameSvc.StartDemoGame(context.Background(), req) if err != nil { log.Println("StartDemoGame error:", err) + + // Handle provider disabled case specifically + if strings.Contains(err.Error(), "is disabled") { + return c.Status(fiber.StatusForbidden).JSON(domain.ErrorResponse{ + Message: "Provider is disabled", + Error: err.Error(), + }) + } + + // Fallback for other errors return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{ Message: "Failed to start demo game", Error: err.Error(), @@ -182,6 +220,7 @@ func (h *Handler) StartDemoGame(c *fiber.Ctx) error { }) } + func (h *Handler) GetBalance(c *fiber.Ctx) error { var req domain.BalanceRequest if err := c.BodyParser(&req); err != nil { diff --git a/static/logos/popok-dark.png b/static/logos/popok-dark.png new file mode 100644 index 0000000..71c9e50 Binary files /dev/null and b/static/logos/popok-dark.png differ diff --git a/static/logos/popok-light.png b/static/logos/popok-light.png new file mode 100644 index 0000000..40f051b Binary files /dev/null and b/static/logos/popok-light.png differ