Yimaru-BackEnd/internal/repository/odds.go
OneTap Technologies a282080133 addign odd data
2025-04-11 15:12:55 +03:00

116 lines
3.2 KiB
Go

package repository
import (
"context"
"encoding/json"
"fmt"
"os"
"strconv"
"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) SaveNonLiveMarket(ctx context.Context, m domain.Market) error {
if len(m.Odds) == 0 {
fmt.Printf("⚠️ Market has no odds: %s (%s)\n", m.MarketType, m.EventID)
return nil
}
for _, raw := range m.Odds {
var item map[string]interface{}
if err := json.Unmarshal(raw, &item); err != nil {
fmt.Printf("❌ Invalid odd JSON for %s (%s): %v\n", m.MarketType, m.EventID, err)
continue
}
header := getString(item["header"])
name := getString(item["name"])
handicap := getString(item["handicap"])
oddsVal := getFloat(item["odds"])
// Marshal the full list of odds for reference (if needed)
rawOddsBytes, _ := json.Marshal(m.Odds)
params := dbgen.InsertNonLiveOddParams{
EventID: pgtype.Text{String: m.EventID, Valid: m.EventID != ""},
Fi: pgtype.Text{String: m.FI, Valid: m.FI != ""},
RawEventID: pgtype.Text{String: m.EventID, Valid: m.EventID != ""},
MarketType: m.MarketType,
MarketName: pgtype.Text{String: m.MarketName, Valid: m.MarketName != ""},
MarketCategory: pgtype.Text{String: m.MarketCategory, Valid: m.MarketCategory != ""},
MarketID: pgtype.Text{String: m.MarketID, Valid: m.MarketID != ""},
Header: pgtype.Text{String: header, Valid: header != ""},
Name: pgtype.Text{String: name, Valid: name != ""},
Handicap: pgtype.Text{String: handicap, Valid: handicap != ""},
OddsValue: pgtype.Float8{Float64: oddsVal, Valid: oddsVal != 0},
Section: m.MarketCategory,
Category: pgtype.Text{Valid: false},
RawOdds: rawOddsBytes,
}
err := s.queries.InsertNonLiveOdd(ctx, params)
if err != nil {
fmt.Printf("❌ Failed to insert odd for market %s (%s): %v\n", m.MarketType, m.EventID, err)
_ = writeFailedMarketLog(m, err)
continue
}
fmt.Printf("✅ Inserted odd: %s | type=%s | header=%s | name=%s\n", m.EventID, m.MarketType, header, name)
}
return nil
}
func writeFailedMarketLog(m domain.Market, 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.Market `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 getString(v interface{}) string {
if s, ok := v.(string); ok {
return s
}
return ""
}
func getFloat(v interface{}) float64 {
if s, ok := v.(string); ok {
f, err := strconv.ParseFloat(s, 64)
if err == nil {
return f
}
}
return 0
}
func (s *Store) GetUpcomingEventIDs(ctx context.Context) ([]string, error) {
return s.queries.GetUpcomingEventIDs(ctx)
}