diff --git a/db/migrations/000001_fortune.up.sql b/db/migrations/000001_fortune.up.sql index 3456bb4..a935963 100644 --- a/db/migrations/000001_fortune.up.sql +++ b/db/migrations/000001_fortune.up.sql @@ -289,7 +289,8 @@ CREATE TABLE IF NOT EXISTS settings ( ); CREATE TABLE bonus ( id BIGSERIAL PRIMARY KEY, - multiplier REAL NOT NULL + multiplier REAL NOT NULL, + balance_cap BIGINT NOT NULL DEFAULT 0 ); -- Views CREATE VIEW companies_details AS diff --git a/db/query/bonus.sql b/db/query/bonus.sql index c516162..82b3113 100644 --- a/db/query/bonus.sql +++ b/db/query/bonus.sql @@ -1,12 +1,17 @@ -- name: CreateBonusMultiplier :exec -INSERT INTO bonus (multiplier) -VALUES ($1); +INSERT INTO bonus (multiplier, balance_cap) +VALUES ($1, $2); -- name: GetBonusMultiplier :many SELECT id, multiplier FROM bonus; +-- name: GetBonusBalanceCap :many +SELECT id, balance_cap +FROM bonus; + -- name: UpdateBonusMultiplier :exec UPDATE bonus -SET multiplier = $1 -WHERE id = $2; \ No newline at end of file +SET multiplier = $1, + balance_cap = $2 +WHERE id = $3; \ No newline at end of file diff --git a/gen/db/bonus.sql.go b/gen/db/bonus.sql.go index 21ef5c7..12677b8 100644 --- a/gen/db/bonus.sql.go +++ b/gen/db/bonus.sql.go @@ -10,29 +10,69 @@ import ( ) const CreateBonusMultiplier = `-- name: CreateBonusMultiplier :exec -INSERT INTO bonus (multiplier) -VALUES ($1) +INSERT INTO bonus (multiplier, balance_cap) +VALUES ($1, $2) ` -func (q *Queries) CreateBonusMultiplier(ctx context.Context, multiplier float32) error { - _, err := q.db.Exec(ctx, CreateBonusMultiplier, multiplier) +type CreateBonusMultiplierParams struct { + Multiplier float32 `json:"multiplier"` + BalanceCap int64 `json:"balance_cap"` +} + +func (q *Queries) CreateBonusMultiplier(ctx context.Context, arg CreateBonusMultiplierParams) error { + _, err := q.db.Exec(ctx, CreateBonusMultiplier, arg.Multiplier, arg.BalanceCap) return err } +const GetBonusBalanceCap = `-- name: GetBonusBalanceCap :many +SELECT id, balance_cap +FROM bonus +` + +type GetBonusBalanceCapRow struct { + ID int64 `json:"id"` + BalanceCap int64 `json:"balance_cap"` +} + +func (q *Queries) GetBonusBalanceCap(ctx context.Context) ([]GetBonusBalanceCapRow, error) { + rows, err := q.db.Query(ctx, GetBonusBalanceCap) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetBonusBalanceCapRow + for rows.Next() { + var i GetBonusBalanceCapRow + if err := rows.Scan(&i.ID, &i.BalanceCap); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const GetBonusMultiplier = `-- name: GetBonusMultiplier :many SELECT id, multiplier FROM bonus ` -func (q *Queries) GetBonusMultiplier(ctx context.Context) ([]Bonu, error) { +type GetBonusMultiplierRow struct { + ID int64 `json:"id"` + Multiplier float32 `json:"multiplier"` +} + +func (q *Queries) GetBonusMultiplier(ctx context.Context) ([]GetBonusMultiplierRow, error) { rows, err := q.db.Query(ctx, GetBonusMultiplier) if err != nil { return nil, err } defer rows.Close() - var items []Bonu + var items []GetBonusMultiplierRow for rows.Next() { - var i Bonu + var i GetBonusMultiplierRow if err := rows.Scan(&i.ID, &i.Multiplier); err != nil { return nil, err } @@ -46,16 +86,18 @@ func (q *Queries) GetBonusMultiplier(ctx context.Context) ([]Bonu, error) { const UpdateBonusMultiplier = `-- name: UpdateBonusMultiplier :exec UPDATE bonus -SET multiplier = $1 -WHERE id = $2 +SET multiplier = $1, + balance_cap = $2 +WHERE id = $3 ` type UpdateBonusMultiplierParams struct { Multiplier float32 `json:"multiplier"` + BalanceCap int64 `json:"balance_cap"` ID int64 `json:"id"` } func (q *Queries) UpdateBonusMultiplier(ctx context.Context, arg UpdateBonusMultiplierParams) error { - _, err := q.db.Exec(ctx, UpdateBonusMultiplier, arg.Multiplier, arg.ID) + _, err := q.db.Exec(ctx, UpdateBonusMultiplier, arg.Multiplier, arg.BalanceCap, arg.ID) return err } diff --git a/gen/db/models.go b/gen/db/models.go index b99623f..e801d9d 100644 --- a/gen/db/models.go +++ b/gen/db/models.go @@ -131,6 +131,7 @@ type BetWithOutcome struct { type Bonu struct { ID int64 `json:"id"` Multiplier float32 `json:"multiplier"` + BalanceCap int64 `json:"balance_cap"` } type Branch struct { diff --git a/internal/repository/bonus.go b/internal/repository/bonus.go index b253ad2..c4f57ac 100644 --- a/internal/repository/bonus.go +++ b/internal/repository/bonus.go @@ -6,17 +6,25 @@ import ( dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db" ) -func (s *Store) CreateBonusMultiplier(ctx context.Context, multiplier float32) error { - return s.queries.CreateBonusMultiplier(ctx, multiplier) +func (s *Store) CreateBonusMultiplier(ctx context.Context, multiplier float32, balance_cap int64) error { + return s.queries.CreateBonusMultiplier(ctx, dbgen.CreateBonusMultiplierParams{ + Multiplier: multiplier, + BalanceCap: balance_cap, + }) } -func (s *Store) GetBonusMultiplier(ctx context.Context) ([]dbgen.Bonu, error) { +func (s *Store) GetBonusMultiplier(ctx context.Context) ([]dbgen.GetBonusMultiplierRow, error) { return s.queries.GetBonusMultiplier(ctx) } -func (s *Store) UpdateBonusMultiplier(ctx context.Context, id int64, mulitplier float32) error { +func (s *Store) GetBonusBalanceCap(ctx context.Context) ([]dbgen.GetBonusBalanceCapRow, error) { + return s.queries.GetBonusBalanceCap(ctx) +} + +func (s *Store) UpdateBonusMultiplier(ctx context.Context, id int64, mulitplier float32, balance_cap int64) error { return s.queries.UpdateBonusMultiplier(ctx, dbgen.UpdateBonusMultiplierParams{ ID: id, Multiplier: mulitplier, + BalanceCap: balance_cap, }) } diff --git a/internal/services/bonus/port.go b/internal/services/bonus/port.go index 02b59ca..2147b51 100644 --- a/internal/services/bonus/port.go +++ b/internal/services/bonus/port.go @@ -7,7 +7,8 @@ import ( ) type BonusStore interface { - CreateBonusMultiplier(ctx context.Context, multiplier float32) error - GetBonusMultiplier(ctx context.Context) ([]dbgen.Bonu, error) - UpdateBonusMultiplier(ctx context.Context, id int64, mulitplier float32) error + CreateBonusMultiplier(ctx context.Context, multiplier float32, balance_cap int64) error + GetBonusMultiplier(ctx context.Context) ([]dbgen.GetBonusMultiplierRow, error) + GetBonusBalanceCap(ctx context.Context) ([]dbgen.GetBonusBalanceCapRow, error) + UpdateBonusMultiplier(ctx context.Context, id int64, mulitplier float32, balance_cap int64) error } diff --git a/internal/services/bonus/service.go b/internal/services/bonus/service.go index f55107c..51e008a 100644 --- a/internal/services/bonus/service.go +++ b/internal/services/bonus/service.go @@ -16,14 +16,18 @@ func NewService(bonusStore BonusStore) *Service { } } -func (s *Service) CreateBonusMultiplier(ctx context.Context, multiplier float32) error { - return s.bonusStore.CreateBonusMultiplier(ctx, multiplier) +func (s *Service) CreateBonusMultiplier(ctx context.Context, multiplier float32, balance_cap int64) error { + return s.bonusStore.CreateBonusMultiplier(ctx, multiplier, balance_cap) } -func (s *Service) GetBonusMultiplier(ctx context.Context) ([]dbgen.Bonu, error) { +func (s *Service) GetBonusMultiplier(ctx context.Context) ([]dbgen.GetBonusMultiplierRow, error) { return s.bonusStore.GetBonusMultiplier(ctx) } -func (s *Service) UpdateBonusMultiplier(ctx context.Context, id int64, mulitplier float32) error { - return s.bonusStore.UpdateBonusMultiplier(ctx, id, mulitplier) +func (s *Service) GetBonusBalanceCap(ctx context.Context) ([]dbgen.GetBonusBalanceCapRow, error) { + return s.bonusStore.GetBonusBalanceCap(ctx) +} + +func (s *Service) UpdateBonusMultiplier(ctx context.Context, id int64, mulitplier float32, balance_cap int64) error { + return s.bonusStore.UpdateBonusMultiplier(ctx, id, mulitplier, balance_cap) } diff --git a/internal/web_server/handlers/bonus.go b/internal/web_server/handlers/bonus.go index 19f0e4f..f4e5a27 100644 --- a/internal/web_server/handlers/bonus.go +++ b/internal/web_server/handlers/bonus.go @@ -8,6 +8,7 @@ import ( func (h *Handler) CreateBonusMultiplier(c *fiber.Ctx) error { var req struct { Multiplier float32 `json:"multiplier"` + BalanceCap int64 `json:"balance_cap"` } if err := c.BodyParser(&req); err != nil { @@ -27,7 +28,7 @@ func (h *Handler) CreateBonusMultiplier(c *fiber.Ctx) error { return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil) } - if err := h.bonusSvc.CreateBonusMultiplier(c.Context(), req.Multiplier); err != nil { + if err := h.bonusSvc.CreateBonusMultiplier(c.Context(), req.Multiplier, req.BalanceCap); err != nil { h.logger.Error("failed to create bonus multiplier", "error", err) return response.WriteJSON(c, fiber.StatusInternalServerError, "failed to create bonus mulitplier", nil, nil) } @@ -49,6 +50,7 @@ func (h *Handler) UpdateBonusMultiplier(c *fiber.Ctx) error { var req struct { ID int64 `json:"id"` Multiplier float32 `json:"multiplier"` + BalanceCap int64 `json:"balance_cap"` } if err := c.BodyParser(&req); err != nil { @@ -56,7 +58,7 @@ func (h *Handler) UpdateBonusMultiplier(c *fiber.Ctx) error { return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil) } - if err := h.bonusSvc.UpdateBonusMultiplier(c.Context(), req.ID, req.Multiplier); err != nil { + if err := h.bonusSvc.UpdateBonusMultiplier(c.Context(), req.ID, req.Multiplier, req.BalanceCap); err != nil { h.logger.Error("failed to update bonus multiplier", "error", err) return response.WriteJSON(c, fiber.StatusInternalServerError, "failed to update bonus mulitplier", nil, nil) } diff --git a/internal/web_server/handlers/chapa.go b/internal/web_server/handlers/chapa.go index ddfb32d..3ec49db 100644 --- a/internal/web_server/handlers/chapa.go +++ b/internal/web_server/handlers/chapa.go @@ -2,6 +2,7 @@ package handlers import ( "fmt" + "math" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/gofiber/fiber/v2" @@ -66,7 +67,15 @@ func (h *Handler) InitiateDeposit(c *fiber.Ctx) error { multiplier = bonusMultiplier[0].Multiplier } - _, err = h.walletSvc.AddToWallet(c.Context(), wallet.StaticID, domain.ToCurrency(float32(amount)*multiplier), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}) + var balanceCap int64 = 0 + bonusBalanceCap, err := h.bonusSvc.GetBonusBalanceCap(c.Context()) + if err == nil { + balanceCap = bonusBalanceCap[0].BalanceCap + } + + capedBalanceAmount := domain.Currency((math.Min(req.Amount, float64(balanceCap)) * float64(multiplier)) * 100) + + _, err = h.walletSvc.AddToWallet(c.Context(), wallet.StaticID, capedBalanceAmount, domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}) if err != nil { h.logger.Error("Failed to add bonus to static wallet", "walletID", wallet.StaticID, "user id", userID, "error", err) return err