- Updated league handling to ensure valid page size checks and improved error handling for sport ID parsing. - Introduced new endpoint to update global league settings with comprehensive validation and error logging. - Refactored odds settings management, including saving, removing, and updating odds settings with enhanced validation. - Added tenant slug retrieval by token, ensuring proper user and company validation. - Improved middleware to check for active company status and adjusted route permissions for various endpoints. - Added SQL script to fix auto-increment desynchronization across multiple tables.
337 lines
8.7 KiB
Go
337 lines
8.7 KiB
Go
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 int64, eventID int64) (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 int64, eventID int64, 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, eventID int64, filter domain.OddMarketWithEventFilter) ([]domain.OddMarket, error) {
|
|
odds, err := s.queries.GetOddsByEventID(ctx, dbgen.GetOddsByEventIDParams{
|
|
EventID: eventID,
|
|
Status: filter.Status.ToPG(),
|
|
IsLive: filter.IsLive.ToPG(),
|
|
Limit: filter.Limit.ToPG(),
|
|
Offset: filter.Offset.ToPG(),
|
|
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, eventID int64, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error) {
|
|
|
|
odds, err := s.queries.GetOddsWithSettingsByEventID(ctx, dbgen.GetOddsWithSettingsByEventIDParams{
|
|
EventID: eventID,
|
|
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 int64) 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)
|
|
}
|
|
|
|
func (s *Store) UpdateGlobalOddsSetting(ctx context.Context, odd domain.UpdateGlobalOddMarketSettings) error {
|
|
return s.queries.UpdateGlobalOddsSetting(ctx, dbgen.UpdateGlobalOddsSettingParams{
|
|
ID: odd.OddMarketID,
|
|
DefaultIsActive: odd.IsActive.ToPG(),
|
|
})
|
|
}
|
|
|
|
func (s *Store) DeleteAllCompanyOddsSetting(ctx context.Context, companyID int64) error {
|
|
return s.queries.DeleteAllCompanyOddsSetting(ctx, companyID)
|
|
}
|
|
|
|
func (s *Store) DeleteCompanyOddsSettingByOddMarketID(ctx context.Context, companyID int64, oddMarketID int64) error {
|
|
return s.queries.DeleteCompanyOddsSettingByOddMarketID(ctx, dbgen.DeleteCompanyOddsSettingByOddMarketIDParams{
|
|
CompanyID: companyID,
|
|
OddsMarketID: oddMarketID,
|
|
})
|
|
}
|