From 62258b7ecb6c1afe308ca2c367f181c6e9c8466f Mon Sep 17 00:00:00 2001 From: Asher Samuel Date: Mon, 6 Oct 2025 14:47:01 +0300 Subject: [PATCH] raffle ticket limit --- db/migrations/000001_fortune.up.sql | 4 +- db/query/raffle.sql | 20 +++++- gen/db/auth.sql.go | 2 +- gen/db/bet.sql.go | 2 +- gen/db/bet_stat.sql.go | 2 +- gen/db/bonus.sql.go | 2 +- gen/db/branch.sql.go | 2 +- gen/db/cashier.sql.go | 2 +- gen/db/company.sql.go | 2 +- gen/db/copyfrom.go | 2 +- gen/db/db.go | 2 +- gen/db/direct_deposit.sql.go | 2 +- gen/db/disabled_odds.sql.go | 2 +- gen/db/enet_pulse.sql.go | 2 +- gen/db/event_history.sql.go | 2 +- gen/db/events.sql.go | 2 +- gen/db/events_stat.sql.go | 2 +- gen/db/flags.sql.go | 2 +- gen/db/institutions.sql.go | 2 +- gen/db/issue_reporting.sql.go | 2 +- gen/db/leagues.sql.go | 2 +- gen/db/location.sql.go | 2 +- gen/db/models.go | 17 ++--- gen/db/monitor.sql.go | 2 +- gen/db/notification.sql.go | 2 +- gen/db/odd_history.sql.go | 2 +- gen/db/odds.sql.go | 2 +- gen/db/otp.sql.go | 2 +- gen/db/raffle.sql.go | 70 ++++++++++++++++++--- gen/db/referal.sql.go | 2 +- gen/db/report.sql.go | 2 +- gen/db/result.sql.go | 2 +- gen/db/result_log.sql.go | 2 +- gen/db/settings.sql.go | 2 +- gen/db/shop_transactions.sql.go | 2 +- gen/db/ticket.sql.go | 2 +- gen/db/transfer.sql.go | 2 +- gen/db/user.sql.go | 2 +- gen/db/virtual_games.sql.go | 2 +- gen/db/wallet.sql.go | 2 +- internal/domain/raffle.go | 24 +++---- internal/repository/raffel.go | 33 +++++++--- internal/services/raffle/port.go | 3 + internal/services/raffle/service.go | 12 ++++ internal/web_server/handlers/bet_handler.go | 43 ++++++++++--- 45 files changed, 215 insertions(+), 83 deletions(-) diff --git a/db/migrations/000001_fortune.up.sql b/db/migrations/000001_fortune.up.sql index c2e98cb..d0e992b 100644 --- a/db/migrations/000001_fortune.up.sql +++ b/db/migrations/000001_fortune.up.sql @@ -509,6 +509,8 @@ CREATE TABLE IF NOT EXISTS raffles ( name VARCHAR(255) NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT NOW(), expires_at TIMESTAMP NOT NULL, + -- -1 means there is no limit for the raffle + ticket_limit INT NOT NULL DEFAULT -1, type VARCHAR(50) NOT NULL CHECK (type IN ('virtual', 'sport')), status VARCHAR(50) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'completed')) ); @@ -762,4 +764,4 @@ ADD CONSTRAINT fk_event_settings_company FOREIGN KEY (company_id) REFERENCES com ADD CONSTRAINT fk_event_settings_event FOREIGN KEY (event_id) REFERENCES events (id) ON DELETE CASCADE; ALTER TABLE company_odd_settings ADD CONSTRAINT fk_odds_settings_company FOREIGN KEY (company_id) REFERENCES companies (id) ON DELETE CASCADE, - ADD CONSTRAINT fk_odds_settings_odds_market FOREIGN KEY (odds_market_id) REFERENCES odds_market (id) ON DELETE CASCADE; \ No newline at end of file + ADD CONSTRAINT fk_odds_settings_odds_market FOREIGN KEY (odds_market_id) REFERENCES odds_market (id) ON DELETE CASCADE; diff --git a/db/query/raffle.sql b/db/query/raffle.sql index 55f302c..68318a6 100644 --- a/db/query/raffle.sql +++ b/db/query/raffle.sql @@ -1,6 +1,6 @@ -- name: CreateRaffle :one -INSERT INTO raffles (company_id, name, expires_at, type) -VALUES ($1, $2, $3, $4) +INSERT INTO raffles (company_id, name, expires_at, ticket_limit, type) +VALUES ($1, $2, $3, $4, $5) RETURNING *; -- name: GetRafflesOfCompany :many @@ -71,3 +71,19 @@ FROM raffle_sport_filters WHERE raffle_id = $1 AND sport_id = $2 AND league_id = $3; + +-- name: CheckSportRaffleHasFilter :one +SELECT EXISTS ( + SELECT 1 FROM raffle_sport_filters WHERE raffle_id = $1 +) AS has_filter; + +-- name: GetRaffleTicketLimit :one +SELECT ticket_limit +FROM raffles +WHERE id = $1; + +-- name: GetRaffleTicketCount :one +SELECT COUNT(*) +FROM raffle_tickets +WHERE raffle_id = $1 + AND user_id = $2; diff --git a/gen/db/auth.sql.go b/gen/db/auth.sql.go index 7d8d59d..8dd2280 100644 --- a/gen/db/auth.sql.go +++ b/gen/db/auth.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: auth.sql package dbgen diff --git a/gen/db/bet.sql.go b/gen/db/bet.sql.go index 8e6254c..a9fac0e 100644 --- a/gen/db/bet.sql.go +++ b/gen/db/bet.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: bet.sql package dbgen diff --git a/gen/db/bet_stat.sql.go b/gen/db/bet_stat.sql.go index 275ef07..9a7b494 100644 --- a/gen/db/bet_stat.sql.go +++ b/gen/db/bet_stat.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: bet_stat.sql package dbgen diff --git a/gen/db/bonus.sql.go b/gen/db/bonus.sql.go index 7c6f168..1a5d8e9 100644 --- a/gen/db/bonus.sql.go +++ b/gen/db/bonus.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: bonus.sql package dbgen diff --git a/gen/db/branch.sql.go b/gen/db/branch.sql.go index a9a57b8..89d2959 100644 --- a/gen/db/branch.sql.go +++ b/gen/db/branch.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: branch.sql package dbgen diff --git a/gen/db/cashier.sql.go b/gen/db/cashier.sql.go index fc4a7f8..55e69d2 100644 --- a/gen/db/cashier.sql.go +++ b/gen/db/cashier.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: cashier.sql package dbgen diff --git a/gen/db/company.sql.go b/gen/db/company.sql.go index ba728e7..0ec7a34 100644 --- a/gen/db/company.sql.go +++ b/gen/db/company.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: company.sql package dbgen diff --git a/gen/db/copyfrom.go b/gen/db/copyfrom.go index 1212253..f7a4793 100644 --- a/gen/db/copyfrom.go +++ b/gen/db/copyfrom.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: copyfrom.go package dbgen diff --git a/gen/db/db.go b/gen/db/db.go index 84de07c..8134784 100644 --- a/gen/db/db.go +++ b/gen/db/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 package dbgen diff --git a/gen/db/direct_deposit.sql.go b/gen/db/direct_deposit.sql.go index be02750..ff5a3b2 100644 --- a/gen/db/direct_deposit.sql.go +++ b/gen/db/direct_deposit.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: direct_deposit.sql package dbgen diff --git a/gen/db/disabled_odds.sql.go b/gen/db/disabled_odds.sql.go index b9cc744..58913cf 100644 --- a/gen/db/disabled_odds.sql.go +++ b/gen/db/disabled_odds.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: disabled_odds.sql package dbgen diff --git a/gen/db/enet_pulse.sql.go b/gen/db/enet_pulse.sql.go index a2c131b..9e72da8 100644 --- a/gen/db/enet_pulse.sql.go +++ b/gen/db/enet_pulse.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: enet_pulse.sql package dbgen diff --git a/gen/db/event_history.sql.go b/gen/db/event_history.sql.go index a4f1c2e..35946cd 100644 --- a/gen/db/event_history.sql.go +++ b/gen/db/event_history.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: event_history.sql package dbgen diff --git a/gen/db/events.sql.go b/gen/db/events.sql.go index a8345fb..1feaf00 100644 --- a/gen/db/events.sql.go +++ b/gen/db/events.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: events.sql package dbgen diff --git a/gen/db/events_stat.sql.go b/gen/db/events_stat.sql.go index 677fa2a..615e2fa 100644 --- a/gen/db/events_stat.sql.go +++ b/gen/db/events_stat.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: events_stat.sql package dbgen diff --git a/gen/db/flags.sql.go b/gen/db/flags.sql.go index 653543f..4b82cac 100644 --- a/gen/db/flags.sql.go +++ b/gen/db/flags.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: flags.sql package dbgen diff --git a/gen/db/institutions.sql.go b/gen/db/institutions.sql.go index 324ac3e..61ca108 100644 --- a/gen/db/institutions.sql.go +++ b/gen/db/institutions.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: institutions.sql package dbgen diff --git a/gen/db/issue_reporting.sql.go b/gen/db/issue_reporting.sql.go index 7fcb4af..e35fba1 100644 --- a/gen/db/issue_reporting.sql.go +++ b/gen/db/issue_reporting.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: issue_reporting.sql package dbgen diff --git a/gen/db/leagues.sql.go b/gen/db/leagues.sql.go index 912e257..b724e00 100644 --- a/gen/db/leagues.sql.go +++ b/gen/db/leagues.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: leagues.sql package dbgen diff --git a/gen/db/location.sql.go b/gen/db/location.sql.go index 008aa61..254c73a 100644 --- a/gen/db/location.sql.go +++ b/gen/db/location.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: location.sql package dbgen diff --git a/gen/db/models.go b/gen/db/models.go index 339efb8..04f3ff9 100644 --- a/gen/db/models.go +++ b/gen/db/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 package dbgen @@ -554,13 +554,14 @@ type Otp struct { } type Raffle struct { - ID int32 `json:"id"` - CompanyID int32 `json:"company_id"` - Name string `json:"name"` - CreatedAt pgtype.Timestamp `json:"created_at"` - ExpiresAt pgtype.Timestamp `json:"expires_at"` - Type string `json:"type"` - Status string `json:"status"` + ID int32 `json:"id"` + CompanyID int32 `json:"company_id"` + Name string `json:"name"` + CreatedAt pgtype.Timestamp `json:"created_at"` + ExpiresAt pgtype.Timestamp `json:"expires_at"` + TicketLimit int32 `json:"ticket_limit"` + Type string `json:"type"` + Status string `json:"status"` } type RaffleGameFilter struct { diff --git a/gen/db/monitor.sql.go b/gen/db/monitor.sql.go index a9a7ecb..b5f248f 100644 --- a/gen/db/monitor.sql.go +++ b/gen/db/monitor.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: monitor.sql package dbgen diff --git a/gen/db/notification.sql.go b/gen/db/notification.sql.go index f6747fb..14d3a4c 100644 --- a/gen/db/notification.sql.go +++ b/gen/db/notification.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: notification.sql package dbgen diff --git a/gen/db/odd_history.sql.go b/gen/db/odd_history.sql.go index 3fe7dd9..dd834c5 100644 --- a/gen/db/odd_history.sql.go +++ b/gen/db/odd_history.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: odd_history.sql package dbgen diff --git a/gen/db/odds.sql.go b/gen/db/odds.sql.go index e7c687e..d1e676d 100644 --- a/gen/db/odds.sql.go +++ b/gen/db/odds.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: odds.sql package dbgen diff --git a/gen/db/otp.sql.go b/gen/db/otp.sql.go index 7dba175..c96aaaa 100644 --- a/gen/db/otp.sql.go +++ b/gen/db/otp.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: otp.sql package dbgen diff --git a/gen/db/raffle.sql.go b/gen/db/raffle.sql.go index a7a364e..8d0be34 100644 --- a/gen/db/raffle.sql.go +++ b/gen/db/raffle.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: raffle.sql package dbgen @@ -35,6 +35,19 @@ func (q *Queries) AddSportRaffleFilter(ctx context.Context, arg AddSportRaffleFi return i, err } +const CheckSportRaffleHasFilter = `-- name: CheckSportRaffleHasFilter :one +SELECT EXISTS ( + SELECT 1 FROM raffle_sport_filters WHERE raffle_id = $1 +) AS has_filter +` + +func (q *Queries) CheckSportRaffleHasFilter(ctx context.Context, raffleID int32) (bool, error) { + row := q.db.QueryRow(ctx, CheckSportRaffleHasFilter, raffleID) + var has_filter bool + err := row.Scan(&has_filter) + return has_filter, err +} + const CheckValidSportRaffleFilter = `-- name: CheckValidSportRaffleFilter :one SELECT COUNT(*) > 0 AS exists FROM raffle_sport_filters @@ -57,16 +70,17 @@ func (q *Queries) CheckValidSportRaffleFilter(ctx context.Context, arg CheckVali } const CreateRaffle = `-- name: CreateRaffle :one -INSERT INTO raffles (company_id, name, expires_at, type) -VALUES ($1, $2, $3, $4) -RETURNING id, company_id, name, created_at, expires_at, type, status +INSERT INTO raffles (company_id, name, expires_at, ticket_limit, type) +VALUES ($1, $2, $3, $4, $5) +RETURNING id, company_id, name, created_at, expires_at, ticket_limit, type, status ` type CreateRaffleParams struct { - CompanyID int32 `json:"company_id"` - Name string `json:"name"` - ExpiresAt pgtype.Timestamp `json:"expires_at"` - Type string `json:"type"` + CompanyID int32 `json:"company_id"` + Name string `json:"name"` + ExpiresAt pgtype.Timestamp `json:"expires_at"` + TicketLimit int32 `json:"ticket_limit"` + Type string `json:"type"` } func (q *Queries) CreateRaffle(ctx context.Context, arg CreateRaffleParams) (Raffle, error) { @@ -74,6 +88,7 @@ func (q *Queries) CreateRaffle(ctx context.Context, arg CreateRaffleParams) (Raf arg.CompanyID, arg.Name, arg.ExpiresAt, + arg.TicketLimit, arg.Type, ) var i Raffle @@ -83,6 +98,7 @@ func (q *Queries) CreateRaffle(ctx context.Context, arg CreateRaffleParams) (Raf &i.Name, &i.CreatedAt, &i.ExpiresAt, + &i.TicketLimit, &i.Type, &i.Status, ) @@ -140,7 +156,7 @@ func (q *Queries) CreateRaffleWinner(ctx context.Context, arg CreateRaffleWinner const DeleteRaffle = `-- name: DeleteRaffle :one DELETE FROM raffles WHERE id = $1 -RETURNING id, company_id, name, created_at, expires_at, type, status +RETURNING id, company_id, name, created_at, expires_at, ticket_limit, type, status ` func (q *Queries) DeleteRaffle(ctx context.Context, id int32) (Raffle, error) { @@ -152,6 +168,7 @@ func (q *Queries) DeleteRaffle(ctx context.Context, id int32) (Raffle, error) { &i.Name, &i.CreatedAt, &i.ExpiresAt, + &i.TicketLimit, &i.Type, &i.Status, ) @@ -219,8 +236,40 @@ func (q *Queries) GetRaffleStanding(ctx context.Context, arg GetRaffleStandingPa return items, nil } +const GetRaffleTicketCount = `-- name: GetRaffleTicketCount :one +SELECT COUNT(*) +FROM raffle_tickets +WHERE raffle_id = $1 + AND user_id = $2 +` + +type GetRaffleTicketCountParams struct { + RaffleID int32 `json:"raffle_id"` + UserID int32 `json:"user_id"` +} + +func (q *Queries) GetRaffleTicketCount(ctx context.Context, arg GetRaffleTicketCountParams) (int64, error) { + row := q.db.QueryRow(ctx, GetRaffleTicketCount, arg.RaffleID, arg.UserID) + var count int64 + err := row.Scan(&count) + return count, err +} + +const GetRaffleTicketLimit = `-- name: GetRaffleTicketLimit :one +SELECT ticket_limit +FROM raffles +WHERE id = $1 +` + +func (q *Queries) GetRaffleTicketLimit(ctx context.Context, id int32) (int32, error) { + row := q.db.QueryRow(ctx, GetRaffleTicketLimit, id) + var ticket_limit int32 + err := row.Scan(&ticket_limit) + return ticket_limit, err +} + const GetRafflesOfCompany = `-- name: GetRafflesOfCompany :many -SELECT id, company_id, name, created_at, expires_at, type, status FROM raffles WHERE company_id = $1 +SELECT id, company_id, name, created_at, expires_at, ticket_limit, type, status FROM raffles WHERE company_id = $1 ` func (q *Queries) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]Raffle, error) { @@ -238,6 +287,7 @@ func (q *Queries) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]R &i.Name, &i.CreatedAt, &i.ExpiresAt, + &i.TicketLimit, &i.Type, &i.Status, ); err != nil { diff --git a/gen/db/referal.sql.go b/gen/db/referal.sql.go index caaa01a..99d8bb2 100644 --- a/gen/db/referal.sql.go +++ b/gen/db/referal.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: referal.sql package dbgen diff --git a/gen/db/report.sql.go b/gen/db/report.sql.go index 1a1ccde..d6193c1 100644 --- a/gen/db/report.sql.go +++ b/gen/db/report.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: report.sql package dbgen diff --git a/gen/db/result.sql.go b/gen/db/result.sql.go index bff7b1e..899561b 100644 --- a/gen/db/result.sql.go +++ b/gen/db/result.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: result.sql package dbgen diff --git a/gen/db/result_log.sql.go b/gen/db/result_log.sql.go index 468795e..3f11e16 100644 --- a/gen/db/result_log.sql.go +++ b/gen/db/result_log.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: result_log.sql package dbgen diff --git a/gen/db/settings.sql.go b/gen/db/settings.sql.go index 96ea916..76eb504 100644 --- a/gen/db/settings.sql.go +++ b/gen/db/settings.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: settings.sql package dbgen diff --git a/gen/db/shop_transactions.sql.go b/gen/db/shop_transactions.sql.go index bcd884e..7664dbb 100644 --- a/gen/db/shop_transactions.sql.go +++ b/gen/db/shop_transactions.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: shop_transactions.sql package dbgen diff --git a/gen/db/ticket.sql.go b/gen/db/ticket.sql.go index bc9bb5f..45603ba 100644 --- a/gen/db/ticket.sql.go +++ b/gen/db/ticket.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: ticket.sql package dbgen diff --git a/gen/db/transfer.sql.go b/gen/db/transfer.sql.go index b2a1066..fe25cbe 100644 --- a/gen/db/transfer.sql.go +++ b/gen/db/transfer.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: transfer.sql package dbgen diff --git a/gen/db/user.sql.go b/gen/db/user.sql.go index f2f9fff..9b16163 100644 --- a/gen/db/user.sql.go +++ b/gen/db/user.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: user.sql package dbgen diff --git a/gen/db/virtual_games.sql.go b/gen/db/virtual_games.sql.go index 5a2809a..b98f602 100644 --- a/gen/db/virtual_games.sql.go +++ b/gen/db/virtual_games.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: virtual_games.sql package dbgen diff --git a/gen/db/wallet.sql.go b/gen/db/wallet.sql.go index fcde631..ccb2d37 100644 --- a/gen/db/wallet.sql.go +++ b/gen/db/wallet.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.29.0 +// sqlc v1.30.0 // source: wallet.sql package dbgen diff --git a/internal/domain/raffle.go b/internal/domain/raffle.go index a8307b8..ebbd9bf 100644 --- a/internal/domain/raffle.go +++ b/internal/domain/raffle.go @@ -3,13 +3,14 @@ package domain import "time" type Raffle struct { - ID int32 - CompanyID int32 - Name string - CreatedAt time.Time - ExpiresAt time.Time - Type string - Status string + ID int32 + CompanyID int32 + Name string + CreatedAt time.Time + ExpiresAt time.Time + TicketLimit int32 + Type string + Status string } type RaffleFilter struct { @@ -64,10 +65,11 @@ type RaffleTicketRes struct { } type CreateRaffle struct { - CompanyID int32 `json:"company_id" validate:"required"` - Name string `json:"name" validate:"required"` - ExpiresAt *time.Time `json:"expires_at" validate:"required"` - Type string `json:"type" validate:"required"` + CompanyID int32 `json:"company_id" validate:"required"` + Name string `json:"name" validate:"required"` + ExpiresAt *time.Time `json:"expires_at" validate:"required"` + TicketLimit int32 `json:"ticket_limit" validate:"required"` + Type string `json:"type" validate:"required"` } type CreateRaffleTicket struct { diff --git a/internal/repository/raffel.go b/internal/repository/raffel.go index 6e37013..298ed9e 100644 --- a/internal/repository/raffel.go +++ b/internal/repository/raffel.go @@ -10,13 +10,14 @@ import ( func convertRaffleOutcome(raffle dbgen.Raffle) domain.Raffle { return domain.Raffle{ - ID: raffle.ID, - CompanyID: raffle.CompanyID, - Name: raffle.Name, - CreatedAt: raffle.CreatedAt.Time, - ExpiresAt: raffle.ExpiresAt.Time, - Type: raffle.Type, - Status: raffle.Status, + ID: raffle.ID, + CompanyID: raffle.CompanyID, + Name: raffle.Name, + CreatedAt: raffle.CreatedAt.Time, + ExpiresAt: raffle.ExpiresAt.Time, + TicketLimit: raffle.TicketLimit, + Type: raffle.Type, + Status: raffle.Status, } } @@ -48,7 +49,8 @@ func convertCreateRaffle(raffle domain.CreateRaffle) dbgen.CreateRaffleParams { Time: *raffle.ExpiresAt, Valid: true, }, - Type: raffle.Type, + TicketLimit: raffle.TicketLimit, + Type: raffle.Type, } } @@ -191,3 +193,18 @@ func (s *Store) CheckValidSportRaffleFilter(ctx context.Context, raffleID int32, return res, nil } + +func (s *Store) GetRaffleTicketLimit(ctx context.Context, raffleID int32) (int32, error) { + return s.queries.GetRaffleTicketLimit(ctx, raffleID) +} + +func (s *Store) GetRaffleTicketCount(ctx context.Context, raffleID, userID int32) (int64, error) { + return s.queries.GetRaffleTicketCount(ctx, dbgen.GetRaffleTicketCountParams{ + RaffleID: raffleID, + UserID: userID, + }) +} + +func (s *Store) CheckSportRaffleHasFilter(ctx context.Context, raffleID int32) (bool, error) { + return s.queries.CheckSportRaffleHasFilter(ctx, raffleID) +} diff --git a/internal/services/raffle/port.go b/internal/services/raffle/port.go index 39f5bfa..edbe4d3 100644 --- a/internal/services/raffle/port.go +++ b/internal/services/raffle/port.go @@ -16,9 +16,12 @@ type RaffleStore interface { CreateRaffleWinner(ctx context.Context, raffleWinnerParams domain.RaffleWinnerParams) error SetRaffleComplete(ctx context.Context, raffleID int32) error CheckValidSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) (bool, error) + CheckSportRaffleHasFilter(ctx context.Context, raffleID int32) (bool, error) CreateRaffleTicket(ctx context.Context, raffleTicketParams domain.CreateRaffleTicket) (domain.RaffleTicket, error) GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error) SuspendRaffleTicket(ctx context.Context, raffleTicketID int32) error UnSuspendRaffleTicket(ctx context.Context, raffleID int32) error + GetRaffleTicketCount(ctx context.Context, raffleID, userID int32) (int64, error) + GetRaffleTicketLimit(ctx context.Context, raffleID int32) (int32, error) } diff --git a/internal/services/raffle/service.go b/internal/services/raffle/service.go index 017d164..3483839 100644 --- a/internal/services/raffle/service.go +++ b/internal/services/raffle/service.go @@ -64,3 +64,15 @@ func (s *Service) UnSuspendRaffleTicket(ctx context.Context, raffleID int32) err func (s *Service) CheckValidSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) (bool, error) { return s.raffleStore.CheckValidSportRaffleFilter(ctx, raffleID, sportID, leagueID) } + +func (s *Service) CheckSportRaffleHasFilter(ctx context.Context, raffleID int32) (bool, error) { + return s.raffleStore.CheckSportRaffleHasFilter(ctx, raffleID) +} + +func (s *Service) GetRaffleTicketCount(ctx context.Context, raffleID, userID int32) (int64, error) { + return s.raffleStore.GetRaffleTicketCount(ctx, raffleID, userID) +} + +func (s *Service) GetRaffleTicketLimit(ctx context.Context, raffleID int32) (int32, error) { + return s.raffleStore.GetRaffleTicketLimit(ctx, raffleID) +} diff --git a/internal/web_server/handlers/bet_handler.go b/internal/web_server/handlers/bet_handler.go index 7677b2e..8fe7d5f 100644 --- a/internal/web_server/handlers/bet_handler.go +++ b/internal/web_server/handlers/bet_handler.go @@ -259,24 +259,53 @@ func (h *Handler) CreateBetInternal(c *fiber.Ctx, req domain.CreateBetReq, userI sportAndLeagueIDs = append(sportAndLeagueIDs, ids) } - fmt.Println("sportAndLeagueIDs: ", sportAndLeagueIDs) - for _, raffle := range raffles { // TODO: only fetch pending raffles from db if raffle.Status == "completed" { continue } - // only require one sport and league combo to be valide to make the raffle ticket - foundValid := false + raffleTicketLimit, err := h.raffleSvc.GetRaffleTicketLimit(c.Context(), raffle.ID) + if err != nil { + continue + } + + // check raffle ticke count + userTicketCount, err := h.raffleSvc.GetRaffleTicketCount(c.Context(), raffle.ID, int32(userID)) + if err != nil { + continue + } + + if userTicketCount == int64(raffleTicketLimit) { + h.mongoLoggerSvc.Info("User reached max ticket count allowed for current raffle", + zap.Int("status_code", fiber.StatusForbidden), + zap.Int64("raffleID", int64(raffle.ID)), + zap.Int64("userID", userID), + zap.Int64("companyID", companyID), + zap.Time("timestamp", time.Now()), + ) + continue + } + + // empty raffle filter means there is no filter (all is allowed) + hasFilter, err := h.raffleSvc.CheckSportRaffleHasFilter(c.Context(), raffle.ID) + if err != nil { + continue + } + + foundValid := !hasFilter + + // only require one sport and league combo to be valid to make the raffle ticket for _, sportAndLeagueID := range sportAndLeagueIDs { + if foundValid { + break + } + res, err := h.raffleSvc.CheckValidSportRaffleFilter(c.Context(), raffle.ID, sportAndLeagueID[0], sportAndLeagueID[1]) if err != nil { continue } - fmt.Println(sportAndLeagueID, res) - foundValid = foundValid || res } @@ -289,7 +318,7 @@ func (h *Handler) CreateBetInternal(c *fiber.Ctx, req domain.CreateBetReq, userI UserID: int32(userID), } - _, err := h.raffleSvc.CreateRaffleTicket(c.Context(), raffleTicket) + _, err = h.raffleSvc.CreateRaffleTicket(c.Context(), raffleTicket) if err != nil { h.mongoLoggerSvc.Error("Failed to create raffle ticket", zap.Int("status_code", fiber.StatusInternalServerError),