317 lines
11 KiB
Go
317 lines
11 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
|
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
type VirtualGameRepository interface {
|
|
CountVirtualGameProviders(ctx context.Context) (int64, error)
|
|
CreateVirtualGameProvider(ctx context.Context, arg dbgen.CreateVirtualGameProviderParams) (dbgen.VirtualGameProvider, error)
|
|
DeleteVirtualGameProvider(ctx context.Context, providerID string) error
|
|
GetVirtualGameProviderByID(ctx context.Context, providerID string) (dbgen.VirtualGameProvider, error)
|
|
ListVirtualGameProviders(ctx context.Context, limit, offset int32) ([]dbgen.VirtualGameProvider, error)
|
|
UpdateVirtualGameProviderEnabled(ctx context.Context, providerID string, enabled bool) (dbgen.VirtualGameProvider, error)
|
|
CreateVirtualGameSession(ctx context.Context, session *domain.VirtualGameSession) error
|
|
GetVirtualGameSessionByToken(ctx context.Context, token string) (*domain.VirtualGameSession, error)
|
|
UpdateVirtualGameSessionStatus(ctx context.Context, id int64, status string) error
|
|
CreateVirtualGameTransaction(ctx context.Context, tx *domain.VirtualGameTransaction) error
|
|
GetVirtualGameTransactionByExternalID(ctx context.Context, externalID string) (*domain.VirtualGameTransaction, error)
|
|
UpdateVirtualGameTransactionStatus(ctx context.Context, id int64, status string) error
|
|
// WithTransaction(ctx context.Context, fn func(ctx context.Context) error) error
|
|
AddFavoriteGame(ctx context.Context, userID, gameID int64) error
|
|
RemoveFavoriteGame(ctx context.Context, userID, gameID int64) error
|
|
ListFavoriteGames(ctx context.Context, userID int64) ([]int64, error)
|
|
|
|
GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error)
|
|
GetUserGameHistory(ctx context.Context, userID int64) ([]domain.VirtualGameHistory, error)
|
|
CreateVirtualGameHistory(ctx context.Context, his *domain.VirtualGameHistory) error
|
|
}
|
|
|
|
type VirtualGameRepo struct {
|
|
store *Store
|
|
}
|
|
|
|
// GetGameCounts implements VirtualGameRepository.
|
|
// func (r *VirtualGameRepo) GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total int64, active int64, inactive int64, err error) {
|
|
// panic("unimplemented")
|
|
// }
|
|
|
|
// func convertDBVirtualGameProvider(p dbgen.VirtualGameProvider) domain.VirtualGameProvider {
|
|
// var logoDark *string
|
|
// if p.LogoDark.Valid {
|
|
// logoDark = &p.LogoDark.String
|
|
// }
|
|
// var logoLight *string
|
|
// if p.LogoLight.Valid {
|
|
// logoLight = &p.LogoLight.String
|
|
// }
|
|
// return domain.VirtualGameProvider{
|
|
// // ID: p.ID,
|
|
// ProviderID: p.ProviderID,
|
|
// ProviderName: p.ProviderName,
|
|
// LogoDark: logoDark,
|
|
// LogoLight: logoLight,
|
|
// Enabled: p.Enabled,
|
|
// CreatedAt: p.CreatedAt.Time,
|
|
// UpdatedAt: &p.UpdatedAt.Time,
|
|
// }
|
|
// }
|
|
|
|
func ConvertCreateVirtualGameProvider(p domain.VirtualGameProvider) dbgen.CreateVirtualGameProviderParams {
|
|
return dbgen.CreateVirtualGameProviderParams{
|
|
ProviderID: p.ProviderID,
|
|
ProviderName: p.ProviderName,
|
|
LogoDark: pgtype.Text{String: func() string {
|
|
if p.LogoDark != nil {
|
|
return *p.LogoDark
|
|
}
|
|
return ""
|
|
}(), Valid: p.LogoDark != nil},
|
|
LogoLight: pgtype.Text{String: func() string {
|
|
if p.LogoLight != nil {
|
|
return *p.LogoLight
|
|
}
|
|
return ""
|
|
}(), Valid: p.LogoLight != nil},
|
|
Enabled: p.Enabled,
|
|
// CreatedAt: time.Now(),
|
|
}
|
|
}
|
|
|
|
func NewVirtualGameRepository(store *Store) VirtualGameRepository {
|
|
return &VirtualGameRepo{store: store}
|
|
}
|
|
|
|
func (r *VirtualGameRepo) CreateVirtualGameProvider(ctx context.Context, arg dbgen.CreateVirtualGameProviderParams) (dbgen.VirtualGameProvider, error) {
|
|
return r.store.queries.CreateVirtualGameProvider(ctx, arg)
|
|
}
|
|
|
|
func (r *VirtualGameRepo) DeleteVirtualGameProvider(ctx context.Context, providerID string) error {
|
|
return r.store.queries.DeleteVirtualGameProvider(ctx, providerID)
|
|
}
|
|
|
|
func (r *VirtualGameRepo) GetVirtualGameProviderByID(ctx context.Context, providerID string) (dbgen.VirtualGameProvider, error) {
|
|
return r.store.queries.GetVirtualGameProviderByID(ctx, providerID)
|
|
}
|
|
|
|
func (r *VirtualGameRepo) ListVirtualGameProviders(ctx context.Context, limit, offset int32) ([]dbgen.VirtualGameProvider, error) {
|
|
args := dbgen.ListVirtualGameProvidersParams{
|
|
Limit: limit,
|
|
Offset: offset,
|
|
}
|
|
return r.store.queries.ListVirtualGameProviders(ctx, args)
|
|
}
|
|
|
|
func (r *VirtualGameRepo) UpdateVirtualGameProviderEnabled(ctx context.Context, providerID string, enabled bool) (dbgen.VirtualGameProvider, error) {
|
|
params := dbgen.UpdateVirtualGameProviderEnabledParams{
|
|
ProviderID: providerID,
|
|
Enabled: enabled,
|
|
}
|
|
return r.store.queries.UpdateVirtualGameProviderEnabled(ctx, params)
|
|
}
|
|
|
|
func (r *VirtualGameRepo) AddFavoriteGame(ctx context.Context, userID, gameID int64) error {
|
|
params := dbgen.AddFavoriteGameParams{
|
|
UserID: userID,
|
|
GameID: gameID,
|
|
}
|
|
return r.store.queries.AddFavoriteGame(ctx, params)
|
|
}
|
|
|
|
func (r *VirtualGameRepo) RemoveFavoriteGame(ctx context.Context, userID, gameID int64) error {
|
|
params := dbgen.RemoveFavoriteGameParams{
|
|
UserID: userID,
|
|
GameID: gameID,
|
|
}
|
|
return r.store.queries.RemoveFavoriteGame(ctx, params)
|
|
}
|
|
|
|
func (r *VirtualGameRepo) ListFavoriteGames(ctx context.Context, userID int64) ([]int64, error) {
|
|
return r.store.queries.ListFavoriteGames(ctx, userID)
|
|
}
|
|
|
|
func (r *VirtualGameRepo) CountVirtualGameProviders(ctx context.Context) (int64, error) {
|
|
return r.store.queries.CountVirtualGameProviders(ctx)
|
|
}
|
|
|
|
func (r *VirtualGameRepo) CreateVirtualGameSession(ctx context.Context, session *domain.VirtualGameSession) error {
|
|
params := dbgen.CreateVirtualGameSessionParams{
|
|
UserID: session.UserID,
|
|
GameID: session.GameID,
|
|
SessionToken: session.SessionToken,
|
|
Currency: session.Currency,
|
|
Status: session.Status,
|
|
ExpiresAt: pgtype.Timestamptz{Time: session.ExpiresAt, Valid: true},
|
|
}
|
|
_, err := r.store.queries.CreateVirtualGameSession(ctx, params)
|
|
return err
|
|
}
|
|
|
|
func (r *VirtualGameRepo) GetVirtualGameSessionByToken(ctx context.Context, token string) (*domain.VirtualGameSession, error) {
|
|
dbSession, err := r.store.queries.GetVirtualGameSessionByToken(ctx, token)
|
|
if err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
return &domain.VirtualGameSession{
|
|
ID: dbSession.ID,
|
|
UserID: dbSession.UserID,
|
|
GameID: dbSession.GameID,
|
|
SessionToken: dbSession.SessionToken,
|
|
Currency: dbSession.Currency,
|
|
Status: dbSession.Status,
|
|
CreatedAt: dbSession.CreatedAt.Time,
|
|
UpdatedAt: dbSession.UpdatedAt.Time,
|
|
ExpiresAt: dbSession.ExpiresAt.Time,
|
|
}, nil
|
|
}
|
|
|
|
func (r *VirtualGameRepo) UpdateVirtualGameSessionStatus(ctx context.Context, id int64, status string) error {
|
|
return r.store.queries.UpdateVirtualGameSessionStatus(ctx, dbgen.UpdateVirtualGameSessionStatusParams{
|
|
ID: id,
|
|
Status: status,
|
|
})
|
|
}
|
|
|
|
func (r *VirtualGameRepo) CreateVirtualGameTransaction(ctx context.Context, tx *domain.VirtualGameTransaction) error {
|
|
params := dbgen.CreateVirtualGameTransactionParams{
|
|
SessionID: tx.SessionID,
|
|
UserID: tx.UserID,
|
|
WalletID: tx.WalletID,
|
|
TransactionType: tx.TransactionType,
|
|
Amount: tx.Amount,
|
|
Currency: tx.Currency,
|
|
ExternalTransactionID: tx.ExternalTransactionID,
|
|
Status: tx.Status,
|
|
}
|
|
_, err := r.store.queries.CreateVirtualGameTransaction(ctx, params)
|
|
return err
|
|
}
|
|
|
|
func (r *VirtualGameRepo) CreateVirtualGameHistory(ctx context.Context, his *domain.VirtualGameHistory) error {
|
|
params := dbgen.CreateVirtualGameHistoryParams{
|
|
SessionID: pgtype.Text{String: his.SessionID, Valid: true},
|
|
UserID: his.UserID,
|
|
// WalletID: pgtype.Int8{Int64: *his.WalletID, Valid: true},
|
|
TransactionType: his.TransactionType,
|
|
Amount: his.Amount,
|
|
Currency: his.Currency,
|
|
ExternalTransactionID: his.ExternalTransactionID,
|
|
Status: his.Status,
|
|
}
|
|
_, err := r.store.queries.CreateVirtualGameHistory(ctx, params)
|
|
return err
|
|
}
|
|
|
|
func (r *VirtualGameRepo) GetVirtualGameTransactionByExternalID(ctx context.Context, externalID string) (*domain.VirtualGameTransaction, error) {
|
|
dbTx, err := r.store.queries.GetVirtualGameTransactionByExternalID(ctx, externalID)
|
|
if err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
return &domain.VirtualGameTransaction{
|
|
ID: dbTx.ID,
|
|
SessionID: dbTx.SessionID,
|
|
UserID: dbTx.UserID,
|
|
WalletID: dbTx.WalletID,
|
|
TransactionType: dbTx.TransactionType,
|
|
Amount: dbTx.Amount,
|
|
Currency: dbTx.Currency,
|
|
ExternalTransactionID: dbTx.ExternalTransactionID,
|
|
Status: dbTx.Status,
|
|
CreatedAt: dbTx.CreatedAt.Time,
|
|
UpdatedAt: dbTx.UpdatedAt.Time,
|
|
}, nil
|
|
}
|
|
|
|
func (r *VirtualGameRepo) UpdateVirtualGameTransactionStatus(ctx context.Context, id int64, status string) error {
|
|
return r.store.queries.UpdateVirtualGameTransactionStatus(ctx, dbgen.UpdateVirtualGameTransactionStatusParams{
|
|
ID: id,
|
|
Status: status,
|
|
})
|
|
}
|
|
|
|
func (r *VirtualGameRepo) GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) {
|
|
query := `SELECT
|
|
COUNT(*) as total,
|
|
COUNT(CASE WHEN is_active = true THEN 1 END) as active,
|
|
COUNT(CASE WHEN is_active = false THEN 1 END) as inactive
|
|
FROM virtual_games`
|
|
|
|
args := []interface{}{}
|
|
argPos := 1
|
|
|
|
// Add filters if provided
|
|
if filter.StartTime.Valid {
|
|
query += fmt.Sprintf(" WHERE created_at >= $%d", argPos)
|
|
args = append(args, filter.StartTime.Value)
|
|
argPos++
|
|
}
|
|
if filter.EndTime.Valid {
|
|
query += fmt.Sprintf(" AND created_at <= $%d", argPos)
|
|
args = append(args, filter.EndTime.Value)
|
|
argPos++
|
|
}
|
|
|
|
row := r.store.conn.QueryRow(ctx, query, args...)
|
|
err = row.Scan(&total, &active, &inactive)
|
|
if err != nil {
|
|
return 0, 0, 0, fmt.Errorf("failed to get game counts: %w", err)
|
|
}
|
|
|
|
return total, active, inactive, nil
|
|
}
|
|
|
|
func (r *VirtualGameRepo) GetUserGameHistory(ctx context.Context, userID int64) ([]domain.VirtualGameHistory, error) {
|
|
query := `SELECT game_id FROM virtual_game_histories WHERE user_id = $1 AND transaction_type = 'BET' ORDER BY created_at DESC LIMIT 100`
|
|
rows, err := r.store.conn.Query(ctx, query, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var history []domain.VirtualGameHistory
|
|
for rows.Next() {
|
|
var tx domain.VirtualGameHistory
|
|
if err := rows.Scan(&tx.GameID); err == nil {
|
|
history = append(history, tx)
|
|
}
|
|
}
|
|
return history, nil
|
|
}
|
|
|
|
// func (r *VirtualGameRepo) WithTransaction(ctx context.Context, fn func(ctx context.Context) error) error {
|
|
// _, tx, err := r.store.BeginTx(ctx)
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
|
|
// txCtx := context.WithValue(ctx, contextTxKey, tx)
|
|
|
|
// defer func() {
|
|
// if p := recover(); p != nil {
|
|
// tx.Rollback(ctx)
|
|
// panic(p)
|
|
// }
|
|
// }()
|
|
|
|
// err = fn(txCtx)
|
|
// if err != nil {
|
|
// tx.Rollback(ctx)
|
|
// return err
|
|
// }
|
|
|
|
// return tx.Commit(ctx)
|
|
// }
|