diff --git a/cmd/main.go b/cmd/main.go index cc41c96..09192e1 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -88,8 +88,8 @@ func main() { branchSvc := branch.NewService(store) companySvc := company.NewService(store) leagueSvc := league.New(store) - betSvc := bet.NewService(store, eventSvc, oddsSvc, *walletSvc, *branchSvc, logger) - resultSvc := result.NewService(store, cfg, logger, *betSvc, oddsSvc, eventSvc) + betSvc := bet.NewService(store, eventSvc, *oddsSvc, *walletSvc, *branchSvc, logger) + resultSvc := result.NewService(store, cfg, logger, *betSvc, *oddsSvc, eventSvc) notificationRepo := repository.NewNotificationRepository(store) referalRepo := repository.NewReferralRepository(store) vitualGameRepo := repository.NewVirtualGameRepository(store) @@ -123,7 +123,7 @@ func main() { store, ) - httpserver.StartDataFetchingCrons(eventSvc, oddsSvc, resultSvc) + httpserver.StartDataFetchingCrons(eventSvc, *oddsSvc, resultSvc) httpserver.StartTicketCrons(*ticketSvc) app := httpserver.NewApp(cfg.Port, v, authSvc, logger, jwtutil.JwtConfig{ diff --git a/internal/domain/event.go b/internal/domain/event.go index 4ea2d1a..932fd82 100644 --- a/internal/domain/event.go +++ b/internal/domain/event.go @@ -118,8 +118,8 @@ type Odds struct { } type EventFilter struct { - SportID ValidString - LeagueID ValidString + SportID ValidInt32 + LeagueID ValidInt32 FirstStartTime ValidTime LastStartTime ValidTime Limit ValidInt64 diff --git a/internal/repository/event.go b/internal/repository/event.go index 2ae01dd..a4b9aef 100644 --- a/internal/repository/event.go +++ b/internal/repository/event.go @@ -127,13 +127,13 @@ func (s *Store) GetExpiredUpcomingEvents(ctx context.Context, filter domain.Even func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, int64, error) { events, err := s.queries.GetPaginatedUpcomingEvents(ctx, dbgen.GetPaginatedUpcomingEventsParams{ - LeagueID: pgtype.Text{ - String: filter.LeagueID.Value, - Valid: filter.LeagueID.Valid, + LeagueID: pgtype.Int4{ + Int32: int32(filter.LeagueID.Value), + Valid: filter.LeagueID.Valid, }, - SportID: pgtype.Text{ - String: filter.SportID.Value, - Valid: filter.SportID.Valid, + SportID: pgtype.Int4{ + Int32: int32(filter.SportID.Value), + Valid: filter.SportID.Valid, }, Limit: pgtype.Int4{ Int32: int32(filter.Limit.Value), @@ -176,13 +176,13 @@ func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.Ev } } totalCount, err := s.queries.GetTotalEvents(ctx, dbgen.GetTotalEventsParams{ - LeagueID: pgtype.Text{ - String: filter.LeagueID.Value, - Valid: filter.LeagueID.Valid, + LeagueID: pgtype.Int4{ + Int32: int32(filter.LeagueID.Value), + Valid: filter.LeagueID.Valid, }, - SportID: pgtype.Text{ - String: filter.SportID.Value, - Valid: filter.SportID.Valid, + SportID: pgtype.Int4{ + Int32: int32(filter.SportID.Value), + Valid: filter.SportID.Valid, }, FirstStartTime: pgtype.Timestamp{ Time: filter.FirstStartTime.Value.UTC(), diff --git a/internal/services/bet/service.go b/internal/services/bet/service.go index cd84525..ff4424f 100644 --- a/internal/services/bet/service.go +++ b/internal/services/bet/service.go @@ -29,13 +29,13 @@ var ( type Service struct { betStore BetStore eventSvc event.Service - prematchSvc odds.Service + prematchSvc odds.ServiceImpl walletSvc wallet.Service branchSvc branch.Service logger *slog.Logger } -func NewService(betStore BetStore, eventSvc event.Service, prematchSvc odds.Service, walletSvc wallet.Service, branchSvc branch.Service, logger *slog.Logger) *Service { +func NewService(betStore BetStore, eventSvc event.Service, prematchSvc odds.ServiceImpl, walletSvc wallet.Service, branchSvc branch.Service, logger *slog.Logger) *Service { return &Service{ betStore: betStore, eventSvc: eventSvc, diff --git a/internal/services/odds/service.go b/internal/services/odds/service.go index 6bc3305..2ee4504 100644 --- a/internal/services/odds/service.go +++ b/internal/services/odds/service.go @@ -79,13 +79,6 @@ func (s *ServiceImpl) fetchBet365Odds(ctx context.Context) error { for index, event := range eventIDs { log.Printf("📡 Fetching prematch odds for event ID: %v (%d/%d) ", event.ID, index, len(eventIDs)) - sportID, err := strconv.ParseInt(event.SportID, 10, 64) - if err != nil { - s.logger.Error("Failed to parse sport id", "error", err) - errs = append(errs, fmt.Errorf("failed to parse sport id %s: %w", event.SportID, err)) - continue - } - oddsData, err := s.FetchNonLiveOddsByEventID(ctx, event.ID) if err != nil { s.logger.Error("Failed to fetch prematch odds", "eventID", event.ID, "error", err) @@ -93,7 +86,7 @@ func (s *ServiceImpl) fetchBet365Odds(ctx context.Context) error { continue } - parsedOddSections, err := s.ParseOddSections(ctx, oddsData.Results[0], sportID) + parsedOddSections, err := s.ParseOddSections(ctx, oddsData.Results[0], event.SportID) if err != nil { s.logger.Error("Failed to parse odd section", "error", err) errs = append(errs, fmt.Errorf("failed to parse odd section for event %v: %w", event.ID, err)) @@ -215,92 +208,6 @@ func (s *ServiceImpl) fetchBwinOdds(ctx context.Context) error { return nil } -func (s *ServiceImpl) fetchBwinOdds(ctx context.Context) error { - // getting odds for a specific event is not possible for bwin, most specific we can get is fetch odds on a single sport - // so instead of having event and odds fetched separetly event will also be fetched along with the odds - sportIds := []int{4, 12, 7} - for _, sportId := range sportIds { - url := fmt.Sprintf("https://api.b365api.com/v1/bwin/prematch?sport_id=%d&token=%s", sportId, s.config.Bet365Token) - req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) - if err != nil { - log.Printf("❌ Failed to create request for sportId %d: %v", sportId, err) - continue - } - - resp, err := s.client.Do(req) - if err != nil { - log.Printf("❌ Failed to fetch request for sportId %d: %v", sportId, err) - continue - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - log.Printf("❌ Failed to read response body for sportId %d: %v", sportId, err) - continue - } - - var data struct { - Success int `json:"success"` - Results []map[string]interface{} `json:"results"` - } - - if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 { - fmt.Printf("Decode failed for sport_id=%d\nRaw: %s\n", sportId, string(body)) - continue - } - - for _, res := range data.Results { - if getInt(res["Id"]) == -1 { - continue - } - - event := domain.Event{ - ID: strconv.Itoa(getInt(res["Id"])), - SportID: int32(getInt(res["SportId"])), - LeagueID: int32(getInt(res["LeagueId"])), - LeagueName: getString(res["Leaguename"]), - HomeTeam: getString(res["HomeTeam"]), - HomeTeamID: int32(getInt(res["HomeTeamId"])), - AwayTeam: getString(res["AwayTeam"]), - AwayTeamID: int32(getInt(res["AwayTeamId"])), - StartTime: time.Now().UTC().Format(time.RFC3339), - TimerStatus: "1", - IsLive: true, - Status: "live", - Source: "bwin", - } - - if err := s.store.SaveEvent(ctx, event); err != nil { - fmt.Printf("Could not store live event [id=%s]: %v\n", event.ID, err) - continue - } - - for _, market := range []string{"Markets, optionMarkets"} { - for _, m := range getMapArray(res[market]) { - name := getMap(m["name"]) - marketName := getString(name["value"]) - - market := domain.Market{ - EventID: event.ID, - MarketID: getString(m["id"]), - MarketCategory: getString(m["category"]), - MarketName: marketName, - Source: "bwin", - } - - results := getMapArray(m["results"]) - market.Odds = results - - s.store.SaveNonLiveMarket(ctx, market) - - } - } - } - - } - return nil -} func (s *ServiceImpl) FetchNonLiveOddsByEventID(ctx context.Context, eventIDStr string) (domain.BaseNonLiveOddResponse, error) { @@ -340,7 +247,7 @@ func (s *ServiceImpl) FetchNonLiveOddsByEventID(ctx context.Context, eventIDStr return oddsData, nil } -func (s *ServiceImpl) ParseOddSections(ctx context.Context, res json.RawMessage, sportID int64) (domain.ParseOddSectionsRes, error) { +func (s *ServiceImpl) ParseOddSections(ctx context.Context, res json.RawMessage, sportID int32) (domain.ParseOddSectionsRes, error) { var sections map[string]domain.OddsSection var OtherRes []domain.OddsSection var eventFI string diff --git a/internal/services/result/service.go b/internal/services/result/service.go index e1a44ef..dab02ef 100644 --- a/internal/services/result/service.go +++ b/internal/services/result/service.go @@ -24,11 +24,11 @@ type Service struct { logger *slog.Logger client *http.Client betSvc bet.Service - oddSvc odds.Service + oddSvc odds.ServiceImpl eventSvc event.Service } -func NewService(repo *repository.Store, cfg *config.Config, logger *slog.Logger, betSvc bet.Service, oddSvc odds.Service, eventSvc event.Service) *Service { +func NewService(repo *repository.Store, cfg *config.Config, logger *slog.Logger, betSvc bet.Service, oddSvc odds.ServiceImpl, eventSvc event.Service) *Service { return &Service{ repo: repo, config: cfg, @@ -304,7 +304,7 @@ func (s *Service) GetResultsForEvent(ctx context.Context, eventID string) (json. return json.RawMessage{}, nil, err } - sportID, err := strconv.ParseInt(commonResp.SportID, 10, 64) + sportID, err := strconv.ParseInt(commonResp.SportID, 10, 32) if err != nil { s.logger.Error("Failed to parse sport id", "event_id", eventID, "error", err) return json.RawMessage{}, nil, fmt.Errorf("failed to parse sport id: %w", err) @@ -324,7 +324,7 @@ func (s *Service) GetResultsForEvent(ctx context.Context, eventID string) (json. return json.RawMessage{}, nil, fmt.Errorf("failed to fetch non-live odds for event %s: %w", eventID, err) } - parsedOddSections, err := s.oddSvc.ParseOddSections(ctx, odds.Results[0], sportID) + parsedOddSections, err := s.oddSvc.ParseOddSections(ctx, odds.Results[0], int32(sportID)) if err != nil { s.logger.Error("Failed to parse odd section", "error", err) return json.RawMessage{}, nil, fmt.Errorf("failed to parse odd section for event %v: %w", eventID, err) diff --git a/internal/web_server/cron.go b/internal/web_server/cron.go index 89a6dbe..49b7fa0 100644 --- a/internal/web_server/cron.go +++ b/internal/web_server/cron.go @@ -14,7 +14,7 @@ import ( "github.com/robfig/cron/v3" ) -func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.Service, resultService *resultsvc.Service) { +func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.ServiceImpl, resultService *resultsvc.Service) { c := cron.New(cron.WithSeconds()) schedule := []struct { diff --git a/internal/web_server/routes.go b/internal/web_server/routes.go index e8f83e6..849ae3c 100644 --- a/internal/web_server/routes.go +++ b/internal/web_server/routes.go @@ -35,8 +35,8 @@ func (a *App) initAppRoutes() { a.companySvc, a.prematchSvc, a.eventSvc, - *a.resultSvc, a.leagueSvc, + *a.resultSvc, a.cfg, )