Enetpulse tournament+tournament_stages imlementations
This commit is contained in:
parent
6ceff2843e
commit
76bf4ed75a
|
|
@ -190,7 +190,13 @@ func main() {
|
|||
logger,
|
||||
)
|
||||
|
||||
enePulseSvc := enetpulse.New(
|
||||
*cfg,
|
||||
store,
|
||||
)
|
||||
|
||||
go httpserver.SetupReportandVirtualGameCronJobs(context.Background(), reportSvc, veliVirtualGameService, "C:/Users/User/Desktop")
|
||||
go httpserver.StartEnetPulseCron(enePulseSvc, domain.MongoDBLogger)
|
||||
go httpserver.ProcessBetCashback(context.TODO(), betSvc)
|
||||
|
||||
bankRepository := repository.NewBankRepository(store)
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
CREATE TABLE IF NOT EXISTS results (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
bet_outcome_id BIGINT NOT NULL,
|
||||
event_id BIGINT NOT NULL,
|
||||
odd_id BIGINT NOT NULL,
|
||||
market_id BIGINT NOT NULL,
|
||||
status INT NOT NULL,
|
||||
score VARCHAR(255),
|
||||
full_time_score VARCHAR(255),
|
||||
half_time_score VARCHAR(255),
|
||||
ss VARCHAR(255),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (bet_outcome_id) REFERENCES bet_outcomes (id)
|
||||
);
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
CREATE TABLE IF NOT EXISTS enetpulse_sports (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
sport_id VARCHAR(50) NOT NULL UNIQUE, -- from API "id"
|
||||
name VARCHAR(255) NOT NULL, -- from API "name"
|
||||
updates_count INT DEFAULT 0, -- from API "n"
|
||||
last_updated_at TIMESTAMPTZ, -- from API "ut"
|
||||
status INT DEFAULT 1, -- optional status (active/inactive)
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS enetpulse_tournament_templates (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
template_id VARCHAR(50) NOT NULL UNIQUE, -- from API "id"
|
||||
name VARCHAR(255) NOT NULL, -- from API "name"
|
||||
sport_fk VARCHAR(50) NOT NULL REFERENCES enetpulse_sports(sport_id) ON DELETE CASCADE,
|
||||
gender VARCHAR(20) DEFAULT 'unknown', -- from API "gender" {male, female, mixed, unknown}
|
||||
updates_count INT DEFAULT 0, -- from API "n"
|
||||
last_updated_at TIMESTAMPTZ, -- from API "ut"
|
||||
status INT DEFAULT 1, -- optional status (active/inactive)
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
64
db/migrations/000011_enet_pulse.up.sql
Normal file
64
db/migrations/000011_enet_pulse.up.sql
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
CREATE TABLE IF NOT EXISTS enetpulse_sports (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
sport_id VARCHAR(50) NOT NULL UNIQUE, -- from API "id"
|
||||
name VARCHAR(255) NOT NULL, -- from API "name"
|
||||
updates_count INT DEFAULT 0, -- from API "n"
|
||||
last_updated_at TIMESTAMPTZ, -- from API "ut"
|
||||
status INT DEFAULT 1, -- optional status (active/inactive)
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS enetpulse_tournament_templates (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
template_id VARCHAR(50) NOT NULL UNIQUE, -- from API "id"
|
||||
name VARCHAR(255) NOT NULL, -- from API "name"
|
||||
sport_fk VARCHAR(50) NOT NULL REFERENCES enetpulse_sports(sport_id) ON DELETE CASCADE,
|
||||
gender VARCHAR(20) DEFAULT 'unknown', -- from API "gender" {male, female, mixed, unknown}
|
||||
updates_count INT DEFAULT 0, -- from API "n"
|
||||
last_updated_at TIMESTAMPTZ, -- from API "ut"
|
||||
status INT DEFAULT 1, -- optional status (active/inactive)
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS enetpulse_tournaments (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
tournament_id VARCHAR(50) NOT NULL UNIQUE, -- from API "id"
|
||||
name VARCHAR(255) NOT NULL, -- from API "name"
|
||||
|
||||
-- Link to the template it belongs to:
|
||||
tournament_template_fk VARCHAR(50) NOT NULL
|
||||
REFERENCES enetpulse_tournament_templates(template_id) ON DELETE CASCADE,
|
||||
|
||||
updates_count INT DEFAULT 0, -- from API "n"
|
||||
last_updated_at TIMESTAMPTZ, -- from API "ut"
|
||||
status INT DEFAULT 1, -- optional active/inactive flag
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
-- Create table for tournament stages
|
||||
CREATE TABLE IF NOT EXISTS enetpulse_tournament_stages (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
stage_id VARCHAR(50) NOT NULL UNIQUE, -- from API "id"
|
||||
name VARCHAR(255) NOT NULL, -- from API "name"
|
||||
tournament_fk VARCHAR(50) NOT NULL REFERENCES enetpulse_tournaments(tournament_id) ON DELETE CASCADE,
|
||||
-- from API "tournamentFK"
|
||||
gender VARCHAR(20) DEFAULT 'unknown', -- from API "gender" {male, female, mixed, unknown}
|
||||
country_fk VARCHAR(50), -- from API "countryFK"
|
||||
country_name VARCHAR(255), -- from API "country_name"
|
||||
start_date TIMESTAMPTZ, -- from API "startdate"
|
||||
end_date TIMESTAMPTZ, -- from API "enddate"
|
||||
updates_count INT DEFAULT 0, -- from API "n"
|
||||
last_updated_at TIMESTAMPTZ, -- from API "ut"
|
||||
status INT DEFAULT 1, -- optional status (active/inactive)
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
-- Index to quickly query by tournament_fk
|
||||
CREATE INDEX IF NOT EXISTS idx_enetpulse_tournament_stages_tournament_fk
|
||||
ON enetpulse_tournament_stages (tournament_fk);
|
||||
|
||||
|
||||
|
|
@ -9,6 +9,13 @@ INSERT INTO enetpulse_sports (
|
|||
) VALUES (
|
||||
$1, $2, $3, $4, $5, NOW()
|
||||
)
|
||||
ON CONFLICT (sport_id) DO UPDATE
|
||||
SET
|
||||
name = EXCLUDED.name,
|
||||
updates_count = EXCLUDED.updates_count,
|
||||
last_updated_at = EXCLUDED.last_updated_at,
|
||||
status = EXCLUDED.status,
|
||||
updated_at = NOW()
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetAllEnetpulseSports :many
|
||||
|
|
@ -34,12 +41,18 @@ INSERT INTO enetpulse_tournament_templates (
|
|||
last_updated_at,
|
||||
status,
|
||||
updated_at
|
||||
) VALUES (
|
||||
$1, $2, $3, $4, $5, $6, $7, NOW()
|
||||
)
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())
|
||||
ON CONFLICT (template_id) DO UPDATE
|
||||
SET
|
||||
name = EXCLUDED.name,
|
||||
sport_fk = EXCLUDED.sport_fk,
|
||||
gender = EXCLUDED.gender,
|
||||
updates_count = EXCLUDED.updates_count,
|
||||
last_updated_at = EXCLUDED.last_updated_at,
|
||||
status = EXCLUDED.status,
|
||||
updated_at = NOW()
|
||||
RETURNING *;
|
||||
|
||||
|
||||
-- name: GetAllEnetpulseTournamentTemplates :many
|
||||
SELECT
|
||||
id,
|
||||
|
|
@ -55,3 +68,67 @@ SELECT
|
|||
FROM enetpulse_tournament_templates
|
||||
ORDER BY name;
|
||||
|
||||
-- name: CreateEnetpulseTournament :one
|
||||
INSERT INTO enetpulse_tournaments (
|
||||
tournament_id,
|
||||
name,
|
||||
tournament_template_fk,
|
||||
updates_count,
|
||||
last_updated_at,
|
||||
status
|
||||
) VALUES ($1, $2, $3, $4, $5, $6)
|
||||
ON CONFLICT (tournament_id) DO UPDATE
|
||||
SET
|
||||
name = EXCLUDED.name,
|
||||
tournament_template_fk = EXCLUDED.tournament_template_fk,
|
||||
updates_count = EXCLUDED.updates_count,
|
||||
last_updated_at = EXCLUDED.last_updated_at,
|
||||
status = EXCLUDED.status
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetAllEnetpulseTournaments :many
|
||||
SELECT *
|
||||
FROM enetpulse_tournaments
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
-- name: CreateEnetpulseTournamentStage :one
|
||||
INSERT INTO enetpulse_tournament_stages (
|
||||
stage_id,
|
||||
name,
|
||||
tournament_fk,
|
||||
gender,
|
||||
country_fk,
|
||||
country_name,
|
||||
start_date,
|
||||
end_date,
|
||||
updates_count,
|
||||
last_updated_at,
|
||||
status
|
||||
) VALUES (
|
||||
$1, -- stage_id
|
||||
$2, -- name
|
||||
$3, -- tournament_fk
|
||||
$4, -- gender
|
||||
$5, -- country_fk
|
||||
$6, -- country_name
|
||||
$7, -- start_date
|
||||
$8, -- end_date
|
||||
$9, -- updates_count
|
||||
$10, -- last_updated_at
|
||||
$11 -- status
|
||||
)
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetAllEnetpulseTournamentStages :many
|
||||
SELECT *
|
||||
FROM enetpulse_tournament_stages
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
-- name: GetTournamentStagesByTournamentFK :many
|
||||
SELECT *
|
||||
FROM enetpulse_tournament_stages
|
||||
WHERE tournament_fk = $1
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,13 @@ INSERT INTO enetpulse_sports (
|
|||
) VALUES (
|
||||
$1, $2, $3, $4, $5, NOW()
|
||||
)
|
||||
ON CONFLICT (sport_id) DO UPDATE
|
||||
SET
|
||||
name = EXCLUDED.name,
|
||||
updates_count = EXCLUDED.updates_count,
|
||||
last_updated_at = EXCLUDED.last_updated_at,
|
||||
status = EXCLUDED.status,
|
||||
updated_at = NOW()
|
||||
RETURNING id, sport_id, name, updates_count, last_updated_at, status, created_at, updated_at
|
||||
`
|
||||
|
||||
|
|
@ -55,6 +62,135 @@ func (q *Queries) CreateEnetpulseSport(ctx context.Context, arg CreateEnetpulseS
|
|||
return i, err
|
||||
}
|
||||
|
||||
const CreateEnetpulseTournament = `-- name: CreateEnetpulseTournament :one
|
||||
INSERT INTO enetpulse_tournaments (
|
||||
tournament_id,
|
||||
name,
|
||||
tournament_template_fk,
|
||||
updates_count,
|
||||
last_updated_at,
|
||||
status
|
||||
) VALUES ($1, $2, $3, $4, $5, $6)
|
||||
ON CONFLICT (tournament_id) DO UPDATE
|
||||
SET
|
||||
name = EXCLUDED.name,
|
||||
tournament_template_fk = EXCLUDED.tournament_template_fk,
|
||||
updates_count = EXCLUDED.updates_count,
|
||||
last_updated_at = EXCLUDED.last_updated_at,
|
||||
status = EXCLUDED.status
|
||||
RETURNING id, tournament_id, name, tournament_template_fk, updates_count, last_updated_at, status, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateEnetpulseTournamentParams struct {
|
||||
TournamentID string `json:"tournament_id"`
|
||||
Name string `json:"name"`
|
||||
TournamentTemplateFk string `json:"tournament_template_fk"`
|
||||
UpdatesCount pgtype.Int4 `json:"updates_count"`
|
||||
LastUpdatedAt pgtype.Timestamptz `json:"last_updated_at"`
|
||||
Status pgtype.Int4 `json:"status"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateEnetpulseTournament(ctx context.Context, arg CreateEnetpulseTournamentParams) (EnetpulseTournament, error) {
|
||||
row := q.db.QueryRow(ctx, CreateEnetpulseTournament,
|
||||
arg.TournamentID,
|
||||
arg.Name,
|
||||
arg.TournamentTemplateFk,
|
||||
arg.UpdatesCount,
|
||||
arg.LastUpdatedAt,
|
||||
arg.Status,
|
||||
)
|
||||
var i EnetpulseTournament
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.TournamentID,
|
||||
&i.Name,
|
||||
&i.TournamentTemplateFk,
|
||||
&i.UpdatesCount,
|
||||
&i.LastUpdatedAt,
|
||||
&i.Status,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const CreateEnetpulseTournamentStage = `-- name: CreateEnetpulseTournamentStage :one
|
||||
INSERT INTO enetpulse_tournament_stages (
|
||||
stage_id,
|
||||
name,
|
||||
tournament_fk,
|
||||
gender,
|
||||
country_fk,
|
||||
country_name,
|
||||
start_date,
|
||||
end_date,
|
||||
updates_count,
|
||||
last_updated_at,
|
||||
status
|
||||
) VALUES (
|
||||
$1, -- stage_id
|
||||
$2, -- name
|
||||
$3, -- tournament_fk
|
||||
$4, -- gender
|
||||
$5, -- country_fk
|
||||
$6, -- country_name
|
||||
$7, -- start_date
|
||||
$8, -- end_date
|
||||
$9, -- updates_count
|
||||
$10, -- last_updated_at
|
||||
$11 -- status
|
||||
)
|
||||
RETURNING id, stage_id, name, tournament_fk, gender, country_fk, country_name, start_date, end_date, updates_count, last_updated_at, status, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateEnetpulseTournamentStageParams struct {
|
||||
StageID string `json:"stage_id"`
|
||||
Name string `json:"name"`
|
||||
TournamentFk string `json:"tournament_fk"`
|
||||
Gender pgtype.Text `json:"gender"`
|
||||
CountryFk pgtype.Text `json:"country_fk"`
|
||||
CountryName pgtype.Text `json:"country_name"`
|
||||
StartDate pgtype.Timestamptz `json:"start_date"`
|
||||
EndDate pgtype.Timestamptz `json:"end_date"`
|
||||
UpdatesCount pgtype.Int4 `json:"updates_count"`
|
||||
LastUpdatedAt pgtype.Timestamptz `json:"last_updated_at"`
|
||||
Status pgtype.Int4 `json:"status"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateEnetpulseTournamentStage(ctx context.Context, arg CreateEnetpulseTournamentStageParams) (EnetpulseTournamentStage, error) {
|
||||
row := q.db.QueryRow(ctx, CreateEnetpulseTournamentStage,
|
||||
arg.StageID,
|
||||
arg.Name,
|
||||
arg.TournamentFk,
|
||||
arg.Gender,
|
||||
arg.CountryFk,
|
||||
arg.CountryName,
|
||||
arg.StartDate,
|
||||
arg.EndDate,
|
||||
arg.UpdatesCount,
|
||||
arg.LastUpdatedAt,
|
||||
arg.Status,
|
||||
)
|
||||
var i EnetpulseTournamentStage
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.StageID,
|
||||
&i.Name,
|
||||
&i.TournamentFk,
|
||||
&i.Gender,
|
||||
&i.CountryFk,
|
||||
&i.CountryName,
|
||||
&i.StartDate,
|
||||
&i.EndDate,
|
||||
&i.UpdatesCount,
|
||||
&i.LastUpdatedAt,
|
||||
&i.Status,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const CreateEnetpulseTournamentTemplate = `-- name: CreateEnetpulseTournamentTemplate :one
|
||||
INSERT INTO enetpulse_tournament_templates (
|
||||
template_id,
|
||||
|
|
@ -65,9 +201,16 @@ INSERT INTO enetpulse_tournament_templates (
|
|||
last_updated_at,
|
||||
status,
|
||||
updated_at
|
||||
) VALUES (
|
||||
$1, $2, $3, $4, $5, $6, $7, NOW()
|
||||
)
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())
|
||||
ON CONFLICT (template_id) DO UPDATE
|
||||
SET
|
||||
name = EXCLUDED.name,
|
||||
sport_fk = EXCLUDED.sport_fk,
|
||||
gender = EXCLUDED.gender,
|
||||
updates_count = EXCLUDED.updates_count,
|
||||
last_updated_at = EXCLUDED.last_updated_at,
|
||||
status = EXCLUDED.status,
|
||||
updated_at = NOW()
|
||||
RETURNING id, template_id, name, sport_fk, gender, updates_count, last_updated_at, status, created_at, updated_at
|
||||
`
|
||||
|
||||
|
|
@ -150,6 +293,47 @@ func (q *Queries) GetAllEnetpulseSports(ctx context.Context) ([]EnetpulseSport,
|
|||
return items, nil
|
||||
}
|
||||
|
||||
const GetAllEnetpulseTournamentStages = `-- name: GetAllEnetpulseTournamentStages :many
|
||||
SELECT id, stage_id, name, tournament_fk, gender, country_fk, country_name, start_date, end_date, updates_count, last_updated_at, status, created_at, updated_at
|
||||
FROM enetpulse_tournament_stages
|
||||
ORDER BY created_at DESC
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllEnetpulseTournamentStages(ctx context.Context) ([]EnetpulseTournamentStage, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllEnetpulseTournamentStages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []EnetpulseTournamentStage
|
||||
for rows.Next() {
|
||||
var i EnetpulseTournamentStage
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.StageID,
|
||||
&i.Name,
|
||||
&i.TournamentFk,
|
||||
&i.Gender,
|
||||
&i.CountryFk,
|
||||
&i.CountryName,
|
||||
&i.StartDate,
|
||||
&i.EndDate,
|
||||
&i.UpdatesCount,
|
||||
&i.LastUpdatedAt,
|
||||
&i.Status,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetAllEnetpulseTournamentTemplates = `-- name: GetAllEnetpulseTournamentTemplates :many
|
||||
SELECT
|
||||
id,
|
||||
|
|
@ -196,3 +380,81 @@ func (q *Queries) GetAllEnetpulseTournamentTemplates(ctx context.Context) ([]Ene
|
|||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetAllEnetpulseTournaments = `-- name: GetAllEnetpulseTournaments :many
|
||||
SELECT id, tournament_id, name, tournament_template_fk, updates_count, last_updated_at, status, created_at, updated_at
|
||||
FROM enetpulse_tournaments
|
||||
ORDER BY created_at DESC
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllEnetpulseTournaments(ctx context.Context) ([]EnetpulseTournament, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllEnetpulseTournaments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []EnetpulseTournament
|
||||
for rows.Next() {
|
||||
var i EnetpulseTournament
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.TournamentID,
|
||||
&i.Name,
|
||||
&i.TournamentTemplateFk,
|
||||
&i.UpdatesCount,
|
||||
&i.LastUpdatedAt,
|
||||
&i.Status,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetTournamentStagesByTournamentFK = `-- name: GetTournamentStagesByTournamentFK :many
|
||||
SELECT id, stage_id, name, tournament_fk, gender, country_fk, country_name, start_date, end_date, updates_count, last_updated_at, status, created_at, updated_at
|
||||
FROM enetpulse_tournament_stages
|
||||
WHERE tournament_fk = $1
|
||||
ORDER BY created_at DESC
|
||||
`
|
||||
|
||||
func (q *Queries) GetTournamentStagesByTournamentFK(ctx context.Context, tournamentFk string) ([]EnetpulseTournamentStage, error) {
|
||||
rows, err := q.db.Query(ctx, GetTournamentStagesByTournamentFK, tournamentFk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []EnetpulseTournamentStage
|
||||
for rows.Next() {
|
||||
var i EnetpulseTournamentStage
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.StageID,
|
||||
&i.Name,
|
||||
&i.TournamentFk,
|
||||
&i.Gender,
|
||||
&i.CountryFk,
|
||||
&i.CountryName,
|
||||
&i.StartDate,
|
||||
&i.EndDate,
|
||||
&i.UpdatesCount,
|
||||
&i.LastUpdatedAt,
|
||||
&i.Status,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,6 +255,35 @@ type EnetpulseSport struct {
|
|||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
type EnetpulseTournament struct {
|
||||
ID int64 `json:"id"`
|
||||
TournamentID string `json:"tournament_id"`
|
||||
Name string `json:"name"`
|
||||
TournamentTemplateFk string `json:"tournament_template_fk"`
|
||||
UpdatesCount pgtype.Int4 `json:"updates_count"`
|
||||
LastUpdatedAt pgtype.Timestamptz `json:"last_updated_at"`
|
||||
Status pgtype.Int4 `json:"status"`
|
||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
type EnetpulseTournamentStage struct {
|
||||
ID int64 `json:"id"`
|
||||
StageID string `json:"stage_id"`
|
||||
Name string `json:"name"`
|
||||
TournamentFk string `json:"tournament_fk"`
|
||||
Gender pgtype.Text `json:"gender"`
|
||||
CountryFk pgtype.Text `json:"country_fk"`
|
||||
CountryName pgtype.Text `json:"country_name"`
|
||||
StartDate pgtype.Timestamptz `json:"start_date"`
|
||||
EndDate pgtype.Timestamptz `json:"end_date"`
|
||||
UpdatesCount pgtype.Int4 `json:"updates_count"`
|
||||
LastUpdatedAt pgtype.Timestamptz `json:"last_updated_at"`
|
||||
Status pgtype.Int4 `json:"status"`
|
||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
type EnetpulseTournamentTemplate struct {
|
||||
ID int64 `json:"id"`
|
||||
TemplateID string `json:"template_id"`
|
||||
|
|
|
|||
|
|
@ -409,3 +409,56 @@ type CreateEnetpulseTournamentTemplate struct {
|
|||
LastUpdatedAt time.Time `json:"lastUpdatedAt"` // from API "ut"
|
||||
Status int `json:"status"` // optional, e.g., active/inactive
|
||||
}
|
||||
|
||||
type CreateEnetpulseTournament struct {
|
||||
TournamentID string // API "id"
|
||||
Name string // API "name"
|
||||
TournamentTemplateFK string // API "tournament_templateFK" (links to template_id)
|
||||
UpdatesCount int // API "n"
|
||||
LastUpdatedAt time.Time // API "ut"
|
||||
Status int // optional, default 1
|
||||
}
|
||||
|
||||
type EnetpulseTournament struct {
|
||||
ID int64 // internal DB PK
|
||||
TournamentID string
|
||||
Name string
|
||||
TournamentTemplateFK string
|
||||
UpdatesCount int
|
||||
LastUpdatedAt time.Time
|
||||
Status int
|
||||
CreatedAt time.Time
|
||||
UpdatedAt *time.Time
|
||||
}
|
||||
|
||||
type EnetpulseTournamentStage struct {
|
||||
ID int64 `json:"id"`
|
||||
StageID string `json:"stage_id"` // API id
|
||||
Name string `json:"name"` // API name
|
||||
TournamentFK string `json:"tournament_fk"` // Foreign key to tournament
|
||||
Gender string `json:"gender"` // male/female/mixed/unknown
|
||||
CountryFK string `json:"country_fk"` // country FK from API
|
||||
StartDate time.Time `json:"start_date"` // start date/time
|
||||
EndDate time.Time `json:"end_date"` // end date/time
|
||||
UpdatesCount int `json:"updates_count"` // n from API
|
||||
LastUpdatedAt time.Time `json:"last_updated_at"` // ut from API
|
||||
CountryName string `json:"country_name"` // country name from API
|
||||
Status int `json:"status"` // active/inactive
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ✅ Struct for creating new tournament stage rows
|
||||
type CreateEnetpulseTournamentStage struct {
|
||||
StageID string `json:"stage_id"` // API id
|
||||
Name string `json:"name"` // API name
|
||||
TournamentFK string `json:"tournament_fk"` // DB foreign key to tournaments
|
||||
Gender string `json:"gender"` // male/female/mixed/unknown
|
||||
CountryFK string `json:"country_fk"` // country FK from API
|
||||
StartDate time.Time `json:"start_date"` // start date/time
|
||||
EndDate time.Time `json:"end_date"` // end date/time
|
||||
UpdatesCount int `json:"updates_count"` // n from API
|
||||
LastUpdatedAt time.Time `json:"last_updated_at"` // ut from API
|
||||
CountryName string `json:"country_name"` // country name from API
|
||||
Status int `json:"status"` // active/inactive
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package repository
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
|
|
@ -63,6 +64,145 @@ func (s *Store) GetAllEnetpulseTournamentTemplates(ctx context.Context) ([]domai
|
|||
return templates, nil
|
||||
}
|
||||
|
||||
// Store.go
|
||||
func (s *Store) CreateEnetpulseTournament(
|
||||
ctx context.Context,
|
||||
tournament domain.CreateEnetpulseTournament,
|
||||
) (domain.EnetpulseTournament, error) {
|
||||
// Convert domain model to DB model if needed
|
||||
dbTournament, err := s.queries.CreateEnetpulseTournament(
|
||||
ctx,
|
||||
ConvertCreateEnetpulseTournament(tournament),
|
||||
)
|
||||
if err != nil {
|
||||
return domain.EnetpulseTournament{}, err
|
||||
}
|
||||
return ConvertDBEnetpulseTournament(dbTournament), nil
|
||||
}
|
||||
|
||||
// store.go
|
||||
func (s *Store) GetAllEnetpulseTournaments(ctx context.Context) ([]domain.EnetpulseTournament, error) {
|
||||
dbTournaments, err := s.queries.GetAllEnetpulseTournaments(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tournaments []domain.EnetpulseTournament
|
||||
for _, dbT := range dbTournaments {
|
||||
tournaments = append(tournaments, ConvertDBEnetpulseTournament(dbT))
|
||||
}
|
||||
|
||||
return tournaments, nil
|
||||
}
|
||||
|
||||
func (s *Store) CreateEnetpulseTournamentStage(
|
||||
ctx context.Context,
|
||||
stage domain.CreateEnetpulseTournamentStage,
|
||||
) (domain.EnetpulseTournamentStage, error) {
|
||||
// Convert domain model to DB model if needed
|
||||
dbStage, err := s.queries.CreateEnetpulseTournamentStage(
|
||||
ctx,
|
||||
ConvertCreateEnetpulseTournamentStage(stage),
|
||||
)
|
||||
if err != nil {
|
||||
return domain.EnetpulseTournamentStage{}, err
|
||||
}
|
||||
return ConvertDBEnetpulseTournamentStage(dbStage), nil
|
||||
}
|
||||
|
||||
// Fetch all tournament stages
|
||||
func (s *Store) GetAllEnetpulseTournamentStages(ctx context.Context) ([]domain.EnetpulseTournamentStage, error) {
|
||||
dbStages, err := s.queries.GetAllEnetpulseTournamentStages(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var stages []domain.EnetpulseTournamentStage
|
||||
for _, dbStage := range dbStages {
|
||||
stages = append(stages, ConvertDBEnetpulseTournamentStage(dbStage))
|
||||
}
|
||||
|
||||
return stages, nil
|
||||
}
|
||||
|
||||
// Optional: Fetch stages by TournamentFK
|
||||
func (s *Store) GetTournamentStagesByTournamentFK(ctx context.Context, tournamentFK string) ([]domain.EnetpulseTournamentStage, error) {
|
||||
dbStages, err := s.queries.GetTournamentStagesByTournamentFK(ctx, tournamentFK)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var stages []domain.EnetpulseTournamentStage
|
||||
for _, dbStage := range dbStages {
|
||||
stages = append(stages, ConvertDBEnetpulseTournamentStage(dbStage))
|
||||
}
|
||||
|
||||
return stages, nil
|
||||
}
|
||||
|
||||
// func ConvertCreateEnetpulseTournamentStage(stage domain.CreateEnetpulseTournamentStage) dbgen.EnetpulseTournamentStage {
|
||||
// return dbgen.EnetpulseTournamentStage{
|
||||
// StageID: stage.StageID,
|
||||
// Name: stage.Name,
|
||||
// TournamentFK: stage.TournamentFK,
|
||||
// Gender: stage.Gender,
|
||||
// CountryFK: stage.CountryFK,
|
||||
// StartDate: stage.StartDate,
|
||||
// EndDate: stage.EndDate,
|
||||
// UpdatesCount: int32(stage.UpdatesCount),
|
||||
// LastUpdatedAt: stage.LastUpdatedAt,
|
||||
// CountryName: stage.CountryName,
|
||||
// Status: int32(stage.Status),
|
||||
// UpdatedAt: time.Now(),
|
||||
// }
|
||||
// }
|
||||
|
||||
func ConvertCreateEnetpulseTournamentStage(stage domain.CreateEnetpulseTournamentStage) dbgen.CreateEnetpulseTournamentStageParams {
|
||||
return dbgen.CreateEnetpulseTournamentStageParams{
|
||||
StageID: stage.StageID,
|
||||
Name: stage.Name,
|
||||
TournamentFk: stage.TournamentFK,
|
||||
Gender: pgtype.Text{String: stage.Gender, Valid: stage.Gender != ""},
|
||||
CountryFk: pgtype.Text{String: stage.CountryFK, Valid: stage.CountryFK != ""},
|
||||
StartDate: pgtype.Timestamptz{Time: stage.StartDate, Valid: !stage.StartDate.IsZero()},
|
||||
EndDate: pgtype.Timestamptz{Time: stage.EndDate, Valid: !stage.EndDate.IsZero()},
|
||||
UpdatesCount: pgtype.Int4{Int32: int32(stage.UpdatesCount), Valid: true},
|
||||
LastUpdatedAt: pgtype.Timestamptz{Time: stage.LastUpdatedAt, Valid: !stage.LastUpdatedAt.IsZero()},
|
||||
CountryName: pgtype.Text{String: stage.CountryName, Valid: stage.CountryFK != ""},
|
||||
Status: pgtype.Int4{Int32: int32(stage.Status), Valid: true},
|
||||
// Las: pgtype.Timestamptz{Time: time.Now(), Valid: true},
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBEnetpulseTournamentStage(db dbgen.EnetpulseTournamentStage) domain.EnetpulseTournamentStage {
|
||||
return domain.EnetpulseTournamentStage{
|
||||
ID: db.ID,
|
||||
StageID: db.StageID,
|
||||
Name: db.Name,
|
||||
TournamentFK: db.TournamentFk,
|
||||
Gender: db.Gender.String,
|
||||
CountryFK: db.CountryFk.String,
|
||||
StartDate: db.StartDate.Time,
|
||||
EndDate: db.EndDate.Time,
|
||||
UpdatesCount: func() int {
|
||||
if db.UpdatesCount.Valid {
|
||||
return int(db.UpdatesCount.Int32)
|
||||
}
|
||||
return 0
|
||||
}(),
|
||||
LastUpdatedAt: db.LastUpdatedAt.Time,
|
||||
CountryName: db.CountryName.String,
|
||||
Status: func() int {
|
||||
if db.Status.Valid {
|
||||
return int(db.Status.Int32)
|
||||
}
|
||||
return 0
|
||||
}(),
|
||||
CreatedAt: db.CreatedAt.Time,
|
||||
UpdatedAt: db.UpdatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCreateEnetpulseSport(s domain.CreateEnetpulseSport) dbgen.CreateEnetpulseSportParams {
|
||||
return dbgen.CreateEnetpulseSportParams{
|
||||
SportID: s.SportID,
|
||||
|
|
@ -139,3 +279,45 @@ func ConvertCreateEnetpulseTournamentTemplate(
|
|||
Status: pgtype.Int4{Int32: int32(t.Status), Valid: true},
|
||||
}
|
||||
}
|
||||
|
||||
// Convert domain to DB insert struct for sqlc
|
||||
func ConvertCreateEnetpulseTournament(t domain.CreateEnetpulseTournament) dbgen.CreateEnetpulseTournamentParams {
|
||||
return dbgen.CreateEnetpulseTournamentParams{
|
||||
TournamentID: t.TournamentID,
|
||||
Name: t.Name,
|
||||
TournamentTemplateFk: t.TournamentTemplateFK,
|
||||
UpdatesCount: pgtype.Int4{Int32: int32(t.UpdatesCount), Valid: true},
|
||||
LastUpdatedAt: pgtype.Timestamptz{Time: t.LastUpdatedAt, Valid: !t.LastUpdatedAt.IsZero()},
|
||||
Status: pgtype.Int4{Int32: int32(t.Status), Valid: true},
|
||||
}
|
||||
}
|
||||
|
||||
// Convert DB row to domain model
|
||||
func ConvertDBEnetpulseTournament(dbT dbgen.EnetpulseTournament) domain.EnetpulseTournament {
|
||||
return domain.EnetpulseTournament{
|
||||
ID: dbT.ID,
|
||||
TournamentID: dbT.TournamentID,
|
||||
Name: dbT.Name,
|
||||
TournamentTemplateFK: dbT.TournamentTemplateFk,
|
||||
UpdatesCount: func() int {
|
||||
if dbT.UpdatesCount.Valid {
|
||||
return int(dbT.UpdatesCount.Int32)
|
||||
}
|
||||
return 0
|
||||
}(),
|
||||
LastUpdatedAt: dbT.LastUpdatedAt.Time,
|
||||
Status: func() int {
|
||||
if dbT.Status.Valid {
|
||||
return int(dbT.Status.Int32)
|
||||
}
|
||||
return 0
|
||||
}(),
|
||||
CreatedAt: dbT.CreatedAt.Time,
|
||||
UpdatedAt: func() *time.Time {
|
||||
if dbT.UpdatedAt.Valid {
|
||||
return &dbT.UpdatedAt.Time
|
||||
}
|
||||
return nil
|
||||
}(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,19 @@ func (s *Service) FetchAndStoreSports(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) GetAllSports(ctx context.Context) ([]domain.EnetpulseSport, error) {
|
||||
// 1️⃣ Fetch all sports from the store (database)
|
||||
sports, err := s.store.GetAllEnetpulseSports(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch sports from DB: %w", err)
|
||||
}
|
||||
|
||||
// 2️⃣ Optionally, you can log the count or perform other transformations
|
||||
// s.logger.Info("Fetched sports from DB", zap.Int("count", len(sports)))
|
||||
|
||||
return sports, nil
|
||||
}
|
||||
|
||||
func (s *Service) FetchAndStoreTournamentTemplates(ctx context.Context) error {
|
||||
// 1️⃣ Fetch all sports from the database
|
||||
sports, err := s.store.GetAllEnetpulseSports(ctx)
|
||||
|
|
@ -118,15 +131,27 @@ func (s *Service) FetchAndStoreTournamentTemplates(ctx context.Context) error {
|
|||
return fmt.Errorf("failed to fetch sports from DB: %w", err)
|
||||
}
|
||||
|
||||
// Template struct
|
||||
type TournamentTemplate struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
SportFK string `json:"sportFK"`
|
||||
Gender string `json:"gender"`
|
||||
N string `json:"n"`
|
||||
UT string `json:"ut"`
|
||||
}
|
||||
|
||||
for _, sport := range sports {
|
||||
// 2️⃣ Compose URL for each sport using its sportID
|
||||
// 2️⃣ Compose URL for each sport using its Enetpulse sportFK
|
||||
url := fmt.Sprintf(
|
||||
"http://eapi.enetpulse.com/tournament_template/list/?sportFK=%s&username=%s&token=%s",
|
||||
sport.SportID,
|
||||
sport.SportID, // must be Enetpulse sportFK
|
||||
s.cfg.EnetPulseConfig.UserName,
|
||||
s.cfg.EnetPulseConfig.Token,
|
||||
)
|
||||
|
||||
fmt.Println("Fetching tournament templates:", url)
|
||||
|
||||
// 3️⃣ Create HTTP request
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
|
|
@ -146,23 +171,33 @@ func (s *Service) FetchAndStoreTournamentTemplates(ctx context.Context) error {
|
|||
sport.SportID, resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
// 5️⃣ Decode JSON response
|
||||
var templatesResp struct {
|
||||
TournamentTemplates map[string]struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
SportFK string `json:"sportFK"`
|
||||
Gender string `json:"gender"`
|
||||
N string `json:"n"` // updates count
|
||||
UT string `json:"ut"` // timestamp
|
||||
} `json:"tournament_templates"`
|
||||
// 5️⃣ Decode JSON response flexibly
|
||||
var raw struct {
|
||||
TournamentTemplates json.RawMessage `json:"tournament_templates"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&templatesResp); err != nil {
|
||||
return fmt.Errorf("decoding tournament templates for sport %s: %w", sport.SportID, err)
|
||||
bodyBytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading tournament templates response for sport %s: %w", sport.SportID, err)
|
||||
}
|
||||
if err := json.Unmarshal(bodyBytes, &raw); err != nil {
|
||||
return fmt.Errorf("unmarshalling raw tournament templates for sport %s: %w", sport.SportID, err)
|
||||
}
|
||||
|
||||
// 6️⃣ Iterate and store each tournament template
|
||||
for _, tmpl := range templatesResp.TournamentTemplates {
|
||||
// 6️⃣ Parse depending on object or array
|
||||
templates := map[string]TournamentTemplate{}
|
||||
if len(raw.TournamentTemplates) > 0 && raw.TournamentTemplates[0] == '{' {
|
||||
// Object (normal case)
|
||||
if err := json.Unmarshal(raw.TournamentTemplates, &templates); err != nil {
|
||||
return fmt.Errorf("decoding tournament templates (object) for sport %s: %w", sport.SportID, err)
|
||||
}
|
||||
} else {
|
||||
// Array or empty → skip safely
|
||||
fmt.Printf("No tournament templates found for sport %s\n", sport.SportID)
|
||||
continue
|
||||
}
|
||||
|
||||
// 7️⃣ Iterate and store each tournament template
|
||||
for _, tmpl := range templates {
|
||||
updatesCount := 0
|
||||
if tmpl.N != "" {
|
||||
if n, err := strconv.Atoi(tmpl.N); err == nil {
|
||||
|
|
@ -175,29 +210,248 @@ func (s *Service) FetchAndStoreTournamentTemplates(ctx context.Context) error {
|
|||
lastUpdatedAt = time.Time{}
|
||||
}
|
||||
|
||||
// Convert sport.SportID from string to int64
|
||||
sportFK, err := strconv.ParseInt(sport.SportID, 10, 64)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to convert sport.SportID '%s' to int64: %v\n", sport.SportID, err)
|
||||
continue
|
||||
}
|
||||
|
||||
createTemplate := domain.CreateEnetpulseTournamentTemplate{
|
||||
TemplateID: tmpl.ID,
|
||||
Name: tmpl.Name,
|
||||
SportFK: sport.ID, // use DB sport ID
|
||||
SportFK: sportFK, // use DB sport ID internally
|
||||
Gender: tmpl.Gender,
|
||||
UpdatesCount: updatesCount,
|
||||
LastUpdatedAt: lastUpdatedAt,
|
||||
Status: 1, // default active
|
||||
}
|
||||
|
||||
// Insert into DB
|
||||
if _, err := s.store.CreateEnetpulseTournamentTemplate(ctx, createTemplate); err != nil {
|
||||
// Log error but continue
|
||||
// s.logger.Error("failed to store tournament template", zap.String("template_id", tmpl.ID), zap.Error(err))
|
||||
fmt.Printf("failed to store tournament template %s: %v\n", tmpl.ID, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// s.logger.Info("Successfully fetched and stored all tournament templates")
|
||||
fmt.Println("✅ Successfully fetched and stored all tournament templates")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) GetAllTournamentTemplates(ctx context.Context) ([]domain.EnetpulseTournamentTemplate, error) {
|
||||
// 1️⃣ Fetch all tournament templates from the store (database)
|
||||
templates, err := s.store.GetAllEnetpulseTournamentTemplates(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch tournament templates from DB: %w", err)
|
||||
}
|
||||
|
||||
// 2️⃣ Optionally, you can log the count or perform other transformations
|
||||
// s.logger.Info("Fetched tournament templates from DB", zap.Int("count", len(templates)))
|
||||
|
||||
return templates, nil
|
||||
}
|
||||
|
||||
func (s *Service) FetchAndStoreTournaments(ctx context.Context) error {
|
||||
// 1️⃣ Fetch all tournament templates from the database
|
||||
templates, err := s.store.GetAllEnetpulseTournamentTemplates(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch tournament templates from DB: %w", err)
|
||||
}
|
||||
|
||||
for _, tmpl := range templates {
|
||||
// 2️⃣ Compose URL for each tournament template
|
||||
url := fmt.Sprintf(
|
||||
"http://eapi.enetpulse.com/tournament/list/?tournament_templateFK=%s&username=%s&token=%s",
|
||||
tmpl.TemplateID,
|
||||
s.cfg.EnetPulseConfig.UserName,
|
||||
s.cfg.EnetPulseConfig.Token,
|
||||
)
|
||||
|
||||
// 3️⃣ Create HTTP request
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating tournament request for template %s: %w", tmpl.TemplateID, err)
|
||||
}
|
||||
|
||||
// 4️⃣ Execute request
|
||||
resp, err := s.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("requesting tournaments for template %s: %w", tmpl.TemplateID, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return fmt.Errorf("failed to fetch tournaments for template %s (status %d): %s",
|
||||
tmpl.TemplateID, resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
// 5️⃣ Decode JSON response
|
||||
var tournamentsResp struct {
|
||||
Tournaments map[string]struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
TournamentTemplateFK string `json:"tournament_templateFK"`
|
||||
N string `json:"n"` // updates count
|
||||
UT string `json:"ut"` // timestamp
|
||||
} `json:"tournaments"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&tournamentsResp); err != nil {
|
||||
return fmt.Errorf("decoding tournaments for template %s: %w", tmpl.TemplateID, err)
|
||||
}
|
||||
|
||||
// 6️⃣ Iterate and store each tournament
|
||||
for _, t := range tournamentsResp.Tournaments {
|
||||
updatesCount := 0
|
||||
if t.N != "" {
|
||||
if n, err := strconv.Atoi(t.N); err == nil {
|
||||
updatesCount = n
|
||||
}
|
||||
}
|
||||
|
||||
lastUpdatedAt, err := time.Parse(time.RFC3339, t.UT)
|
||||
if err != nil {
|
||||
lastUpdatedAt = time.Time{}
|
||||
}
|
||||
|
||||
createTournament := domain.CreateEnetpulseTournament{
|
||||
TournamentID: t.ID,
|
||||
Name: t.Name,
|
||||
TournamentTemplateFK: tmpl.TemplateID, // DB ID of template
|
||||
UpdatesCount: updatesCount,
|
||||
LastUpdatedAt: lastUpdatedAt,
|
||||
Status: 1, // default active
|
||||
}
|
||||
|
||||
// Insert into DB
|
||||
if _, err := s.store.CreateEnetpulseTournament(ctx, createTournament); err != nil {
|
||||
// Log error but continue
|
||||
// s.logger.Error("failed to store tournament", zap.String("tournament_id", t.ID), zap.Error(err))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// s.logger.Info("Successfully fetched and stored all tournaments")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) GetAllTournaments(ctx context.Context) ([]domain.EnetpulseTournament, error) {
|
||||
// 1️⃣ Fetch all tournaments from the store (database)
|
||||
tournaments, err := s.store.GetAllEnetpulseTournaments(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch tournaments from DB: %w", err)
|
||||
}
|
||||
|
||||
// 2️⃣ Optionally log count or do transformations
|
||||
// s.logger.Info("Fetched tournaments from DB", zap.Int("count", len(tournaments)))
|
||||
|
||||
return tournaments, nil
|
||||
}
|
||||
|
||||
func (s *Service) FetchAndStoreTournamentStages(ctx context.Context) error {
|
||||
// 1️⃣ Get all tournaments from DB
|
||||
tournaments, err := s.store.GetAllEnetpulseTournaments(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch tournaments from DB: %w", err)
|
||||
}
|
||||
|
||||
// 2️⃣ Loop through each tournament
|
||||
for _, t := range tournaments {
|
||||
// Compose URL for each tournament
|
||||
url := fmt.Sprintf(
|
||||
"http://eapi.enetpulse.com/tournament_stage/list/?language_typeFK=3&tz=Europe/Sofia&tournamentFK=%s&username=%s&token=%s",
|
||||
t.TournamentID,
|
||||
s.cfg.EnetPulseConfig.UserName,
|
||||
s.cfg.EnetPulseConfig.Token,
|
||||
)
|
||||
|
||||
// 3️⃣ Create HTTP request
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
// log and skip
|
||||
// s.logger.Error("creating tournament stages request", zap.String("tournament_id", t.TournamentID), zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
// 4️⃣ Execute request
|
||||
resp, err := s.httpClient.Do(req)
|
||||
if err != nil {
|
||||
// s.logger.Error("requesting tournament stages", zap.String("tournament_id", t.TournamentID), zap.Error(err))
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
// s.logger.Error("unexpected status code fetching stages", zap.String("tournament_id", t.TournamentID), zap.Int("status", resp.StatusCode))
|
||||
_ = body
|
||||
continue
|
||||
}
|
||||
|
||||
// 5️⃣ Decode JSON response (based on EnetPulse response format)
|
||||
var stagesResp struct {
|
||||
Stages map[string]struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
TournamentFK string `json:"tournamentFK"`
|
||||
N string `json:"n"` // updates count
|
||||
UT string `json:"ut"` // timestamp
|
||||
} `json:"tournament_stages"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&stagesResp); err != nil {
|
||||
// s.logger.Error("decoding tournament stages", zap.String("tournament_id", t.TournamentID), zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
// 6️⃣ Iterate and store each stage
|
||||
for _, st := range stagesResp.Stages {
|
||||
updatesCount := 0
|
||||
if st.N != "" {
|
||||
if n, err := strconv.Atoi(st.N); err == nil {
|
||||
updatesCount = n
|
||||
}
|
||||
}
|
||||
|
||||
lastUpdatedAt, err := time.Parse(time.RFC3339, st.UT)
|
||||
if err != nil {
|
||||
lastUpdatedAt = time.Time{}
|
||||
}
|
||||
|
||||
createStage := domain.CreateEnetpulseTournamentStage{
|
||||
StageID: st.ID,
|
||||
Name: st.Name,
|
||||
TournamentFK: t.TournamentID, // DB ID of the tournament
|
||||
UpdatesCount: updatesCount,
|
||||
LastUpdatedAt: lastUpdatedAt,
|
||||
Status: 1,
|
||||
}
|
||||
|
||||
// Insert into DB
|
||||
if _, err := s.store.CreateEnetpulseTournamentStage(ctx, createStage); err != nil {
|
||||
// s.logger.Error("failed to store tournament stage", zap.String("stage_id", st.ID), zap.Error(err))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// s.logger.Info("Successfully fetched and stored all tournament stages for all tournaments")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) GetAllTournamentStages(ctx context.Context) ([]domain.EnetpulseTournamentStage, error) {
|
||||
// 1️⃣ Fetch all tournament stages from the store (database)
|
||||
stages, err := s.store.GetAllEnetpulseTournamentStages(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch tournament stages from DB: %w", err)
|
||||
}
|
||||
|
||||
// 2️⃣ Optionally log count or perform transformations
|
||||
// s.logger.Info("Fetched tournament stages from DB", zap.Int("count", len(stages)))
|
||||
|
||||
return stages, nil
|
||||
}
|
||||
|
||||
func (s *Service) FetchTournamentTemplates(ctx context.Context) (*domain.TournamentTemplatesResponse, error) {
|
||||
url := fmt.Sprintf(
|
||||
"http://eapi.enetpulse.com/tournamenttemplate/list/?username=%s&token=%s",
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ func StartEnetPulseCron(enetPulseSvc *enetpulse.Service, mongoLogger *zap.Logger
|
|||
task func()
|
||||
}{
|
||||
{
|
||||
spec: "0 * * * * *", // Every minute
|
||||
spec: "0 0,10,20,30,40,50 * * * *", // Every 10 minutes
|
||||
task: func() {
|
||||
mongoLogger.Info("Began fetching and storing sports cron task")
|
||||
if err := enetPulseSvc.FetchAndStoreSports(context.Background()); err != nil {
|
||||
|
|
@ -271,6 +271,24 @@ func StartEnetPulseCron(enetPulseSvc *enetpulse.Service, mongoLogger *zap.Logger
|
|||
} else {
|
||||
mongoLogger.Info("Completed fetching and storing tournament templates without errors")
|
||||
}
|
||||
|
||||
mongoLogger.Info("Began fetching and storing tournaments cron task")
|
||||
if err := enetPulseSvc.FetchAndStoreTournaments(context.Background()); err != nil {
|
||||
mongoLogger.Error("Failed to fetch and store tournaments",
|
||||
zap.Error(err),
|
||||
)
|
||||
} else {
|
||||
mongoLogger.Info("Completed fetching and storing tournaments without errors")
|
||||
}
|
||||
|
||||
mongoLogger.Info("Began fetching and storing tournament stages cron task")
|
||||
if err := enetPulseSvc.FetchAndStoreTournamentStages(context.Background()); err != nil {
|
||||
mongoLogger.Error("Failed to fetch and store tournament stages",
|
||||
zap.Error(err),
|
||||
)
|
||||
} else {
|
||||
mongoLogger.Info("Completed fetching and storing tournament stages without errors")
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -288,6 +306,6 @@ func StartEnetPulseCron(enetPulseSvc *enetpulse.Service, mongoLogger *zap.Logger
|
|||
}
|
||||
|
||||
c.Start()
|
||||
log.Println("EnetPulse cron jobs started for fetching and storing sports and tournament templates")
|
||||
mongoLogger.Info("EnetPulse cron jobs started for fetching and storing sports and tournament templates")
|
||||
log.Println("EnetPulse cron jobs started for sports, tournament templates, tournaments, and tournament stages")
|
||||
mongoLogger.Info("EnetPulse cron jobs started for sports, tournament templates, tournaments, and tournament stages")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,118 @@ func (h *Handler) GetPreMatchOdds(c *fiber.Ctx) error {
|
|||
})
|
||||
}
|
||||
|
||||
// GetAllSports godoc
|
||||
// @Summary Get all sports
|
||||
// @Description Fetches all sports stored in the database
|
||||
// @Tags EnetPulse - Sports
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} domain.Response{data=[]domain.EnetpulseSport}
|
||||
// @Failure 502 {object} domain.ErrorResponse
|
||||
// @Router /api/v1/enetpulse/sports [get]
|
||||
func (h *Handler) GetAllSports(c *fiber.Ctx) error {
|
||||
// Call service
|
||||
sports, err := h.enetPulseSvc.GetAllSports(c.Context())
|
||||
if err != nil {
|
||||
log.Println("GetAllSports error:", err)
|
||||
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to fetch sports",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||
Message: "Sports fetched successfully",
|
||||
Data: sports,
|
||||
StatusCode: fiber.StatusOK,
|
||||
Success: true,
|
||||
})
|
||||
}
|
||||
|
||||
// GetAllTournamentTemplates godoc
|
||||
// @Summary Get all tournament templates
|
||||
// @Description Fetches all tournament templates stored in the database
|
||||
// @Tags EnetPulse - Tournament Templates
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} domain.Response{data=[]domain.EnetpulseTournamentTemplate}
|
||||
// @Failure 502 {object} domain.ErrorResponse
|
||||
// @Router /api/v1/enetpulse/tournament-templates [get]
|
||||
func (h *Handler) GetAllTournamentTemplates(c *fiber.Ctx) error {
|
||||
// Call service
|
||||
templates, err := h.enetPulseSvc.GetAllTournamentTemplates(c.Context())
|
||||
if err != nil {
|
||||
log.Println("GetAllTournamentTemplates error:", err)
|
||||
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to fetch tournament templates",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||
Message: "Tournament templates fetched successfully",
|
||||
Data: templates,
|
||||
StatusCode: fiber.StatusOK,
|
||||
Success: true,
|
||||
})
|
||||
}
|
||||
|
||||
// GetAllTournaments godoc
|
||||
// @Summary Get all tournaments
|
||||
// @Description Fetches all tournaments stored in the database
|
||||
// @Tags EnetPulse - Tournaments
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} domain.Response{data=[]domain.EnetpulseTournament}
|
||||
// @Failure 502 {object} domain.ErrorResponse
|
||||
// @Router /api/v1/enetpulse/tournaments [get]
|
||||
func (h *Handler) GetAllTournaments(c *fiber.Ctx) error {
|
||||
// Call service
|
||||
tournaments, err := h.enetPulseSvc.GetAllTournaments(c.Context())
|
||||
if err != nil {
|
||||
log.Println("GetAllTournaments error:", err)
|
||||
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to fetch tournaments",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||
Message: "Tournaments fetched successfully",
|
||||
Data: tournaments,
|
||||
StatusCode: fiber.StatusOK,
|
||||
Success: true,
|
||||
})
|
||||
}
|
||||
|
||||
// GetAllTournamentStages godoc
|
||||
// @Summary Get all tournament stages
|
||||
// @Description Fetches all tournament stages stored in the database
|
||||
// @Tags EnetPulse - Tournament Stages
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} domain.Response{data=[]domain.EnetpulseTournamentStage}
|
||||
// @Failure 502 {object} domain.ErrorResponse
|
||||
// @Router /api/v1/enetpulse/tournament-stages [get]
|
||||
func (h *Handler) GetAllTournamentStages(c *fiber.Ctx) error {
|
||||
// Call service
|
||||
stages, err := h.enetPulseSvc.GetAllTournamentStages(c.Context())
|
||||
if err != nil {
|
||||
log.Println("GetAllTournamentStages error:", err)
|
||||
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to fetch tournament stages",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||
Message: "Tournament stages fetched successfully",
|
||||
Data: stages,
|
||||
StatusCode: fiber.StatusOK,
|
||||
Success: true,
|
||||
})
|
||||
}
|
||||
|
||||
// Helper: parse comma-separated string into []int
|
||||
func parseIntSlice(input string) []int {
|
||||
if input == "" {
|
||||
|
|
|
|||
|
|
@ -271,6 +271,10 @@ func (a *App) initAppRoutes() {
|
|||
|
||||
//EnetPulse
|
||||
groupV1.Get("/odds/pre-match", h.GetPreMatchOdds)
|
||||
groupV1.Get("/sports", h.GetAllSports)
|
||||
groupV1.Get("/tournament_templates", h.GetAllTournamentTemplates)
|
||||
groupV1.Get("/tournaments", h.GetAllTournamentTemplates)
|
||||
groupV1.Get("/tournament_stages", h.GetAllTournamentStages)
|
||||
|
||||
// Leagues
|
||||
tenant.Get("/leagues", h.GetAllLeagues)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user