diff --git a/cmd/main.go b/cmd/main.go index 9fcfad3..07471fe 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -153,7 +153,7 @@ func main() { virtualGameSvc := virtualgameservice.New(vitualGameRepo, *walletSvc, store, cfg, logger) aleaService := alea.NewAleaPlayService(vitualGameRepo, *walletSvc, cfg, logger) veliCLient := veli.NewClient(cfg, walletSvc) - veliVirtualGameService := veli.New(virtualGameSvc, vitualGameRepo, veliCLient, walletSvc, wallet.TransferStore(store), cfg) + veliVirtualGameService := veli.New(virtualGameSvc, vitualGameRepo, veliCLient, walletSvc, wallet.TransferStore(store), domain.MongoDBLogger, cfg) atlasClient := atlas.NewClient(cfg, walletSvc) atlasVirtualGameService := atlas.New(virtualGameSvc, vitualGameRepo, atlasClient, walletSvc, wallet.TransferStore(store), cfg) recommendationSvc := recommendation.NewService(recommendationRepo) diff --git a/db/data/001_initial_seed_data.sql b/db/data/001_initial_seed_data.sql index 479027e..159a658 100644 --- a/db/data/001_initial_seed_data.sql +++ b/db/data/001_initial_seed_data.sql @@ -93,7 +93,7 @@ VALUES ('sms_provider', 'afro_message'), ('send_sms_on_bet_finish', 'false'), ('welcome_bonus_active', 'false'), ('welcome_bonus_multiplier', '1.5'), - ('welcome_bonus_multiplier', '100000'), + ('welcome_bonus_cap', '100000'), ('welcome_bonus_count', '3'), ('welcome_bonus_expiry', '10') ON CONFLICT (key) DO NOTHING; -- Users diff --git a/db/query/virtual_games.sql b/db/query/virtual_games.sql index 1e81b98..46e5061 100644 --- a/db/query/virtual_games.sql +++ b/db/query/virtual_games.sql @@ -1,77 +1,157 @@ -- name: CreateVirtualGameProvider :one INSERT INTO virtual_game_providers ( - provider_id, provider_name, logo_dark, logo_light, enabled -) VALUES ( - $1, $2, $3, $4, $5 -) RETURNING id, provider_id, provider_name, logo_dark, logo_light, enabled, created_at, updated_at; - + provider_id, + provider_name, + logo_dark, + logo_light, + enabled + ) +VALUES ($1, $2, $3, $4, $5) +RETURNING id, + provider_id, + provider_name, + logo_dark, + logo_light, + enabled, + created_at, + updated_at; -- name: DeleteVirtualGameProvider :exec DELETE FROM virtual_game_providers WHERE provider_id = $1; - -- name: DeleteAllVirtualGameProviders :exec DELETE FROM virtual_game_providers; - -- name: GetVirtualGameProviderByID :one -SELECT id, provider_id, provider_name, logo_dark, logo_light, enabled, created_at, updated_at +SELECT id, + provider_id, + provider_name, + logo_dark, + logo_light, + enabled, + created_at, + updated_at FROM virtual_game_providers WHERE provider_id = $1; - -- name: ListVirtualGameProviders :many -SELECT id, provider_id, provider_name, logo_dark, logo_light, enabled, created_at, updated_at +SELECT id, + provider_id, + provider_name, + logo_dark, + logo_light, + enabled, + created_at, + updated_at FROM virtual_game_providers ORDER BY created_at DESC LIMIT $1 OFFSET $2; - -- name: CountVirtualGameProviders :one SELECT COUNT(*) AS total FROM virtual_game_providers; - -- name: UpdateVirtualGameProviderEnabled :one UPDATE virtual_game_providers SET enabled = $2, updated_at = CURRENT_TIMESTAMP WHERE provider_id = $1 -RETURNING id, provider_id, provider_name, logo_dark, logo_light, enabled, created_at, updated_at; - +RETURNING id, + provider_id, + provider_name, + logo_dark, + logo_light, + enabled, + created_at, + updated_at; -- name: CreateVirtualGameSession :one INSERT INTO virtual_game_sessions ( - user_id, game_id, session_token, currency, status, expires_at -) VALUES ( - $1, $2, $3, $4, $5, $6 -) RETURNING id, user_id, game_id, session_token, currency, status, created_at, updated_at, expires_at; + user_id, + game_id, + session_token, + currency, + status, + expires_at + ) +VALUES ($1, $2, $3, $4, $5, $6) +RETURNING id, + user_id, + game_id, + session_token, + currency, + status, + created_at, + updated_at, + expires_at; -- name: GetVirtualGameSessionByToken :one -SELECT id, user_id, game_id, session_token, currency, status, created_at, updated_at, expires_at +SELECT id, + user_id, + game_id, + session_token, + currency, + status, + created_at, + updated_at, + expires_at FROM virtual_game_sessions WHERE session_token = $1; -- name: UpdateVirtualGameSessionStatus :exec UPDATE virtual_game_sessions -SET status = $2, updated_at = CURRENT_TIMESTAMP +SET status = $2, + updated_at = CURRENT_TIMESTAMP WHERE id = $1; -- name: CreateVirtualGameTransaction :one INSERT INTO virtual_game_transactions ( - session_id, user_id, company_id, provider, wallet_id, transaction_type, amount, currency, external_transaction_id, status -) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10 -) RETURNING id, session_id, user_id, company_id, provider, wallet_id, transaction_type, amount, currency, external_transaction_id, status, created_at, updated_at; --- name: CreateVirtualGameHistory :one -INSERT INTO virtual_game_histories ( + session_id, + user_id, + company_id, + provider, + wallet_id, + transaction_type, + amount, + currency, + external_transaction_id, + status + ) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) +RETURNING id, session_id, user_id, company_id, provider, wallet_id, - game_id, transaction_type, amount, currency, external_transaction_id, - reference_transaction_id, - status -) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12 -) RETURNING - id, + status, + created_at, + updated_at; +-- name: CreateVirtualGameHistory :one +INSERT INTO virtual_game_histories ( + session_id, + user_id, + company_id, + provider, + wallet_id, + game_id, + transaction_type, + amount, + currency, + external_transaction_id, + reference_transaction_id, + status + ) +VALUES ( + $1, + $2, + $3, + $4, + $5, + $6, + $7, + $8, + $9, + $10, + $11, + $12 + ) +RETURNING id, session_id, user_id, company_id, @@ -87,60 +167,78 @@ INSERT INTO virtual_game_histories ( created_at, updated_at; -- name: GetVirtualGameTransactionByExternalID :one -SELECT id, session_id, user_id, wallet_id, transaction_type, amount, currency, external_transaction_id, status, created_at, updated_at +SELECT id, + session_id, + user_id, + wallet_id, + transaction_type, + amount, + currency, + external_transaction_id, + status, + created_at, + updated_at FROM virtual_game_transactions WHERE external_transaction_id = $1; -- name: UpdateVirtualGameTransactionStatus :exec UPDATE virtual_game_transactions -SET status = $2, updated_at = CURRENT_TIMESTAMP +SET status = $2, + updated_at = CURRENT_TIMESTAMP WHERE id = $1; -- name: GetVirtualGameSummaryInRange :many -SELECT - c.name AS company_name, +SELECT c.name AS company_name, vg.name AS game_name, COUNT(vgt.id) AS number_of_bets, COALESCE(SUM(vgt.amount), 0) AS total_transaction_sum FROM virtual_game_transactions vgt -JOIN virtual_game_sessions vgs ON vgt.session_id = vgs.id -JOIN virtual_games vg ON vgs.game_id = vg.id -JOIN companies c ON vgt.company_id = c.id + JOIN virtual_game_sessions vgs ON vgt.session_id = vgs.id + JOIN virtual_games vg ON vgs.game_id = vg.id + JOIN companies c ON vgt.company_id = c.id WHERE vgt.transaction_type = 'BET' - AND vgt.created_at BETWEEN $1 AND $2 -GROUP BY c.name, vg.name; + AND vgt.created_at BETWEEN $1 AND $2 +GROUP BY c.name, + vg.name; -- name: AddFavoriteGame :exec -INSERT INTO favorite_games ( - user_id, - game_id, - created_at -) VALUES ($1, $2, NOW()) -ON CONFLICT (user_id, game_id) DO NOTHING; +INSERT INTO favorite_games (user_id, game_id, created_at) +VALUES ($1, $2, NOW()) ON CONFLICT (user_id, game_id) DO NOTHING; -- name: RemoveFavoriteGame :exec DELETE FROM favorite_games -WHERE user_id = $1 AND game_id = $2; +WHERE user_id = $1 + AND game_id = $2; -- name: ListFavoriteGames :many SELECT game_id FROM favorite_games WHERE user_id = $1; - -- name: CreateVirtualGame :one INSERT INTO virtual_games ( - game_id, - provider_id, - name, - category, - device_type, - volatility, - rtp, - has_demo, - has_free_bets, - bets, - thumbnail, - status -) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12 -) -RETURNING - id, + game_id, + provider_id, + name, + category, + device_type, + volatility, + rtp, + has_demo, + has_free_bets, + bets, + thumbnail, + status + ) +VALUES ( + $1, + $2, + $3, + $4, + $5, + $6, + $7, + $8, + $9, + $10, + $11, + $12 + ) +RETURNING id, game_id, provider_id, name, @@ -155,10 +253,8 @@ RETURNING status, created_at, updated_at; - -- name: GetAllVirtualGames :many -SELECT - vg.id, +SELECT vg.id, vg.game_id, vg.provider_id, vp.provider_name, @@ -175,14 +271,20 @@ SELECT vg.created_at, vg.updated_at FROM virtual_games vg -JOIN virtual_game_providers vp ON vg.provider_id = vp.provider_id -WHERE - ($1::text IS NULL OR vg.category = $1) -- category filter (optional) - AND ($2::text IS NULL OR vg.name ILIKE '%' || $2 || '%') -- search by name (optional) + JOIN virtual_game_providers vp ON vg.provider_id = vp.provider_id +WHERE ( + vg.category = sqlc.narg('category') + OR sqlc.narg('category') IS NULL + ) + AND ( + name ILIKE '%' || sqlc.narg('name') || '%' + OR sqlc.narg('name') IS NULL + ) + AND ( + vg.provider_id = sqlc.narg('provider_id') + OR sqlc.narg('provider_id') IS NULL + ) ORDER BY vg.created_at DESC -LIMIT $3 OFFSET $4; - +LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset'); -- name: DeleteAllVirtualGames :exec -DELETE FROM virtual_games; - - +DELETE FROM virtual_games; \ No newline at end of file diff --git a/gen/db/virtual_games.sql.go b/gen/db/virtual_games.sql.go index 33697d7..5a2809a 100644 --- a/gen/db/virtual_games.sql.go +++ b/gen/db/virtual_games.sql.go @@ -12,12 +12,8 @@ import ( ) const AddFavoriteGame = `-- name: AddFavoriteGame :exec -INSERT INTO favorite_games ( - user_id, - game_id, - created_at -) VALUES ($1, $2, NOW()) -ON CONFLICT (user_id, game_id) DO NOTHING +INSERT INTO favorite_games (user_id, game_id, created_at) +VALUES ($1, $2, NOW()) ON CONFLICT (user_id, game_id) DO NOTHING ` type AddFavoriteGameParams struct { @@ -44,23 +40,34 @@ func (q *Queries) CountVirtualGameProviders(ctx context.Context) (int64, error) const CreateVirtualGame = `-- name: CreateVirtualGame :one INSERT INTO virtual_games ( - game_id, - provider_id, - name, - category, - device_type, - volatility, - rtp, - has_demo, - has_free_bets, - bets, - thumbnail, - status -) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12 -) -RETURNING - id, + game_id, + provider_id, + name, + category, + device_type, + volatility, + rtp, + has_demo, + has_free_bets, + bets, + thumbnail, + status + ) +VALUES ( + $1, + $2, + $3, + $4, + $5, + $6, + $7, + $8, + $9, + $10, + $11, + $12 + ) +RETURNING id, game_id, provider_id, name, @@ -130,22 +137,34 @@ func (q *Queries) CreateVirtualGame(ctx context.Context, arg CreateVirtualGamePa const CreateVirtualGameHistory = `-- name: CreateVirtualGameHistory :one INSERT INTO virtual_game_histories ( - session_id, - user_id, - company_id, - provider, - wallet_id, - game_id, - transaction_type, - amount, - currency, - external_transaction_id, - reference_transaction_id, - status -) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12 -) RETURNING - id, + session_id, + user_id, + company_id, + provider, + wallet_id, + game_id, + transaction_type, + amount, + currency, + external_transaction_id, + reference_transaction_id, + status + ) +VALUES ( + $1, + $2, + $3, + $4, + $5, + $6, + $7, + $8, + $9, + $10, + $11, + $12 + ) +RETURNING id, session_id, user_id, company_id, @@ -215,10 +234,21 @@ func (q *Queries) CreateVirtualGameHistory(ctx context.Context, arg CreateVirtua const CreateVirtualGameProvider = `-- name: CreateVirtualGameProvider :one INSERT INTO virtual_game_providers ( - provider_id, provider_name, logo_dark, logo_light, enabled -) VALUES ( - $1, $2, $3, $4, $5 -) RETURNING id, provider_id, provider_name, logo_dark, logo_light, enabled, created_at, updated_at + provider_id, + provider_name, + logo_dark, + logo_light, + enabled + ) +VALUES ($1, $2, $3, $4, $5) +RETURNING id, + provider_id, + provider_name, + logo_dark, + logo_light, + enabled, + created_at, + updated_at ` type CreateVirtualGameProviderParams struct { @@ -253,10 +283,23 @@ func (q *Queries) CreateVirtualGameProvider(ctx context.Context, arg CreateVirtu const CreateVirtualGameSession = `-- name: CreateVirtualGameSession :one INSERT INTO virtual_game_sessions ( - user_id, game_id, session_token, currency, status, expires_at -) VALUES ( - $1, $2, $3, $4, $5, $6 -) RETURNING id, user_id, game_id, session_token, currency, status, created_at, updated_at, expires_at + user_id, + game_id, + session_token, + currency, + status, + expires_at + ) +VALUES ($1, $2, $3, $4, $5, $6) +RETURNING id, + user_id, + game_id, + session_token, + currency, + status, + created_at, + updated_at, + expires_at ` type CreateVirtualGameSessionParams struct { @@ -294,10 +337,31 @@ func (q *Queries) CreateVirtualGameSession(ctx context.Context, arg CreateVirtua const CreateVirtualGameTransaction = `-- name: CreateVirtualGameTransaction :one INSERT INTO virtual_game_transactions ( - session_id, user_id, company_id, provider, wallet_id, transaction_type, amount, currency, external_transaction_id, status -) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10 -) RETURNING id, session_id, user_id, company_id, provider, wallet_id, transaction_type, amount, currency, external_transaction_id, status, created_at, updated_at + session_id, + user_id, + company_id, + provider, + wallet_id, + transaction_type, + amount, + currency, + external_transaction_id, + status + ) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) +RETURNING id, + session_id, + user_id, + company_id, + provider, + wallet_id, + transaction_type, + amount, + currency, + external_transaction_id, + status, + created_at, + updated_at ` type CreateVirtualGameTransactionParams struct { @@ -390,8 +454,7 @@ func (q *Queries) DeleteVirtualGameProvider(ctx context.Context, providerID stri } const GetAllVirtualGames = `-- name: GetAllVirtualGames :many -SELECT - vg.id, +SELECT vg.id, vg.game_id, vg.provider_id, vp.provider_name, @@ -408,19 +471,29 @@ SELECT vg.created_at, vg.updated_at FROM virtual_games vg -JOIN virtual_game_providers vp ON vg.provider_id = vp.provider_id -WHERE - ($1::text IS NULL OR vg.category = $1) -- category filter (optional) - AND ($2::text IS NULL OR vg.name ILIKE '%' || $2 || '%') -- search by name (optional) + JOIN virtual_game_providers vp ON vg.provider_id = vp.provider_id +WHERE ( + vg.category = $1 + OR $1 IS NULL + ) + AND ( + name ILIKE '%' || $2 || '%' + OR $2 IS NULL + ) + AND ( + vg.provider_id = $3 + OR $3 IS NULL + ) ORDER BY vg.created_at DESC -LIMIT $3 OFFSET $4 +LIMIT $5 OFFSET $4 ` type GetAllVirtualGamesParams struct { - Column1 string `json:"column_1"` - Column2 string `json:"column_2"` - Limit int32 `json:"limit"` - Offset int32 `json:"offset"` + Category pgtype.Text `json:"category"` + Name pgtype.Text `json:"name"` + ProviderID pgtype.Text `json:"provider_id"` + Offset pgtype.Int4 `json:"offset"` + Limit pgtype.Int4 `json:"limit"` } type GetAllVirtualGamesRow struct { @@ -444,10 +517,11 @@ type GetAllVirtualGamesRow struct { func (q *Queries) GetAllVirtualGames(ctx context.Context, arg GetAllVirtualGamesParams) ([]GetAllVirtualGamesRow, error) { rows, err := q.db.Query(ctx, GetAllVirtualGames, - arg.Column1, - arg.Column2, - arg.Limit, + arg.Category, + arg.Name, + arg.ProviderID, arg.Offset, + arg.Limit, ) if err != nil { return nil, err @@ -485,7 +559,14 @@ func (q *Queries) GetAllVirtualGames(ctx context.Context, arg GetAllVirtualGames } const GetVirtualGameProviderByID = `-- name: GetVirtualGameProviderByID :one -SELECT id, provider_id, provider_name, logo_dark, logo_light, enabled, created_at, updated_at +SELECT id, + provider_id, + provider_name, + logo_dark, + logo_light, + enabled, + created_at, + updated_at FROM virtual_game_providers WHERE provider_id = $1 ` @@ -507,7 +588,15 @@ func (q *Queries) GetVirtualGameProviderByID(ctx context.Context, providerID str } const GetVirtualGameSessionByToken = `-- name: GetVirtualGameSessionByToken :one -SELECT id, user_id, game_id, session_token, currency, status, created_at, updated_at, expires_at +SELECT id, + user_id, + game_id, + session_token, + currency, + status, + created_at, + updated_at, + expires_at FROM virtual_game_sessions WHERE session_token = $1 ` @@ -530,18 +619,18 @@ func (q *Queries) GetVirtualGameSessionByToken(ctx context.Context, sessionToken } const GetVirtualGameSummaryInRange = `-- name: GetVirtualGameSummaryInRange :many -SELECT - c.name AS company_name, +SELECT c.name AS company_name, vg.name AS game_name, COUNT(vgt.id) AS number_of_bets, COALESCE(SUM(vgt.amount), 0) AS total_transaction_sum FROM virtual_game_transactions vgt -JOIN virtual_game_sessions vgs ON vgt.session_id = vgs.id -JOIN virtual_games vg ON vgs.game_id = vg.id -JOIN companies c ON vgt.company_id = c.id + JOIN virtual_game_sessions vgs ON vgt.session_id = vgs.id + JOIN virtual_games vg ON vgs.game_id = vg.id + JOIN companies c ON vgt.company_id = c.id WHERE vgt.transaction_type = 'BET' - AND vgt.created_at BETWEEN $1 AND $2 -GROUP BY c.name, vg.name + AND vgt.created_at BETWEEN $1 AND $2 +GROUP BY c.name, + vg.name ` type GetVirtualGameSummaryInRangeParams struct { @@ -582,7 +671,17 @@ func (q *Queries) GetVirtualGameSummaryInRange(ctx context.Context, arg GetVirtu } const GetVirtualGameTransactionByExternalID = `-- name: GetVirtualGameTransactionByExternalID :one -SELECT id, session_id, user_id, wallet_id, transaction_type, amount, currency, external_transaction_id, status, created_at, updated_at +SELECT id, + session_id, + user_id, + wallet_id, + transaction_type, + amount, + currency, + external_transaction_id, + status, + created_at, + updated_at FROM virtual_game_transactions WHERE external_transaction_id = $1 ` @@ -647,7 +746,14 @@ func (q *Queries) ListFavoriteGames(ctx context.Context, userID int64) ([]int64, } const ListVirtualGameProviders = `-- name: ListVirtualGameProviders :many -SELECT id, provider_id, provider_name, logo_dark, logo_light, enabled, created_at, updated_at +SELECT id, + provider_id, + provider_name, + logo_dark, + logo_light, + enabled, + created_at, + updated_at FROM virtual_game_providers ORDER BY created_at DESC LIMIT $1 OFFSET $2 @@ -689,7 +795,8 @@ func (q *Queries) ListVirtualGameProviders(ctx context.Context, arg ListVirtualG const RemoveFavoriteGame = `-- name: RemoveFavoriteGame :exec DELETE FROM favorite_games -WHERE user_id = $1 AND game_id = $2 +WHERE user_id = $1 + AND game_id = $2 ` type RemoveFavoriteGameParams struct { @@ -707,7 +814,14 @@ UPDATE virtual_game_providers SET enabled = $2, updated_at = CURRENT_TIMESTAMP WHERE provider_id = $1 -RETURNING id, provider_id, provider_name, logo_dark, logo_light, enabled, created_at, updated_at +RETURNING id, + provider_id, + provider_name, + logo_dark, + logo_light, + enabled, + created_at, + updated_at ` type UpdateVirtualGameProviderEnabledParams struct { @@ -733,7 +847,8 @@ func (q *Queries) UpdateVirtualGameProviderEnabled(ctx context.Context, arg Upda const UpdateVirtualGameSessionStatus = `-- name: UpdateVirtualGameSessionStatus :exec UPDATE virtual_game_sessions -SET status = $2, updated_at = CURRENT_TIMESTAMP +SET status = $2, + updated_at = CURRENT_TIMESTAMP WHERE id = $1 ` @@ -749,7 +864,8 @@ func (q *Queries) UpdateVirtualGameSessionStatus(ctx context.Context, arg Update const UpdateVirtualGameTransactionStatus = `-- name: UpdateVirtualGameTransactionStatus :exec UPDATE virtual_game_transactions -SET status = $2, updated_at = CURRENT_TIMESTAMP +SET status = $2, + updated_at = CURRENT_TIMESTAMP WHERE id = $1 ` diff --git a/internal/services/event/service.go b/internal/services/event/service.go index 09673d3..798a925 100644 --- a/internal/services/event/service.go +++ b/internal/services/event/service.go @@ -217,9 +217,9 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur s.mongoLogger.Error("Failed to fetch event data for page", zap.Error(err)) return } - const pageLimit int = 200 sportIDs := []int{1, 18, 17, 3, 83, 15, 12, 19, 8, 16, 91} + // const pageLimit int = 1 // sportIDs := []int{1} var skippedLeague []string diff --git a/internal/services/virtualGame/veli/game_orchestration.go b/internal/services/virtualGame/veli/game_orchestration.go index 55d312d..4728119 100644 --- a/internal/services/virtualGame/veli/game_orchestration.go +++ b/internal/services/virtualGame/veli/game_orchestration.go @@ -7,11 +7,16 @@ import ( dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/jackc/pgx/v5/pgtype" + "go.uber.org/zap" ) func (s *Service) AddProviders(ctx context.Context, req domain.ProviderRequest) (*domain.ProviderResponse, error) { + + logger := s.mongoLogger.With(zap.String("service", "AddProviders"), zap.Any("ProviderRequest", req)) + // 0. Remove all existing providers first if err := s.repo.DeleteAllVirtualGameProviders(ctx); err != nil { + logger.Error("failed to delete all virtual game providers", zap.Error(err)) return nil, fmt.Errorf("failed to clear existing providers: %w", err) } @@ -21,6 +26,7 @@ func (s *Service) AddProviders(ctx context.Context, req domain.ProviderRequest) } // Optional fields + sigParams["extraData"] = fmt.Sprintf("%t", req.ExtraData) // false is still included if req.Size > 0 { sigParams["size"] = fmt.Sprintf("%d", req.Size) } else { @@ -50,6 +56,7 @@ func (s *Service) AddProviders(ctx context.Context, req domain.ProviderRequest) } if _, err := s.repo.CreateVirtualGameProvider(ctx, createParams); err != nil { + logger.Error("failed to add provider", zap.Error(err)) return nil, fmt.Errorf("failed to add provider %s: %w", p.ProviderID, err) } } @@ -64,6 +71,7 @@ func (s *Service) AddProviders(ctx context.Context, req domain.ProviderRequest) } if _, err := s.repo.CreateVirtualGameProvider(ctx, popokParams); err != nil { + logger.Error("failed to add popok provider", zap.Any("popokParams", popokParams), zap.Error(err)) return nil, fmt.Errorf("failed to add popok provider: %w", err) } @@ -80,9 +88,10 @@ func (s *Service) AddProviders(ctx context.Context, req domain.ProviderRequest) func (s *Service) GetAllVirtualGames(ctx context.Context, params dbgen.GetAllVirtualGamesParams) ([]domain.UnifiedGame, error) { // Build params for repo call - + logger := s.mongoLogger.With(zap.String("service", "GetAllVirtualGames"), zap.Any("params", params)) rows, err := s.repo.ListAllVirtualGames(ctx, params) if err != nil { + logger.Error("[GetAllVirtualGames] Failed to fetch virtual games", zap.Error(err)) return nil, fmt.Errorf("failed to fetch virtual games: %w", err) } @@ -128,16 +137,29 @@ func (s *Service) GetAllVirtualGames(ctx context.Context, params dbgen.GetAllVir } func (s *Service) FetchAndStoreAllVirtualGames(ctx context.Context, req domain.ProviderRequest, currency string) ([]domain.UnifiedGame, error) { - var allGames []domain.UnifiedGame + logger := s.mongoLogger.With( + zap.String("service", "FetchAndStoreAllVirtualGames"), + zap.Any("ProviderRequest", req), + ) + + // This is necessary, since the provider is a foreign key + _, err := s.AddProviders(ctx, req) + if err != nil { + return nil, fmt.Errorf("failed to add providers to database: %w", err) + } + + var allGames []domain.UnifiedGame // --- 1. Get providers from external API --- providersRes, err := s.GetProviders(ctx, req) if err != nil { + logger.Error("Failed to fetch provider", zap.Error(err)) return nil, fmt.Errorf("failed to fetch providers: %w", err) } // --- 2. Fetch games for each provider --- for _, p := range providersRes.Items { + // Violates foreign key if the provider isn't added games, err := s.GetGames(ctx, domain.GameListRequest{ BrandID: s.cfg.VeliGames.BrandID, ProviderID: p.ProviderID, @@ -145,6 +167,7 @@ func (s *Service) FetchAndStoreAllVirtualGames(ctx context.Context, req domain.P Size: req.Size, }) if err != nil { + logger.Error("failed to get veli games", zap.String("ProviderID", p.ProviderID), zap.Error(err)) continue // skip failing provider but continue others } @@ -164,7 +187,7 @@ func (s *Service) FetchAndStoreAllVirtualGames(ctx context.Context, req domain.P allGames = append(allGames, unified) // --- Save to DB --- - _, _ = s.repo.CreateVirtualGame(ctx, dbgen.CreateVirtualGameParams{ + _, err = s.repo.CreateVirtualGame(ctx, dbgen.CreateVirtualGameParams{ GameID: g.GameID, ProviderID: g.ProviderID, Name: g.Name, @@ -190,12 +213,17 @@ func (s *Service) FetchAndStoreAllVirtualGames(ctx context.Context, req domain.P // Thumbnail: g.Thumbnail, // Status: g.Status, }) + + if err != nil { + logger.Error("failed to create virtual game", zap.Error(err)) + } } } // --- 3. Handle PopOK separately --- popokGames, err := s.virtualGameSvc.ListGames(ctx, currency) if err != nil { + logger.Error("failed to fetch PopOk games", zap.Error(err)) return nil, fmt.Errorf("failed to fetch PopOK games: %w", err) } @@ -221,7 +249,7 @@ func (s *Service) FetchAndStoreAllVirtualGames(ctx context.Context, req domain.P } // --- Save to DB --- - _, _ = s.repo.CreateVirtualGame(ctx, dbgen.CreateVirtualGameParams{ + _, err = s.repo.CreateVirtualGame(ctx, dbgen.CreateVirtualGameParams{ GameID: fmt.Sprintf("popok-%d", g.ID), ProviderID: "popok", Name: g.GameName, @@ -235,6 +263,10 @@ func (s *Service) FetchAndStoreAllVirtualGames(ctx context.Context, req domain.P Valid: true, }, }) + + if err != nil { + logger.Error("failed to create virtual game", zap.Error(err)) + } } return allGames, nil diff --git a/internal/services/virtualGame/veli/service.go b/internal/services/virtualGame/veli/service.go index 49eb716..3f41633 100644 --- a/internal/services/virtualGame/veli/service.go +++ b/internal/services/virtualGame/veli/service.go @@ -11,6 +11,7 @@ import ( "github.com/SamuelTariku/FortuneBet-Backend/internal/repository" virtualgameservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet" + "go.uber.org/zap" ) var ( @@ -26,16 +27,26 @@ type Service struct { client *Client walletSvc *wallet.Service transfetStore wallet.TransferStore + mongoLogger *zap.Logger cfg *config.Config } -func New(virtualGameSvc virtualgameservice.VirtualGameService, repo repository.VirtualGameRepository, client *Client, walletSvc *wallet.Service, transferStore wallet.TransferStore, cfg *config.Config) *Service { +func New( + virtualGameSvc virtualgameservice.VirtualGameService, + repo repository.VirtualGameRepository, + client *Client, + walletSvc *wallet.Service, + transferStore wallet.TransferStore, + mongoLogger *zap.Logger, + cfg *config.Config, +) *Service { return &Service{ virtualGameSvc: virtualGameSvc, repo: repo, client: client, walletSvc: walletSvc, transfetStore: transferStore, + mongoLogger: mongoLogger, cfg: cfg, } } diff --git a/internal/web_server/handlers/virtual_games_hadlers.go b/internal/web_server/handlers/virtual_games_hadlers.go index 058f4e0..c077906 100644 --- a/internal/web_server/handlers/virtual_games_hadlers.go +++ b/internal/web_server/handlers/virtual_games_hadlers.go @@ -12,6 +12,7 @@ import ( "github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/veli" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" "github.com/gofiber/fiber/v2" + "github.com/jackc/pgx/v5/pgtype" ) type launchVirtualGameReq struct { @@ -50,12 +51,29 @@ func (h *Handler) ListVirtualGames(c *fiber.Ctx) error { } category := c.Query("category", "") search := c.Query("search", "") + providerID := c.Query("providerID", "") params := dbgen.GetAllVirtualGamesParams{ - Column1: category, - Column2: search, - Limit: int32(limit), - Offset: int32(offset), + Category: pgtype.Text{ + String: category, + Valid: category != "", + }, + Name: pgtype.Text{ + String: search, + Valid: search != "", + }, + ProviderID: pgtype.Text{ + String: providerID, + Valid: providerID != "", + }, + Offset: pgtype.Int4{ + Int32: int32(offset), + Valid: offset != 0, + }, + Limit: pgtype.Int4{ + Int32: int32(limit), + Valid: limit != 0, + }, } // --- Call service method ---