add raffle filters

This commit is contained in:
Asher Samuel 2025-09-21 16:14:08 +03:00
parent 723ca34660
commit ee27ec7f10
45 changed files with 163 additions and 38 deletions

View File

@ -523,6 +523,19 @@ CREATE TABLE IF NOT EXISTS raffle_winners (
rank INT NOT NULL, rank INT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW() created_at TIMESTAMP NOT NULL DEFAULT NOW()
); );
CREATE TABLE IF NOT EXISTS raffle_sport_filters (
id SERIAL PRIMARY KEY,
raffle_id INT NOT NULL REFERENCES raffles(id) ON DELETE CASCADE,
sport_id BIGINT NOT NULL,
league_id BIGINT NOT NULL,
CONSTRAINT unique_raffle_sport_league UNIQUE (raffle_id, sport_id, league_id)
);
CREATE TABLE IF NOT EXISTS raffle_game_filters (
id SERIAL PRIMARY KEY,
raffle_id INT NOT NULL REFERENCES raffles(id) ON DELETE CASCADE,
game_id VARCHAR(150) NOT NULL,
CONSTRAINT unique_raffle_game UNIQUE (raffle_id, game_id)
);
------ Views ------ Views
CREATE VIEW companies_details AS CREATE VIEW companies_details AS
SELECT companies.*, SELECT companies.*,

View File

