adding upcoming data
This commit is contained in:
parent
1726cfd63b
commit
6c478df2b4
|
|
@ -67,7 +67,7 @@ func main() {
|
||||||
app := httpserver.NewApp(cfg.Port, v, authSvc, logger, jwtutil.JwtConfig{
|
app := httpserver.NewApp(cfg.Port, v, authSvc, logger, jwtutil.JwtConfig{
|
||||||
JwtAccessKey: cfg.JwtKey,
|
JwtAccessKey: cfg.JwtKey,
|
||||||
JwtAccessExpiry: cfg.AccessExpiry,
|
JwtAccessExpiry: cfg.AccessExpiry,
|
||||||
}, userSvc, oddsSvc)
|
}, userSvc, oddsSvc, eventSvc)
|
||||||
|
|
||||||
logger.Info("Starting server", "port", cfg.Port)
|
logger.Info("Starting server", "port", cfg.Port)
|
||||||
if err := app.Run(); err != nil {
|
if err := app.Run(); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -65,3 +65,49 @@ ON CONFLICT (id) DO UPDATE SET
|
||||||
|
|
||||||
-- name: ListLiveEvents :many
|
-- name: ListLiveEvents :many
|
||||||
SELECT id FROM events WHERE is_live = true;
|
SELECT id FROM events WHERE is_live = true;
|
||||||
|
|
||||||
|
-- name: GetAllUpcomingEvents :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,
|
||||||
|
fetched_at
|
||||||
|
FROM events
|
||||||
|
WHERE is_live = false
|
||||||
|
AND status = 'upcoming'
|
||||||
|
ORDER BY start_time ASC;
|
||||||
|
-- name: GetUpcomingByID :one
|
||||||
|
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,
|
||||||
|
fetched_at
|
||||||
|
FROM events
|
||||||
|
WHERE id = $1
|
||||||
|
AND is_live = false
|
||||||
|
AND status = 'upcoming'
|
||||||
|
LIMIT 1;
|
||||||
|
|
|
||||||
133
docs/docs.go
133
docs/docs.go
|
|
@ -180,6 +180,82 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/prematch/events": {
|
||||||
|
"get": {
|
||||||
|
"description": "Retrieve all upcoming events from the database",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"prematch"
|
||||||
|
],
|
||||||
|
"summary": "Retrieve all upcoming events",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/domain.UpcomingEvent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/prematch/events/{id}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Retrieve an upcoming event by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"prematch"
|
||||||
|
],
|
||||||
|
"summary": "Retrieve an upcoming by ID",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.UpcomingEvent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/prematch/odds": {
|
"/prematch/odds": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Retrieve all prematch odds from the database",
|
"description": "Retrieve all prematch odds from the database",
|
||||||
|
|
@ -666,6 +742,63 @@ const docTemplate = `{
|
||||||
"RoleCashier"
|
"RoleCashier"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"domain.UpcomingEvent": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"awayKitImage": {
|
||||||
|
"description": "Kit or image for away team (optional)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"awayTeam": {
|
||||||
|
"description": "Away team name (can be empty/null)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"awayTeamID": {
|
||||||
|
"description": "Away team ID (can be empty/null)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"homeKitImage": {
|
||||||
|
"description": "Kit or image for home team (optional)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"homeTeam": {
|
||||||
|
"description": "Home team name (if available)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"homeTeamID": {
|
||||||
|
"description": "Home team ID",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"description": "Event ID",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"leagueCC": {
|
||||||
|
"description": "League country code",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"leagueID": {
|
||||||
|
"description": "League ID",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"leagueName": {
|
||||||
|
"description": "League name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"matchName": {
|
||||||
|
"description": "Match or event name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"sportID": {
|
||||||
|
"description": "Sport ID",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"startTime": {
|
||||||
|
"description": "Converted from \"time\" field in UNIX format",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"handlers.CheckPhoneEmailExistReq": {
|
"handlers.CheckPhoneEmailExistReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,82 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/prematch/events": {
|
||||||
|
"get": {
|
||||||
|
"description": "Retrieve all upcoming events from the database",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"prematch"
|
||||||
|
],
|
||||||
|
"summary": "Retrieve all upcoming events",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/domain.UpcomingEvent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/prematch/events/{id}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Retrieve an upcoming event by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"prematch"
|
||||||
|
],
|
||||||
|
"summary": "Retrieve an upcoming by ID",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.UpcomingEvent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/prematch/odds": {
|
"/prematch/odds": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Retrieve all prematch odds from the database",
|
"description": "Retrieve all prematch odds from the database",
|
||||||
|
|
@ -658,6 +734,63 @@
|
||||||
"RoleCashier"
|
"RoleCashier"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"domain.UpcomingEvent": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"awayKitImage": {
|
||||||
|
"description": "Kit or image for away team (optional)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"awayTeam": {
|
||||||
|
"description": "Away team name (can be empty/null)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"awayTeamID": {
|
||||||
|
"description": "Away team ID (can be empty/null)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"homeKitImage": {
|
||||||
|
"description": "Kit or image for home team (optional)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"homeTeam": {
|
||||||
|
"description": "Home team name (if available)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"homeTeamID": {
|
||||||
|
"description": "Home team ID",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"description": "Event ID",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"leagueCC": {
|
||||||
|
"description": "League country code",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"leagueID": {
|
||||||
|
"description": "League ID",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"leagueName": {
|
||||||
|
"description": "League name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"matchName": {
|
||||||
|
"description": "Match or event name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"sportID": {
|
||||||
|
"description": "Sport ID",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"startTime": {
|
||||||
|
"description": "Converted from \"time\" field in UNIX format",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"handlers.CheckPhoneEmailExistReq": {
|
"handlers.CheckPhoneEmailExistReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,48 @@ definitions:
|
||||||
- RoleBranchManager
|
- RoleBranchManager
|
||||||
- RoleCustomer
|
- RoleCustomer
|
||||||
- RoleCashier
|
- RoleCashier
|
||||||
|
domain.UpcomingEvent:
|
||||||
|
properties:
|
||||||
|
awayKitImage:
|
||||||
|
description: Kit or image for away team (optional)
|
||||||
|
type: string
|
||||||
|
awayTeam:
|
||||||
|
description: Away team name (can be empty/null)
|
||||||
|
type: string
|
||||||
|
awayTeamID:
|
||||||
|
description: Away team ID (can be empty/null)
|
||||||
|
type: string
|
||||||
|
homeKitImage:
|
||||||
|
description: Kit or image for home team (optional)
|
||||||
|
type: string
|
||||||
|
homeTeam:
|
||||||
|
description: Home team name (if available)
|
||||||
|
type: string
|
||||||
|
homeTeamID:
|
||||||
|
description: Home team ID
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
description: Event ID
|
||||||
|
type: string
|
||||||
|
leagueCC:
|
||||||
|
description: League country code
|
||||||
|
type: string
|
||||||
|
leagueID:
|
||||||
|
description: League ID
|
||||||
|
type: string
|
||||||
|
leagueName:
|
||||||
|
description: League name
|
||||||
|
type: string
|
||||||
|
matchName:
|
||||||
|
description: Match or event name
|
||||||
|
type: string
|
||||||
|
sportID:
|
||||||
|
description: Sport ID
|
||||||
|
type: string
|
||||||
|
startTime:
|
||||||
|
description: Converted from "time" field in UNIX format
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
handlers.CheckPhoneEmailExistReq:
|
handlers.CheckPhoneEmailExistReq:
|
||||||
properties:
|
properties:
|
||||||
email:
|
email:
|
||||||
|
|
@ -325,6 +367,56 @@ paths:
|
||||||
summary: Refresh token
|
summary: Refresh token
|
||||||
tags:
|
tags:
|
||||||
- auth
|
- auth
|
||||||
|
/prematch/events:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Retrieve all upcoming events from the database
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/domain.UpcomingEvent'
|
||||||
|
type: array
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
summary: Retrieve all upcoming events
|
||||||
|
tags:
|
||||||
|
- prematch
|
||||||
|
/prematch/events/{id}:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Retrieve an upcoming event by ID
|
||||||
|
parameters:
|
||||||
|
- description: ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.UpcomingEvent'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
summary: Retrieve an upcoming by ID
|
||||||
|
tags:
|
||||||
|
- prematch
|
||||||
/prematch/odds:
|
/prematch/odds:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,154 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const GetAllUpcomingEvents = `-- name: GetAllUpcomingEvents :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,
|
||||||
|
fetched_at
|
||||||
|
FROM events
|
||||||
|
WHERE is_live = false
|
||||||
|
AND status = 'upcoming'
|
||||||
|
ORDER BY start_time ASC
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetAllUpcomingEventsRow struct {
|
||||||
|
ID string
|
||||||
|
SportID pgtype.Text
|
||||||
|
MatchName pgtype.Text
|
||||||
|
HomeTeam pgtype.Text
|
||||||
|
AwayTeam pgtype.Text
|
||||||
|
HomeTeamID pgtype.Text
|
||||||
|
AwayTeamID pgtype.Text
|
||||||
|
HomeKitImage pgtype.Text
|
||||||
|
AwayKitImage pgtype.Text
|
||||||
|
LeagueID pgtype.Text
|
||||||
|
LeagueName pgtype.Text
|
||||||
|
LeagueCc pgtype.Text
|
||||||
|
StartTime pgtype.Timestamp
|
||||||
|
IsLive pgtype.Bool
|
||||||
|
Status pgtype.Text
|
||||||
|
FetchedAt pgtype.Timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetAllUpcomingEvents(ctx context.Context) ([]GetAllUpcomingEventsRow, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetAllUpcomingEvents)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []GetAllUpcomingEventsRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetAllUpcomingEventsRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.SportID,
|
||||||
|
&i.MatchName,
|
||||||
|
&i.HomeTeam,
|
||||||
|
&i.AwayTeam,
|
||||||
|
&i.HomeTeamID,
|
||||||
|
&i.AwayTeamID,
|
||||||
|
&i.HomeKitImage,
|
||||||
|
&i.AwayKitImage,
|
||||||
|
&i.LeagueID,
|
||||||
|
&i.LeagueName,
|
||||||
|
&i.LeagueCc,
|
||||||
|
&i.StartTime,
|
||||||
|
&i.IsLive,
|
||||||
|
&i.Status,
|
||||||
|
&i.FetchedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetUpcomingByID = `-- name: GetUpcomingByID :one
|
||||||
|
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,
|
||||||
|
fetched_at
|
||||||
|
FROM events
|
||||||
|
WHERE id = $1
|
||||||
|
AND is_live = false
|
||||||
|
AND status = 'upcoming'
|
||||||
|
LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetUpcomingByIDRow struct {
|
||||||
|
ID string
|
||||||
|
SportID pgtype.Text
|
||||||
|
MatchName pgtype.Text
|
||||||
|
HomeTeam pgtype.Text
|
||||||
|
AwayTeam pgtype.Text
|
||||||
|
HomeTeamID pgtype.Text
|
||||||
|
AwayTeamID pgtype.Text
|
||||||
|
HomeKitImage pgtype.Text
|
||||||
|
AwayKitImage pgtype.Text
|
||||||
|
LeagueID pgtype.Text
|
||||||
|
LeagueName pgtype.Text
|
||||||
|
LeagueCc pgtype.Text
|
||||||
|
StartTime pgtype.Timestamp
|
||||||
|
IsLive pgtype.Bool
|
||||||
|
Status pgtype.Text
|
||||||
|
FetchedAt pgtype.Timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetUpcomingByID(ctx context.Context, id string) (GetUpcomingByIDRow, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetUpcomingByID, id)
|
||||||
|
var i GetUpcomingByIDRow
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.SportID,
|
||||||
|
&i.MatchName,
|
||||||
|
&i.HomeTeam,
|
||||||
|
&i.AwayTeam,
|
||||||
|
&i.HomeTeamID,
|
||||||
|
&i.AwayTeamID,
|
||||||
|
&i.HomeKitImage,
|
||||||
|
&i.AwayKitImage,
|
||||||
|
&i.LeagueID,
|
||||||
|
&i.LeagueName,
|
||||||
|
&i.LeagueCc,
|
||||||
|
&i.StartTime,
|
||||||
|
&i.IsLive,
|
||||||
|
&i.Status,
|
||||||
|
&i.FetchedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
const InsertEvent = `-- name: InsertEvent :exec
|
const InsertEvent = `-- name: InsertEvent :exec
|
||||||
INSERT INTO events (
|
INSERT INTO events (
|
||||||
id, sport_id, match_name, home_team, away_team,
|
id, sport_id, match_name, home_team, away_team,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -59,3 +60,52 @@ func (s *Store) SaveUpcomingEvent(ctx context.Context, e domain.UpcomingEvent) e
|
||||||
func (s *Store) GetLiveEventIDs(ctx context.Context) ([]string, error) {
|
func (s *Store) GetLiveEventIDs(ctx context.Context) ([]string, error) {
|
||||||
return s.queries.ListLiveEvents(ctx)
|
return s.queries.ListLiveEvents(ctx)
|
||||||
}
|
}
|
||||||
|
func (s *Store) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error) {
|
||||||
|
events, err := s.queries.GetAllUpcomingEvents(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
upcomingEvents := make([]domain.UpcomingEvent, len(events))
|
||||||
|
for i, e := range events {
|
||||||
|
upcomingEvents[i] = domain.UpcomingEvent{
|
||||||
|
ID: e.ID,
|
||||||
|
SportID: e.SportID.String,
|
||||||
|
MatchName: e.MatchName.String,
|
||||||
|
HomeTeam: e.HomeTeam.String,
|
||||||
|
AwayTeam: e.AwayTeam.String,
|
||||||
|
HomeTeamID: e.HomeTeamID.String,
|
||||||
|
AwayTeamID: e.AwayTeamID.String,
|
||||||
|
HomeKitImage: e.HomeKitImage.String,
|
||||||
|
AwayKitImage: e.AwayKitImage.String,
|
||||||
|
LeagueID: e.LeagueID.String,
|
||||||
|
LeagueName: e.LeagueName.String,
|
||||||
|
LeagueCC: e.LeagueCc.String,
|
||||||
|
StartTime: e.StartTime.Time.UTC(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return upcomingEvents, nil
|
||||||
|
}
|
||||||
|
func (s *Store) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) {
|
||||||
|
event, err := s.queries.GetUpcomingByID(ctx, ID)
|
||||||
|
if err != nil {
|
||||||
|
return domain.UpcomingEvent{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.UpcomingEvent{
|
||||||
|
ID: event.ID,
|
||||||
|
SportID: event.SportID.String,
|
||||||
|
MatchName: event.MatchName.String,
|
||||||
|
HomeTeam: event.HomeTeam.String,
|
||||||
|
AwayTeam: event.AwayTeam.String,
|
||||||
|
HomeTeamID: event.HomeTeamID.String,
|
||||||
|
AwayTeamID: event.AwayTeamID.String,
|
||||||
|
HomeKitImage: event.HomeKitImage.String,
|
||||||
|
AwayKitImage: event.AwayKitImage.String,
|
||||||
|
LeagueID: event.LeagueID.String,
|
||||||
|
LeagueName: event.LeagueName.String,
|
||||||
|
LeagueCC: event.LeagueCc.String,
|
||||||
|
StartTime: event.StartTime.Time.UTC(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
package event
|
package event
|
||||||
|
|
||||||
import "context"
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
)
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
FetchLiveEvents(ctx context.Context) error
|
FetchLiveEvents(ctx context.Context) error
|
||||||
FetchUpcomingEvents(ctx context.Context) error
|
FetchUpcomingEvents(ctx context.Context) error
|
||||||
|
GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error)
|
||||||
|
GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
||||||
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
type service struct {
|
type service struct {
|
||||||
|
|
@ -173,3 +174,10 @@ func getInt(v interface{}) int {
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
func (s *service) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error) {
|
||||||
|
return s.store.GetAllUpcomingEvents(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) {
|
||||||
|
return s.store.GetUpcomingEventByID(ctx, ID)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
||||||
jwtutil "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/jwt"
|
jwtutil "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/jwt"
|
||||||
|
|
@ -23,6 +24,7 @@ type App struct {
|
||||||
validator *customvalidator.CustomValidator
|
validator *customvalidator.CustomValidator
|
||||||
JwtConfig jwtutil.JwtConfig
|
JwtConfig jwtutil.JwtConfig
|
||||||
prematchSvc *odds.ServiceImpl
|
prematchSvc *odds.ServiceImpl
|
||||||
|
eventSvc event.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApp(
|
func NewApp(
|
||||||
|
|
@ -32,6 +34,7 @@ func NewApp(
|
||||||
JwtConfig jwtutil.JwtConfig,
|
JwtConfig jwtutil.JwtConfig,
|
||||||
userSvc *user.Service,
|
userSvc *user.Service,
|
||||||
prematchSvc *odds.ServiceImpl,
|
prematchSvc *odds.ServiceImpl,
|
||||||
|
eventSvc event.Service,
|
||||||
) *App {
|
) *App {
|
||||||
app := fiber.New(fiber.Config{
|
app := fiber.New(fiber.Config{
|
||||||
CaseSensitive: true,
|
CaseSensitive: true,
|
||||||
|
|
@ -48,6 +51,7 @@ func NewApp(
|
||||||
JwtConfig: JwtConfig,
|
JwtConfig: JwtConfig,
|
||||||
userSvc: userSvc,
|
userSvc: userSvc,
|
||||||
prematchSvc: prematchSvc,
|
prematchSvc: prematchSvc,
|
||||||
|
eventSvc: eventSvc,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.initAppRoutes()
|
s.initAppRoutes()
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
|
||||||
}{
|
}{
|
||||||
|
|
||||||
{
|
{
|
||||||
spec: "*/5 * * * * *", // Every 5 seconds
|
spec: "0 0 * * * *", // Every hour at minute 0 and second 0
|
||||||
task: func() {
|
task: func() {
|
||||||
if err := eventService.FetchUpcomingEvents(context.Background()); err != nil {
|
if err := eventService.FetchUpcomingEvents(context.Background()); err != nil {
|
||||||
log.Printf("FetchUpcomingEvents error: %v", err)
|
log.Printf("FetchUpcomingEvents error: %v", err)
|
||||||
|
|
@ -26,8 +26,6 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
spec: "*/5 * * * * *", // Every 5 seconds
|
spec: "*/5 * * * * *", // Every 5 seconds
|
||||||
task: func() {
|
task: func() {
|
||||||
|
|
@ -39,7 +37,7 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
spec: "0 * * * * *", // Every 1 minute
|
spec: "0 0 * * * *", // Every hour at minute 0 and second 0
|
||||||
task: func() {
|
task: func() {
|
||||||
if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
|
if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
|
||||||
log.Printf("FetchNonLiveOdds error: %v", err)
|
log.Printf("FetchNonLiveOdds error: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package handlers
|
||||||
import (
|
import (
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
)
|
)
|
||||||
|
|
@ -78,3 +79,47 @@ func GetRawOddsByID(logger *slog.Logger, prematchSvc *odds.ServiceImpl) fiber.Ha
|
||||||
return response.WriteJSON(c, fiber.StatusOK, "Raw odds retrieved successfully", rawOdds, nil)
|
return response.WriteJSON(c, fiber.StatusOK, "Raw odds retrieved successfully", rawOdds, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Summary Retrieve all upcoming events
|
||||||
|
// @Description Retrieve all upcoming events from the database
|
||||||
|
// @Tags prematch
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {array} domain.UpcomingEvent
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /prematch/events [get]
|
||||||
|
func GetAllUpcomingEvents(logger *slog.Logger, eventSvc event.Service) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
events, err := eventSvc.GetAllUpcomingEvents(c.Context())
|
||||||
|
if err != nil {
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve all upcoming events", nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "All upcoming events retrieved successfully", events, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// @Summary Retrieve an upcoming by ID
|
||||||
|
// @Description Retrieve an upcoming event by ID
|
||||||
|
// @Tags prematch
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "ID"
|
||||||
|
// @Success 200 {object} domain.UpcomingEvent
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /prematch/events/{id} [get]
|
||||||
|
func GetUpcomingEventByID(logger *slog.Logger, eventSvc event.Service) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
id := c.Params("id")
|
||||||
|
if id == "" {
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Missing id", nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
event, err := eventSvc.GetUpcomingEventByID(c.Context(), id)
|
||||||
|
if err != nil {
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve upcoming event", nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Upcoming event retrieved successfully", event, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@ func (a *App) initAppRoutes() {
|
||||||
a.fiber.Get("/prematch/odds/:event_id", handlers.GetPrematchOdds(a.logger, a.prematchSvc))
|
a.fiber.Get("/prematch/odds/:event_id", handlers.GetPrematchOdds(a.logger, a.prematchSvc))
|
||||||
a.fiber.Get("/prematch/odds", handlers.GetALLPrematchOdds(a.logger, a.prematchSvc))
|
a.fiber.Get("/prematch/odds", handlers.GetALLPrematchOdds(a.logger, a.prematchSvc))
|
||||||
a.fiber.Get("/prematch/odds/raw/:raw_odds_id", handlers.GetRawOddsByID(a.logger, a.prematchSvc))
|
a.fiber.Get("/prematch/odds/raw/:raw_odds_id", handlers.GetRawOddsByID(a.logger, a.prematchSvc))
|
||||||
|
|
||||||
|
a.fiber.Get("/prematch/events/:id", handlers.GetUpcomingEventByID(a.logger, a.eventSvc))
|
||||||
|
a.fiber.Get("/prematch/events", handlers.GetAllUpcomingEvents(a.logger, a.eventSvc))
|
||||||
// Swagger
|
// Swagger
|
||||||
a.fiber.Get("/swagger/*", fiberSwagger.WrapHandler)
|
a.fiber.Get("/swagger/*", fiberSwagger.WrapHandler)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user