virtual game provider report
This commit is contained in:
parent
4104d7d371
commit
e98477d6cc
10
cmd/main.go
10
cmd/main.go
|
|
@ -59,6 +59,7 @@ import (
|
|||
virtualgameservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame"
|
||||
alea "github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/Alea"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/atlas"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/orchestration"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/veli"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet/monitor"
|
||||
|
|
@ -153,6 +154,12 @@ func main() {
|
|||
aleaService := alea.NewAleaPlayService(vitualGameRepo, *walletSvc, cfg, logger)
|
||||
veliCLient := veli.NewClient(cfg, walletSvc)
|
||||
veliVirtualGameService := veli.New(virtualGameSvc, vitualGameRepo, veliCLient, walletSvc, wallet.TransferStore(store), domain.MongoDBLogger, cfg)
|
||||
orchestrationSvc := orchestration.New(
|
||||
virtualGameSvc,
|
||||
virtuaGamesRepo,
|
||||
cfg,
|
||||
veliCLient,
|
||||
)
|
||||
atlasClient := atlas.NewClient(cfg, walletSvc)
|
||||
atlasVirtualGameService := atlas.New(virtualGameSvc, vitualGameRepo, atlasClient, walletSvc, wallet.TransferStore(store), cfg)
|
||||
recommendationSvc := recommendation.NewService(recommendationRepo)
|
||||
|
|
@ -194,7 +201,7 @@ func main() {
|
|||
)
|
||||
|
||||
go httpserver.StartEnetPulseCron(enePulseSvc, domain.MongoDBLogger)
|
||||
go httpserver.SetupReportandVirtualGameCronJobs(context.Background(), reportSvc, veliVirtualGameService, "C:/Users/User/Desktop")
|
||||
go httpserver.SetupReportandVirtualGameCronJobs(context.Background(), reportSvc, orchestrationSvc, "C:/Users/User/Desktop")
|
||||
go httpserver.ProcessBetCashback(context.TODO(), betSvc)
|
||||
|
||||
bankRepository := repository.NewBankRepository(store)
|
||||
|
|
@ -259,6 +266,7 @@ func main() {
|
|||
enetPulseSvc,
|
||||
atlasVirtualGameService,
|
||||
veliVirtualGameService,
|
||||
orchestrationSvc,
|
||||
telebirrSvc,
|
||||
arifpaySvc,
|
||||
santimpaySvc,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,24 @@ CREATE TABLE IF NOT EXISTS virtual_game_providers (
|
|||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS virtual_game_provider_reports (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
provider_id VARCHAR(100) NOT NULL REFERENCES virtual_game_providers(provider_id) ON DELETE CASCADE,
|
||||
report_date DATE NOT NULL,
|
||||
total_games_played BIGINT DEFAULT 0,
|
||||
total_bets NUMERIC(18,2) DEFAULT 0,
|
||||
total_payouts NUMERIC(18,2) DEFAULT 0,
|
||||
total_profit NUMERIC(18,2) GENERATED ALWAYS AS (total_bets - total_payouts) STORED,
|
||||
total_players BIGINT DEFAULT 0,
|
||||
report_type VARCHAR(50) DEFAULT 'daily',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_unique_provider_report
|
||||
ON virtual_game_provider_reports (provider_id, report_date, report_type);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS virtual_games (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
game_id VARCHAR(150) NOT NULL,
|
||||
|
|
@ -54,6 +72,25 @@ CREATE TABLE IF NOT EXISTS virtual_games (
|
|||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_virtual_games_provider_game ON virtual_games (provider_id, game_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS virtual_game_reports (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
game_id VARCHAR(150) NOT NULL REFERENCES virtual_games(game_id) ON DELETE CASCADE,
|
||||
provider_id VARCHAR(100) NOT NULL REFERENCES virtual_game_providers(provider_id) ON DELETE CASCADE,
|
||||
report_date DATE NOT NULL,
|
||||
total_rounds BIGINT DEFAULT 0,
|
||||
total_bets NUMERIC(18,2) DEFAULT 0,
|
||||
total_payouts NUMERIC(18,2) DEFAULT 0,
|
||||
total_profit NUMERIC(18,2) GENERATED ALWAYS AS (total_bets - total_payouts) STORED,
|
||||
total_players BIGINT DEFAULT 0,
|
||||
report_type VARCHAR(50) DEFAULT 'daily',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_unique_game_report
|
||||
ON virtual_game_reports (game_id, report_date, report_type);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS wallets (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
balance BIGINT NOT NULL DEFAULT 0,
|
||||
|
|
|
|||
|
|
@ -288,3 +288,86 @@ ORDER BY vg.created_at DESC
|
|||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: DeleteAllVirtualGames :exec
|
||||
DELETE FROM virtual_games;
|
||||
|
||||
|
||||
-- name: CreateVirtualGameProviderReport :one
|
||||
INSERT INTO virtual_game_provider_reports (
|
||||
provider_id,
|
||||
report_date,
|
||||
total_games_played,
|
||||
total_bets,
|
||||
total_payouts,
|
||||
total_players,
|
||||
report_type,
|
||||
created_at,
|
||||
updated_at
|
||||
) VALUES (
|
||||
$1, $2, $3, $4, $5, $6, COALESCE($7, 'daily'), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
|
||||
)
|
||||
ON CONFLICT (provider_id, report_date, report_type) DO UPDATE
|
||||
SET
|
||||
total_games_played = EXCLUDED.total_games_played,
|
||||
total_bets = EXCLUDED.total_bets,
|
||||
total_payouts = EXCLUDED.total_payouts,
|
||||
total_players = EXCLUDED.total_players,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
RETURNING *;
|
||||
|
||||
|
||||
-- name: CreateVirtualGameReport :one
|
||||
INSERT INTO virtual_game_reports (
|
||||
game_id,
|
||||
provider_id,
|
||||
report_date,
|
||||
total_rounds,
|
||||
total_bets,
|
||||
total_payouts,
|
||||
total_players,
|
||||
report_type,
|
||||
created_at,
|
||||
updated_at
|
||||
) VALUES (
|
||||
$1, $2, $3, $4, $5, $6, $7, COALESCE($8, 'daily'), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
|
||||
)
|
||||
ON CONFLICT (game_id, report_date, report_type) DO UPDATE
|
||||
SET
|
||||
total_rounds = EXCLUDED.total_rounds,
|
||||
total_bets = EXCLUDED.total_bets,
|
||||
total_payouts = EXCLUDED.total_payouts,
|
||||
total_players = EXCLUDED.total_players,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetVirtualGameProviderReportByProviderAndDate :one
|
||||
SELECT *
|
||||
FROM virtual_game_provider_reports
|
||||
WHERE provider_id = $1
|
||||
AND report_date = $2
|
||||
AND report_type = $3;
|
||||
|
||||
-- name: UpdateVirtualGameProviderReportByDate :exec
|
||||
UPDATE virtual_game_provider_reports
|
||||
SET
|
||||
total_games_played = total_games_played + $4,
|
||||
total_bets = total_bets + $5,
|
||||
total_payouts = total_payouts + $6,
|
||||
total_players = total_players + $7,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE
|
||||
provider_id = $1
|
||||
AND report_date = $2
|
||||
AND report_type = $3;
|
||||
|
||||
-- name: ListVirtualGameProviderReportsByGamesPlayedAsc :many
|
||||
SELECT *
|
||||
FROM virtual_game_provider_reports
|
||||
ORDER BY total_games_played ASC;
|
||||
|
||||
-- name: ListVirtualGameProviderReportsByGamesPlayedDesc :many
|
||||
SELECT *
|
||||
FROM virtual_game_provider_reports
|
||||
ORDER BY total_games_played DESC;
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
90
docs/docs.go
90
docs/docs.go
|
|
@ -4627,6 +4627,58 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/orchestrator/virtual-game/provider-reports/asc": {
|
||||
"get": {
|
||||
"description": "Retrieves all virtual game provider reports sorted by total_games_played in ascending order",
|
||||
"tags": [
|
||||
"VirtualGames - Orchestration"
|
||||
],
|
||||
"summary": "List virtual game provider reports (ascending)",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/domain.VirtualGameProviderReport"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/orchestrator/virtual-game/provider-reports/desc": {
|
||||
"get": {
|
||||
"description": "Retrieves all virtual game provider reports sorted by total_games_played in descending order",
|
||||
"tags": [
|
||||
"VirtualGames - Orchestration"
|
||||
],
|
||||
"summary": "List virtual game provider reports (descending)",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/domain.VirtualGameProviderReport"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/orchestrator/virtual-games": {
|
||||
"get": {
|
||||
"description": "Returns all virtual games with optional filters (category, search, pagination)",
|
||||
|
|
@ -13452,6 +13504,44 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.VirtualGameProviderReport": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"provider_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"report_date": {
|
||||
"type": "string"
|
||||
},
|
||||
"report_type": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_bets": {
|
||||
"type": "number"
|
||||
},
|
||||
"total_games_played": {
|
||||
"type": "integer"
|
||||
},
|
||||
"total_payouts": {
|
||||
"type": "number"
|
||||
},
|
||||
"total_players": {
|
||||
"type": "integer"
|
||||
},
|
||||
"total_profit": {
|
||||
"type": "number"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.WebhookRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
|||
|
|
@ -4619,6 +4619,58 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/orchestrator/virtual-game/provider-reports/asc": {
|
||||
"get": {
|
||||
"description": "Retrieves all virtual game provider reports sorted by total_games_played in ascending order",
|
||||
"tags": [
|
||||
"VirtualGames - Orchestration"
|
||||
],
|
||||
"summary": "List virtual game provider reports (ascending)",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/domain.VirtualGameProviderReport"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/orchestrator/virtual-game/provider-reports/desc": {
|
||||
"get": {
|
||||
"description": "Retrieves all virtual game provider reports sorted by total_games_played in descending order",
|
||||
"tags": [
|
||||
"VirtualGames - Orchestration"
|
||||
],
|
||||
"summary": "List virtual game provider reports (descending)",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/domain.VirtualGameProviderReport"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/orchestrator/virtual-games": {
|
||||
"get": {
|
||||
"description": "Returns all virtual games with optional filters (category, search, pagination)",
|
||||
|
|
@ -13444,6 +13496,44 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.VirtualGameProviderReport": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"provider_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"report_date": {
|
||||
"type": "string"
|
||||
},
|
||||
"report_type": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_bets": {
|
||||
"type": "number"
|
||||
},
|
||||
"total_games_played": {
|
||||
"type": "integer"
|
||||
},
|
||||
"total_payouts": {
|
||||
"type": "number"
|
||||
},
|
||||
"total_players": {
|
||||
"type": "integer"
|
||||
},
|
||||
"total_profit": {
|
||||
"type": "number"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.WebhookRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
|||
|
|
@ -2431,6 +2431,31 @@ definitions:
|
|||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
domain.VirtualGameProviderReport:
|
||||
properties:
|
||||
created_at:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
provider_id:
|
||||
type: string
|
||||
report_date:
|
||||
type: string
|
||||
report_type:
|
||||
type: string
|
||||
total_bets:
|
||||
type: number
|
||||
total_games_played:
|
||||
type: integer
|
||||
total_payouts:
|
||||
type: number
|
||||
total_players:
|
||||
type: integer
|
||||
total_profit:
|
||||
type: number
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
domain.WebhookRequest:
|
||||
properties:
|
||||
nonce:
|
||||
|
|
@ -7167,6 +7192,42 @@ paths:
|
|||
summary: Create a operation
|
||||
tags:
|
||||
- branch
|
||||
/api/v1/orchestrator/virtual-game/provider-reports/asc:
|
||||
get:
|
||||
description: Retrieves all virtual game provider reports sorted by total_games_played
|
||||
in ascending order
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/domain.VirtualGameProviderReport'
|
||||
type: array
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/domain.ErrorResponse'
|
||||
summary: List virtual game provider reports (ascending)
|
||||
tags:
|
||||
- VirtualGames - Orchestration
|
||||
/api/v1/orchestrator/virtual-game/provider-reports/desc:
|
||||
get:
|
||||
description: Retrieves all virtual game provider reports sorted by total_games_played
|
||||
in descending order
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/domain.VirtualGameProviderReport'
|
||||
type: array
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/domain.ErrorResponse'
|
||||
summary: List virtual game provider reports (descending)
|
||||
tags:
|
||||
- VirtualGames - Orchestration
|
||||
/api/v1/orchestrator/virtual-games:
|
||||
get:
|
||||
consumes:
|
||||
|
|
|
|||
|
|
@ -1063,6 +1063,35 @@ type VirtualGameProvider struct {
|
|||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
type VirtualGameProviderReport struct {
|
||||
ID int64 `json:"id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
TotalGamesPlayed pgtype.Int8 `json:"total_games_played"`
|
||||
TotalBets pgtype.Numeric `json:"total_bets"`
|
||||
TotalPayouts pgtype.Numeric `json:"total_payouts"`
|
||||
TotalProfit pgtype.Numeric `json:"total_profit"`
|
||||
TotalPlayers pgtype.Int8 `json:"total_players"`
|
||||
ReportType pgtype.Text `json:"report_type"`
|
||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
type VirtualGameReport struct {
|
||||
ID int64 `json:"id"`
|
||||
GameID string `json:"game_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
TotalRounds pgtype.Int8 `json:"total_rounds"`
|
||||
TotalBets pgtype.Numeric `json:"total_bets"`
|
||||
TotalPayouts pgtype.Numeric `json:"total_payouts"`
|
||||
TotalProfit pgtype.Numeric `json:"total_profit"`
|
||||
TotalPlayers pgtype.Int8 `json:"total_players"`
|
||||
ReportType pgtype.Text `json:"report_type"`
|
||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
type VirtualGameSession struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID int64 `json:"user_id"`
|
||||
|
|
|
|||
|
|
@ -281,6 +281,132 @@ func (q *Queries) CreateVirtualGameProvider(ctx context.Context, arg CreateVirtu
|
|||
return i, err
|
||||
}
|
||||
|
||||
const CreateVirtualGameProviderReport = `-- name: CreateVirtualGameProviderReport :one
|
||||
INSERT INTO virtual_game_provider_reports (
|
||||
provider_id,
|
||||
report_date,
|
||||
total_games_played,
|
||||
total_bets,
|
||||
total_payouts,
|
||||
total_players,
|
||||
report_type,
|
||||
created_at,
|
||||
updated_at
|
||||
) VALUES (
|
||||
$1, $2, $3, $4, $5, $6, COALESCE($7, 'daily'), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
|
||||
)
|
||||
ON CONFLICT (provider_id, report_date, report_type) DO UPDATE
|
||||
SET
|
||||
total_games_played = EXCLUDED.total_games_played,
|
||||
total_bets = EXCLUDED.total_bets,
|
||||
total_payouts = EXCLUDED.total_payouts,
|
||||
total_players = EXCLUDED.total_players,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
RETURNING id, provider_id, report_date, total_games_played, total_bets, total_payouts, total_profit, total_players, report_type, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateVirtualGameProviderReportParams struct {
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
TotalGamesPlayed pgtype.Int8 `json:"total_games_played"`
|
||||
TotalBets pgtype.Numeric `json:"total_bets"`
|
||||
TotalPayouts pgtype.Numeric `json:"total_payouts"`
|
||||
TotalPlayers pgtype.Int8 `json:"total_players"`
|
||||
Column7 interface{} `json:"column_7"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateVirtualGameProviderReport(ctx context.Context, arg CreateVirtualGameProviderReportParams) (VirtualGameProviderReport, error) {
|
||||
row := q.db.QueryRow(ctx, CreateVirtualGameProviderReport,
|
||||
arg.ProviderID,
|
||||
arg.ReportDate,
|
||||
arg.TotalGamesPlayed,
|
||||
arg.TotalBets,
|
||||
arg.TotalPayouts,
|
||||
arg.TotalPlayers,
|
||||
arg.Column7,
|
||||
)
|
||||
var i VirtualGameProviderReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.TotalGamesPlayed,
|
||||
&i.TotalBets,
|
||||
&i.TotalPayouts,
|
||||
&i.TotalProfit,
|
||||
&i.TotalPlayers,
|
||||
&i.ReportType,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const CreateVirtualGameReport = `-- name: CreateVirtualGameReport :one
|
||||
INSERT INTO virtual_game_reports (
|
||||
game_id,
|
||||
provider_id,
|
||||
report_date,
|
||||
total_rounds,
|
||||
total_bets,
|
||||
total_payouts,
|
||||
total_players,
|
||||
report_type,
|
||||
created_at,
|
||||
updated_at
|
||||
) VALUES (
|
||||
$1, $2, $3, $4, $5, $6, $7, COALESCE($8, 'daily'), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
|
||||
)
|
||||
ON CONFLICT (game_id, report_date, report_type) DO UPDATE
|
||||
SET
|
||||
total_rounds = EXCLUDED.total_rounds,
|
||||
total_bets = EXCLUDED.total_bets,
|
||||
total_payouts = EXCLUDED.total_payouts,
|
||||
total_players = EXCLUDED.total_players,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
RETURNING id, game_id, provider_id, report_date, total_rounds, total_bets, total_payouts, total_profit, total_players, report_type, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateVirtualGameReportParams struct {
|
||||
GameID string `json:"game_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
TotalRounds pgtype.Int8 `json:"total_rounds"`
|
||||
TotalBets pgtype.Numeric `json:"total_bets"`
|
||||
TotalPayouts pgtype.Numeric `json:"total_payouts"`
|
||||
TotalPlayers pgtype.Int8 `json:"total_players"`
|
||||
Column8 interface{} `json:"column_8"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateVirtualGameReport(ctx context.Context, arg CreateVirtualGameReportParams) (VirtualGameReport, error) {
|
||||
row := q.db.QueryRow(ctx, CreateVirtualGameReport,
|
||||
arg.GameID,
|
||||
arg.ProviderID,
|
||||
arg.ReportDate,
|
||||
arg.TotalRounds,
|
||||
arg.TotalBets,
|
||||
arg.TotalPayouts,
|
||||
arg.TotalPlayers,
|
||||
arg.Column8,
|
||||
)
|
||||
var i VirtualGameReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.GameID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.TotalRounds,
|
||||
&i.TotalBets,
|
||||
&i.TotalPayouts,
|
||||
&i.TotalProfit,
|
||||
&i.TotalPlayers,
|
||||
&i.ReportType,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const CreateVirtualGameSession = `-- name: CreateVirtualGameSession :one
|
||||
INSERT INTO virtual_game_sessions (
|
||||
user_id,
|
||||
|
|
@ -587,6 +713,39 @@ func (q *Queries) GetVirtualGameProviderByID(ctx context.Context, providerID str
|
|||
return i, err
|
||||
}
|
||||
|
||||
const GetVirtualGameProviderReportByProviderAndDate = `-- name: GetVirtualGameProviderReportByProviderAndDate :one
|
||||
SELECT id, provider_id, report_date, total_games_played, total_bets, total_payouts, total_profit, total_players, report_type, created_at, updated_at
|
||||
FROM virtual_game_provider_reports
|
||||
WHERE provider_id = $1
|
||||
AND report_date = $2
|
||||
AND report_type = $3
|
||||
`
|
||||
|
||||
type GetVirtualGameProviderReportByProviderAndDateParams struct {
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType pgtype.Text `json:"report_type"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetVirtualGameProviderReportByProviderAndDate(ctx context.Context, arg GetVirtualGameProviderReportByProviderAndDateParams) (VirtualGameProviderReport, error) {
|
||||
row := q.db.QueryRow(ctx, GetVirtualGameProviderReportByProviderAndDate, arg.ProviderID, arg.ReportDate, arg.ReportType)
|
||||
var i VirtualGameProviderReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.TotalGamesPlayed,
|
||||
&i.TotalBets,
|
||||
&i.TotalPayouts,
|
||||
&i.TotalProfit,
|
||||
&i.TotalPlayers,
|
||||
&i.ReportType,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const GetVirtualGameSessionByToken = `-- name: GetVirtualGameSessionByToken :one
|
||||
SELECT id,
|
||||
user_id,
|
||||
|
|
@ -745,6 +904,82 @@ func (q *Queries) ListFavoriteGames(ctx context.Context, userID int64) ([]int64,
|
|||
return items, nil
|
||||
}
|
||||
|
||||
const ListVirtualGameProviderReportsByGamesPlayedAsc = `-- name: ListVirtualGameProviderReportsByGamesPlayedAsc :many
|
||||
SELECT id, provider_id, report_date, total_games_played, total_bets, total_payouts, total_profit, total_players, report_type, created_at, updated_at
|
||||
FROM virtual_game_provider_reports
|
||||
ORDER BY total_games_played ASC
|
||||
`
|
||||
|
||||
func (q *Queries) ListVirtualGameProviderReportsByGamesPlayedAsc(ctx context.Context) ([]VirtualGameProviderReport, error) {
|
||||
rows, err := q.db.Query(ctx, ListVirtualGameProviderReportsByGamesPlayedAsc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []VirtualGameProviderReport
|
||||
for rows.Next() {
|
||||
var i VirtualGameProviderReport
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.TotalGamesPlayed,
|
||||
&i.TotalBets,
|
||||
&i.TotalPayouts,
|
||||
&i.TotalProfit,
|
||||
&i.TotalPlayers,
|
||||
&i.ReportType,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const ListVirtualGameProviderReportsByGamesPlayedDesc = `-- name: ListVirtualGameProviderReportsByGamesPlayedDesc :many
|
||||
SELECT id, provider_id, report_date, total_games_played, total_bets, total_payouts, total_profit, total_players, report_type, created_at, updated_at
|
||||
FROM virtual_game_provider_reports
|
||||
ORDER BY total_games_played DESC
|
||||
`
|
||||
|
||||
func (q *Queries) ListVirtualGameProviderReportsByGamesPlayedDesc(ctx context.Context) ([]VirtualGameProviderReport, error) {
|
||||
rows, err := q.db.Query(ctx, ListVirtualGameProviderReportsByGamesPlayedDesc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []VirtualGameProviderReport
|
||||
for rows.Next() {
|
||||
var i VirtualGameProviderReport
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.TotalGamesPlayed,
|
||||
&i.TotalBets,
|
||||
&i.TotalPayouts,
|
||||
&i.TotalProfit,
|
||||
&i.TotalPlayers,
|
||||
&i.ReportType,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const ListVirtualGameProviders = `-- name: ListVirtualGameProviders :many
|
||||
SELECT id,
|
||||
provider_id,
|
||||
|
|
@ -845,6 +1080,43 @@ func (q *Queries) UpdateVirtualGameProviderEnabled(ctx context.Context, arg Upda
|
|||
return i, err
|
||||
}
|
||||
|
||||
const UpdateVirtualGameProviderReportByDate = `-- name: UpdateVirtualGameProviderReportByDate :exec
|
||||
UPDATE virtual_game_provider_reports
|
||||
SET
|
||||
total_games_played = total_games_played + $4,
|
||||
total_bets = total_bets + $5,
|
||||
total_payouts = total_payouts + $6,
|
||||
total_players = total_players + $7,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE
|
||||
provider_id = $1
|
||||
AND report_date = $2
|
||||
AND report_type = $3
|
||||
`
|
||||
|
||||
type UpdateVirtualGameProviderReportByDateParams struct {
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType pgtype.Text `json:"report_type"`
|
||||
TotalGamesPlayed pgtype.Int8 `json:"total_games_played"`
|
||||
TotalBets pgtype.Numeric `json:"total_bets"`
|
||||
TotalPayouts pgtype.Numeric `json:"total_payouts"`
|
||||
TotalPlayers pgtype.Int8 `json:"total_players"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateVirtualGameProviderReportByDate(ctx context.Context, arg UpdateVirtualGameProviderReportByDateParams) error {
|
||||
_, err := q.db.Exec(ctx, UpdateVirtualGameProviderReportByDate,
|
||||
arg.ProviderID,
|
||||
arg.ReportDate,
|
||||
arg.ReportType,
|
||||
arg.TotalGamesPlayed,
|
||||
arg.TotalBets,
|
||||
arg.TotalPayouts,
|
||||
arg.TotalPlayers,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const UpdateVirtualGameSessionStatus = `-- name: UpdateVirtualGameSessionStatus :exec
|
||||
UPDATE virtual_game_sessions
|
||||
SET status = $2,
|
||||
|
|
|
|||
|
|
@ -316,3 +316,61 @@ type UnifiedGame struct {
|
|||
Status int `json:"status,omitempty"`
|
||||
DemoURL string `json:"demoUrl"`
|
||||
}
|
||||
|
||||
type CreateVirtualGameProviderReport struct {
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate time.Time `json:"report_date"`
|
||||
TotalGamesPlayed int64 `json:"total_games_played"`
|
||||
TotalBets float64 `json:"total_bets"`
|
||||
TotalPayouts float64 `json:"total_payouts"`
|
||||
TotalPlayers int64 `json:"total_players"`
|
||||
ReportType string `json:"report_type"` // e.g., "daily", "weekly"
|
||||
}
|
||||
|
||||
type VirtualGameProviderReport struct {
|
||||
ID int64 `json:"id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate time.Time `json:"report_date"`
|
||||
TotalGamesPlayed int64 `json:"total_games_played"`
|
||||
TotalBets float64 `json:"total_bets"`
|
||||
TotalPayouts float64 `json:"total_payouts"`
|
||||
TotalProfit float64 `json:"total_profit"`
|
||||
TotalPlayers int64 `json:"total_players"`
|
||||
ReportType string `json:"report_type"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type CreateVirtualGameReport struct {
|
||||
GameID string `json:"game_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate time.Time `json:"report_date"`
|
||||
TotalRounds int64 `json:"total_rounds"`
|
||||
TotalBets float64 `json:"total_bets"`
|
||||
TotalPayouts float64 `json:"total_payouts"`
|
||||
TotalPlayers int64 `json:"total_players"`
|
||||
ReportType string `json:"report_type"` // e.g., "daily", "weekly"
|
||||
}
|
||||
|
||||
type VirtualGameReport struct {
|
||||
ID int64 `json:"id"`
|
||||
GameID string `json:"game_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate time.Time `json:"report_date"`
|
||||
TotalRounds int64 `json:"total_rounds"`
|
||||
TotalBets float64 `json:"total_bets"`
|
||||
TotalPayouts float64 `json:"total_payouts"`
|
||||
TotalProfit float64 `json:"total_profit"`
|
||||
TotalPlayers int64 `json:"total_players"`
|
||||
ReportType string `json:"report_type"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type CreateVirtualGameProviderReportsRequest struct {
|
||||
Reports []CreateVirtualGameProviderReport
|
||||
}
|
||||
|
||||
type CreateVirtualGameReportsRequest struct {
|
||||
Reports []CreateVirtualGameReport
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import (
|
|||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
|
|
@ -36,6 +38,12 @@ type VirtualGameRepository interface {
|
|||
CreateVirtualGame(ctx context.Context, arg dbgen.CreateVirtualGameParams) (dbgen.VirtualGame, error)
|
||||
ListAllVirtualGames(ctx context.Context, arg dbgen.GetAllVirtualGamesParams) ([]dbgen.GetAllVirtualGamesRow, error)
|
||||
RemoveAllVirtualGames(ctx context.Context) error
|
||||
CreateVirtualGameProviderReport(ctx context.Context, report domain.CreateVirtualGameProviderReport) (domain.VirtualGameProviderReport, error)
|
||||
CreateVirtualGameReport(ctx context.Context, report domain.CreateVirtualGameReport) (domain.VirtualGameReport, error)
|
||||
GetVirtualGameProviderReportByProviderAndDate(ctx context.Context, providerID string, createdAt time.Time, reportType string) (domain.VirtualGameProviderReport, error)
|
||||
UpdateVirtualGameProviderReportByDate(ctx context.Context, providerID string, reportDate time.Time, reportType string, totalGamesPlayed int64, totalBets float64, totalPayouts float64, totalPlayers int64) error
|
||||
ListVirtualGameProviderReportsByGamesPlayedAsc(ctx context.Context) ([]domain.VirtualGameProviderReport, error)
|
||||
ListVirtualGameProviderReportsByGamesPlayedDesc(ctx context.Context) ([]domain.VirtualGameProviderReport, error)
|
||||
}
|
||||
|
||||
type VirtualGameRepo struct {
|
||||
|
|
@ -314,3 +322,183 @@ func (r *VirtualGameRepo) ListAllVirtualGames(ctx context.Context, arg dbgen.Get
|
|||
func (r *VirtualGameRepo) RemoveAllVirtualGames(ctx context.Context) error {
|
||||
return r.store.queries.DeleteAllVirtualGames(ctx)
|
||||
}
|
||||
|
||||
func (r *VirtualGameRepo) CreateVirtualGameProviderReport(
|
||||
ctx context.Context,
|
||||
report domain.CreateVirtualGameProviderReport,
|
||||
) (domain.VirtualGameProviderReport, error) {
|
||||
dbReport, err := r.store.queries.CreateVirtualGameProviderReport(
|
||||
ctx,
|
||||
ConvertCreateVirtualGameProviderReport(report),
|
||||
)
|
||||
if err != nil {
|
||||
return domain.VirtualGameProviderReport{}, err
|
||||
}
|
||||
|
||||
return ConvertDBVirtualGameProviderReport(dbReport), nil
|
||||
}
|
||||
|
||||
func (r *VirtualGameRepo) CreateVirtualGameReport(
|
||||
ctx context.Context,
|
||||
report domain.CreateVirtualGameReport,
|
||||
) (domain.VirtualGameReport, error) {
|
||||
dbReport, err := r.store.queries.CreateVirtualGameReport(
|
||||
ctx,
|
||||
ConvertCreateVirtualGameReport(report),
|
||||
)
|
||||
if err != nil {
|
||||
return domain.VirtualGameReport{}, err
|
||||
}
|
||||
|
||||
return ConvertDBVirtualGameReport(dbReport), nil
|
||||
}
|
||||
|
||||
func (r *VirtualGameRepo) GetVirtualGameProviderReportByProviderAndDate(
|
||||
ctx context.Context,
|
||||
providerID string,
|
||||
reportDate time.Time,
|
||||
reportType string,
|
||||
) (domain.VirtualGameProviderReport, error) {
|
||||
arg := dbgen.GetVirtualGameProviderReportByProviderAndDateParams{
|
||||
ProviderID: providerID,
|
||||
ReportDate: pgtype.Date{Time: reportDate, Valid: true},
|
||||
ReportType: pgtype.Text{String: reportType, Valid: true},
|
||||
}
|
||||
|
||||
dbReport, err := r.store.queries.GetVirtualGameProviderReportByProviderAndDate(ctx, arg)
|
||||
if err != nil {
|
||||
return domain.VirtualGameProviderReport{}, err
|
||||
}
|
||||
|
||||
return ConvertDBVirtualGameProviderReport(dbReport), nil
|
||||
}
|
||||
|
||||
func (r *VirtualGameRepo) UpdateVirtualGameProviderReportByDate(
|
||||
ctx context.Context,
|
||||
providerID string,
|
||||
reportDate time.Time,
|
||||
reportType string,
|
||||
totalGamesPlayed int64,
|
||||
totalBets float64,
|
||||
totalPayouts float64,
|
||||
totalPlayers int64,
|
||||
) error {
|
||||
arg := dbgen.UpdateVirtualGameProviderReportByDateParams{
|
||||
ProviderID: providerID,
|
||||
ReportDate: pgtype.Date{Time: reportDate, Valid: true},
|
||||
ReportType: pgtype.Text{String: reportType, Valid: true},
|
||||
TotalGamesPlayed: pgtype.Int8{Int64: totalGamesPlayed, Valid: true},
|
||||
TotalBets: pgtype.Numeric{},
|
||||
TotalPayouts: pgtype.Numeric{},
|
||||
TotalPlayers: pgtype.Int8{Int64: totalPlayers, Valid: true},
|
||||
}
|
||||
|
||||
// Safely convert float64 → pgtype.Numeric
|
||||
if err := arg.TotalBets.Scan(totalBets); err != nil {
|
||||
return fmt.Errorf("failed to set total_bets: %w", err)
|
||||
}
|
||||
if err := arg.TotalPayouts.Scan(totalPayouts); err != nil {
|
||||
return fmt.Errorf("failed to set total_payouts: %w", err)
|
||||
}
|
||||
|
||||
if err := r.store.queries.UpdateVirtualGameProviderReportByDate(ctx, arg); err != nil {
|
||||
return fmt.Errorf("failed to update provider report for %s: %w", providerID, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *VirtualGameRepo) ListVirtualGameProviderReportsByGamesPlayedAsc(
|
||||
ctx context.Context,
|
||||
) ([]domain.VirtualGameProviderReport, error) {
|
||||
dbReports, err := r.store.queries.ListVirtualGameProviderReportsByGamesPlayedAsc(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reports := make([]domain.VirtualGameProviderReport, len(dbReports))
|
||||
for i, r := range dbReports {
|
||||
reports[i] = ConvertDBVirtualGameProviderReport(r)
|
||||
}
|
||||
|
||||
return reports, nil
|
||||
}
|
||||
|
||||
func (r *VirtualGameRepo) ListVirtualGameProviderReportsByGamesPlayedDesc(
|
||||
ctx context.Context,
|
||||
) ([]domain.VirtualGameProviderReport, error) {
|
||||
dbReports, err := r.store.queries.ListVirtualGameProviderReportsByGamesPlayedDesc(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reports := make([]domain.VirtualGameProviderReport, len(dbReports))
|
||||
for i, r := range dbReports {
|
||||
reports[i] = ConvertDBVirtualGameProviderReport(r)
|
||||
}
|
||||
|
||||
return reports, nil
|
||||
}
|
||||
|
||||
func ConvertCreateVirtualGameProviderReport(r domain.CreateVirtualGameProviderReport) dbgen.CreateVirtualGameProviderReportParams {
|
||||
// var totalBets, totalPayouts pgtype.Numeric
|
||||
|
||||
// _ = r.TotalBets.
|
||||
// _ = totalPayouts.Set(r.TotalPayouts)
|
||||
|
||||
return dbgen.CreateVirtualGameProviderReportParams{
|
||||
ProviderID: r.ProviderID,
|
||||
ReportDate: pgtype.Date{Time: r.ReportDate, Valid: true},
|
||||
TotalGamesPlayed: pgtype.Int8{Int64: r.TotalGamesPlayed, Valid: true},
|
||||
TotalBets: pgtype.Numeric{Exp: int32(r.TotalBets)},
|
||||
TotalPayouts: pgtype.Numeric{Exp: int32(r.TotalPayouts)},
|
||||
TotalPlayers: pgtype.Int8{Int64: r.TotalPlayers, Valid: true},
|
||||
Column7: pgtype.Text{String: r.ReportType, Valid: true},
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBVirtualGameProviderReport(db dbgen.VirtualGameProviderReport) domain.VirtualGameProviderReport {
|
||||
return domain.VirtualGameProviderReport{
|
||||
ID: db.ID,
|
||||
ProviderID: db.ProviderID,
|
||||
ReportDate: db.ReportDate.Time,
|
||||
TotalGamesPlayed: db.TotalGamesPlayed.Int64,
|
||||
TotalBets: float64(db.TotalBets.Exp),
|
||||
TotalPayouts: float64(db.TotalPayouts.Exp),
|
||||
TotalProfit: float64(db.TotalProfit.Exp),
|
||||
TotalPlayers: db.TotalPlayers.Int64,
|
||||
ReportType: db.ReportType.String,
|
||||
CreatedAt: db.CreatedAt.Time,
|
||||
UpdatedAt: db.UpdatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCreateVirtualGameReport(r domain.CreateVirtualGameReport) dbgen.CreateVirtualGameReportParams {
|
||||
return dbgen.CreateVirtualGameReportParams{
|
||||
GameID: r.GameID,
|
||||
ProviderID: r.ProviderID,
|
||||
ReportDate: pgtype.Date{Time: r.ReportDate},
|
||||
TotalRounds: pgtype.Int8{Int64: r.TotalRounds},
|
||||
TotalBets: pgtype.Numeric{Exp: int32(r.TotalBets)},
|
||||
TotalPayouts: pgtype.Numeric{Exp: int32(r.TotalPayouts)},
|
||||
TotalPlayers: pgtype.Int8{Int64: r.TotalPlayers},
|
||||
Column8: r.ReportType,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBVirtualGameReport(db dbgen.VirtualGameReport) domain.VirtualGameReport {
|
||||
return domain.VirtualGameReport{
|
||||
ID: db.ID,
|
||||
GameID: db.GameID,
|
||||
ProviderID: db.ProviderID,
|
||||
ReportDate: db.ReportDate.Time,
|
||||
TotalRounds: db.TotalRounds.Int64,
|
||||
TotalBets: float64(db.TotalBets.Exp),
|
||||
TotalPayouts: float64(db.TotalPayouts.Exp),
|
||||
TotalProfit: float64(db.TotalProfit.Exp),
|
||||
TotalPlayers: db.TotalPlayers.Int64,
|
||||
ReportType: db.ReportType.String,
|
||||
CreatedAt: db.CreatedAt.Time,
|
||||
UpdatedAt: db.UpdatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
package virtualgameservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
)
|
||||
|
||||
// Remove a provider by provider_id
|
||||
func (s *service) RemoveProvider(ctx context.Context, providerID string) error {
|
||||
return s.repo.DeleteVirtualGameProvider(ctx, providerID)
|
||||
}
|
||||
|
||||
// Fetch provider by provider_id
|
||||
func (s *service) GetProviderByID(ctx context.Context, providerID string) (dbgen.VirtualGameProvider, error) {
|
||||
return s.repo.GetVirtualGameProviderByID(ctx, providerID)
|
||||
}
|
||||
|
||||
// List providers with pagination
|
||||
func (s *service) ListProviders(ctx context.Context, limit, offset int32) ([]domain.VirtualGameProvider, int64, error) {
|
||||
providers, err := s.repo.ListVirtualGameProviders(ctx, limit, offset)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
total, err := s.repo.CountVirtualGameProviders(ctx)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Convert []dbgen.VirtualGameProvider to []domain.VirtualGameProvider
|
||||
domainProviders := make([]domain.VirtualGameProvider, len(providers))
|
||||
for i, p := range providers {
|
||||
var logoDark *string
|
||||
if p.LogoDark.Valid {
|
||||
logoDark = &p.LogoDark.String
|
||||
}
|
||||
|
||||
var logoLight *string
|
||||
if p.LogoLight.Valid {
|
||||
logoLight = &p.LogoLight.String
|
||||
}
|
||||
|
||||
domainProviders[i] = domain.VirtualGameProvider{
|
||||
ProviderID: p.ProviderID,
|
||||
ProviderName: p.ProviderName,
|
||||
Enabled: p.Enabled,
|
||||
LogoDark: logoDark,
|
||||
LogoLight: logoLight,
|
||||
CreatedAt: p.CreatedAt.Time,
|
||||
UpdatedAt: &p.UpdatedAt.Time,
|
||||
// Add other fields as needed
|
||||
}
|
||||
}
|
||||
|
||||
return domainProviders, total, nil
|
||||
}
|
||||
|
||||
// Enable/Disable a provider
|
||||
func (s *service) SetProviderEnabled(ctx context.Context, providerID string, enabled bool) (*domain.VirtualGameProvider, error) {
|
||||
provider, err := s.repo.UpdateVirtualGameProviderEnabled(ctx, providerID, enabled)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to update provider enabled status", "provider_id", providerID, "enabled", enabled, "error", err)
|
||||
return nil, err
|
||||
}
|
||||
now := time.Now()
|
||||
provider.UpdatedAt.Time = now
|
||||
|
||||
domainProvider := &domain.VirtualGameProvider{
|
||||
ProviderID: provider.ProviderID,
|
||||
ProviderName: provider.ProviderName,
|
||||
Enabled: provider.Enabled,
|
||||
CreatedAt: provider.CreatedAt.Time,
|
||||
UpdatedAt: &provider.UpdatedAt.Time,
|
||||
// Add other fields as needed
|
||||
}
|
||||
|
||||
return domainProvider, nil
|
||||
}
|
||||
14
internal/services/virtualGame/orchestration/port.go
Normal file
14
internal/services/virtualGame/orchestration/port.go
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package orchestration
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
)
|
||||
|
||||
type OrchestrationService interface {
|
||||
FetchAndStoreAllVirtualGames(ctx context.Context, req domain.ProviderRequest, currency string) ([]domain.UnifiedGame, error)
|
||||
GetAllVirtualGames(ctx context.Context, params dbgen.GetAllVirtualGamesParams) ([]domain.UnifiedGame, error)
|
||||
AddProviders(ctx context.Context, req domain.ProviderRequest) (*domain.ProviderResponse, error)
|
||||
}
|
||||
526
internal/services/virtualGame/orchestration/service.go
Normal file
526
internal/services/virtualGame/orchestration/service.go
Normal file
|
|
@ -0,0 +1,526 @@
|
|||
package orchestration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
||||
virtualgameservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/veli"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
virtualGameSvc virtualgameservice.VirtualGameService
|
||||
veliVirtualGameSvc veli.VeliVirtualGameService
|
||||
repo repository.VirtualGameRepository
|
||||
cfg *config.Config
|
||||
client *veli.Client
|
||||
}
|
||||
|
||||
func New(virtualGameSvc virtualgameservice.VirtualGameService, repo repository.VirtualGameRepository, cfg *config.Config, client *veli.Client) *Service {
|
||||
return &Service{
|
||||
virtualGameSvc: virtualGameSvc,
|
||||
repo: repo,
|
||||
cfg: cfg,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) AddProviders(ctx context.Context, req domain.ProviderRequest) (*domain.ProviderResponse, error) {
|
||||
|
||||
// logger := s.mongoLogger.With(zap.String("service", "AddProviders"), zap.Any("ProviderRequest", req))
|
||||
|
||||
// 0. Remove all existing providers first
|
||||
if err := s.repo.DeleteAllVirtualGameProviders(ctx); err != nil {
|
||||
// logger.Error("failed to delete all virtual game providers", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to clear existing providers: %w", err)
|
||||
}
|
||||
|
||||
// 1. Prepare signature parameters
|
||||
sigParams := map[string]any{
|
||||
"brandId": req.BrandID,
|
||||
}
|
||||
|
||||
// Optional fields
|
||||
sigParams["extraData"] = fmt.Sprintf("%t", req.ExtraData) // false is still included
|
||||
if req.Size > 0 {
|
||||
sigParams["size"] = fmt.Sprintf("%d", req.Size)
|
||||
} else {
|
||||
sigParams["size"] = ""
|
||||
}
|
||||
|
||||
if req.Page > 0 {
|
||||
sigParams["page"] = fmt.Sprintf("%d", req.Page)
|
||||
} else {
|
||||
sigParams["page"] = ""
|
||||
}
|
||||
|
||||
// 2. Call external API
|
||||
var res domain.ProviderResponse
|
||||
if err := s.client.Post(ctx, "/game-lists/public/providers", req, sigParams, &res); err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch providers: %w", err)
|
||||
}
|
||||
|
||||
// 3. Loop through fetched providers and insert into DB
|
||||
for _, p := range res.Items {
|
||||
createParams := dbgen.CreateVirtualGameProviderParams{
|
||||
ProviderID: p.ProviderID,
|
||||
ProviderName: p.ProviderName,
|
||||
LogoDark: pgtype.Text{String: p.LogoForDark, Valid: p.LogoForDark != ""},
|
||||
LogoLight: pgtype.Text{String: p.LogoForLight, Valid: p.LogoForLight != ""},
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
if _, err := s.repo.CreateVirtualGameProvider(ctx, createParams); err != nil {
|
||||
// logger.Error("failed to add provider", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to add provider %s: %w", p.ProviderID, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Always add "popok" provider manually
|
||||
popokParams := dbgen.CreateVirtualGameProviderParams{
|
||||
ProviderID: "popok",
|
||||
ProviderName: "Popok Gaming",
|
||||
LogoDark: pgtype.Text{String: fmt.Sprintf("%v/static/logos/popok-dark.png", s.cfg.PopOK.CallbackURL), Valid: true}, // adjust as needed
|
||||
LogoLight: pgtype.Text{String: fmt.Sprintf("%v/static/logos/popok-light.png", s.cfg.PopOK.CallbackURL), Valid: true}, // adjust as needed
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
atlasParams := dbgen.CreateVirtualGameProviderParams{
|
||||
ProviderID: "atlas",
|
||||
ProviderName: "Atlas Gaming",
|
||||
LogoDark: pgtype.Text{String: "/static/logos/atlas-dark.png", Valid: true}, // adjust as needed
|
||||
LogoLight: pgtype.Text{String: "/static/logos/atlas-light.png", Valid: true}, // adjust as needed
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
if _, err := s.repo.CreateVirtualGameProvider(ctx, popokParams); err != nil {
|
||||
// logger.Error("failed to add popok provider", zap.Any("popokParams", popokParams), zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to add popok provider: %w", err)
|
||||
}
|
||||
|
||||
if _, err := s.repo.CreateVirtualGameProvider(ctx, atlasParams); err != nil {
|
||||
return nil, fmt.Errorf("failed to add atlas provider: %w", err)
|
||||
}
|
||||
|
||||
// Optionally also append it to the response for consistency
|
||||
// res.Items = append(res.Items, domain.VirtualGameProvider{
|
||||
// ProviderID: uuid.New().String(),
|
||||
// ProviderName: "Popok Gaming",
|
||||
// LogoForDark: "/static/logos/popok-dark.png",
|
||||
// LogoForLight: "/static/logos/popok-light.png",
|
||||
// })
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (s *Service) GetAllVirtualGames(ctx context.Context, params dbgen.GetAllVirtualGamesParams) ([]domain.UnifiedGame, error) {
|
||||
// Build params for repo call
|
||||
// logger := s.mongoLogger.With(zap.String("service", "GetAllVirtualGames"), zap.Any("params", params))
|
||||
rows, err := s.repo.ListAllVirtualGames(ctx, params)
|
||||
if err != nil {
|
||||
// logger.Error("[GetAllVirtualGames] Failed to fetch virtual games", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to fetch virtual games: %w", err)
|
||||
}
|
||||
|
||||
var allGames []domain.UnifiedGame
|
||||
for _, r := range rows {
|
||||
// --- Convert nullable Rtp to *float64 ---
|
||||
var rtpPtr *float64
|
||||
if r.Rtp.Valid {
|
||||
rtpFloat, err := r.Rtp.Float64Value()
|
||||
if err == nil {
|
||||
rtpPtr = new(float64)
|
||||
*rtpPtr = rtpFloat.Float64
|
||||
}
|
||||
}
|
||||
var betsFloat64 []float64
|
||||
for _, bet := range r.Bets {
|
||||
if bet.Valid {
|
||||
betFloat, err := bet.Float64Value()
|
||||
if err == nil {
|
||||
betsFloat64 = append(betsFloat64, betFloat.Float64)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allGames = append(allGames, domain.UnifiedGame{
|
||||
GameID: r.GameID,
|
||||
ProviderID: r.ProviderID,
|
||||
Provider: r.ProviderName,
|
||||
Name: r.Name,
|
||||
Category: r.Category.String,
|
||||
DeviceType: r.DeviceType.String,
|
||||
Volatility: r.Volatility.String,
|
||||
RTP: rtpPtr,
|
||||
HasDemo: r.HasDemo.Bool,
|
||||
HasFreeBets: r.HasFreeBets.Bool,
|
||||
Bets: betsFloat64,
|
||||
Thumbnail: r.Thumbnail.String,
|
||||
Status: int(r.Status.Int32), // nullable status
|
||||
})
|
||||
}
|
||||
|
||||
return allGames, nil
|
||||
}
|
||||
|
||||
func (s *Service) FetchAndStoreAllVirtualGames(ctx context.Context, req domain.ProviderRequest, currency string) ([]domain.UnifiedGame, error) {
|
||||
// logger := s.mongoLogger.With(
|
||||
// zap.String("service", "FetchAndStoreAllVirtualGames"),
|
||||
// zap.Any("ProviderRequest", req),
|
||||
// )
|
||||
|
||||
// This is necessary since the provider is a foreign key
|
||||
_, err := s.AddProviders(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to add providers to database: %w", err)
|
||||
}
|
||||
|
||||
var allGames []domain.UnifiedGame
|
||||
|
||||
// --- 1. Existing providers (Veli Games) ---
|
||||
providersRes, err := s.veliVirtualGameSvc.GetProviders(ctx, req)
|
||||
if err != nil {
|
||||
// logger.Error("Failed to fetch provider", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to fetch providers: %w", err)
|
||||
}
|
||||
|
||||
// --- 2. Fetch games for each provider (Veli Games) ---
|
||||
for _, p := range providersRes.Items {
|
||||
games, err := s.veliVirtualGameSvc.GetGames(ctx, domain.GameListRequest{
|
||||
BrandID: s.cfg.VeliGames.BrandID,
|
||||
ProviderID: p.ProviderID,
|
||||
Page: req.Page,
|
||||
Size: req.Size,
|
||||
})
|
||||
if err != nil {
|
||||
// logger.Error("failed to get veli games", zap.String("ProviderID", p.ProviderID), zap.Error(err))
|
||||
continue // skip failing provider but continue others
|
||||
}
|
||||
|
||||
for _, g := range games {
|
||||
unified := domain.UnifiedGame{
|
||||
GameID: g.GameID,
|
||||
ProviderID: g.ProviderID,
|
||||
Provider: p.ProviderName,
|
||||
Name: g.Name,
|
||||
Category: g.Category,
|
||||
DeviceType: g.DeviceType,
|
||||
HasDemo: g.HasDemoMode,
|
||||
HasFreeBets: g.HasFreeBets,
|
||||
}
|
||||
allGames = append(allGames, unified)
|
||||
|
||||
// Save to DB
|
||||
_, err = s.repo.CreateVirtualGame(ctx, dbgen.CreateVirtualGameParams{
|
||||
GameID: g.GameID,
|
||||
ProviderID: g.ProviderID,
|
||||
Name: g.Name,
|
||||
Category: pgtype.Text{
|
||||
String: g.Category,
|
||||
Valid: g.Category != "",
|
||||
},
|
||||
DeviceType: pgtype.Text{
|
||||
String: g.DeviceType,
|
||||
Valid: g.DeviceType != "",
|
||||
},
|
||||
HasDemo: pgtype.Bool{
|
||||
Bool: g.HasDemoMode,
|
||||
Valid: true,
|
||||
},
|
||||
HasFreeBets: pgtype.Bool{
|
||||
Bool: g.HasFreeBets,
|
||||
Valid: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
// logger.Error("failed to create virtual game", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- 3. Fetch Atlas-V games ---
|
||||
atlasGames, err := s.veliVirtualGameSvc.GetAtlasVGames(ctx)
|
||||
if err != nil {
|
||||
// logger.Error("failed to fetch Atlas-V games", zap.Error(err))
|
||||
} else {
|
||||
for _, g := range atlasGames {
|
||||
unified := domain.UnifiedGame{
|
||||
GameID: g.GameID,
|
||||
ProviderID: "atlasv",
|
||||
Provider: "Atlas-V Gaming", // "Atlas-V"
|
||||
Name: g.Name,
|
||||
Category: g.Category, // using Type as Category
|
||||
Thumbnail: g.Thumbnail,
|
||||
HasDemo: true,
|
||||
DemoURL: g.DemoURL,
|
||||
}
|
||||
allGames = append(allGames, unified)
|
||||
|
||||
// Save to DB
|
||||
_, err = s.repo.CreateVirtualGame(ctx, dbgen.CreateVirtualGameParams{
|
||||
GameID: g.GameID,
|
||||
ProviderID: "atlasv",
|
||||
Name: g.Name,
|
||||
Category: pgtype.Text{
|
||||
String: g.Category,
|
||||
Valid: g.Category != "",
|
||||
},
|
||||
Thumbnail: pgtype.Text{
|
||||
String: g.Thumbnail,
|
||||
Valid: g.Thumbnail != "",
|
||||
},
|
||||
HasDemo: pgtype.Bool{
|
||||
Bool: g.HasDemoMode,
|
||||
Valid: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
// logger.Error("failed to create Atlas-V virtual game", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- 4. Handle PopOK separately ---
|
||||
popokGames, err := s.virtualGameSvc.ListGames(ctx, currency)
|
||||
if err != nil {
|
||||
// logger.Error("failed to fetch PopOk games", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to fetch PopOK games: %w", err)
|
||||
}
|
||||
|
||||
for _, g := range popokGames {
|
||||
unified := domain.UnifiedGame{
|
||||
GameID: fmt.Sprintf("%d", g.ID),
|
||||
ProviderID: "popok",
|
||||
Provider: "PopOK",
|
||||
Name: g.GameName,
|
||||
Category: "Crash",
|
||||
Bets: g.Bets,
|
||||
Thumbnail: g.Thumbnail,
|
||||
Status: g.Status,
|
||||
}
|
||||
allGames = append(allGames, unified)
|
||||
|
||||
// Convert []float64 to []pgtype.Numeric
|
||||
var betsNumeric []pgtype.Numeric
|
||||
for _, bet := range g.Bets {
|
||||
var num pgtype.Numeric
|
||||
_ = num.Scan(bet)
|
||||
betsNumeric = append(betsNumeric, num)
|
||||
}
|
||||
|
||||
// Save to DB
|
||||
_, err = s.repo.CreateVirtualGame(ctx, dbgen.CreateVirtualGameParams{
|
||||
GameID: fmt.Sprintf("%d", g.ID),
|
||||
ProviderID: "popok",
|
||||
Name: g.GameName,
|
||||
Bets: betsNumeric,
|
||||
Thumbnail: pgtype.Text{
|
||||
String: g.Thumbnail,
|
||||
Valid: g.Thumbnail != "",
|
||||
},
|
||||
Status: pgtype.Int4{
|
||||
Int32: int32(g.Status),
|
||||
Valid: true,
|
||||
},
|
||||
HasDemo: pgtype.Bool{
|
||||
Bool: true,
|
||||
Valid: true,
|
||||
},
|
||||
Category: pgtype.Text{
|
||||
String: "Crash",
|
||||
Valid: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
// logger.Error("failed to create PopOK virtual game", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
return allGames, nil
|
||||
}
|
||||
|
||||
func (s *Service) RemoveProvider(ctx context.Context, providerID string) error {
|
||||
return s.repo.DeleteVirtualGameProvider(ctx, providerID)
|
||||
}
|
||||
|
||||
// Fetch provider by provider_id
|
||||
func (s *Service) GetProviderByID(ctx context.Context, providerID string) (dbgen.VirtualGameProvider, error) {
|
||||
return s.repo.GetVirtualGameProviderByID(ctx, providerID)
|
||||
}
|
||||
|
||||
// List providers with pagination
|
||||
func (s *Service) ListProviders(ctx context.Context, limit, offset int32) ([]domain.VirtualGameProvider, int64, error) {
|
||||
providers, err := s.repo.ListVirtualGameProviders(ctx, limit, offset)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
total, err := s.repo.CountVirtualGameProviders(ctx)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Convert []dbgen.VirtualGameProvider to []domain.VirtualGameProvider
|
||||
domainProviders := make([]domain.VirtualGameProvider, len(providers))
|
||||
for i, p := range providers {
|
||||
var logoDark *string
|
||||
if p.LogoDark.Valid {
|
||||
logoDark = &p.LogoDark.String
|
||||
}
|
||||
|
||||
var logoLight *string
|
||||
if p.LogoLight.Valid {
|
||||
logoLight = &p.LogoLight.String
|
||||
}
|
||||
|
||||
domainProviders[i] = domain.VirtualGameProvider{
|
||||
ProviderID: p.ProviderID,
|
||||
ProviderName: p.ProviderName,
|
||||
Enabled: p.Enabled,
|
||||
LogoDark: logoDark,
|
||||
LogoLight: logoLight,
|
||||
CreatedAt: p.CreatedAt.Time,
|
||||
UpdatedAt: &p.UpdatedAt.Time,
|
||||
// Add other fields as needed
|
||||
}
|
||||
}
|
||||
|
||||
return domainProviders, total, nil
|
||||
}
|
||||
|
||||
// Enable/Disable a provider
|
||||
func (s *Service) SetProviderEnabled(ctx context.Context, providerID string, enabled bool) (*domain.VirtualGameProvider, error) {
|
||||
provider, err := s.repo.UpdateVirtualGameProviderEnabled(ctx, providerID, enabled)
|
||||
if err != nil {
|
||||
//s.logger.Error("Failed to update provider enabled status", "provider_id", providerID, "enabled", enabled, "error", err)
|
||||
return nil, err
|
||||
}
|
||||
now := time.Now()
|
||||
provider.UpdatedAt.Time = now
|
||||
|
||||
domainProvider := &domain.VirtualGameProvider{
|
||||
ProviderID: provider.ProviderID,
|
||||
ProviderName: provider.ProviderName,
|
||||
Enabled: provider.Enabled,
|
||||
CreatedAt: provider.CreatedAt.Time,
|
||||
UpdatedAt: &provider.UpdatedAt.Time,
|
||||
// Add other fields as needed
|
||||
}
|
||||
|
||||
return domainProvider, nil
|
||||
}
|
||||
|
||||
func (s *Service) CreateVirtualGameProviderReport(ctx context.Context, report domain.CreateVirtualGameProviderReport) (domain.VirtualGameProviderReport, error) {
|
||||
// Example: logger := s.mongoLogger.With(zap.String("service", "CreateVirtualGameProviderReport"), zap.Any("Report", report))
|
||||
|
||||
// Call repository to create the report
|
||||
created, err := s.repo.CreateVirtualGameProviderReport(ctx, report)
|
||||
if err != nil {
|
||||
// logger.Error("failed to create provider report", zap.Error(err), zap.Any("report", report))
|
||||
return domain.VirtualGameProviderReport{}, fmt.Errorf("failed to create provider report for provider %s: %w", report.ProviderID, err)
|
||||
}
|
||||
|
||||
// Return the created report
|
||||
return created, nil
|
||||
}
|
||||
|
||||
func (s *Service) CreateVirtualGameReport(ctx context.Context, report domain.CreateVirtualGameReport) (domain.VirtualGameReport, error) {
|
||||
// Example: logger := s.mongoLogger.With(zap.String("service", "CreateVirtualGameReport"), zap.Any("Report", report))
|
||||
|
||||
// Call repository to create the report
|
||||
created, err := s.repo.CreateVirtualGameReport(ctx, report)
|
||||
if err != nil {
|
||||
// logger.Error("failed to create game report", zap.Error(err), zap.Any("report", report))
|
||||
return domain.VirtualGameReport{}, fmt.Errorf("failed to create game report for game %s: %w", report.GameID, err)
|
||||
}
|
||||
|
||||
// Return the created report
|
||||
return created, nil
|
||||
}
|
||||
|
||||
func (s *Service) GetVirtualGameProviderReportByProviderAndDate(
|
||||
ctx context.Context,
|
||||
providerID string,
|
||||
reportDate time.Time,
|
||||
reportType string,
|
||||
) (domain.VirtualGameProviderReport, error) {
|
||||
// Example logger if needed
|
||||
// logger := s.mongoLogger.With(zap.String("service", "GetVirtualGameProviderReportByProviderAndDate"),
|
||||
// zap.String("provider_id", providerID),
|
||||
// zap.Time("report_date", reportDate),
|
||||
// zap.String("report_type", reportType),
|
||||
// )
|
||||
|
||||
report, err := s.repo.GetVirtualGameProviderReportByProviderAndDate(ctx, providerID, reportDate, reportType)
|
||||
if err != nil {
|
||||
// logger.Error("failed to retrieve virtual game provider report", zap.Error(err))
|
||||
return domain.VirtualGameProviderReport{}, fmt.Errorf(
|
||||
"failed to retrieve provider report for provider %s on %s (%s): %w",
|
||||
providerID, reportDate.Format("2006-01-02"), reportType, err,
|
||||
)
|
||||
}
|
||||
|
||||
return report, nil
|
||||
}
|
||||
|
||||
func (s *Service) UpdateVirtualGameProviderReportByDate(
|
||||
ctx context.Context,
|
||||
providerID string,
|
||||
reportDate time.Time,
|
||||
reportType string,
|
||||
totalGamesPlayed int64,
|
||||
totalBets float64,
|
||||
totalPayouts float64,
|
||||
totalPlayers int64,
|
||||
) error {
|
||||
// Optionally log or trace the update
|
||||
// Example: s.mongoLogger.Info("Updating virtual game provider report",
|
||||
// zap.String("provider_id", providerID),
|
||||
// zap.Time("report_date", reportDate),
|
||||
// zap.String("report_type", reportType),
|
||||
// )
|
||||
|
||||
err := s.repo.UpdateVirtualGameProviderReportByDate(
|
||||
ctx,
|
||||
providerID,
|
||||
reportDate,
|
||||
reportType,
|
||||
totalGamesPlayed,
|
||||
totalBets,
|
||||
totalPayouts,
|
||||
totalPlayers,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update provider report for provider %s on %s (%s): %w",
|
||||
providerID,
|
||||
reportDate.Format("2006-01-02"),
|
||||
reportType,
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) ListVirtualGameProviderReportsByGamesPlayedAsc(ctx context.Context) ([]domain.VirtualGameProviderReport, error) {
|
||||
reports, err := s.repo.ListVirtualGameProviderReportsByGamesPlayedAsc(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch virtual game provider reports ascending: %w", err)
|
||||
}
|
||||
return reports, nil
|
||||
}
|
||||
|
||||
// ListVirtualGameProviderReportsByGamesPlayedDesc fetches all reports sorted by total_games_played descending.
|
||||
func (s *Service) ListVirtualGameProviderReportsByGamesPlayedDesc(ctx context.Context) ([]domain.VirtualGameProviderReport, error) {
|
||||
reports, err := s.repo.ListVirtualGameProviderReportsByGamesPlayedDesc(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch virtual game provider reports descending: %w", err)
|
||||
}
|
||||
return reports, nil
|
||||
}
|
||||
|
|
@ -3,16 +3,15 @@ package virtualgameservice
|
|||
import (
|
||||
"context"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
)
|
||||
|
||||
type VirtualGameService interface {
|
||||
// AddProvider(ctx context.Context, req domain.ProviderRequest) (*domain.ProviderResponse, error)
|
||||
RemoveProvider(ctx context.Context, providerID string) error
|
||||
GetProviderByID(ctx context.Context, providerID string) (dbgen.VirtualGameProvider, error)
|
||||
ListProviders(ctx context.Context, limit, offset int32) ([]domain.VirtualGameProvider, int64, error)
|
||||
SetProviderEnabled(ctx context.Context, providerID string, enabled bool) (*domain.VirtualGameProvider, error)
|
||||
// RemoveProvider(ctx context.Context, providerID string) error
|
||||
// GetProviderByID(ctx context.Context, providerID string) (dbgen.VirtualGameProvider, error)
|
||||
// ListProviders(ctx context.Context, limit, offset int32) ([]domain.VirtualGameProvider, int64, error)
|
||||
// SetProviderEnabled(ctx context.Context, providerID string, enabled bool) (*domain.VirtualGameProvider, error)
|
||||
|
||||
GenerateGameLaunchURL(ctx context.Context, userID int64, gameID, currency, mode string) (string, error)
|
||||
HandleCallback(ctx context.Context, callback *domain.PopOKCallback) error
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ func (c *Client) generateSignature(params map[string]any) (string, error) {
|
|||
|
||||
|
||||
// POST helper
|
||||
func (c *Client) post(ctx context.Context, path string, body any, sigParams map[string]any, result any) error {
|
||||
func (c *Client) Post(ctx context.Context, path string, body any, sigParams map[string]any, result any) error {
|
||||
data, _ := json.Marshal(body)
|
||||
sig, err := c.generateSignature(sigParams)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -1,326 +1 @@
|
|||
package veli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func (s *Service) AddProviders(ctx context.Context, req domain.ProviderRequest) (*domain.ProviderResponse, error) {
|
||||
|
||||
logger := s.mongoLogger.With(zap.String("service", "AddProviders"), zap.Any("ProviderRequest", req))
|
||||
|
||||
// 0. Remove all existing providers first
|
||||
if err := s.repo.DeleteAllVirtualGameProviders(ctx); err != nil {
|
||||
logger.Error("failed to delete all virtual game providers", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to clear existing providers: %w", err)
|
||||
}
|
||||
|
||||
// 1. Prepare signature parameters
|
||||
sigParams := map[string]any{
|
||||
"brandId": req.BrandID,
|
||||
}
|
||||
|
||||
// Optional fields
|
||||
sigParams["extraData"] = fmt.Sprintf("%t", req.ExtraData) // false is still included
|
||||
if req.Size > 0 {
|
||||
sigParams["size"] = fmt.Sprintf("%d", req.Size)
|
||||
} else {
|
||||
sigParams["size"] = ""
|
||||
}
|
||||
|
||||
if req.Page > 0 {
|
||||
sigParams["page"] = fmt.Sprintf("%d", req.Page)
|
||||
} else {
|
||||
sigParams["page"] = ""
|
||||
}
|
||||
|
||||
// 2. Call external API
|
||||
var res domain.ProviderResponse
|
||||
if err := s.client.post(ctx, "/game-lists/public/providers", req, sigParams, &res); err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch providers: %w", err)
|
||||
}
|
||||
|
||||
// 3. Loop through fetched providers and insert into DB
|
||||
for _, p := range res.Items {
|
||||
createParams := dbgen.CreateVirtualGameProviderParams{
|
||||
ProviderID: p.ProviderID,
|
||||
ProviderName: p.ProviderName,
|
||||
LogoDark: pgtype.Text{String: p.LogoForDark, Valid: p.LogoForDark != ""},
|
||||
LogoLight: pgtype.Text{String: p.LogoForLight, Valid: p.LogoForLight != ""},
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
if _, err := s.repo.CreateVirtualGameProvider(ctx, createParams); err != nil {
|
||||
logger.Error("failed to add provider", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to add provider %s: %w", p.ProviderID, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Always add "popok" provider manually
|
||||
popokParams := dbgen.CreateVirtualGameProviderParams{
|
||||
ProviderID: "popok",
|
||||
ProviderName: "Popok Gaming",
|
||||
LogoDark: pgtype.Text{String: fmt.Sprintf("%v/static/logos/popok-dark.png", s.cfg.PopOK.CallbackURL), Valid: true}, // adjust as needed
|
||||
LogoLight: pgtype.Text{String: fmt.Sprintf("%v/static/logos/popok-light.png", s.cfg.PopOK.CallbackURL), Valid: true}, // adjust as needed
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
atlasParams := dbgen.CreateVirtualGameProviderParams{
|
||||
ProviderID: "atlas",
|
||||
ProviderName: "Atlas Gaming",
|
||||
LogoDark: pgtype.Text{String: "/static/logos/atlas-dark.png", Valid: true}, // adjust as needed
|
||||
LogoLight: pgtype.Text{String: "/static/logos/atlas-light.png", Valid: true}, // adjust as needed
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
if _, err := s.repo.CreateVirtualGameProvider(ctx, popokParams); err != nil {
|
||||
logger.Error("failed to add popok provider", zap.Any("popokParams", popokParams), zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to add popok provider: %w", err)
|
||||
}
|
||||
|
||||
if _, err := s.repo.CreateVirtualGameProvider(ctx, atlasParams); err != nil {
|
||||
return nil, fmt.Errorf("failed to add atlas provider: %w", err)
|
||||
}
|
||||
|
||||
// Optionally also append it to the response for consistency
|
||||
// res.Items = append(res.Items, domain.VirtualGameProvider{
|
||||
// ProviderID: uuid.New().String(),
|
||||
// ProviderName: "Popok Gaming",
|
||||
// LogoForDark: "/static/logos/popok-dark.png",
|
||||
// LogoForLight: "/static/logos/popok-light.png",
|
||||
// })
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (s *Service) GetAllVirtualGames(ctx context.Context, params dbgen.GetAllVirtualGamesParams) ([]domain.UnifiedGame, error) {
|
||||
// Build params for repo call
|
||||
logger := s.mongoLogger.With(zap.String("service", "GetAllVirtualGames"), zap.Any("params", params))
|
||||
rows, err := s.repo.ListAllVirtualGames(ctx, params)
|
||||
if err != nil {
|
||||
logger.Error("[GetAllVirtualGames] Failed to fetch virtual games", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to fetch virtual games: %w", err)
|
||||
}
|
||||
|
||||
var allGames []domain.UnifiedGame
|
||||
for _, r := range rows {
|
||||
// --- Convert nullable Rtp to *float64 ---
|
||||
var rtpPtr *float64
|
||||
if r.Rtp.Valid {
|
||||
rtpFloat, err := r.Rtp.Float64Value()
|
||||
if err == nil {
|
||||
rtpPtr = new(float64)
|
||||
*rtpPtr = rtpFloat.Float64
|
||||
}
|
||||
}
|
||||
var betsFloat64 []float64
|
||||
for _, bet := range r.Bets {
|
||||
if bet.Valid {
|
||||
betFloat, err := bet.Float64Value()
|
||||
if err == nil {
|
||||
betsFloat64 = append(betsFloat64, betFloat.Float64)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allGames = append(allGames, domain.UnifiedGame{
|
||||
GameID: r.GameID,
|
||||
ProviderID: r.ProviderID,
|
||||
Provider: r.ProviderName,
|
||||
Name: r.Name,
|
||||
Category: r.Category.String,
|
||||
DeviceType: r.DeviceType.String,
|
||||
Volatility: r.Volatility.String,
|
||||
RTP: rtpPtr,
|
||||
HasDemo: r.HasDemo.Bool,
|
||||
HasFreeBets: r.HasFreeBets.Bool,
|
||||
Bets: betsFloat64,
|
||||
Thumbnail: r.Thumbnail.String,
|
||||
Status: int(r.Status.Int32), // nullable status
|
||||
})
|
||||
}
|
||||
|
||||
return allGames, nil
|
||||
}
|
||||
|
||||
func (s *Service) FetchAndStoreAllVirtualGames(ctx context.Context, req domain.ProviderRequest, currency string) ([]domain.UnifiedGame, error) {
|
||||
logger := s.mongoLogger.With(
|
||||
zap.String("service", "FetchAndStoreAllVirtualGames"),
|
||||
zap.Any("ProviderRequest", req),
|
||||
)
|
||||
|
||||
// This is necessary since the provider is a foreign key
|
||||
_, err := s.AddProviders(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to add providers to database: %w", err)
|
||||
}
|
||||
|
||||
var allGames []domain.UnifiedGame
|
||||
|
||||
// --- 1. Existing providers (Veli Games) ---
|
||||
providersRes, err := s.GetProviders(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error("Failed to fetch provider", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to fetch providers: %w", err)
|
||||
}
|
||||
|
||||
// --- 2. Fetch games for each provider (Veli Games) ---
|
||||
for _, p := range providersRes.Items {
|
||||
games, err := s.GetGames(ctx, domain.GameListRequest{
|
||||
BrandID: s.cfg.VeliGames.BrandID,
|
||||
ProviderID: p.ProviderID,
|
||||
Page: req.Page,
|
||||
Size: req.Size,
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error("failed to get veli games", zap.String("ProviderID", p.ProviderID), zap.Error(err))
|
||||
continue // skip failing provider but continue others
|
||||
}
|
||||
|
||||
for _, g := range games {
|
||||
unified := domain.UnifiedGame{
|
||||
GameID: g.GameID,
|
||||
ProviderID: g.ProviderID,
|
||||
Provider: p.ProviderName,
|
||||
Name: g.Name,
|
||||
Category: g.Category,
|
||||
DeviceType: g.DeviceType,
|
||||
HasDemo: g.HasDemoMode,
|
||||
HasFreeBets: g.HasFreeBets,
|
||||
}
|
||||
allGames = append(allGames, unified)
|
||||
|
||||
// Save to DB
|
||||
_, err = s.repo.CreateVirtualGame(ctx, dbgen.CreateVirtualGameParams{
|
||||
GameID: g.GameID,
|
||||
ProviderID: g.ProviderID,
|
||||
Name: g.Name,
|
||||
Category: pgtype.Text{
|
||||
String: g.Category,
|
||||
Valid: g.Category != "",
|
||||
},
|
||||
DeviceType: pgtype.Text{
|
||||
String: g.DeviceType,
|
||||
Valid: g.DeviceType != "",
|
||||
},
|
||||
HasDemo: pgtype.Bool{
|
||||
Bool: g.HasDemoMode,
|
||||
Valid: true,
|
||||
},
|
||||
HasFreeBets: pgtype.Bool{
|
||||
Bool: g.HasFreeBets,
|
||||
Valid: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error("failed to create virtual game", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- 3. Fetch Atlas-V games ---
|
||||
atlasGames, err := s.GetAtlasVGames(ctx)
|
||||
if err != nil {
|
||||
logger.Error("failed to fetch Atlas-V games", zap.Error(err))
|
||||
} else {
|
||||
for _, g := range atlasGames {
|
||||
unified := domain.UnifiedGame{
|
||||
GameID: g.GameID,
|
||||
ProviderID: "atlasv",
|
||||
Provider: "Atlas-V Gaming", // "Atlas-V"
|
||||
Name: g.Name,
|
||||
Category: g.Category, // using Type as Category
|
||||
Thumbnail: g.Thumbnail,
|
||||
HasDemo: true,
|
||||
DemoURL: g.DemoURL,
|
||||
}
|
||||
allGames = append(allGames, unified)
|
||||
|
||||
// Save to DB
|
||||
_, err = s.repo.CreateVirtualGame(ctx, dbgen.CreateVirtualGameParams{
|
||||
GameID: g.GameID,
|
||||
ProviderID: "atlasv",
|
||||
Name: g.Name,
|
||||
Category: pgtype.Text{
|
||||
String: g.Category,
|
||||
Valid: g.Category != "",
|
||||
},
|
||||
Thumbnail: pgtype.Text{
|
||||
String: g.Thumbnail,
|
||||
Valid: g.Thumbnail != "",
|
||||
},
|
||||
HasDemo: pgtype.Bool{
|
||||
Bool: g.HasDemoMode,
|
||||
Valid: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error("failed to create Atlas-V virtual game", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- 4. Handle PopOK separately ---
|
||||
popokGames, err := s.virtualGameSvc.ListGames(ctx, currency)
|
||||
if err != nil {
|
||||
logger.Error("failed to fetch PopOk games", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to fetch PopOK games: %w", err)
|
||||
}
|
||||
|
||||
for _, g := range popokGames {
|
||||
unified := domain.UnifiedGame{
|
||||
GameID: fmt.Sprintf("%d", g.ID),
|
||||
ProviderID: "popok",
|
||||
Provider: "PopOK",
|
||||
Name: g.GameName,
|
||||
Category: "Crash",
|
||||
Bets: g.Bets,
|
||||
Thumbnail: g.Thumbnail,
|
||||
Status: g.Status,
|
||||
}
|
||||
allGames = append(allGames, unified)
|
||||
|
||||
// Convert []float64 to []pgtype.Numeric
|
||||
var betsNumeric []pgtype.Numeric
|
||||
for _, bet := range g.Bets {
|
||||
var num pgtype.Numeric
|
||||
_ = num.Scan(bet)
|
||||
betsNumeric = append(betsNumeric, num)
|
||||
}
|
||||
|
||||
// Save to DB
|
||||
_, err = s.repo.CreateVirtualGame(ctx, dbgen.CreateVirtualGameParams{
|
||||
GameID: fmt.Sprintf("%d", g.ID),
|
||||
ProviderID: "popok",
|
||||
Name: g.GameName,
|
||||
Bets: betsNumeric,
|
||||
Thumbnail: pgtype.Text{
|
||||
String: g.Thumbnail,
|
||||
Valid: g.Thumbnail != "",
|
||||
},
|
||||
Status: pgtype.Int4{
|
||||
Int32: int32(g.Status),
|
||||
Valid: true,
|
||||
},
|
||||
HasDemo: pgtype.Bool{
|
||||
Bool: true,
|
||||
Valid: true,
|
||||
},
|
||||
Category: pgtype.Text{
|
||||
String: "Crash",
|
||||
Valid: true,
|
||||
},
|
||||
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error("failed to create PopOK virtual game", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
return allGames, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ func (s *Service) GetProviders(ctx context.Context, req domain.ProviderRequest)
|
|||
}
|
||||
|
||||
var res domain.ProviderResponse
|
||||
err := s.client.post(ctx, "/game-lists/public/providers", req, sigParams, &res)
|
||||
err := s.client.Post(ctx, "/game-lists/public/providers", req, sigParams, &res)
|
||||
return &res, err
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +139,7 @@ func (s *Service) GetGames(ctx context.Context, req domain.GameListRequest) ([]d
|
|||
var res struct {
|
||||
Items []domain.GameEntity `json:"items"`
|
||||
}
|
||||
if err := s.client.post(ctx, "/game-lists/public/games", req, sigParams, &res); err != nil {
|
||||
if err := s.client.Post(ctx, "/game-lists/public/games", req, sigParams, &res); err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch games for provider %s: %w", req.ProviderID, err)
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ func (s *Service) StartGame(ctx context.Context, req domain.GameStartRequest) (*
|
|||
|
||||
// 3. Call external API
|
||||
var res domain.GameStartResponse
|
||||
if err := s.client.post(ctx, "/unified-api/public/start-game", req, sigParams, &res); err != nil {
|
||||
if err := s.client.Post(ctx, "/unified-api/public/start-game", req, sigParams, &res); err != nil {
|
||||
return nil, fmt.Errorf("failed to start game with provider %s: %w", req.ProviderID, err)
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +205,7 @@ func (s *Service) StartDemoGame(ctx context.Context, req domain.DemoGameRequest)
|
|||
|
||||
// 3. Call external API
|
||||
var res domain.GameStartResponse
|
||||
if err := s.client.post(ctx, "/unified-api/public/start-demo-game", req, sigParams, &res); err != nil {
|
||||
if err := s.client.Post(ctx, "/unified-api/public/start-demo-game", req, sigParams, &res); err != nil {
|
||||
return nil, fmt.Errorf("failed to start demo game with provider %s: %w", req.ProviderID, err)
|
||||
}
|
||||
|
||||
|
|
@ -598,7 +598,7 @@ func (s *Service) GetGamingActivity(ctx context.Context, req domain.GamingActivi
|
|||
|
||||
// --- Actual API Call ---
|
||||
var res domain.GamingActivityResponse
|
||||
err := s.client.post(ctx, "/report-api/public/gaming-activity", req, sigParams, &res)
|
||||
err := s.client.Post(ctx, "/report-api/public/gaming-activity", req, sigParams, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -639,7 +639,7 @@ func (s *Service) GetHugeWins(ctx context.Context, req domain.HugeWinsRequest) (
|
|||
|
||||
// --- Actual API Call ---
|
||||
var res domain.HugeWinsResponse
|
||||
err := s.client.post(ctx, "/report-api/public/gaming-activity/huge-wins", req, sigParams, &res)
|
||||
err := s.client.Post(ctx, "/report-api/public/gaming-activity/huge-wins", req, sigParams, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -662,7 +662,7 @@ func (s *Service) GetCreditBalances(ctx context.Context, brandID string) ([]doma
|
|||
Credits []domain.CreditBalance `json:"credits"`
|
||||
}
|
||||
|
||||
if err := s.client.post(ctx, "/report-api/public/credit/balances", body, nil, &res); err != nil {
|
||||
if err := s.client.Post(ctx, "/report-api/public/credit/balances", body, nil, &res); err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch credit balances: %w", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import (
|
|||
virtualgameservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame"
|
||||
alea "github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/Alea"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/atlas"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/orchestration"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/veli"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
|
||||
jwtutil "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/jwt"
|
||||
|
|
@ -48,7 +49,8 @@ import (
|
|||
type App struct {
|
||||
enetPulseSvc *enetpulse.Service
|
||||
atlasVirtualGameService atlas.AtlasVirtualGameService
|
||||
veliVirtualGameService veli.VeliVirtualGameService
|
||||
veliVirtualGameService *veli.Service
|
||||
orchestrationSvc *orchestration.Service
|
||||
telebirrSvc *telebirr.TelebirrService
|
||||
arifpaySvc *arifpay.ArifpayService
|
||||
santimpaySvc *santimpay.SantimPayService
|
||||
|
|
@ -90,7 +92,8 @@ type App struct {
|
|||
func NewApp(
|
||||
enetPulseSvc *enetpulse.Service,
|
||||
atlasVirtualGameService atlas.AtlasVirtualGameService,
|
||||
veliVirtualGameService veli.VeliVirtualGameService,
|
||||
veliVirtualGameService *veli.Service,
|
||||
orchestrationSvc *orchestration.Service,
|
||||
telebirrSvc *telebirr.TelebirrService,
|
||||
arifpaySvc *arifpay.ArifpayService,
|
||||
santimpaySvc *santimpay.SantimPayService,
|
||||
|
|
@ -146,6 +149,7 @@ func NewApp(
|
|||
enetPulseSvc: enetPulseSvc,
|
||||
atlasVirtualGameService: atlasVirtualGameService,
|
||||
veliVirtualGameService: veliVirtualGameService,
|
||||
orchestrationSvc: orchestrationSvc,
|
||||
telebirrSvc: telebirrSvc,
|
||||
arifpaySvc: arifpaySvc,
|
||||
santimpaySvc: santimpaySvc,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import (
|
|||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/report"
|
||||
resultsvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/result"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/veli"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/orchestration"
|
||||
"github.com/robfig/cron/v3"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
|
@ -160,21 +160,18 @@ func StartCleanupCrons(ticketService ticket.Service, notificationSvc *notificati
|
|||
func SetupReportandVirtualGameCronJobs(
|
||||
ctx context.Context,
|
||||
reportService *report.Service,
|
||||
virtualGameService *veli.Service, // inject your virtual game service
|
||||
virtualGameOrchestrationService *orchestration.Service,
|
||||
outputDir string,
|
||||
) {
|
||||
c := cron.New(cron.WithSeconds()) // use WithSeconds for testing
|
||||
c := cron.New(cron.WithSeconds()) // WithSeconds for testing, remove in prod
|
||||
|
||||
schedule := []struct {
|
||||
spec string
|
||||
period string
|
||||
}{
|
||||
// {
|
||||
// spec: "*/60 * * * * *", // Every 1 minute for testing
|
||||
// period: "test",
|
||||
// },
|
||||
// { spec: "*/60 * * * * *", period: "test" }, // every 60 seconds for testing
|
||||
{
|
||||
spec: "0 0 0 * * *", // Daily at midnight
|
||||
spec: "0 0 0 * * *", // daily at midnight
|
||||
period: "daily",
|
||||
},
|
||||
}
|
||||
|
|
@ -183,7 +180,7 @@ func SetupReportandVirtualGameCronJobs(
|
|||
period := job.period
|
||||
|
||||
if _, err := c.AddFunc(job.spec, func() {
|
||||
log.Printf("[%s] Running virtual game fetch & store job...", period)
|
||||
log.Printf("[%s] Running virtual game & provider report job...", period)
|
||||
|
||||
brandID := os.Getenv("VELI_BRAND_ID")
|
||||
if brandID == "" {
|
||||
|
|
@ -191,6 +188,7 @@ func SetupReportandVirtualGameCronJobs(
|
|||
return
|
||||
}
|
||||
|
||||
// Step 1. Fetch and store all virtual games
|
||||
req := domain.ProviderRequest{
|
||||
BrandID: brandID,
|
||||
ExtraData: true,
|
||||
|
|
@ -198,7 +196,7 @@ func SetupReportandVirtualGameCronJobs(
|
|||
Page: 1,
|
||||
}
|
||||
|
||||
allGames, err := virtualGameService.FetchAndStoreAllVirtualGames(ctx, req, "ETB")
|
||||
allGames, err := virtualGameOrchestrationService.FetchAndStoreAllVirtualGames(ctx, req, "ETB")
|
||||
if err != nil {
|
||||
log.Printf("[%s] Error fetching/storing virtual games: %v", period, err)
|
||||
return
|
||||
|
|
@ -206,19 +204,42 @@ func SetupReportandVirtualGameCronJobs(
|
|||
|
||||
log.Printf("[%s] Successfully fetched & stored %d virtual games", period, len(allGames))
|
||||
|
||||
// --- Generate reports only for daily runs ---
|
||||
if period == "daily" {
|
||||
now := time.Now()
|
||||
from := time.Date(now.Year(), now.Month(), now.Day()-1, 0, 0, 0, 0, now.Location())
|
||||
to := time.Date(now.Year(), now.Month(), now.Day()-1, 23, 59, 59, 0, now.Location())
|
||||
// Step 2. Fetch all providers
|
||||
providers, total, err := virtualGameOrchestrationService.ListProviders(ctx, 1000, 0)
|
||||
if err != nil {
|
||||
log.Printf("[%s] Failed to list providers: %v", period, err)
|
||||
return
|
||||
} else if total == 0 {
|
||||
log.Printf("[%s] No providers found, skipping report generation", period)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Running daily report for period %s -> %s", from.Format(time.RFC3339), to.Format(time.RFC3339))
|
||||
if err := reportService.GenerateReport(ctx, from, to); err != nil {
|
||||
log.Printf("Error generating daily report: %v", err)
|
||||
} else {
|
||||
log.Printf("Successfully generated daily report")
|
||||
log.Printf("[%s] Found %d total providers", period, total)
|
||||
|
||||
// Step 3. Create provider-level daily report entries
|
||||
reportDate := time.Now().UTC().Truncate(24 * time.Hour)
|
||||
for _, p := range providers {
|
||||
createReq := domain.CreateVirtualGameProviderReport{
|
||||
ProviderID: p.ProviderID,
|
||||
ReportDate: reportDate,
|
||||
TotalGamesPlayed: 0,
|
||||
TotalBets: 0,
|
||||
TotalPayouts: 0,
|
||||
TotalPlayers: 0,
|
||||
ReportType: period, // "daily"
|
||||
}
|
||||
|
||||
_, err := virtualGameOrchestrationService.CreateVirtualGameProviderReport(ctx, createReq)
|
||||
if err != nil {
|
||||
log.Printf("[%s] Failed to create report for provider %s: %v", period, p.ProviderID, err)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("[%s] Created daily report row for provider: %s", period, p.ProviderID)
|
||||
}
|
||||
|
||||
log.Printf("[%s] Daily provider reports created successfully", period)
|
||||
|
||||
}); err != nil {
|
||||
log.Fatalf("Failed to schedule %s cron job: %v", period, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// GetAtlasVGames godoc
|
||||
|
|
@ -52,7 +54,7 @@ func (h *Handler) GetAtlasVGames(c *fiber.Ctx) error {
|
|||
// @Failure 502 {object} domain.ErrorResponse
|
||||
// @Router /api/v1/atlas/init-game [post]
|
||||
func (h *Handler) InitAtlasGame(c *fiber.Ctx) error {
|
||||
// Retrieve user ID from context
|
||||
// 1️⃣ Retrieve user ID from context
|
||||
userId, ok := c.Locals("user_id").(int64)
|
||||
if !ok {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(domain.ErrorResponse{
|
||||
|
|
@ -61,6 +63,7 @@ func (h *Handler) InitAtlasGame(c *fiber.Ctx) error {
|
|||
})
|
||||
}
|
||||
|
||||
// 2️⃣ Parse request body
|
||||
var req domain.AtlasGameInitRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
|
|
@ -69,30 +72,53 @@ func (h *Handler) InitAtlasGame(c *fiber.Ctx) error {
|
|||
})
|
||||
}
|
||||
|
||||
// Attach user ID to request
|
||||
// 3️⃣ Attach user ID to request
|
||||
req.PlayerID = fmt.Sprintf("%d", userId)
|
||||
|
||||
// Default language if not provided
|
||||
// 4️⃣ Set defaults if not provided
|
||||
if req.Language == "" {
|
||||
req.Language = "en"
|
||||
}
|
||||
|
||||
// Default currency if not provided
|
||||
if req.Currency == "" {
|
||||
req.Currency = "USD"
|
||||
}
|
||||
|
||||
// Call the service
|
||||
// 5️⃣ Call the Atlas service
|
||||
res, err := h.atlasVirtualGameSvc.InitGame(context.Background(), req)
|
||||
if err != nil {
|
||||
log.Println("InitAtlasGame error:", err)
|
||||
|
||||
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to initialize Atlas game",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
// 6️⃣ Update provider report: increment total_games_played
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
reportDate := time.Now().Truncate(24 * time.Hour)
|
||||
reportType := "daily"
|
||||
providerID := "atlas" // all Atlas games belong to this provider
|
||||
|
||||
err := h.orchestrationSvc.UpdateVirtualGameProviderReportByDate(
|
||||
ctx,
|
||||
providerID,
|
||||
reportDate,
|
||||
reportType,
|
||||
1, // increment total_games_played by 1
|
||||
0, // total_bets (no change)
|
||||
0, // total_payouts (no change)
|
||||
1, // total_players (no change)
|
||||
)
|
||||
if err != nil {
|
||||
h.InternalServerErrorLogger().Error("Failed to update total_games_played for Atlas game",
|
||||
zap.String("provider_id", providerID),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
// 7️⃣ Return response to user
|
||||
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||
Message: "Game initialized successfully",
|
||||
Data: res,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import (
|
|||
virtualgameservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame"
|
||||
alea "github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/Alea"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/atlas"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/orchestration"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/veli"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
|
||||
jwtutil "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/jwt"
|
||||
|
|
@ -41,6 +42,7 @@ import (
|
|||
)
|
||||
|
||||
type Handler struct {
|
||||
orchestrationSvc *orchestration.Service
|
||||
enetPulseSvc *enetpulse.Service
|
||||
telebirrSvc *telebirr.TelebirrService
|
||||
arifpaySvc *arifpay.ArifpayService
|
||||
|
|
@ -68,7 +70,7 @@ type Handler struct {
|
|||
leagueSvc league.Service
|
||||
virtualGameSvc virtualgameservice.VirtualGameService
|
||||
aleaVirtualGameSvc alea.AleaVirtualGameService
|
||||
veliVirtualGameSvc veli.VeliVirtualGameService
|
||||
veliVirtualGameSvc *veli.Service
|
||||
atlasVirtualGameSvc atlas.AtlasVirtualGameService
|
||||
recommendationSvc recommendation.RecommendationService
|
||||
authSvc *authentication.Service
|
||||
|
|
@ -80,6 +82,7 @@ type Handler struct {
|
|||
}
|
||||
|
||||
func New(
|
||||
orchestrationSvc *orchestration.Service,
|
||||
enetPulseSvc *enetpulse.Service,
|
||||
telebirrSvc *telebirr.TelebirrService,
|
||||
arifpaySvc *arifpay.ArifpayService,
|
||||
|
|
@ -99,7 +102,7 @@ func New(
|
|||
bonusSvc *bonus.Service,
|
||||
virtualGameSvc virtualgameservice.VirtualGameService,
|
||||
aleaVirtualGameSvc alea.AleaVirtualGameService,
|
||||
veliVirtualGameSvc veli.VeliVirtualGameService,
|
||||
veliVirtualGameSvc *veli.Service,
|
||||
atlasVirtualGameSvc atlas.AtlasVirtualGameService,
|
||||
recommendationSvc recommendation.RecommendationService,
|
||||
userSvc *user.Service,
|
||||
|
|
@ -118,6 +121,7 @@ func New(
|
|||
mongoLoggerSvc *zap.Logger,
|
||||
) *Handler {
|
||||
return &Handler{
|
||||
orchestrationSvc: orchestrationSvc,
|
||||
enetPulseSvc: enetPulseSvc,
|
||||
telebirrSvc: telebirrSvc,
|
||||
arifpaySvc: arifpaySvc,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package handlers
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
// "fmt"
|
||||
"strings"
|
||||
|
||||
|
|
@ -120,15 +122,6 @@ func (h *Handler) GetGamesByProvider(c *fiber.Ctx) error {
|
|||
// @Failure 502 {object} domain.ErrorResponse
|
||||
// @Router /api/v1/veli/start-game [post]
|
||||
func (h *Handler) StartGame(c *fiber.Ctx) error {
|
||||
// userId, ok := c.Locals("user_id").(int64)
|
||||
// fmt.Printf("\n\nVeli Start Game User ID is %v\n\n", userId)
|
||||
// if !ok {
|
||||
// return c.Status(fiber.StatusUnauthorized).JSON(domain.ErrorResponse{
|
||||
// Error: "missing user id",
|
||||
// Message: "Unauthorized",
|
||||
// })
|
||||
// }
|
||||
|
||||
var req domain.GameStartRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
|
|
@ -137,11 +130,6 @@ func (h *Handler) StartGame(c *fiber.Ctx) error {
|
|||
})
|
||||
}
|
||||
|
||||
// There needs to be a way to generate a sessionID
|
||||
|
||||
// Attach user ID to request
|
||||
// req.PlayerID = fmt.Sprintf("%d", userId)
|
||||
|
||||
// Default brand if not provided
|
||||
if req.BrandID == "" {
|
||||
req.BrandID = h.Cfg.VeliGames.BrandID
|
||||
|
|
@ -149,13 +137,14 @@ func (h *Handler) StartGame(c *fiber.Ctx) error {
|
|||
|
||||
req.IP = c.IP()
|
||||
|
||||
// 1️⃣ Call StartGame service
|
||||
res, err := h.veliVirtualGameSvc.StartGame(context.Background(), req)
|
||||
if err != nil {
|
||||
h.InternalServerErrorLogger().Error("Failed to [VeliGameHandler]StartGame",
|
||||
zap.Any("request", req),
|
||||
zap.Error(err),
|
||||
)
|
||||
// Handle provider disabled case specifically
|
||||
|
||||
if strings.Contains(err.Error(), "is disabled") {
|
||||
return c.Status(fiber.StatusForbidden).JSON(domain.ErrorResponse{
|
||||
Message: "Provider is disabled",
|
||||
|
|
@ -163,13 +152,39 @@ func (h *Handler) StartGame(c *fiber.Ctx) error {
|
|||
})
|
||||
}
|
||||
|
||||
// Fallback for other errors
|
||||
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to start game",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
// 2️⃣ Game started successfully → Update total_games_played
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
reportDate := time.Now().Truncate(24 * time.Hour)
|
||||
reportType := "daily"
|
||||
|
||||
// Increment total_games_played by 1
|
||||
err := h.orchestrationSvc.UpdateVirtualGameProviderReportByDate(
|
||||
ctx,
|
||||
req.ProviderID,
|
||||
reportDate,
|
||||
reportType,
|
||||
1, // increment total_games_played by 1
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
h.InternalServerErrorLogger().Error("Failed to update total_games_played",
|
||||
zap.String("provider_id", req.ProviderID),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
// 3️⃣ Return response to user
|
||||
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||
Message: "Game started successfully",
|
||||
Data: res,
|
||||
|
|
@ -261,15 +276,13 @@ func (h *Handler) GetBalance(c *fiber.Ctx) error {
|
|||
func (h *Handler) PlaceBet(c *fiber.Ctx) error {
|
||||
var req domain.BetRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
// return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
Message: "Invalid request body",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
// Signature check optional here
|
||||
|
||||
// 1️⃣ Process the bet with the external provider
|
||||
res, err := h.veliVirtualGameSvc.ProcessBet(c.Context(), req)
|
||||
if err != nil {
|
||||
if errors.Is(err, veli.ErrDuplicateTransaction) {
|
||||
|
|
@ -279,10 +292,42 @@ func (h *Handler) PlaceBet(c *fiber.Ctx) error {
|
|||
Message: "Failed to process bet",
|
||||
Error: err.Error(),
|
||||
})
|
||||
// return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(res)
|
||||
// 2️⃣ If bet successful → update total_bets in the report
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
reportDate := time.Now().Truncate(24 * time.Hour)
|
||||
reportType := "daily"
|
||||
|
||||
// Increment total_bets by the bet amount
|
||||
err := h.orchestrationSvc.UpdateVirtualGameProviderReportByDate(
|
||||
ctx,
|
||||
req.ProviderID,
|
||||
reportDate,
|
||||
reportType,
|
||||
0, // total_games_played (no change)
|
||||
req.Amount.Amount, // add this bet to total_bets
|
||||
0, // total_payouts (no change)
|
||||
0, // total_players (no change)
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
h.InternalServerErrorLogger().Error("Failed to update total_bets after bet",
|
||||
zap.String("provider_id", req.ProviderID),
|
||||
zap.Float64("bet_amount", req.Amount.Amount),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
// 3️⃣ Return success response
|
||||
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||
Message: "Bet processed successfully",
|
||||
Data: res,
|
||||
StatusCode: fiber.StatusOK,
|
||||
Success: true,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *Handler) RegisterWin(c *fiber.Ctx) error {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,54 @@ type launchVirtualGameRes struct {
|
|||
LaunchURL string `json:"launch_url"`
|
||||
}
|
||||
|
||||
// ListVirtualGameProviderReportsAscHandler
|
||||
// @Summary List virtual game provider reports (ascending)
|
||||
// @Description Retrieves all virtual game provider reports sorted by total_games_played in ascending order
|
||||
// @Tags VirtualGames - Orchestration
|
||||
// @Success 200 {array} domain.VirtualGameProviderReport
|
||||
// @Failure 500 {object} domain.ErrorResponse
|
||||
// @Router /api/v1/orchestrator/virtual-game/provider-reports/asc [get]
|
||||
func (h *Handler) ListVirtualGameProviderReportsAscHandler(c *fiber.Ctx) error {
|
||||
reports, err := h.orchestrationSvc.ListVirtualGameProviderReportsByGamesPlayedAsc(c.Context())
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to fetch virtual game provider reports ascending",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||
Message: "Virtual game provider reports retrieved successfully",
|
||||
Data: reports,
|
||||
StatusCode: fiber.StatusOK,
|
||||
Success: true,
|
||||
})
|
||||
}
|
||||
|
||||
// ListVirtualGameProviderReportsDescHandler
|
||||
// @Summary List virtual game provider reports (descending)
|
||||
// @Description Retrieves all virtual game provider reports sorted by total_games_played in descending order
|
||||
// @Tags VirtualGames - Orchestration
|
||||
// @Success 200 {array} domain.VirtualGameProviderReport
|
||||
// @Failure 500 {object} domain.ErrorResponse
|
||||
// @Router /api/v1/orchestrator/virtual-game/provider-reports/desc [get]
|
||||
func (h *Handler) ListVirtualGameProviderReportsDescHandler(c *fiber.Ctx) error {
|
||||
reports, err := h.orchestrationSvc.ListVirtualGameProviderReportsByGamesPlayedDesc(c.Context())
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to fetch virtual game provider reports descending",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||
Message: "Virtual game provider reports retrieved successfully",
|
||||
Data: reports,
|
||||
StatusCode: fiber.StatusOK,
|
||||
Success: true,
|
||||
})
|
||||
}
|
||||
|
||||
// ListVirtualGames godoc
|
||||
// @Summary List all virtual games
|
||||
// @Description Returns all virtual games with optional filters (category, search, pagination)
|
||||
|
|
@ -77,7 +125,7 @@ func (h *Handler) ListVirtualGames(c *fiber.Ctx) error {
|
|||
}
|
||||
|
||||
// --- Call service method ---
|
||||
games, err := h.veliVirtualGameSvc.GetAllVirtualGames(c.Context(), params)
|
||||
games, err := h.orchestrationSvc.GetAllVirtualGames(c.Context(), params)
|
||||
if err != nil {
|
||||
log.Println("ListVirtualGames error:", err)
|
||||
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
|
||||
|
|
@ -105,7 +153,7 @@ func (h *Handler) ListVirtualGames(c *fiber.Ctx) error {
|
|||
// @Router /api/v1/virtual-game/providers/{provider_id} [delete]
|
||||
func (h *Handler) RemoveProvider(c *fiber.Ctx) error {
|
||||
providerID := c.Params("providerID")
|
||||
if err := h.virtualGameSvc.RemoveProvider(c.Context(), providerID); err != nil {
|
||||
if err := h.orchestrationSvc.RemoveProvider(c.Context(), providerID); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Could not remove provider")
|
||||
}
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
|
|
@ -122,7 +170,7 @@ func (h *Handler) RemoveProvider(c *fiber.Ctx) error {
|
|||
// @Router /api/v1/virtual-game/providers/{provider_id} [get]
|
||||
func (h *Handler) GetProviderByID(c *fiber.Ctx) error {
|
||||
providerID := c.Params("providerID")
|
||||
provider, err := h.virtualGameSvc.GetProviderByID(c.Context(), providerID)
|
||||
provider, err := h.orchestrationSvc.GetProviderByID(c.Context(), providerID)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Could not fetch provider")
|
||||
}
|
||||
|
|
@ -143,7 +191,7 @@ func (h *Handler) ListProviders(c *fiber.Ctx) error {
|
|||
limit, _ := strconv.Atoi(c.Query("limit", "20"))
|
||||
offset, _ := strconv.Atoi(c.Query("offset", "0"))
|
||||
|
||||
providers, total, err := h.virtualGameSvc.ListProviders(c.Context(), int32(limit), int32(offset))
|
||||
providers, total, err := h.orchestrationSvc.ListProviders(c.Context(), int32(limit), int32(offset))
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Could not list providers")
|
||||
}
|
||||
|
|
@ -168,7 +216,7 @@ func (h *Handler) SetProviderEnabled(c *fiber.Ctx) error {
|
|||
providerID := c.Params("providerID")
|
||||
enabled, _ := strconv.ParseBool(c.Query("enabled", "true"))
|
||||
|
||||
provider, err := h.virtualGameSvc.SetProviderEnabled(c.Context(), providerID, enabled)
|
||||
provider, err := h.orchestrationSvc.SetProviderEnabled(c.Context(), providerID, enabled)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Could not update provider status")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
|
||||
func (a *App) initAppRoutes() {
|
||||
h := handlers.New(
|
||||
a.orchestrationSvc,
|
||||
a.enetPulseSvc,
|
||||
a.telebirrSvc,
|
||||
a.arifpaySvc,
|
||||
|
|
@ -467,6 +468,8 @@ func (a *App) initAppRoutes() {
|
|||
groupV1.Delete("/virtual-game/favorites/:gameID", a.authMiddleware, h.RemoveFavorite)
|
||||
groupV1.Get("/virtual-game/favorites", a.authMiddleware, h.ListFavorites)
|
||||
|
||||
groupV1.Get("/orchestrator/virtual-game/provider-reports/asc", a.OnlyAdminAndAbove, h.ListVirtualGameProviderReportsAscHandler)
|
||||
groupV1.Get("/orchestrator/virtual-game/provider-reports/desc", a.OnlyAdminAndAbove, h.ListVirtualGameProviderReportsDescHandler)
|
||||
groupV1.Delete("/virtual-game/orchestrator/providers/:provideID", a.authMiddleware, h.RemoveProvider)
|
||||
groupV1.Get("/virtual-game/orchestrator/providers/:provideID", a.authMiddleware, h.GetProviderByID)
|
||||
groupV1.Get("/virtual-game/orchestrator/games", h.ListVirtualGames)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user