@ -59,3 +59,8 @@ RETURNING *;
UPDATE raffles UPDATE raffles
SET status = 'completed' SET status = 'completed'
WHERE id = $1; WHERE id = $1;
-- name: AddSportRaffleFilter :one
INSERT INTO raffle_sport_filters (raffle_id, sport_id, league_id)
VALUES ($1, $2, $3)
RETURNING *;

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: auth.sql // source: auth.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: bet.sql // source: bet.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: bet_stat.sql // source: bet_stat.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: bonus.sql // source: bonus.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: branch.sql // source: branch.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: cashier.sql // source: cashier.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: company.sql // source: company.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: copyfrom.go // source: copyfrom.go
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: direct_deposit.sql // source: direct_deposit.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: disabled_odds.sql // source: disabled_odds.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: event_history.sql // source: event_history.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: events.sql // source: events.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: events_stat.sql // source: events_stat.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: flags.sql // source: flags.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: institutions.sql // source: institutions.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: issue_reporting.sql // source: issue_reporting.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: leagues.sql // source: leagues.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: location.sql // source: location.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
package dbgen package dbgen
@ -495,6 +495,19 @@ type Raffle struct {
Status string `json:"status"` Status string `json:"status"`
} }
type RaffleGameFilter struct {
ID int32 `json:"id"`
RaffleID int32 `json:"raffle_id"`
GameID string `json:"game_id"`
}
type RaffleSportFilter struct {
ID int32 `json:"id"`
RaffleID int32 `json:"raffle_id"`
SportID int64 `json:"sport_id"`
LeagueID int64 `json:"league_id"`
}
type RaffleTicket struct { type RaffleTicket struct {
ID int32 `json:"id"` ID int32 `json:"id"`
RaffleID int32 `json:"raffle_id"` RaffleID int32 `json:"raffle_id"`

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: monitor.sql // source: monitor.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: notification.sql // source: notification.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: odd_history.sql // source: odd_history.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: odds.sql // source: odds.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: otp.sql // source: otp.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: raffle.sql // source: raffle.sql
package dbgen package dbgen
@ -11,6 +11,30 @@ import (
"github.com/jackc/pgx/v5/pgtype" "github.com/jackc/pgx/v5/pgtype"
) )
const AddSportRaffleFilter = `-- name: AddSportRaffleFilter :one
INSERT INTO raffle_sport_filters (raffle_id, sport_id, league_id)
VALUES ($1, $2, $3)
RETURNING id, raffle_id, sport_id, league_id
`
type AddSportRaffleFilterParams struct {
RaffleID int32 `json:"raffle_id"`
SportID int64 `json:"sport_id"`
LeagueID int64 `json:"league_id"`
}
func (q *Queries) AddSportRaffleFilter(ctx context.Context, arg AddSportRaffleFilterParams) (RaffleSportFilter, error) {
row := q.db.QueryRow(ctx, AddSportRaffleFilter, arg.RaffleID, arg.SportID, arg.LeagueID)
var i RaffleSportFilter
err := row.Scan(
&i.ID,
&i.RaffleID,
&i.SportID,
&i.LeagueID,
)
return i, err
}
const CreateRaffle = `-- name: CreateRaffle :one const CreateRaffle = `-- name: CreateRaffle :one
INSERT INTO raffles (company_id, name, expires_at, type) INSERT INTO raffles (company_id, name, expires_at, type)
VALUES ($1, $2, $3, $4) VALUES ($1, $2, $3, $4)

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: referal.sql // source: referal.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: report.sql // source: report.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: result.sql // source: result.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: result_log.sql // source: result_log.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: settings.sql // source: settings.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: shop_transactions.sql // source: shop_transactions.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: ticket.sql // source: ticket.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: transfer.sql // source: transfer.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: user.sql // source: user.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: virtual_games.sql // source: virtual_games.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: wallet.sql // source: wallet.sql
package dbgen package dbgen

View File

@ -12,6 +12,15 @@ type Raffle struct {
Status string Status string
} }
type RaffleFilter struct {
// requireds will depend on type of raffle (sport or game)
Type string `json:"type" validate:"required,oneof=sport game"`
RaffleID int32 `json:"raffle_id" validate:"required"`
SportID int32 `json:"sport_id" validate:"required_if=Type sport"`
LeagueID int32 `json:"league_id" validate:"required_if=Type sport"`
GameID string `json:"game_id" validate:"required_if=Type game"`
}
type RaffleStanding struct { type RaffleStanding struct {
UserID int64 UserID int64
RaffleID int32 RaffleID int32

View File

@ -169,3 +169,12 @@ func (s *Store) CreateRaffleWinner(ctx context.Context, raffleWinnerParams domai
func (s *Store) SetRaffleComplete(ctx context.Context, raffleID int32) error { func (s *Store) SetRaffleComplete(ctx context.Context, raffleID int32) error {
return s.queries.SetRaffleComplete(ctx, raffleID) return s.queries.SetRaffleComplete(ctx, raffleID)
} }
func (s *Store) AddSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) error {
_, err := s.queries.AddSportRaffleFilter(ctx, dbgen.AddSportRaffleFilterParams{
RaffleID: raffleID,
SportID: sportID,
LeagueID: leagueID,
})
return err
}

View File

@ -9,11 +9,13 @@ import (
type RaffleStore interface { type RaffleStore interface {
CreateRaffle(ctx context.Context, raffle domain.CreateRaffle) (domain.Raffle, error) CreateRaffle(ctx context.Context, raffle domain.CreateRaffle) (domain.Raffle, error)
AddSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) error
DeleteRaffle(ctx context.Context, raffleID int32) (domain.Raffle, error) DeleteRaffle(ctx context.Context, raffleID int32) (domain.Raffle, error)
GetRafflesOfCompany(ctx context.Context, companyID int32) ([]dbgen.Raffle, error) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]dbgen.Raffle, error)
GetRaffleStanding(ctx context.Context, raffleID, limit int32) ([]domain.RaffleStanding, error) GetRaffleStanding(ctx context.Context, raffleID, limit int32) ([]domain.RaffleStanding, error)
CreateRaffleWinner(ctx context.Context, raffleWinnerParams domain.RaffleWinnerParams) error CreateRaffleWinner(ctx context.Context, raffleWinnerParams domain.RaffleWinnerParams) error
SetRaffleComplete(ctx context.Context, raffleID int32) error SetRaffleComplete(ctx context.Context, raffleID int32) error
CreateRaffleTicket(ctx context.Context, raffleTicketParams domain.CreateRaffleTicket) (domain.RaffleTicket, error) CreateRaffleTicket(ctx context.Context, raffleTicketParams domain.CreateRaffleTicket) (domain.RaffleTicket, error)
GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error) GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error)
SuspendRaffleTicket(ctx context.Context, raffleTicketID int32) error SuspendRaffleTicket(ctx context.Context, raffleTicketID int32) error

View File

@ -21,6 +21,10 @@ func (s *Service) CreateRaffle(ctx context.Context, raffle domain.CreateRaffle)
return s.raffleStore.CreateRaffle(ctx, raffle) return s.raffleStore.CreateRaffle(ctx, raffle)
} }
func (s *Service) AddSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) error {
return s.raffleStore.AddSportRaffleFilter(ctx, raffleID, sportID, leagueID)
}
func (s *Service) DeleteRaffle(ctx context.Context, raffleID int32) (domain.Raffle, error) { func (s *Service) DeleteRaffle(ctx context.Context, raffleID int32) (domain.Raffle, error) {
return s.raffleStore.DeleteRaffle(ctx, raffleID) return s.raffleStore.DeleteRaffle(ctx, raffleID)
} }

