package repository import ( "context" "encoding/json" "os" "time" dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/jackc/pgx/v5/pgtype" ) func (s *Store) SaveOddMarket(ctx context.Context, m domain.CreateOddMarket) error { if len(m.Odds) == 0 { return nil } params, err := domain.ConvertCreateOddMarket(m) if err != nil { return err } err = s.queries.InsertOddsMarket(ctx, params) if err != nil { _ = writeFailedMarketLog(m, err) return err } return nil } func writeFailedMarketLog(m domain.CreateOddMarket, err error) error { logDir := "logs" logFile := logDir + "/failed_markets.log" if mkErr := os.MkdirAll(logDir, 0755); mkErr != nil { return mkErr } f, fileErr := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if fileErr != nil { return fileErr } defer f.Close() entry := struct { Time string `json:"time"` Error string `json:"error"` Record domain.CreateOddMarket `json:"record"` }{ Time: time.Now().Format(time.RFC3339), Error: err.Error(), Record: m, } jsonData, _ := json.MarshalIndent(entry, "", " ") _, writeErr := f.WriteString(string(jsonData) + "\n\n") return writeErr } func (s *Store) GetAllOdds(ctx context.Context, filter domain.OddMarketFilter) ([]domain.OddMarket, error) { rows, err := s.queries.GetAllOdds(ctx, dbgen.GetAllOddsParams{ Offset: filter.Offset.ToPG(), Limit: filter.Limit.ToPG(), }) if err != nil { return nil, err } domainOdds, err := domain.ConvertDBOddMarkets(rows) if err != nil { return nil, err } return domainOdds, nil } func (s *Store) GetAllOddsWithSettings(ctx context.Context, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error) { odds, err := s.queries.GetAllOddsWithSettings(ctx, dbgen.GetAllOddsWithSettingsParams{ CompanyID: companyID, Offset: filter.Offset.ToPG(), Limit: filter.Limit.ToPG(), }) if err != nil { return nil, err } // domainOdds, err := domain.ConvertDBOddMarketWithSettings(odds) // if err != nil { // return nil, err // } result := make([]domain.OddMarketWithSettings, len(odds)) for i, o := range odds { var rawOdds []json.RawMessage if len(o.RawOdds) > 0 { if err := json.Unmarshal(o.RawOdds, &rawOdds); err != nil { return nil, err } } else { rawOdds = []json.RawMessage{} // explicit empty slice } result[i] = domain.OddMarketWithSettings{ ID: o.ID, EventID: o.EventID, MarketType: o.MarketType, MarketName: o.MarketName, MarketCategory: o.MarketCategory, MarketID: o.MarketID, RawOdds: rawOdds, FetchedAt: o.FetchedAt.Time, ExpiresAt: o.ExpiresAt.Time, IsActive: o.IsActive, } } return result, nil } func (s *Store) GetOddByID(ctx context.Context, id int64) (domain.OddMarket, error) { odd, err := s.queries.GetOddByID(ctx, id) if err != nil { return domain.OddMarket{}, err } convertedOdd, err := domain.ConvertDBOddMarket(odd) if err != nil { return domain.OddMarket{}, err } return convertedOdd, nil } func (s *Store) GetOddsByMarketID(ctx context.Context, marketID string, eventID string) (domain.OddMarket, error) { odds, err := s.queries.GetOddsByMarketID(ctx, dbgen.GetOddsByMarketIDParams{ MarketID: marketID, EventID: eventID, }) if err != nil { return domain.OddMarket{}, err } convertedOdd, err := domain.ConvertDBOddMarket(odds) if err != nil { return domain.OddMarket{}, err } return convertedOdd, nil } func (s *Store) GetOddsWithSettingsByMarketID(ctx context.Context, marketID string, eventID string, companyID int64) (domain.OddMarketWithSettings, error) { odds, err := s.queries.GetOddsWithSettingsByMarketID(ctx, dbgen.GetOddsWithSettingsByMarketIDParams{ MarketID: marketID, EventID: eventID, CompanyID: companyID, }) if err != nil { return domain.OddMarketWithSettings{}, err } // convertedOdd, err := domain.ConvertDBOddMarketWithSetting(odds) // if err != nil { // return domain.OddMarketWithSettings{}, err // } var rawOdds []json.RawMessage if len(odds.RawOdds) > 0 { if err := json.Unmarshal(odds.RawOdds, &rawOdds); err != nil { return domain.OddMarketWithSettings{}, err } } else { rawOdds = []json.RawMessage{} // explicit empty slice } converted := domain.OddMarketWithSettings{ ID: odds.ID, EventID: odds.EventID, MarketType: odds.MarketType, MarketName: odds.MarketName, MarketCategory: odds.MarketCategory, MarketID: odds.MarketID, RawOdds: rawOdds, FetchedAt: odds.FetchedAt.Time, ExpiresAt: odds.ExpiresAt.Time, IsActive: odds.IsActive, } return converted, nil } func (s *Store) GetOddsWithSettingsByID(ctx context.Context, ID int64, companyID int64) (domain.OddMarketWithSettings, error) { odds, err := s.queries.GetOddsWithSettingsByID(ctx, dbgen.GetOddsWithSettingsByIDParams{ ID: ID, CompanyID: companyID, }) if err != nil { return domain.OddMarketWithSettings{}, err } // convertedOdd, err := domain.ConvertDBOddMarketWithSetting(odds) // if err != nil { // return domain.OddMarketWithSettings{}, err // } var rawOdds []json.RawMessage if len(odds.RawOdds) > 0 { if err := json.Unmarshal(odds.RawOdds, &rawOdds); err != nil { return domain.OddMarketWithSettings{}, err } } else { rawOdds = []json.RawMessage{} // explicit empty slice } converted := domain.OddMarketWithSettings{ ID: odds.ID, EventID: odds.EventID, MarketType: odds.MarketType, MarketName: odds.MarketName, MarketCategory: odds.MarketCategory, MarketID: odds.MarketID, RawOdds: rawOdds, FetchedAt: odds.FetchedAt.Time, ExpiresAt: odds.ExpiresAt.Time, IsActive: odds.IsActive, } return converted, nil } func (s *Store) GetOddsByEventID(ctx context.Context, upcomingID string, filter domain.OddMarketWithEventFilter) ([]domain.OddMarket, error) { odds, err := s.queries.GetOddsByEventID(ctx, dbgen.GetOddsByEventIDParams{ EventID: upcomingID, Limit: filter.Limit.ToPG(), Offset: filter.Offset.ToPG(), IsLive: pgtype.Bool{ Bool: false, Valid: true, }, Status: pgtype.Text{ String: string(domain.STATUS_PENDING), Valid: true, }, Source: pgtype.Text{}, }) if err != nil { return nil, err } // Map the results to domain.Odd domainOdds, err := domain.ConvertDBOddMarkets(odds) if err != nil { return nil, err } return domainOdds, nil } func (s *Store) GetOddsWithSettingsByEventID(ctx context.Context, upcomingID string, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error) { odds, err := s.queries.GetOddsWithSettingsByEventID(ctx, dbgen.GetOddsWithSettingsByEventIDParams{ EventID: upcomingID, CompanyID: companyID, Offset: filter.Offset.ToPG(), Limit: filter.Limit.ToPG(), }) if err != nil { return nil, err } // Map the results to domain.Odd // domainOdds, err := domain.ConvertDBOddMarketWithSettings(odds) // if err != nil { // return nil, err // } result := make([]domain.OddMarketWithSettings, len(odds)) for i, o := range odds { var rawOdds []json.RawMessage if len(o.RawOdds) > 0 { if err := json.Unmarshal(o.RawOdds, &rawOdds); err != nil { return nil, err } } else { rawOdds = []json.RawMessage{} // explicit empty slice } result[i] = domain.OddMarketWithSettings{ ID: o.ID, EventID: o.EventID, MarketType: o.MarketType, MarketName: o.MarketName, MarketCategory: o.MarketCategory, MarketID: o.MarketID, RawOdds: rawOdds, FetchedAt: o.FetchedAt.Time, ExpiresAt: o.ExpiresAt.Time, IsActive: o.IsActive, } } return result, nil } func (s *Store) DeleteOddsForEvent(ctx context.Context, eventID string) error { return s.queries.DeleteOddsForEvent(ctx, eventID) } func (s *Store) SaveOddsSetting(ctx context.Context, odd domain.CreateOddMarketSettings) error { res, err := domain.ConvertCreateOddMarketSetting(odd) if err != nil { return nil } return s.queries.SaveOddSettings(ctx, res) }