handler for fetching leagues and update league status

This commit is contained in:
Asher Samuel 2025-06-06 15:19:42 +03:00
parent d3506fd03a
commit 9807e8ed14
12 changed files with 181 additions and 18 deletions

View File

@ -23,6 +23,7 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/chapa" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/chapa"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/league"
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notfication" notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notfication"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation"
@ -86,6 +87,7 @@ func main() {
transactionSvc := transaction.NewService(store) transactionSvc := transaction.NewService(store)
branchSvc := branch.NewService(store) branchSvc := branch.NewService(store)
companySvc := company.NewService(store) companySvc := company.NewService(store)
leagueSvc := league.New(store)
betSvc := bet.NewService(store, eventSvc, oddsSvc, *walletSvc, *branchSvc, logger) betSvc := bet.NewService(store, eventSvc, oddsSvc, *walletSvc, *branchSvc, logger)
resultSvc := result.NewService(store, cfg, logger, *betSvc) resultSvc := result.NewService(store, cfg, logger, *betSvc)
notificationRepo := repository.NewNotificationRepository(store) notificationRepo := repository.NewNotificationRepository(store)
@ -128,7 +130,7 @@ func main() {
JwtAccessKey: cfg.JwtKey, JwtAccessKey: cfg.JwtKey,
JwtAccessExpiry: cfg.AccessExpiry, JwtAccessExpiry: cfg.AccessExpiry,
}, userSvc, }, userSvc,
ticketSvc, betSvc, chapaSvc, walletSvc, transactionSvc, branchSvc, companySvc, notificationSvc, oddsSvc, eventSvc, referalSvc, virtualGameSvc, aleaService, veliService, recommendationSvc, resultSvc, cfg) ticketSvc, betSvc, chapaSvc, walletSvc, transactionSvc, branchSvc, companySvc, notificationSvc, oddsSvc, eventSvc, leagueSvc, referalSvc, virtualGameSvc, aleaService, veliService, recommendationSvc, resultSvc, cfg)
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 {

View File

@ -240,6 +240,13 @@ CREATE TABLE leagues (
bet365_id INT, bet365_id INT,
is_active BOOLEAN DEFAULT true is_active BOOLEAN DEFAULT true
); );
CREATE TABLE teams (
id TEXT PRIMARY KEY,
team_name TEXT NOT NULL,
country TEXT,
bet365_id INT,
logo_url TEXT
);
-- Views -- Views
CREATE VIEW companies_details AS CREATE VIEW companies_details AS
SELECT companies.*, SELECT companies.*,

View File

@ -21,6 +21,13 @@ SELECT id,
is_active is_active
FROM leagues FROM leagues
WHERE is_active = true; WHERE is_active = true;
-- name: GetAllLeagues :many
SELECT id,
name,
country_code,
bet365_id,
is_active
FROM leagues;
-- name: CheckLeagueSupport :one -- name: CheckLeagueSupport :one
SELECT EXISTS( SELECT EXISTS(
SELECT 1 SELECT 1
@ -34,4 +41,8 @@ SET name = $1,
country_code = $2, country_code = $2,
bet365_id = $3, bet365_id = $3,
is_active = $4 is_active = $4
WHERE id = $5; WHERE id = $5;
-- name: SetLeagueActive :exec
UPDATE leagues
SET is_active = true
WHERE id = $1;

View File

@ -27,6 +27,41 @@ func (q *Queries) CheckLeagueSupport(ctx context.Context, id int64) (bool, error
return exists, err return exists, err
} }
const GetAllLeagues = `-- name: GetAllLeagues :many
SELECT id,
name,
country_code,
bet365_id,
is_active
FROM leagues
`
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
}
const GetSupportedLeagues = `-- name: GetSupportedLeagues :many const GetSupportedLeagues = `-- name: GetSupportedLeagues :many
SELECT id, SELECT id,
name, name,
@ -99,6 +134,17 @@ func (q *Queries) InsertLeague(ctx context.Context, arg InsertLeagueParams) erro
return err return err
} }
const SetLeagueActive = `-- name: SetLeagueActive :exec
UPDATE leagues
SET is_active = true
WHERE id = $1
`
func (q *Queries) SetLeagueActive(ctx context.Context, id int64) error {
_, err := q.db.Exec(ctx, SetLeagueActive, id)
return err
}
const UpdateLeague = `-- name: UpdateLeague :exec const UpdateLeague = `-- name: UpdateLeague :exec
UPDATE leagues UPDATE leagues
SET name = $1, SET name = $1,

View File

