fix: fixed odd and issues while integrating
This commit is contained in:
parent
fbe2dfd5a3
commit
edec72dfcd
|
|
@ -89,7 +89,7 @@ func main() {
|
|||
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)
|
||||
resultSvc := result.NewService(store, cfg, logger, *betSvc, *oddsSvc, eventSvc, leagueSvc)
|
||||
notificationRepo := repository.NewNotificationRepository(store)
|
||||
referalRepo := repository.NewReferralRepository(store)
|
||||
vitualGameRepo := repository.NewVirtualGameRepository(store)
|
||||
|
|
|
|||
|
|
@ -239,6 +239,7 @@ CREATE TABLE leagues (
|
|||
name TEXT NOT NULL,
|
||||
country_code TEXT,
|
||||
bet365_id INT,
|
||||
sport_id INT NOT NULL,
|
||||
is_active BOOLEAN DEFAULT true
|
||||
);
|
||||
CREATE TABLE teams (
|
||||
|
|
|
|||
|
|
@ -149,24 +149,25 @@ WHERE start_time > now()
|
|||
AND status = 'upcoming'
|
||||
ORDER BY start_time ASC;
|
||||
-- name: GetExpiredUpcomingEvents :many
|
||||
SELECT id,
|
||||
sport_id,
|
||||
match_name,
|
||||
home_team,
|
||||
away_team,
|
||||
home_team_id,
|
||||
away_team_id,
|
||||
home_kit_image,
|
||||
away_kit_image,
|
||||
league_id,
|
||||
league_name,
|
||||
league_cc,
|
||||
start_time,
|
||||
is_live,
|
||||
status,
|
||||
source,
|
||||
fetched_at
|
||||
SELECT events.id,
|
||||
events.sport_id,
|
||||
events.match_name,
|
||||
events.home_team,
|
||||
events.away_team,
|
||||
events.home_team_id,
|
||||
events.away_team_id,
|
||||
events.home_kit_image,
|
||||
events.away_kit_image,
|
||||
events.league_id,
|
||||
events.league_name,
|
||||
events.start_time,
|
||||
events.is_live,
|
||||
events.status,
|
||||
events.source,
|
||||
events.fetched_at,
|
||||
leagues.country_code as league_cc
|
||||
FROM events
|
||||
LEFT JOIN leagues ON leagues.id = league_id
|
||||
WHERE start_time < now()
|
||||
and (
|
||||
status = sqlc.narg('status')
|
||||
|
|
@ -176,6 +177,7 @@ ORDER BY start_time ASC;
|
|||
-- name: GetTotalEvents :one
|
||||
SELECT COUNT(*)
|
||||
FROM events
|
||||
LEFT JOIN leagues ON leagues.id = league_id
|
||||
WHERE is_live = false
|
||||
AND status = 'upcoming'
|
||||
AND (
|
||||
|
|
@ -183,7 +185,7 @@ WHERE is_live = false
|
|||
OR sqlc.narg('league_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = sqlc.narg('sport_id')
|
||||
events.sport_id = sqlc.narg('sport_id')
|
||||
OR sqlc.narg('sport_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
|
|
@ -193,26 +195,31 @@ WHERE is_live = false
|
|||
AND (
|
||||
start_time > sqlc.narg('first_start_time')
|
||||
OR sqlc.narg('first_start_time') IS NULL
|
||||
)
|
||||
AND (
|
||||
leagues.country_code = sqlc.narg('country_code')
|
||||
OR sqlc.narg('country_code') IS NULL
|
||||
);
|
||||
-- name: GetPaginatedUpcomingEvents :many
|
||||
SELECT id,
|
||||
sport_id,
|
||||
match_name,
|
||||
home_team,
|
||||
away_team,
|
||||
home_team_id,
|
||||
away_team_id,
|
||||
home_kit_image,
|
||||
away_kit_image,
|
||||
league_id,
|
||||
league_name,
|
||||
league_cc,
|
||||
start_time,
|
||||
is_live,
|
||||
status,
|
||||
source,
|
||||
fetched_at
|
||||
SELECT events.id,
|
||||
events.sport_id,
|
||||
events.match_name,
|
||||
events.home_team,
|
||||
events.away_team,
|
||||
events.home_team_id,
|
||||
events.away_team_id,
|
||||
events.home_kit_image,
|
||||
events.away_kit_image,
|
||||
events.league_id,
|
||||
events.league_name,
|
||||
events.start_time,
|
||||
events.is_live,
|
||||
events.status,
|
||||
events.source,
|
||||
events.fetched_at,
|
||||
leagues.country_code as league_cc
|
||||
FROM events
|
||||
LEFT JOIN leagues ON leagues.id = league_id
|
||||
WHERE start_time > now()
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
|
|
@ -221,7 +228,7 @@ WHERE start_time > now()
|
|||
OR sqlc.narg('league_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = sqlc.narg('sport_id')
|
||||
events.sport_id = sqlc.narg('sport_id')
|
||||
OR sqlc.narg('sport_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
|
|
@ -232,6 +239,10 @@ WHERE start_time > now()
|
|||
start_time > sqlc.narg('first_start_time')
|
||||
OR sqlc.narg('first_start_time') IS NULL
|
||||
)
|
||||
AND (
|
||||
leagues.country_code = sqlc.narg('country_code')
|
||||
OR sqlc.narg('country_code') IS NULL
|
||||
)
|
||||
ORDER BY start_time ASC
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetUpcomingByID :one
|
||||
|
|
|
|||
|
|
@ -4,29 +4,37 @@ INSERT INTO leagues (
|
|||
name,
|
||||
country_code,
|
||||
bet365_id,
|
||||
sport_id,
|
||||
is_active
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5) ON CONFLICT (id) DO
|
||||
VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT (id) DO
|
||||
UPDATE
|
||||
SET name = EXCLUDED.name,
|
||||
country_code = EXCLUDED.country_code,
|
||||
bet365_id = EXCLUDED.bet365_id,
|
||||
is_active = EXCLUDED.is_active;
|
||||
-- name: GetSupportedLeagues :many
|
||||
SELECT id,
|
||||
name,
|
||||
country_code,
|
||||
bet365_id,
|
||||
is_active
|
||||
FROM leagues
|
||||
WHERE is_active = true;
|
||||
is_active = EXCLUDED.is_active,
|
||||
sport_id = EXCLUDED.sport_id;
|
||||
-- name: GetAllLeagues :many
|
||||
SELECT id,
|
||||
name,
|
||||
country_code,
|
||||
bet365_id,
|
||||
is_active
|
||||
FROM leagues;
|
||||
is_active,
|
||||
sport_id
|
||||
FROM leagues
|
||||
WHERE (
|
||||
country_code = sqlc.narg('country_code')
|
||||
OR sqlc.narg('country_code') IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = sqlc.narg('sport_id')
|
||||
OR sqlc.narg('sport_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
is_active = sqlc.narg('is_active')
|
||||
OR sqlc.narg('is_active') IS NULL
|
||||
)
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: CheckLeagueSupport :one
|
||||
SELECT EXISTS(
|
||||
SELECT 1
|
||||
|
|
@ -36,11 +44,20 @@ SELECT EXISTS(
|
|||
);
|
||||
-- name: UpdateLeague :exec
|
||||
UPDATE leagues
|
||||
SET name = $1,
|
||||
country_code = $2,
|
||||
bet365_id = $3,
|
||||
is_active = $4
|
||||
WHERE id = $5;
|
||||
SET name = COALESCE(sqlc.narg('name'), name),
|
||||
country_code = COALESCE(sqlc.narg('country_code'), country_code),
|
||||
bet365_id = COALESCE(sqlc.narg('bet365_id'), bet365_id),
|
||||
is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
||||
sport_id = COALESCE(sqlc.narg('sport_id'), sport_id)
|
||||
WHERE id = $1;
|
||||
-- name: UpdateLeagueByBet365ID :exec
|
||||
UPDATE leagues
|
||||
SET name = COALESCE(sqlc.narg('name'), name),
|
||||
id = COALESCE(sqlc.narg('id'), id),
|
||||
country_code = COALESCE(sqlc.narg('country_code'), country_code),
|
||||
is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
||||
sport_id = COALESCE(sqlc.narg('sport_id'), sport_id)
|
||||
WHERE bet365_id = $1;
|
||||
-- name: SetLeagueActive :exec
|
||||
UPDATE leagues
|
||||
SET is_active = $2
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ SELECT event_id,
|
|||
is_active
|
||||
FROM odds
|
||||
WHERE is_active = true
|
||||
AND source = 'b365api';
|
||||
AND source = 'bet365';
|
||||
-- name: GetALLPrematchOdds :many
|
||||
SELECT event_id,
|
||||
fi,
|
||||
|
|
@ -82,7 +82,7 @@ SELECT event_id,
|
|||
is_active
|
||||
FROM odds
|
||||
WHERE is_active = true
|
||||
AND source = 'b365api';
|
||||
AND source = 'bet365';
|
||||
-- name: GetRawOddsByMarketID :one
|
||||
SELECT id,
|
||||
market_name,
|
||||
|
|
@ -93,7 +93,7 @@ FROM odds
|
|||
WHERE market_id = $1
|
||||
AND fi = $2
|
||||
AND is_active = true
|
||||
AND source = 'b365api';
|
||||
AND source = 'bet365';
|
||||
-- name: GetPrematchOddsByUpcomingID :many
|
||||
SELECT o.*
|
||||
FROM odds o
|
||||
|
|
@ -102,7 +102,7 @@ WHERE e.id = $1
|
|||
AND e.is_live = false
|
||||
AND e.status = 'upcoming'
|
||||
AND o.is_active = true
|
||||
AND o.source = 'b365api';
|
||||
AND o.source = 'bet365';
|
||||
-- name: GetPaginatedPrematchOddsByUpcomingID :many
|
||||
SELECT o.*
|
||||
FROM odds o
|
||||
|
|
@ -111,5 +111,5 @@ WHERE e.id = $1
|
|||
AND e.is_live = false
|
||||
AND e.status = 'upcoming'
|
||||
AND o.is_active = true
|
||||
AND o.source = 'b365api'
|
||||
AND o.source = 'bet365'
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
|
|
@ -105,24 +105,25 @@ func (q *Queries) GetAllUpcomingEvents(ctx context.Context) ([]GetAllUpcomingEve
|
|||
}
|
||||
|
||||
const GetExpiredUpcomingEvents = `-- name: GetExpiredUpcomingEvents :many
|
||||
SELECT id,
|
||||
sport_id,
|
||||
match_name,
|
||||
home_team,
|
||||
away_team,
|
||||
home_team_id,
|
||||
away_team_id,
|
||||
home_kit_image,
|
||||
away_kit_image,
|
||||
league_id,
|
||||
league_name,
|
||||
league_cc,
|
||||
start_time,
|
||||
is_live,
|
||||
status,
|
||||
source,
|
||||
fetched_at
|
||||
SELECT events.id,
|
||||
events.sport_id,
|
||||
events.match_name,
|
||||
events.home_team,
|
||||
events.away_team,
|
||||
events.home_team_id,
|
||||
events.away_team_id,
|
||||
events.home_kit_image,
|
||||
events.away_kit_image,
|
||||
events.league_id,
|
||||
events.league_name,
|
||||
events.start_time,
|
||||
events.is_live,
|
||||
events.status,
|
||||
events.source,
|
||||
events.fetched_at,
|
||||
leagues.country_code as league_cc
|
||||
FROM events
|
||||
LEFT JOIN leagues ON leagues.id = league_id
|
||||
WHERE start_time < now()
|
||||
and (
|
||||
status = $1
|
||||
|
|
@ -143,12 +144,12 @@ type GetExpiredUpcomingEventsRow struct {
|
|||
AwayKitImage pgtype.Text `json:"away_kit_image"`
|
||||
LeagueID pgtype.Int4 `json:"league_id"`
|
||||
LeagueName pgtype.Text `json:"league_name"`
|
||||
LeagueCc pgtype.Text `json:"league_cc"`
|
||||
StartTime pgtype.Timestamp `json:"start_time"`
|
||||
IsLive pgtype.Bool `json:"is_live"`
|
||||
Status pgtype.Text `json:"status"`
|
||||
Source pgtype.Text `json:"source"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
LeagueCc pgtype.Text `json:"league_cc"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetExpiredUpcomingEvents(ctx context.Context, status pgtype.Text) ([]GetExpiredUpcomingEventsRow, error) {
|
||||
|
|
@ -172,12 +173,12 @@ func (q *Queries) GetExpiredUpcomingEvents(ctx context.Context, status pgtype.Te
|
|||
&i.AwayKitImage,
|
||||
&i.LeagueID,
|
||||
&i.LeagueName,
|
||||
&i.LeagueCc,
|
||||
&i.StartTime,
|
||||
&i.IsLive,
|
||||
&i.Status,
|
||||
&i.Source,
|
||||
&i.FetchedAt,
|
||||
&i.LeagueCc,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -190,24 +191,25 @@ func (q *Queries) GetExpiredUpcomingEvents(ctx context.Context, status pgtype.Te
|
|||
}
|
||||
|
||||
const GetPaginatedUpcomingEvents = `-- name: GetPaginatedUpcomingEvents :many
|
||||
SELECT id,
|
||||
sport_id,
|
||||
match_name,
|
||||
home_team,
|
||||
away_team,
|
||||
home_team_id,
|
||||
away_team_id,
|
||||
home_kit_image,
|
||||
away_kit_image,
|
||||
league_id,
|
||||
league_name,
|
||||
league_cc,
|
||||
start_time,
|
||||
is_live,
|
||||
status,
|
||||
source,
|
||||
fetched_at
|
||||
SELECT events.id,
|
||||
events.sport_id,
|
||||
events.match_name,
|
||||
events.home_team,
|
||||
events.away_team,
|
||||
events.home_team_id,
|
||||
events.away_team_id,
|
||||
events.home_kit_image,
|
||||
events.away_kit_image,
|
||||
events.league_id,
|
||||
events.league_name,
|
||||
events.start_time,
|
||||
events.is_live,
|
||||
events.status,
|
||||
events.source,
|
||||
events.fetched_at,
|
||||
leagues.country_code as league_cc
|
||||
FROM events
|
||||
LEFT JOIN leagues ON leagues.id = league_id
|
||||
WHERE start_time > now()
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
|
|
@ -216,7 +218,7 @@ WHERE start_time > now()
|
|||
OR $1 IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = $2
|
||||
events.sport_id = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
|
|
@ -227,8 +229,12 @@ WHERE start_time > now()
|
|||
start_time > $4
|
||||
OR $4 IS NULL
|
||||
)
|
||||
AND (
|
||||
leagues.country_code = $5
|
||||
OR $5 IS NULL
|
||||
)
|
||||
ORDER BY start_time ASC
|
||||
LIMIT $6 OFFSET $5
|
||||
LIMIT $7 OFFSET $6
|
||||
`
|
||||
|
||||
type GetPaginatedUpcomingEventsParams struct {
|
||||
|
|
@ -236,6 +242,7 @@ type GetPaginatedUpcomingEventsParams struct {
|
|||
SportID pgtype.Int4 `json:"sport_id"`
|
||||
LastStartTime pgtype.Timestamp `json:"last_start_time"`
|
||||
FirstStartTime pgtype.Timestamp `json:"first_start_time"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Offset pgtype.Int4 `json:"offset"`
|
||||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
|
@ -252,12 +259,12 @@ type GetPaginatedUpcomingEventsRow struct {
|
|||
AwayKitImage pgtype.Text `json:"away_kit_image"`
|
||||
LeagueID pgtype.Int4 `json:"league_id"`
|
||||
LeagueName pgtype.Text `json:"league_name"`
|
||||
LeagueCc pgtype.Text `json:"league_cc"`
|
||||
StartTime pgtype.Timestamp `json:"start_time"`
|
||||
IsLive pgtype.Bool `json:"is_live"`
|
||||
Status pgtype.Text `json:"status"`
|
||||
Source pgtype.Text `json:"source"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
LeagueCc pgtype.Text `json:"league_cc"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetPaginatedUpcomingEvents(ctx context.Context, arg GetPaginatedUpcomingEventsParams) ([]GetPaginatedUpcomingEventsRow, error) {
|
||||
|
|
@ -266,6 +273,7 @@ func (q *Queries) GetPaginatedUpcomingEvents(ctx context.Context, arg GetPaginat
|
|||
arg.SportID,
|
||||
arg.LastStartTime,
|
||||
arg.FirstStartTime,
|
||||
arg.CountryCode,
|
||||
arg.Offset,
|
||||
arg.Limit,
|
||||
)
|
||||
|
|
@ -288,12 +296,12 @@ func (q *Queries) GetPaginatedUpcomingEvents(ctx context.Context, arg GetPaginat
|
|||
&i.AwayKitImage,
|
||||
&i.LeagueID,
|
||||
&i.LeagueName,
|
||||
&i.LeagueCc,
|
||||
&i.StartTime,
|
||||
&i.IsLive,
|
||||
&i.Status,
|
||||
&i.Source,
|
||||
&i.FetchedAt,
|
||||
&i.LeagueCc,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -308,6 +316,7 @@ func (q *Queries) GetPaginatedUpcomingEvents(ctx context.Context, arg GetPaginat
|
|||
const GetTotalEvents = `-- name: GetTotalEvents :one
|
||||
SELECT COUNT(*)
|
||||
FROM events
|
||||
LEFT JOIN leagues ON leagues.id = league_id
|
||||
WHERE is_live = false
|
||||
AND status = 'upcoming'
|
||||
AND (
|
||||
|
|
@ -315,7 +324,7 @@ WHERE is_live = false
|
|||
OR $1 IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = $2
|
||||
events.sport_id = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
|
|
@ -326,6 +335,10 @@ WHERE is_live = false
|
|||
start_time > $4
|
||||
OR $4 IS NULL
|
||||
)
|
||||
AND (
|
||||
leagues.country_code = $5
|
||||
OR $5 IS NULL
|
||||
)
|
||||
`
|
||||
|
||||
type GetTotalEventsParams struct {
|
||||
|
|
@ -333,6 +346,7 @@ type GetTotalEventsParams struct {
|
|||
SportID pgtype.Int4 `json:"sport_id"`
|
||||
LastStartTime pgtype.Timestamp `json:"last_start_time"`
|
||||
FirstStartTime pgtype.Timestamp `json:"first_start_time"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetTotalEvents(ctx context.Context, arg GetTotalEventsParams) (int64, error) {
|
||||
|
|
@ -341,6 +355,7 @@ func (q *Queries) GetTotalEvents(ctx context.Context, arg GetTotalEventsParams)
|
|||
arg.SportID,
|
||||
arg.LastStartTime,
|
||||
arg.FirstStartTime,
|
||||
arg.CountryCode,
|
||||
)
|
||||
var count int64
|
||||
err := row.Scan(&count)
|
||||
|
|
|
|||
|
|
@ -32,61 +32,63 @@ SELECT id,
|
|||
name,
|
||||
country_code,
|
||||
bet365_id,
|
||||
is_active
|
||||
is_active,
|
||||
sport_id
|
||||
FROM leagues
|
||||
WHERE (
|
||||
country_code = $1
|
||||
OR $1 IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
is_active = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
LIMIT $5 OFFSET $4
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllLeagues(ctx context.Context) ([]League, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllLeagues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []League
|
||||
for rows.Next() {
|
||||
var i League
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.CountryCode,
|
||||
&i.Bet365ID,
|
||||
&i.IsActive,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
type GetAllLeaguesParams struct {
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
SportID pgtype.Int4 `json:"sport_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
Offset pgtype.Int4 `json:"offset"`
|
||||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
||||
const GetSupportedLeagues = `-- name: GetSupportedLeagues :many
|
||||
SELECT id,
|
||||
name,
|
||||
country_code,
|
||||
bet365_id,
|
||||
is_active
|
||||
FROM leagues
|
||||
WHERE is_active = true
|
||||
`
|
||||
type GetAllLeaguesRow struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetSupportedLeagues(ctx context.Context) ([]League, error) {
|
||||
rows, err := q.db.Query(ctx, GetSupportedLeagues)
|
||||
func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([]GetAllLeaguesRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllLeagues,
|
||||
arg.CountryCode,
|
||||
arg.SportID,
|
||||
arg.IsActive,
|
||||
arg.Offset,
|
||||
arg.Limit,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []League
|
||||
var items []GetAllLeaguesRow
|
||||
for rows.Next() {
|
||||
var i League
|
||||
var i GetAllLeaguesRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.CountryCode,
|
||||
&i.Bet365ID,
|
||||
&i.IsActive,
|
||||
&i.SportID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -104,14 +106,16 @@ INSERT INTO leagues (
|
|||
name,
|
||||
country_code,
|
||||
bet365_id,
|
||||
sport_id,
|
||||
is_active
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5) ON CONFLICT (id) DO
|
||||
VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT (id) DO
|
||||
UPDATE
|
||||
SET name = EXCLUDED.name,
|
||||
country_code = EXCLUDED.country_code,
|
||||
bet365_id = EXCLUDED.bet365_id,
|
||||
is_active = EXCLUDED.is_active
|
||||
is_active = EXCLUDED.is_active,
|
||||
sport_id = EXCLUDED.sport_id
|
||||
`
|
||||
|
||||
type InsertLeagueParams struct {
|
||||
|
|
@ -119,6 +123,7 @@ type InsertLeagueParams struct {
|
|||
Name string `json:"name"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
}
|
||||
|
||||
|
|
@ -128,6 +133,7 @@ func (q *Queries) InsertLeague(ctx context.Context, arg InsertLeagueParams) erro
|
|||
arg.Name,
|
||||
arg.CountryCode,
|
||||
arg.Bet365ID,
|
||||
arg.SportID,
|
||||
arg.IsActive,
|
||||
)
|
||||
return err
|
||||
|
|
@ -151,28 +157,62 @@ func (q *Queries) SetLeagueActive(ctx context.Context, arg SetLeagueActiveParams
|
|||
|
||||
const UpdateLeague = `-- name: UpdateLeague :exec
|
||||
UPDATE leagues
|
||||
SET name = $1,
|
||||
country_code = $2,
|
||||
bet365_id = $3,
|
||||
is_active = $4
|
||||
WHERE id = $5
|
||||
SET name = COALESCE($2, name),
|
||||
country_code = COALESCE($3, country_code),
|
||||
bet365_id = COALESCE($4, bet365_id),
|
||||
is_active = COALESCE($5, is_active),
|
||||
sport_id = COALESCE($6, sport_id)
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
type UpdateLeagueParams struct {
|
||||
Name string `json:"name"`
|
||||
ID int64 `json:"id"`
|
||||
Name pgtype.Text `json:"name"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
ID int64 `json:"id"`
|
||||
SportID pgtype.Int4 `json:"sport_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateLeague(ctx context.Context, arg UpdateLeagueParams) error {
|
||||
_, err := q.db.Exec(ctx, UpdateLeague,
|
||||
arg.ID,
|
||||
arg.Name,
|
||||
arg.CountryCode,
|
||||
arg.Bet365ID,
|
||||
arg.IsActive,
|
||||
arg.ID,
|
||||
arg.SportID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const UpdateLeagueByBet365ID = `-- name: UpdateLeagueByBet365ID :exec
|
||||
UPDATE leagues
|
||||
SET name = COALESCE($2, name),
|
||||
id = COALESCE($3, id),
|
||||
country_code = COALESCE($4, country_code),
|
||||
is_active = COALESCE($5, is_active),
|
||||
sport_id = COALESCE($6, sport_id)
|
||||
WHERE bet365_id = $1
|
||||
`
|
||||
|
||||
type UpdateLeagueByBet365IDParams struct {
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
Name pgtype.Text `json:"name"`
|
||||
ID pgtype.Int8 `json:"id"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
SportID pgtype.Int4 `json:"sport_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateLeagueByBet365ID(ctx context.Context, arg UpdateLeagueByBet365IDParams) error {
|
||||
_, err := q.db.Exec(ctx, UpdateLeagueByBet365ID,
|
||||
arg.Bet365ID,
|
||||
arg.Name,
|
||||
arg.ID,
|
||||
arg.CountryCode,
|
||||
arg.IsActive,
|
||||
arg.SportID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ type League struct {
|
|||
Name string `json:"name"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ SELECT event_id,
|
|||
is_active
|
||||
FROM odds
|
||||
WHERE is_active = true
|
||||
AND source = 'b365api'
|
||||
AND source = 'bet365'
|
||||
`
|
||||
|
||||
type GetALLPrematchOddsRow struct {
|
||||
|
|
@ -94,7 +94,7 @@ WHERE e.id = $1
|
|||
AND e.is_live = false
|
||||
AND e.status = 'upcoming'
|
||||
AND o.is_active = true
|
||||
AND o.source = 'b365api'
|
||||
AND o.source = 'bet365'
|
||||
LIMIT $3 OFFSET $2
|
||||
`
|
||||
|
||||
|
|
@ -159,7 +159,7 @@ SELECT event_id,
|
|||
is_active
|
||||
FROM odds
|
||||
WHERE is_active = true
|
||||
AND source = 'b365api'
|
||||
AND source = 'bet365'
|
||||
`
|
||||
|
||||
type GetPrematchOddsRow struct {
|
||||
|
|
@ -224,7 +224,7 @@ WHERE e.id = $1
|
|||
AND e.is_live = false
|
||||
AND e.status = 'upcoming'
|
||||
AND o.is_active = true
|
||||
AND o.source = 'b365api'
|
||||
AND o.source = 'bet365'
|
||||
`
|
||||
|
||||
func (q *Queries) GetPrematchOddsByUpcomingID(ctx context.Context, id string) ([]Odd, error) {
|
||||
|
|
@ -274,7 +274,7 @@ FROM odds
|
|||
WHERE market_id = $1
|
||||
AND fi = $2
|
||||
AND is_active = true
|
||||
AND source = 'b365api'
|
||||
AND source = 'bet365'
|
||||
`
|
||||
|
||||
type GetRawOddsByMarketIDParams struct {
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ type Odds struct {
|
|||
type EventFilter struct {
|
||||
SportID ValidInt32
|
||||
LeagueID ValidInt32
|
||||
CountryCode ValidString
|
||||
FirstStartTime ValidTime
|
||||
LastStartTime ValidTime
|
||||
Limit ValidInt64
|
||||
|
|
|
|||
|
|
@ -6,4 +6,22 @@ type League struct {
|
|||
CountryCode string `json:"cc" example:"uk"`
|
||||
Bet365ID int32 `json:"bet365_id" example:"1121"`
|
||||
IsActive bool `json:"is_active" example:"false"`
|
||||
SportID int32 `json:"sport_id" example:"1"`
|
||||
}
|
||||
|
||||
type UpdateLeague struct {
|
||||
ID int64 `json:"id" example:"1"`
|
||||
Name ValidString `json:"name" example:"BPL"`
|
||||
CountryCode ValidString `json:"cc" example:"uk"`
|
||||
Bet365ID ValidInt32 `json:"bet365_id" example:"1121"`
|
||||
IsActive ValidBool `json:"is_active" example:"false"`
|
||||
SportID ValidInt32 `json:"sport_id" example:"1"`
|
||||
}
|
||||
|
||||
type LeagueFilter struct {
|
||||
CountryCode ValidString
|
||||
SportID ValidInt32
|
||||
IsActive ValidBool
|
||||
Limit ValidInt64
|
||||
Offset ValidInt64
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ type Score struct {
|
|||
}
|
||||
|
||||
type CommonResultResponse struct {
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
TimeStatus string `json:"time_status"`
|
||||
League League `json:"league"`
|
||||
Home Team `json:"home"`
|
||||
Away Team `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
TimeStatus string `json:"time_status"`
|
||||
League LeagueRes `json:"league"`
|
||||
Home Team `json:"home"`
|
||||
Away Team `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
}
|
||||
|
||||
type FootballResultResponse struct {
|
||||
|
|
|
|||
|
|
@ -153,6 +153,10 @@ func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.Ev
|
|||
Time: filter.LastStartTime.Value.UTC(),
|
||||
Valid: filter.LastStartTime.Valid,
|
||||
},
|
||||
CountryCode: pgtype.Text{
|
||||
String: filter.CountryCode.Value,
|
||||
Valid: filter.CountryCode.Valid,
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
@ -195,6 +199,10 @@ func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.Ev
|
|||
Time: filter.LastStartTime.Value.UTC(),
|
||||
Valid: filter.LastStartTime.Valid,
|
||||
},
|
||||
CountryCode: pgtype.Text{
|
||||
String: filter.CountryCode.Value,
|
||||
Valid: filter.CountryCode.Valid,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
|
|
|
|||
|
|
@ -15,30 +15,33 @@ func (s *Store) SaveLeague(ctx context.Context, l domain.League) error {
|
|||
CountryCode: pgtype.Text{String: l.CountryCode, Valid: true},
|
||||
Bet365ID: pgtype.Int4{Int32: l.Bet365ID, Valid: true},
|
||||
IsActive: pgtype.Bool{Bool: l.IsActive, Valid: true},
|
||||
SportID: l.SportID,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Store) GetSupportedLeagues(ctx context.Context) ([]domain.League, error) {
|
||||
leagues, err := s.queries.GetSupportedLeagues(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
supportedLeagues := make([]domain.League, len(leagues))
|
||||
for i, league := range leagues {
|
||||
supportedLeagues[i] = domain.League{
|
||||
ID: league.ID,
|
||||
Name: league.Name,
|
||||
CountryCode: league.CountryCode.String,
|
||||
Bet365ID: league.Bet365ID.Int32,
|
||||
IsActive: league.IsActive.Bool,
|
||||
}
|
||||
}
|
||||
return supportedLeagues, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetAllLeagues(ctx context.Context) ([]domain.League, error) {
|
||||
l, err := s.queries.GetAllLeagues(ctx)
|
||||
func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.League, error) {
|
||||
l, err := s.queries.GetAllLeagues(ctx, dbgen.GetAllLeaguesParams{
|
||||
CountryCode: pgtype.Text{
|
||||
String: filter.CountryCode.Value,
|
||||
Valid: filter.CountryCode.Valid,
|
||||
},
|
||||
SportID: pgtype.Int4{
|
||||
Int32: filter.SportID.Value,
|
||||
Valid: filter.SportID.Valid,
|
||||
},
|
||||
IsActive: pgtype.Bool{
|
||||
Bool: filter.IsActive.Value,
|
||||
Valid: filter.IsActive.Valid,
|
||||
},
|
||||
Limit: pgtype.Int4{
|
||||
Int32: int32(filter.Limit.Value),
|
||||
Valid: filter.Limit.Valid,
|
||||
},
|
||||
Offset: pgtype.Int4{
|
||||
Int32: int32(filter.Offset.Value * filter.Limit.Value),
|
||||
Valid: filter.Offset.Valid,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -51,6 +54,7 @@ func (s *Store) GetAllLeagues(ctx context.Context) ([]domain.League, error) {
|
|||
CountryCode: league.CountryCode.String,
|
||||
Bet365ID: league.Bet365ID.Int32,
|
||||
IsActive: league.IsActive.Bool,
|
||||
SportID: league.SportID,
|
||||
}
|
||||
}
|
||||
return leagues, nil
|
||||
|
|
@ -70,12 +74,30 @@ func (s *Store) SetLeagueActive(ctx context.Context, leagueId int64, isActive bo
|
|||
})
|
||||
}
|
||||
|
||||
// TODO: update based on id, no need for the entire league (same as the set active one)
|
||||
func (s *Store) SetLeagueInActive(ctx context.Context, l domain.League) error {
|
||||
return s.queries.UpdateLeague(ctx, dbgen.UpdateLeagueParams{
|
||||
Name: l.Name,
|
||||
CountryCode: pgtype.Text{String: l.CountryCode, Valid: true},
|
||||
Bet365ID: pgtype.Int4{Int32: l.Bet365ID, Valid: true},
|
||||
IsActive: pgtype.Bool{Bool: false, Valid: true},
|
||||
func (s *Store) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
||||
err := s.queries.UpdateLeague(ctx, dbgen.UpdateLeagueParams{
|
||||
ID: league.ID,
|
||||
Name: pgtype.Text{
|
||||
String: league.Name.Value,
|
||||
Valid: league.Name.Valid,
|
||||
},
|
||||
CountryCode: pgtype.Text{
|
||||
String: league.CountryCode.Value,
|
||||
Valid: league.CountryCode.Valid,
|
||||
},
|
||||
Bet365ID: pgtype.Int4{
|
||||
Int32: league.Bet365ID.Value,
|
||||
Valid: league.Bet365ID.Valid,
|
||||
},
|
||||
IsActive: pgtype.Bool{
|
||||
Bool: league.IsActive.Value,
|
||||
Valid: league.IsActive.Valid,
|
||||
},
|
||||
SportID: pgtype.Int4{
|
||||
Int32: league.SportID.Value,
|
||||
Valid: league.SportID.Valid,
|
||||
},
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package repository
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
|
|
|||
|
|
@ -209,16 +209,17 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, url, sour
|
|||
// log.Printf("❌ Failed to open leagues file %v", err)
|
||||
// return
|
||||
// }
|
||||
for _, sportID := range sportIDs {
|
||||
for sportIndex, sportID := range sportIDs {
|
||||
var totalPages int = 1
|
||||
var page int = 0
|
||||
var limit int = 100
|
||||
var limit int = 200
|
||||
var count int = 0
|
||||
log.Printf("Sport ID %d", sportID)
|
||||
for page <= totalPages {
|
||||
page = page + 1
|
||||
url := fmt.Sprintf(url, sportID, s.token, page)
|
||||
log.Printf("📡 Fetching data from %s - sport %d, for event data page %d", source, sportID, page)
|
||||
log.Printf("📡 Fetching data from %s - sport %d (%d/%d), for event data page (%d/%d)",
|
||||
source, sportID, sportIndex+1, len(sportIDs), page, totalPages)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
log.Printf("❌ Failed to fetch event data for page %d: %v", page, err)
|
||||
|
|
@ -249,13 +250,23 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, url, sour
|
|||
}
|
||||
|
||||
// doesn't make sense to save and check back to back, but for now it can be here
|
||||
s.store.SaveLeague(ctx, domain.League{
|
||||
// no this its fine to keep it here
|
||||
// but change the league id to bet365 id later
|
||||
err = s.store.SaveLeague(ctx, domain.League{
|
||||
ID: leagueID,
|
||||
Name: ev.League.Name,
|
||||
IsActive: true,
|
||||
SportID: convertInt32(ev.SportID),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Printf("❌ Error Saving League on %v", ev.League.Name)
|
||||
log.Printf("err:%v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if supported, err := s.store.CheckLeagueSupport(ctx, leagueID); !supported || err != nil {
|
||||
log.Printf("Skipping league %v", ev.League.Name)
|
||||
skippedLeague = append(skippedLeague, ev.League.Name)
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import (
|
|||
)
|
||||
|
||||
type Service interface {
|
||||
GetAllLeagues(ctx context.Context) ([]domain.League, error)
|
||||
SaveLeague(ctx context.Context, l domain.League) error
|
||||
GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.League, error)
|
||||
SetLeagueActive(ctx context.Context, leagueId int64, isActive bool) error
|
||||
UpdateLeague(ctx context.Context, league domain.UpdateLeague) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,18 @@ func New(store *repository.Store) Service {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *service) GetAllLeagues(ctx context.Context) ([]domain.League, error) {
|
||||
return s.store.GetAllLeagues(ctx)
|
||||
func (s *service) SaveLeague(ctx context.Context, l domain.League) error {
|
||||
return s.store.SaveLeague(ctx, l)
|
||||
}
|
||||
|
||||
func (s *service) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.League, error) {
|
||||
return s.store.GetAllLeagues(ctx, filter)
|
||||
}
|
||||
|
||||
func (s *service) SetLeagueActive(ctx context.Context, leagueId int64, isActive bool) error {
|
||||
return s.store.SetLeagueActive(ctx, leagueId, isActive)
|
||||
}
|
||||
|
||||
func (s *service) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
||||
return s.store.UpdateLeague(ctx, league)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,18 +41,23 @@ func (s *ServiceImpl) FetchNonLiveOdds(ctx context.Context) error {
|
|||
// wg.Add(2)
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := s.fetchBet365Odds(ctx); err != nil {
|
||||
errChan <- fmt.Errorf("bet365 odds fetching error: %w", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// go func() {
|
||||
// defer wg.Done()
|
||||
// if err := s.fetchBet365Odds(ctx); err != nil {
|
||||
// errChan <- fmt.Errorf("bet365 odds fetching error: %w", err)
|
||||
// if err := s.fetchBwinOdds(ctx); err != nil {
|
||||
// errChan <- fmt.Errorf("bwin odds fetching error: %w", err)
|
||||
// }
|
||||
// }()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := s.fetchBwinOdds(ctx); err != nil {
|
||||
errChan <- fmt.Errorf("bwin odds fetching error: %w", err)
|
||||
}
|
||||
wg.Wait()
|
||||
close(errChan)
|
||||
}()
|
||||
|
||||
var errs []error
|
||||
|
|
@ -118,7 +123,11 @@ func (s *ServiceImpl) fetchBet365Odds(ctx context.Context) error {
|
|||
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
for err := range errs {
|
||||
log.Printf("❌ Error: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) fetchBwinOdds(ctx context.Context) error {
|
||||
|
|
@ -208,7 +217,6 @@ func (s *ServiceImpl) fetchBwinOdds(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (s *ServiceImpl) FetchNonLiveOddsByEventID(ctx context.Context, eventIDStr string) (domain.BaseNonLiveOddResponse, error) {
|
||||
|
||||
eventID, err := strconv.ParseInt(eventIDStr, 10, 64)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
|
@ -15,28 +16,31 @@ import (
|
|||
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/league"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
repo *repository.Store
|
||||
config *config.Config
|
||||
logger *slog.Logger
|
||||
client *http.Client
|
||||
betSvc bet.Service
|
||||
oddSvc odds.ServiceImpl
|
||||
eventSvc event.Service
|
||||
repo *repository.Store
|
||||
config *config.Config
|
||||
logger *slog.Logger
|
||||
client *http.Client
|
||||
betSvc bet.Service
|
||||
oddSvc odds.ServiceImpl
|
||||
eventSvc event.Service
|
||||
leagueSvc league.Service
|
||||
}
|
||||
|
||||
func NewService(repo *repository.Store, cfg *config.Config, logger *slog.Logger, betSvc bet.Service, oddSvc odds.ServiceImpl, eventSvc event.Service) *Service {
|
||||
func NewService(repo *repository.Store, cfg *config.Config, logger *slog.Logger, betSvc bet.Service, oddSvc odds.ServiceImpl, eventSvc event.Service, leagueSvc league.Service) *Service {
|
||||
return &Service{
|
||||
repo: repo,
|
||||
config: cfg,
|
||||
logger: logger,
|
||||
client: &http.Client{Timeout: 10 * time.Second},
|
||||
betSvc: betSvc,
|
||||
oddSvc: oddSvc,
|
||||
eventSvc: eventSvc,
|
||||
repo: repo,
|
||||
config: cfg,
|
||||
logger: logger,
|
||||
client: &http.Client{Timeout: 10 * time.Second},
|
||||
betSvc: betSvc,
|
||||
oddSvc: oddSvc,
|
||||
eventSvc: eventSvc,
|
||||
leagueSvc: leagueSvc,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -274,6 +278,33 @@ func (s *Service) CheckAndUpdateExpiredEvents(ctx context.Context) (int64, error
|
|||
}
|
||||
updated++
|
||||
fmt.Printf("✅ Successfully updated event %v to %v (%d/%d) \n", event.ID, eventStatus, i+1, len(events))
|
||||
|
||||
// Update the league because the league country code is only found on the result response
|
||||
leagueID, err := strconv.ParseInt(commonResp.League.ID, 10, 64)
|
||||
if err != nil {
|
||||
log.Printf("❌ Invalid league id, leagueID %v", commonResp.League.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
err = s.leagueSvc.UpdateLeague(ctx, domain.UpdateLeague{
|
||||
ID: int64(event.LeagueID),
|
||||
CountryCode: domain.ValidString{
|
||||
Value: commonResp.League.CC,
|
||||
Valid: true,
|
||||
},
|
||||
Bet365ID: domain.ValidInt32{
|
||||
Value: int32(leagueID),
|
||||
Valid: true,
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Printf("❌ Error Updating League %v", commonResp.League.Name)
|
||||
log.Printf("err:%v", err)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("✅ Updated League %v with country code %v \n", leagueID, commonResp.League.CC)
|
||||
|
||||
}
|
||||
|
||||
if updated == 0 {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
|
|||
// },
|
||||
// },
|
||||
// {
|
||||
// spec: "0 */15 * * * *", // Every 15 minutes
|
||||
// spec: "0 0 * * * *", // Every 15 minutes
|
||||
// task: func() {
|
||||
// if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
|
||||
// log.Printf("FetchNonLiveOdds error: %v", err)
|
||||
|
|
@ -40,7 +40,7 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
|
|||
// {
|
||||
// spec: "0 */5 * * * *", // Every 5 Minutes
|
||||
// task: func() {
|
||||
// log.Println("Updating expired events...")
|
||||
// log.Println("Updating expired events status...")
|
||||
|
||||
// if _, err := resultService.CheckAndUpdateExpiredEvents(context.Background()); err != nil {
|
||||
// log.Printf("Failed to update events: %v", err)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
|
|
@ -23,7 +24,7 @@ import (
|
|||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /bet [post]
|
||||
func (h *Handler) CreateBet(c *fiber.Ctx) error {
|
||||
|
||||
fmt.Printf("Calling leagues")
|
||||
// Get user_id from middleware
|
||||
userID := c.Locals("user_id").(int64)
|
||||
role := c.Locals("role").(domain.Role)
|
||||
|
|
@ -40,7 +41,7 @@ func (h *Handler) CreateBet(c *fiber.Ctx) error {
|
|||
}
|
||||
|
||||
res, err := h.betSvc.
|
||||
PlaceBet(c.Context(), req, userID, role)
|
||||
PlaceBet(c.Context(), req, userID, role)
|
||||
|
||||
if err != nil {
|
||||
h.logger.Error("PlaceBet failed", "error", err)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,77 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// GetAllLeagues godoc
|
||||
// @Summary Gets all leagues
|
||||
// @Description Gets all leagues
|
||||
// @Tags leagues
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {array} domain.League
|
||||
// @Failure 400 {object} response.APIResponse
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /leagues [get]
|
||||
func (h *Handler) GetAllLeagues(c *fiber.Ctx) error {
|
||||
leagues, err := h.leagueSvc.GetAllLeagues(c.Context())
|
||||
if err != nil {
|
||||
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get leagues", err, nil)
|
||||
page := c.QueryInt("page", 1)
|
||||
pageSize := c.QueryInt("page_size", 10)
|
||||
|
||||
limit := domain.ValidInt64{
|
||||
Value: int64(pageSize),
|
||||
Valid: pageSize == 0,
|
||||
}
|
||||
offset := domain.ValidInt64{
|
||||
Value: int64(page - 1),
|
||||
Valid: true,
|
||||
}
|
||||
|
||||
return response.WriteJSON(c, fiber.StatusOK, "All leagues retrived", leagues, nil)
|
||||
countryCodeQuery := c.Query("cc")
|
||||
countryCode := domain.ValidString{
|
||||
Value: countryCodeQuery,
|
||||
Valid: countryCodeQuery != "",
|
||||
}
|
||||
isActiveQuery := c.QueryBool("is_active", false)
|
||||
isActiveFilter := c.QueryBool("is_active_filter", false)
|
||||
isActive := domain.ValidBool{
|
||||
Value: isActiveQuery,
|
||||
Valid: isActiveFilter,
|
||||
}
|
||||
|
||||
sportIDQuery := c.Query("sport_id")
|
||||
var sportID domain.ValidInt32
|
||||
if sportIDQuery != "" {
|
||||
sportIDint, err := strconv.Atoi(sportIDQuery)
|
||||
if err != nil {
|
||||
h.logger.Error("invalid sport id", "error", err)
|
||||
return response.WriteJSON(c, fiber.StatusBadRequest, "invalid sport id", nil, nil)
|
||||
}
|
||||
sportID = domain.ValidInt32{
|
||||
Value: int32(sportIDint),
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
leagues, err := h.leagueSvc.GetAllLeagues(c.Context(), domain.LeagueFilter{
|
||||
CountryCode: countryCode,
|
||||
IsActive: isActive,
|
||||
SportID: sportID,
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Error fetching league %v \n", err)
|
||||
h.logger.Error("Failed to get leagues", "error", err)
|
||||
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get leagues", err, nil)
|
||||
}
|
||||
return response.WriteJSON(c, fiber.StatusOK, "All leagues retrieved", leagues, nil)
|
||||
}
|
||||
|
||||
type SetLeagueActiveReq struct {
|
||||
|
|
@ -21,6 +79,7 @@ type SetLeagueActiveReq struct {
|
|||
}
|
||||
|
||||
func (h *Handler) SetLeagueActive(c *fiber.Ctx) error {
|
||||
fmt.Printf("Set Active Leagues")
|
||||
leagueIdStr := c.Params("id")
|
||||
if leagueIdStr == "" {
|
||||
response.WriteJSON(c, fiber.StatusBadRequest, "Missing league id", nil, nil)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
|
|
@ -9,33 +10,6 @@ import (
|
|||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// GetPrematchOdds godoc
|
||||
// @Summary Retrieve prematch odds for an event
|
||||
// @Description Retrieve prematch odds for a specific event by event ID
|
||||
// @Tags prematch
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param event_id path string true "Event ID"
|
||||
// @Success 200 {array} domain.Odd
|
||||
// @Failure 400 {object} response.APIResponse
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /prematch/odds/{event_id} [get]
|
||||
func (h *Handler) GetPrematchOdds(c *fiber.Ctx) error {
|
||||
|
||||
eventID := c.Params("event_id")
|
||||
if eventID == "" {
|
||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Missing event_id", nil, nil)
|
||||
}
|
||||
|
||||
odds, err := h.prematchSvc.GetPrematchOdds(c.Context(), eventID)
|
||||
if err != nil {
|
||||
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve odds", nil, nil)
|
||||
}
|
||||
|
||||
return response.WriteJSON(c, fiber.StatusOK, "Prematch odds retrieved successfully", odds, nil)
|
||||
|
||||
}
|
||||
|
||||
// GetALLPrematchOdds
|
||||
// @Summary Retrieve all prematch odds
|
||||
// @Description Retrieve all prematch odds from the database
|
||||
|
|
@ -44,7 +18,7 @@ func (h *Handler) GetPrematchOdds(c *fiber.Ctx) error {
|
|||
// @Produce json
|
||||
// @Success 200 {array} domain.Odd
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /prematch/odds [get]
|
||||
// @Router /odds [get]
|
||||
func (h *Handler) GetALLPrematchOdds(c *fiber.Ctx) error {
|
||||
|
||||
odds, err := h.prematchSvc.GetALLPrematchOdds(c.Context())
|
||||
|
|
@ -67,7 +41,7 @@ func (h *Handler) GetALLPrematchOdds(c *fiber.Ctx) error {
|
|||
// @Success 200 {array} domain.RawOddsByMarketID
|
||||
// @Failure 400 {object} response.APIResponse
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /prematch/odds/upcoming/{upcoming_id}/market/{market_id} [get]
|
||||
// @Router /odds/upcoming/{upcoming_id}/market/{market_id} [get]
|
||||
func (h *Handler) GetRawOddsByMarketID(c *fiber.Ctx) error {
|
||||
|
||||
marketID := c.Params("market_id")
|
||||
|
|
@ -82,7 +56,8 @@ func (h *Handler) GetRawOddsByMarketID(c *fiber.Ctx) error {
|
|||
|
||||
rawOdds, err := h.prematchSvc.GetRawOddsByMarketID(c.Context(), marketID, upcomingID)
|
||||
if err != nil {
|
||||
// h.logger.Error("failed to fetch raw odds", "error", err)
|
||||
fmt.Printf("Failed to fetch raw odds: %v market_id:%v upcomingID:%v\n", err, marketID, upcomingID)
|
||||
h.logger.Error("failed to fetch raw odds", "error", err)
|
||||
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve raw odds", err, nil)
|
||||
}
|
||||
|
||||
|
|
@ -99,20 +74,25 @@ func (h *Handler) GetRawOddsByMarketID(c *fiber.Ctx) error {
|
|||
// @Param page_size query int false "Page size"
|
||||
// @Param league_id query string false "League ID Filter"
|
||||
// @Param sport_id query string false "Sport ID Filter"
|
||||
// @Param cc query string false "Country Code Filter"
|
||||
// @Param first_start_time query string false "Start Time"
|
||||
// @Param last_start_time query string false "End Time"
|
||||
// @Success 200 {array} domain.UpcomingEvent
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /prematch/events [get]
|
||||
// @Router /events [get]
|
||||
func (h *Handler) GetAllUpcomingEvents(c *fiber.Ctx) error {
|
||||
page := c.QueryInt("page", 1)
|
||||
pageSize := c.QueryInt("page_size", 10)
|
||||
limit := domain.ValidInt64{
|
||||
Value: int64(pageSize),
|
||||
Valid: true,
|
||||
}
|
||||
offset := domain.ValidInt64{
|
||||
Value: int64(page - 1),
|
||||
Valid: true,
|
||||
}
|
||||
|
||||
leagueIDQuery := c.Query("league_id")
|
||||
sportIDQuery := c.Query("sport_id")
|
||||
|
||||
firstStartTimeQuery := c.Query("first_start_time")
|
||||
lastStartTimeQuery := c.Query("last_start_time")
|
||||
|
||||
var leagueID domain.ValidInt32
|
||||
if leagueIDQuery != "" {
|
||||
leagueIDInt, err := strconv.Atoi(leagueIDQuery)
|
||||
|
|
@ -125,6 +105,7 @@ func (h *Handler) GetAllUpcomingEvents(c *fiber.Ctx) error {
|
|||
Valid: true,
|
||||
}
|
||||
}
|
||||
sportIDQuery := c.Query("sport_id")
|
||||
var sportID domain.ValidInt32
|
||||
if sportIDQuery != "" {
|
||||
sportIDint, err := strconv.Atoi(sportIDQuery)
|
||||
|
|
@ -137,7 +118,7 @@ func (h *Handler) GetAllUpcomingEvents(c *fiber.Ctx) error {
|
|||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
firstStartTimeQuery := c.Query("first_start_time")
|
||||
var firstStartTime domain.ValidTime
|
||||
if firstStartTimeQuery != "" {
|
||||
firstStartTimeParsed, err := time.Parse(time.RFC3339, firstStartTimeQuery)
|
||||
|
|
@ -150,6 +131,8 @@ func (h *Handler) GetAllUpcomingEvents(c *fiber.Ctx) error {
|
|||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
lastStartTimeQuery := c.Query("last_start_time")
|
||||
var lastStartTime domain.ValidTime
|
||||
if lastStartTimeQuery != "" {
|
||||
lastStartTimeParsed, err := time.Parse(time.RFC3339, lastStartTimeQuery)
|
||||
|
|
@ -163,15 +146,11 @@ func (h *Handler) GetAllUpcomingEvents(c *fiber.Ctx) error {
|
|||
}
|
||||
}
|
||||
|
||||
limit := domain.ValidInt64{
|
||||
Value: int64(pageSize),
|
||||
Valid: true,
|
||||
countryCodeQuery := c.Query("cc")
|
||||
countryCode := domain.ValidString{
|
||||
Value: countryCodeQuery,
|
||||
Valid: countryCodeQuery != "",
|
||||
}
|
||||
offset := domain.ValidInt64{
|
||||
Value: int64(page - 1),
|
||||
Valid: true,
|
||||
}
|
||||
|
||||
events, total, err := h.eventSvc.GetPaginatedUpcomingEvents(
|
||||
c.Context(), domain.EventFilter{
|
||||
SportID: sportID,
|
||||
|
|
@ -180,6 +159,7 @@ func (h *Handler) GetAllUpcomingEvents(c *fiber.Ctx) error {
|
|||
LastStartTime: lastStartTime,
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
CountryCode: countryCode,
|
||||
})
|
||||
|
||||
// fmt.Printf("League ID: %v", leagueID)
|
||||
|
|
@ -201,7 +181,7 @@ func (h *Handler) GetAllUpcomingEvents(c *fiber.Ctx) error {
|
|||
// @Success 200 {object} domain.UpcomingEvent
|
||||
// @Failure 400 {object} response.APIResponse
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /prematch/events/{id} [get]
|
||||
// @Router /events/{id} [get]
|
||||
func (h *Handler) GetUpcomingEventByID(c *fiber.Ctx) error {
|
||||
|
||||
id := c.Params("id")
|
||||
|
|
@ -229,8 +209,8 @@ func (h *Handler) GetUpcomingEventByID(c *fiber.Ctx) error {
|
|||
// @Success 200 {array} domain.Odd
|
||||
// @Failure 400 {object} response.APIResponse
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /prematch/odds/upcoming/{upcoming_id} [get]
|
||||
func (h *Handler) GetPrematchOddsByUpcomingID(c *fiber.Ctx) error {
|
||||
// @Router /odds/upcoming/{upcoming_id} [get]
|
||||
func (h *Handler) GetOddsByUpcomingID(c *fiber.Ctx) error {
|
||||
|
||||
upcomingID := c.Params("upcoming_id")
|
||||
if upcomingID == "" {
|
||||
|
|
@ -269,7 +249,7 @@ type UpdateEventStatusReq struct {
|
|||
// @Success 200 {object} response.APIResponse
|
||||
// @Failure 400 {object} response.APIResponse
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /event/{id}/remove [patch]
|
||||
// @Router /events/{id} [delete]
|
||||
func (h *Handler) SetEventStatusToRemoved(c *fiber.Ctx) error {
|
||||
eventID := c.Params("id")
|
||||
err := h.eventSvc.UpdateEventStatus(c.Context(), eventID, domain.STATUS_REMOVED)
|
||||
|
|
|
|||
|
|
@ -116,10 +116,9 @@ func (a *App) initAppRoutes() {
|
|||
a.fiber.Put("/managers/:id", a.authMiddleware, h.UpdateManagers)
|
||||
a.fiber.Get("/manager/:id/branch", a.authMiddleware, h.GetBranchByManagerID)
|
||||
|
||||
a.fiber.Get("/odds/upcoming/:event_id", h.GetPrematchOdds)
|
||||
a.fiber.Get("/odds", h.GetALLPrematchOdds)
|
||||
a.fiber.Get("/odds/upcoming/:upcoming_id", h.GetOddsByUpcomingID)
|
||||
a.fiber.Get("/odds/upcoming/:upcoming_id/market/:market_id", h.GetRawOddsByMarketID)
|
||||
a.fiber.Get("/odds/upcoming/:upcoming_id", h.GetPrematchOddsByUpcomingID)
|
||||
|
||||
a.fiber.Get("/events", h.GetAllUpcomingEvents)
|
||||
a.fiber.Get("/events/:id", h.GetUpcomingEventByID)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user