View File

@ -50,6 +50,50 @@ func (h *Handler) CreateRaffle(c *fiber.Ctx) error {
return response.WriteJSON(c, fiber.StatusOK, "Raffle created successfully", raffle, nil) return response.WriteJSON(c, fiber.StatusOK, "Raffle created successfully", raffle, nil)
} }
func (h *Handler) AddRaffleFilter(c *fiber.Ctx) error {
var filter domain.RaffleFilter
if err := c.BodyParser(&filter); err != nil {
h.mongoLoggerSvc.Info("Failed to parse raffle filter request",
zap.Int("status_code", fiber.StatusBadRequest),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
}
if valErrs, ok := h.validator.Validate(c, filter); !ok {
var errMsg string
for field, msg := range valErrs {
errMsg += fmt.Sprintf("%s: %s; ", field, msg)
}
h.mongoLoggerSvc.Info("Failed to validate raffle filter",
zap.String("errMsg", errMsg),
zap.Int("status_code", fiber.StatusBadRequest),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusBadRequest, errMsg)
}
switch filter.Type {
case "sport":
err := h.raffleSvc.AddSportRaffleFilter(c.Context(), filter.RaffleID, int64(filter.SportID), int64(filter.LeagueID))
if err != nil {
h.mongoLoggerSvc.Error("Failed to add raffle filter",
zap.Int("status_code", fiber.StatusInternalServerError),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to add raffle filter")
}
// handle game case below
// there won't be a default case since its being handled in the validator
}
return response.WriteJSON(c, fiber.StatusOK, "Raffle filter added successfully", nil, nil)
}
func (h *Handler) DeleteRaffle(c *fiber.Ctx) error { func (h *Handler) DeleteRaffle(c *fiber.Ctx) error {
stringRaffleID := c.Params("id") stringRaffleID := c.Params("id")
raffleID, err := strconv.Atoi(stringRaffleID) raffleID, err := strconv.Atoi(stringRaffleID)

View File

@ -201,9 +201,11 @@ func (a *App) initAppRoutes() {
tenant.Get("/raffle/list", h.GetTenantRaffles) tenant.Get("/raffle/list", h.GetTenantRaffles)
a.fiber.Get("/raffle/standing/:id/:limit", h.GetRaffleStanding) //This needs to be accessible by non-login user a.fiber.Get("/raffle/standing/:id/:limit", h.GetRaffleStanding) //This needs to be accessible by non-login user
a.fiber.Post("/raffle/create", a.authMiddleware, h.CreateRaffle) a.fiber.Post("/raffle/create", a.authMiddleware, h.CreateRaffle)
a.fiber.Post("/raffle/add-filter", a.authMiddleware, h.AddRaffleFilter)
a.fiber.Get("/raffle/delete/:id", a.authMiddleware, h.DeleteRaffle) a.fiber.Get("/raffle/delete/:id", a.authMiddleware, h.DeleteRaffle)
a.fiber.Get("/raffle/company/:id", a.authMiddleware, h.GetRafflesOfCompany) a.fiber.Get("/raffle/company/:id", a.authMiddleware, h.GetRafflesOfCompany)
a.fiber.Get("raffle/winners/:id/:limit", a.authMiddleware, h.GetRaffleWinners) a.fiber.Get("raffle/winners/:id/:limit", a.authMiddleware, h.GetRaffleWinners)
a.fiber.Post("/raffle-ticket/create", a.authMiddleware, h.CreateRaffleTicket) a.fiber.Post("/raffle-ticket/create", a.authMiddleware, h.CreateRaffleTicket)
a.fiber.Get("/raffle-ticket/:id", a.authMiddleware, h.GetUserRaffleTickets) a.fiber.Get("/raffle-ticket/:id", a.authMiddleware, h.GetUserRaffleTickets)
a.fiber.Get("/raffle-ticket/suspend/:id", a.authMiddleware, h.SuspendRaffleTicket) a.fiber.Get("/raffle-ticket/suspend/:id", a.authMiddleware, h.SuspendRaffleTicket)