@ -37,20 +37,34 @@ func (s *Store) GetSupportedLeagues(ctx context.Context) ([]domain.League, error
return supportedLeagues, nil return supportedLeagues, nil
} }
func (s *Store) GetAllLeagues(ctx context.Context) ([]domain.League, error) {
l, err := s.queries.GetAllLeagues(ctx)
if err != nil {
return nil, err
}
leagues := make([]domain.League, len(l))
for i, league := range l {
leagues[i] = domain.League{
ID: league.ID,
Name: league.Name,
CountryCode: league.CountryCode.String,
Bet365ID: league.Bet365ID.Int32,
IsActive: league.IsActive.Bool,
}
}
return leagues, nil
}
func (s *Store) CheckLeagueSupport(ctx context.Context, leagueID int64) (bool, error) { func (s *Store) CheckLeagueSupport(ctx context.Context, leagueID int64) (bool, error) {
return s.queries.CheckLeagueSupport(ctx, leagueID) return s.queries.CheckLeagueSupport(ctx, leagueID)
} }
// TODO: change to only take league id instad of the whole league func (s *Store) SetLeagueActive(ctx context.Context, leagueId int64) error {
func (s *Store) SetLeagueActive(ctx context.Context, l domain.League) error { return s.queries.SetLeagueActive(ctx, leagueId)
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: true, Valid: true},
})
} }
// 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 { func (s *Store) SetLeagueInActive(ctx context.Context, l domain.League) error {
return s.queries.UpdateLeague(ctx, dbgen.UpdateLeagueParams{ return s.queries.UpdateLeague(ctx, dbgen.UpdateLeagueParams{
Name: l.Name, Name: l.Name,

View File

@ -0,0 +1,12 @@
package league
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type Service interface {
GetAllLeagues(ctx context.Context) ([]domain.League, error)
SetLeagueActive(ctx context.Context, leagueId int64) error
}

View File

@ -0,0 +1,26 @@
package league
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
)
type service struct {
store *repository.Store
}
func New(store *repository.Store) Service {
return &service{
store: store,
}
}
func (s *service) GetAllLeagues(ctx context.Context) ([]domain.League, error) {
return s.store.GetAllLeagues(ctx)
}
func (s *service) SetLeagueActive(ctx context.Context, leagueId int64) error {
return s.store.SetLeagueActive(ctx, leagueId)
}

View File

@ -11,6 +11,7 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/chapa" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/chapa"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/league"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation"
referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal" referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal"
@ -56,6 +57,7 @@ type App struct {
Logger *slog.Logger Logger *slog.Logger
prematchSvc *odds.ServiceImpl prematchSvc *odds.ServiceImpl
eventSvc event.Service eventSvc event.Service
leagueSvc league.Service
resultSvc *result.Service resultSvc *result.Service
} }
@ -75,6 +77,7 @@ func NewApp(
notidicationStore *notificationservice.Service, notidicationStore *notificationservice.Service,
prematchSvc *odds.ServiceImpl, prematchSvc *odds.ServiceImpl,
eventSvc event.Service, eventSvc event.Service,
leagueSvc league.Service,
referralSvc referralservice.ReferralStore, referralSvc referralservice.ReferralStore,
virtualGameSvc virtualgameservice.VirtualGameService, virtualGameSvc virtualgameservice.VirtualGameService,
aleaVirtualGameService alea.AleaVirtualGameService, aleaVirtualGameService alea.AleaVirtualGameService,
@ -117,6 +120,7 @@ func NewApp(
Logger: logger, Logger: logger,
prematchSvc: prematchSvc, prematchSvc: prematchSvc,
eventSvc: eventSvc, eventSvc: eventSvc,
leagueSvc: leagueSvc,
virtualGameSvc: virtualGameSvc, virtualGameSvc: virtualGameSvc,
aleaVirtualGameService: aleaVirtualGameService, aleaVirtualGameService: aleaVirtualGameService,
veliVirtualGameService: veliVirtualGameService, veliVirtualGameService: veliVirtualGameService,

View File

@ -10,6 +10,7 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/chapa" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/chapa"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/league"
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notfication" notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notfication"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation"
@ -39,6 +40,7 @@ type Handler struct {
companySvc *company.Service companySvc *company.Service
prematchSvc *odds.ServiceImpl prematchSvc *odds.ServiceImpl
eventSvc event.Service eventSvc event.Service
leagueSvc league.Service
virtualGameSvc virtualgameservice.VirtualGameService virtualGameSvc virtualgameservice.VirtualGameService
aleaVirtualGameSvc alea.AleaVirtualGameService aleaVirtualGameSvc alea.AleaVirtualGameService
veliVirtualGameSvc veli.VeliVirtualGameService veliVirtualGameSvc veli.VeliVirtualGameService
@ -70,6 +72,7 @@ func New(
companySvc *company.Service, companySvc *company.Service,
prematchSvc *odds.ServiceImpl, prematchSvc *odds.ServiceImpl,
eventSvc event.Service, eventSvc event.Service,
leagueSvc league.Service,
cfg *config.Config, cfg *config.Config,
) *Handler { ) *Handler {
return &Handler{ return &Handler{
@ -87,6 +90,7 @@ func New(
companySvc: companySvc, companySvc: companySvc,
prematchSvc: prematchSvc, prematchSvc: prematchSvc,
eventSvc: eventSvc, eventSvc: eventSvc,
leagueSvc: leagueSvc,
virtualGameSvc: virtualGameSvc, virtualGameSvc: virtualGameSvc,
aleaVirtualGameSvc: aleaVirtualGameSvc, aleaVirtualGameSvc: aleaVirtualGameSvc,
veliVirtualGameSvc: veliVirtualGameSvc, veliVirtualGameSvc: veliVirtualGameSvc,

View File

@ -0,0 +1,34 @@
package handlers
import (
"strconv"
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
"github.com/gofiber/fiber/v2"
)
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)
}
return response.WriteJSON(c, fiber.StatusOK, "All leagues retrived", leagues, nil)
}
func (h *Handler) SetLeagueActive(c *fiber.Ctx) error {
leagueIdStr := c.Params("id")
if leagueIdStr == "" {
response.WriteJSON(c, fiber.StatusBadRequest, "Missing league id", nil, nil)
}
leagueId, err := strconv.Atoi(leagueIdStr)
if err != nil {
response.WriteJSON(c, fiber.StatusBadRequest, "invalid league id", nil, nil)
}
if err := h.leagueSvc.SetLeagueActive(c.Context(), int64(leagueId)); err != nil {
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update league", err, nil)
}
return response.WriteJSON(c, fiber.StatusOK, "League updated successfully", nil, nil)
}

View File

@ -35,6 +35,7 @@ func (a *App) initAppRoutes() {
a.companySvc, a.companySvc,
a.prematchSvc, a.prematchSvc,
a.eventSvc, a.eventSvc,
a.leagueSvc,
a.cfg, a.cfg,
) )
@ -114,13 +115,17 @@ func (a *App) initAppRoutes() {
a.fiber.Put("/managers/:id", a.authMiddleware, h.UpdateManagers) a.fiber.Put("/managers/:id", a.authMiddleware, h.UpdateManagers)
a.fiber.Get("/manager/:id/branch", a.authMiddleware, h.GetBranchByManagerID) a.fiber.Get("/manager/:id/branch", a.authMiddleware, h.GetBranchByManagerID)
a.fiber.Get("/prematch/odds/:event_id", h.GetPrematchOdds) a.fiber.Get("/events/odds/:event_id", h.GetPrematchOdds)
a.fiber.Get("/prematch/odds", h.GetALLPrematchOdds) a.fiber.Get("/events/odds", h.GetALLPrematchOdds)
a.fiber.Get("/prematch/odds/upcoming/:upcoming_id/market/:market_id", h.GetRawOddsByMarketID) a.fiber.Get("/events/odds/upcoming/:upcoming_id/market/:market_id", h.GetRawOddsByMarketID)
a.fiber.Get("/prematch/events/:id", h.GetUpcomingEventByID) a.fiber.Get("/events/:id", h.GetUpcomingEventByID)
a.fiber.Get("/prematch/events", h.GetAllUpcomingEvents) a.fiber.Get("/events", h.GetAllUpcomingEvents)
a.fiber.Get("/prematch/odds/upcoming/:upcoming_id", h.GetPrematchOddsByUpcomingID) a.fiber.Get("/events/odds/upcoming/:upcoming_id", h.GetPrematchOddsByUpcomingID)
// Leagues
a.fiber.Get("/leagues", h.GetAllLeagues)
a.fiber.Get("/leagues/:id/set-active", h.SetLeagueActive)
// Swagger // Swagger
a.fiber.Get("/swagger/*", fiberSwagger.FiberWrapHandler()) a.fiber.Get("/swagger/*", fiberSwagger.FiberWrapHandler())

View File

@ -56,8 +56,6 @@ db-up:
db-down: db-down:
@docker compose down @docker compose down
@docker volume rm fortunebet-backend_postgres_data @docker volume rm fortunebet-backend_postgres_data
postgres:
@docker exec -it fortunebet-backend-postgres-1 psql -U root -d gh
.PHONY: sqlc-gen .PHONY: sqlc-gen
sqlc-gen: sqlc-gen:
@sqlc generate @sqlc generate