diff --git a/cmd/main.go b/cmd/main.go index 09192e1..16bf668 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -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) diff --git a/db/migrations/000001_fortune.up.sql b/db/migrations/000001_fortune.up.sql index 18e35d9..c5ad93d 100644 --- a/db/migrations/000001_fortune.up.sql +++ b/db/migrations/000001_fortune.up.sql @@ -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 ( diff --git a/db/query/events.sql b/db/query/events.sql index a02972a..6056738 100644 --- a/db/query/events.sql +++ b/db/query/events.sql @@ -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 diff --git a/db/query/leagues.sql b/db/query/leagues.sql index 5e7bcc7..e8ee241 100644 --- a/db/query/leagues.sql +++ b/db/query/leagues.sql @@ -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 diff --git a/db/query/odds.sql b/db/query/odds.sql index 9de17b3..d13aced 100644 --- a/db/query/odds.sql +++ b/db/query/odds.sql @@ -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'); \ No newline at end of file diff --git a/gen/db/events.sql.go b/gen/db/events.sql.go index fac3414..0ce862a 100644 --- a/gen/db/events.sql.go +++ b/gen/db/events.sql.go @@ -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) diff --git a/gen/db/leagues.sql.go b/gen/db/leagues.sql.go index c41c751..8762f82 100644 --- a/gen/db/leagues.sql.go +++ b/gen/db/leagues.sql.go @@ -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 } diff --git a/gen/db/models.go b/gen/db/models.go index 645a804..d3dad14 100644 --- a/gen/db/models.go +++ b/gen/db/models.go @@ -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"` } diff --git a/gen/db/odds.sql.go b/gen/db/odds.sql.go index 3d92299..1f21fff 100644 --- a/gen/db/odds.sql.go +++ b/gen/db/odds.sql.go @@ -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 { diff --git a/internal/domain/event.go b/internal/domain/event.go index 0501505..fd041a7 100644 --- a/internal/domain/event.go +++ b/internal/domain/event.go @@ -121,6 +121,7 @@ type Odds struct { type EventFilter struct { SportID ValidInt32 LeagueID ValidInt32 + CountryCode ValidString FirstStartTime ValidTime LastStartTime ValidTime Limit ValidInt64 diff --git a/internal/domain/league.go b/internal/domain/league.go index fff88ca..67787a5 100644 --- a/internal/domain/league.go +++ b/internal/domain/league.go @@ -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 } diff --git a/internal/domain/resultres.go b/internal/domain/resultres.go index f00b5a4..f8aad66 100644 --- a/internal/domain/resultres.go +++ b/internal/domain/resultres.go @@ -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 { diff --git a/internal/repository/event.go b/internal/repository/event.go index d466bf7..219c915 100644 --- a/internal/repository/event.go +++ b/internal/repository/event.go @@ -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 diff --git a/internal/repository/league.go b/internal/repository/league.go index 38be3ce..67a1ba0 100644 --- a/internal/repository/league.go +++ b/internal/repository/league.go @@ -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 } diff --git a/internal/repository/odds.go b/internal/repository/odds.go index 875ea97..4da0e21 100644 --- a/internal/repository/odds.go +++ b/internal/repository/odds.go @@ -3,6 +3,7 @@ package repository import ( "context" "encoding/json" + "os" "strconv" "time" diff --git a/internal/services/event/service.go b/internal/services/event/service.go index c3510ff..0ad44a5 100644 --- a/internal/services/event/service.go +++ b/internal/services/event/service.go @@ -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 } diff --git a/internal/services/league/port.go b/internal/services/league/port.go index f527c44..cfcf8b5 100644 --- a/internal/services/league/port.go +++ b/internal/services/league/port.go @@ -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 } diff --git a/internal/services/league/service.go b/internal/services/league/service.go index 9de9210..e23bf22 100644 --- a/internal/services/league/service.go +++ b/internal/services/league/service.go @@ -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) +} diff --git a/internal/services/odds/service.go b/internal/services/odds/service.go index 2ee4504..70c4b08 100644 --- a/internal/services/odds/service.go +++ b/internal/services/odds/service.go @@ -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) diff --git a/internal/services/result/service.go b/internal/services/result/service.go index 56c0e9c..667d0fa 100644 --- a/internal/services/result/service.go +++ b/internal/services/result/service.go @@ -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 { diff --git a/internal/web_server/cron.go b/internal/web_server/cron.go index 49b7fa0..ec8869a 100644 --- a/internal/web_server/cron.go +++ b/internal/web_server/cron.go @@ -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) diff --git a/internal/web_server/handlers/bet_handler.go b/internal/web_server/handlers/bet_handler.go index 18ccca6..a7a0706 100644 --- a/internal/web_server/handlers/bet_handler.go +++ b/internal/web_server/handlers/bet_handler.go @@ -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) diff --git a/internal/web_server/handlers/leagues.go b/internal/web_server/handlers/leagues.go index f4e182b..9bd3299 100644 --- a/internal/web_server/handlers/leagues.go +++ b/internal/web_server/handlers/leagues.go @@ -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) diff --git a/internal/web_server/handlers/prematch.go b/internal/web_server/handlers/prematch.go index 1362d94..7117d1d 100644 --- a/internal/web_server/handlers/prematch.go +++ b/internal/web_server/handlers/prematch.go @@ -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) diff --git a/internal/web_server/routes.go b/internal/web_server/routes.go index cdf034c..9e59e09 100644 --- a/internal/web_server/routes.go +++ b/internal/web_server/routes.go @@ -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)