fix: Refactored and moved store ports into separate folder

- Added stats service
This commit is contained in:
Samuel Tariku 2025-10-29 01:33:50 +03:00
parent 0ffba57ec5
commit e5fdd33a52
114 changed files with 2063 additions and 1692 deletions

View File

@ -17,5 +17,7 @@
"**/internal/services/**/*.go": "${filename}.${dirname}.service",
"**/internal/domain/**/*.go": "${filename}.${dirname}",
"**/internal/repository/**/*.go": "${filename}.repo",
"**/internal/ports/**/*.go": "${filename}.ports",
"**/internal/web_server/handlers/**/*.go": "${filename}.handlers",
},
}

View File

@ -52,6 +52,7 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/result"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/santimpay"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/settings"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/stats"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/telebirr"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/transaction"
@ -109,86 +110,170 @@ func main() {
v := customvalidator.NewCustomValidator(validator.New())
// Initialize services
settingSvc := settings.NewService(store)
settingSvc := settings.NewService(repository.NewSettingStore(store))
messengerSvc := messenger.NewService(settingSvc, cfg)
statSvc := stats.NewService(
repository.NewCompanyStatStore(store),
repository.NewEventStatStore(store),
)
authSvc := authentication.NewService(store, store, cfg.RefreshExpiry)
userSvc := user.NewService(store, store, messengerSvc, cfg)
eventSvc := event.New(cfg.Bet365Token, store, settingSvc, domain.MongoDBLogger, cfg)
oddsSvc := odds.New(store, cfg, eventSvc, logger, domain.MongoDBLogger)
notificationRepo := repository.NewNotificationRepository(store)
virtuaGamesRepo := repository.NewVirtualGameRepository(store)
// var userStore user.UserStore
authSvc := authentication.NewService(
repository.NewUserStore(store),
repository.NewTokenStore(store),
cfg.RefreshExpiry,
)
userSvc := user.NewService(
repository.NewUserStore(store),
repository.NewOTPStore(store),
messengerSvc,
cfg,
)
leagueSvc := league.New(repository.NewLeagueStore(store))
eventSvc := event.New(
cfg.Bet365Token,
repository.NewEventStore(store),
repository.NewEventHistoryStore(store),
*leagueSvc,
settingSvc,
domain.MongoDBLogger,
cfg,
)
oddsSvc := odds.New(
repository.NewOddStore(store),
cfg,
eventSvc,
logger,
domain.MongoDBLogger,
)
// virtuaGamesRepo := repository.NewVirtualGameRepository(store)
// Initialize producer
// topic := "wallet-balance-topic"
// producer := kafka.NewProducer(cfg.KafkaBrokers, topic)
notificationSvc := notificationservice.New(notificationRepo, domain.MongoDBLogger, logger, cfg, messengerSvc, userSvc)
notificationSvc := notificationservice.New(
repository.NewNotificationStore(store),
domain.MongoDBLogger,
logger,
cfg,
messengerSvc,
userSvc,
)
walletSvc := wallet.NewService(
wallet.WalletStore(store),
wallet.TransferStore(store),
wallet.DirectDepositStore(store),
repository.NewWalletStore(store),
repository.NewTransferStore(store),
repository.NewDirectDepositStore(store),
notificationSvc,
userSvc,
domain.MongoDBLogger,
logger,
)
branchSvc := branch.NewService(store)
companySvc := company.NewService(store)
leagueSvc := league.New(store)
ticketSvc := ticket.NewService(store, eventSvc, *oddsSvc, domain.MongoDBLogger, settingSvc, notificationSvc)
betSvc := bet.NewService(store, eventSvc, *oddsSvc, *walletSvc, *branchSvc, *companySvc, *settingSvc, *userSvc, notificationSvc, logger, domain.MongoDBLogger)
resultSvc := result.NewService(store, cfg, logger, domain.MongoDBLogger, *betSvc, *oddsSvc, eventSvc, leagueSvc, notificationSvc, messengerSvc, *userSvc)
bonusSvc := bonus.NewService(store, walletSvc, settingSvc, notificationSvc, domain.MongoDBLogger)
referalRepo := repository.NewReferralRepository(store)
branchSvc := branch.NewService(repository.NewBranchStore(store))
companySvc := company.NewService(repository.NewCompanyStore(store))
ticketSvc := ticket.NewService(
repository.NewTicketStore(store),
eventSvc,
*oddsSvc,
domain.MongoDBLogger,
settingSvc,
)
betSvc := bet.NewService(
repository.NewBetStore(store),
eventSvc,
*oddsSvc,
*walletSvc,
*branchSvc,
*companySvc,
*settingSvc,
*userSvc,
notificationSvc,
logger,
domain.MongoDBLogger,
)
resultSvc := result.NewService(
repository.NewResultLogStore(store),
cfg,
logger,
domain.MongoDBLogger,
*betSvc,
*oddsSvc,
eventSvc,
leagueSvc,
notificationSvc,
messengerSvc,
*userSvc,
)
bonusSvc := bonus.NewService(
repository.NewBonusStore(store),
walletSvc,
settingSvc,
notificationSvc,
domain.MongoDBLogger,
)
vitualGameRepo := repository.NewVirtualGameRepository(store)
recommendationRepo := repository.NewRecommendationRepository(store)
referalSvc := referralservice.New(referalRepo, *walletSvc, *settingSvc, cfg, logger, domain.MongoDBLogger)
raffleSvc := raffle.NewService(store)
referalSvc := referralservice.New(
repository.NewReferralStore(store),
*walletSvc,
*settingSvc,
cfg,
logger,
domain.MongoDBLogger,
)
raffleSvc := raffle.NewService(
repository.NewRaffleStore(store),
)
virtualGameSvc := virtualgameservice.New(vitualGameRepo, *walletSvc, store, cfg, logger)
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)
veliVirtualGameService := veli.New(virtualGameSvc, vitualGameRepo, veliCLient, walletSvc, repository.NewTransferStore(store), domain.MongoDBLogger, cfg)
atlasClient := atlas.NewClient(cfg, walletSvc)
atlasVirtualGameService := atlas.New(virtualGameSvc, vitualGameRepo, atlasClient, walletSvc, wallet.TransferStore(store), cfg)
atlasVirtualGameService := atlas.New(virtualGameSvc, vitualGameRepo, atlasClient, walletSvc, repository.NewTransferStore(store), cfg)
recommendationSvc := recommendation.NewService(recommendationRepo)
chapaClient := chapa.NewClient(cfg.CHAPA_BASE_URL, cfg.CHAPA_SECRET_KEY)
chapaSvc := chapa.NewService(
wallet.TransferStore(store),
repository.NewTransferStore(store),
*walletSvc,
user.UserStore(store),
repository.NewUserStore(store),
cfg,
chapaClient,
)
reportRepo := repository.NewReportRepo(store)
currRepo := repository.NewCurrencyPostgresRepository(store)
fixerFertcherSvc := currency.NewFixerFetcher(
cfg.FIXER_API_KEY,
cfg.FIXER_BASE_URL,
)
transactionSvc := transaction.NewService(store, *branchSvc, *betSvc, *walletSvc, *userSvc)
transactionSvc := transaction.NewService(
repository.NewTransactionStore(store),
*branchSvc,
*betSvc,
*walletSvc,
*userSvc,
)
reportSvc := report.NewService(
store,
bet.BetStore(store),
wallet.WalletStore(store),
transaction.TransactionStore(store),
branch.BranchStore(store),
user.UserStore(store),
reportRepo,
company.CompanyStore(store),
virtuaGamesRepo,
notificationRepo,
repository.NewReportStore(store),
repository.NewBetStore(store),
repository.NewWalletStore(store),
repository.NewTransactionStore(store),
repository.NewBranchStore(store),
repository.NewUserStore(store),
repository.NewOldRepositoryStore(store),
repository.NewCompanyStore(store),
repository.NewVirtualGameRepository(store),
repository.NewNotificationStore(store),
notificationSvc,
eventSvc,
companySvc,
statSvc,
logger,
domain.MongoDBLogger,
cfg,
@ -242,16 +327,16 @@ func main() {
defer exchangeWorker.Stop()
go walletMonitorSvc.Start()
httpserver.StartDataFetchingCrons(eventSvc, *oddsSvc, resultSvc, domain.MongoDBLogger)
httpserver.StartBetAPIDataFetchingCrons(eventSvc, *oddsSvc, resultSvc, domain.MongoDBLogger)
httpserver.StartCleanupCrons(*ticketSvc, notificationSvc, domain.MongoDBLogger)
httpserver.StartStatCrons(*companySvc, eventSvc, domain.MongoDBLogger)
httpserver.StartStatCrons(statSvc, domain.MongoDBLogger)
httpserver.StartReportCrons(reportSvc, domain.MongoDBLogger)
issueReportingRepo := repository.NewReportedIssueRepository(store)
issueReportingSvc := issuereporting.New(issueReportingRepo)
transferStore := wallet.TransferStore(store)
transferStore := repository.NewTransferStore(store)
// walletStore := wallet.WalletStore(store)
arifpaySvc := arifpay.NewArifpayService(cfg, transferStore, walletSvc, &http.Client{
@ -303,6 +388,7 @@ func main() {
// veliService,
recommendationSvc,
resultSvc,
statSvc,
cfg,
domain.MongoDBLogger,
)

View File

@ -393,14 +393,6 @@ CREATE TABLE odd_history (
odd_value DOUBLE PRECISION NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE disabled_odd (
id BIGSERIAL PRIMARY KEY,
company_id BIGINT NOT NULL,
odds_market_id BIGINT NOT NULL,
raw_odd_id BIGINT NOT NULL,
event_id BIGINT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE company_odd_settings (
id BIGSERIAL PRIMARY KEY,
company_id BIGINT NOT NULL,

View File

@ -1,26 +0,0 @@
-- name: InsertDisabledOdds :one
INSERT INTO disabled_odd (
odds_market_id,
company_id,
event_id,
raw_odd_id
)
VALUES ($1, $2, $3, $4)
RETURNING *;
-- name: GetAllDisabledOdds :many
SELECT *
FROM disabled_odd;
-- name: GetDisabledOddByRawOddID :one
SELECT *
FROM disabled_odd
WHERE raw_odd_id = $1;
-- name: GetDisabledOddByID :one
SELECT *
FROM disabled_odd
WHERE raw_odd_id = $1;
-- name: DeleteDisabledOddsByID :exec
DELETE FROM disabled_odd
WHERE raw_odd_id = $1;
-- name: DeleteDisabledOddsByRawOddID :exec
DELETE FROM disabled_odd
WHERE raw_odd_id = $1;

View File

@ -1,139 +0,0 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
// source: disabled_odds.sql
package dbgen
import (
"context"
)
const DeleteDisabledOddsByID = `-- name: DeleteDisabledOddsByID :exec
DELETE FROM disabled_odd
WHERE raw_odd_id = $1
`
func (q *Queries) DeleteDisabledOddsByID(ctx context.Context, rawOddID int64) error {
_, err := q.db.Exec(ctx, DeleteDisabledOddsByID, rawOddID)
return err
}
const DeleteDisabledOddsByRawOddID = `-- name: DeleteDisabledOddsByRawOddID :exec
DELETE FROM disabled_odd
WHERE raw_odd_id = $1
`
func (q *Queries) DeleteDisabledOddsByRawOddID(ctx context.Context, rawOddID int64) error {
_, err := q.db.Exec(ctx, DeleteDisabledOddsByRawOddID, rawOddID)
return err
}
const GetAllDisabledOdds = `-- name: GetAllDisabledOdds :many
SELECT id, company_id, odds_market_id, raw_odd_id, event_id, created_at
FROM disabled_odd
`
func (q *Queries) GetAllDisabledOdds(ctx context.Context) ([]DisabledOdd, error) {
rows, err := q.db.Query(ctx, GetAllDisabledOdds)
if err != nil {
return nil, err
}
defer rows.Close()
var items []DisabledOdd
for rows.Next() {
var i DisabledOdd
if err := rows.Scan(
&i.ID,
&i.CompanyID,
&i.OddsMarketID,
&i.RawOddID,
&i.EventID,
&i.CreatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const GetDisabledOddByID = `-- name: GetDisabledOddByID :one
SELECT id, company_id, odds_market_id, raw_odd_id, event_id, created_at
FROM disabled_odd
WHERE raw_odd_id = $1
`
func (q *Queries) GetDisabledOddByID(ctx context.Context, rawOddID int64) (DisabledOdd, error) {
row := q.db.QueryRow(ctx, GetDisabledOddByID, rawOddID)
var i DisabledOdd
err := row.Scan(
&i.ID,
&i.CompanyID,
&i.OddsMarketID,
&i.RawOddID,
&i.EventID,
&i.CreatedAt,
)
return i, err
}
const GetDisabledOddByRawOddID = `-- name: GetDisabledOddByRawOddID :one
SELECT id, company_id, odds_market_id, raw_odd_id, event_id, created_at
FROM disabled_odd
WHERE raw_odd_id = $1
`
func (q *Queries) GetDisabledOddByRawOddID(ctx context.Context, rawOddID int64) (DisabledOdd, error) {
row := q.db.QueryRow(ctx, GetDisabledOddByRawOddID, rawOddID)
var i DisabledOdd
err := row.Scan(
&i.ID,
&i.CompanyID,
&i.OddsMarketID,
&i.RawOddID,
&i.EventID,
&i.CreatedAt,
)
return i, err
}
const InsertDisabledOdds = `-- name: InsertDisabledOdds :one
INSERT INTO disabled_odd (
odds_market_id,
company_id,
event_id,
raw_odd_id
)
VALUES ($1, $2, $3, $4)
RETURNING id, company_id, odds_market_id, raw_odd_id, event_id, created_at
`
type InsertDisabledOddsParams struct {
OddsMarketID int64 `json:"odds_market_id"`
CompanyID int64 `json:"company_id"`
EventID int64 `json:"event_id"`
RawOddID int64 `json:"raw_odd_id"`
}
func (q *Queries) InsertDisabledOdds(ctx context.Context, arg InsertDisabledOddsParams) (DisabledOdd, error) {
row := q.db.QueryRow(ctx, InsertDisabledOdds,
arg.OddsMarketID,
arg.CompanyID,
arg.EventID,
arg.RawOddID,
)
var i DisabledOdd
err := row.Scan(
&i.ID,
&i.CompanyID,
&i.OddsMarketID,
&i.RawOddID,
&i.EventID,
&i.CreatedAt,
)
return i, err
}

View File

@ -279,15 +279,6 @@ type DirectDeposit struct {
VerifiedAt pgtype.Timestamp `json:"verified_at"`
}
type DisabledOdd struct {
ID int64 `json:"id"`
CompanyID int64 `json:"company_id"`
OddsMarketID int64 `json:"odds_market_id"`
RawOddID int64 `json:"raw_odd_id"`
EventID int64 `json:"event_id"`
CreatedAt pgtype.Timestamp `json:"created_at"`
}
type EnetpulseSport struct {
ID int64 `json:"id"`
SportID string `json:"sport_id"`

View File

@ -0,0 +1,113 @@
package domain
import (
"time"
"math/big"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/jackc/pgx/v5/pgtype"
)
type DirectDepositStatus string
const (
DepositStatusPending DirectDepositStatus = "pending"
DepositStatusCompleted DirectDepositStatus = "completed"
DepositStatusRejected DirectDepositStatus = "rejected"
)
type DirectDeposit struct {
ID int64 `json:"id"`
CustomerID int64 `json:"customer_id"`
WalletID int64 `json:"wallet_id"`
Wallet Wallet `json:"wallet"`
Amount Currency `json:"amount"`
BankReference string `json:"bank_reference"`
SenderAccount string `json:"sender_account"`
Status DirectDepositStatus `json:"status"`
CreatedAt time.Time `json:"created_at"`
VerifiedBy *int64 `json:"verified_by"`
VerificationNotes string `json:"verification_notes"`
VerifiedAt *time.Time `json:"verified_at"`
}
type CreateDirectDeposit struct {
CustomerID int64
WalletID int64
Amount Currency
BankReference string
SenderAccount string
Status DirectDepositStatus
}
type UpdateDirectDeposit struct {
ID int64
Status DirectDepositStatus
VerifiedBy int64
VerificationNotes string
VerifiedAt time.Time
}
type DirectDepositRequest struct {
CustomerID int64 `json:"customer_id" binding:"required"`
Amount Currency `json:"amount" binding:"required,gt=0"`
BankReference string `json:"bank_reference" binding:"required"`
SenderAccount string `json:"sender_account" binding:"required"`
}
type VerifyDirectDepositRequest struct {
DepositID int64 `json:"deposit_id" binding:"required"`
IsVerified bool `json:"is_verified" binding:"required"`
Notes string `json:"notes"`
}
func ConvertDBDirectDeposit(deposit dbgen.DirectDeposit) DirectDeposit {
return DirectDeposit{
ID: deposit.ID,
CustomerID: deposit.CustomerID,
WalletID: deposit.WalletID,
Amount: Currency(deposit.Amount.Int.Int64()),
BankReference: deposit.BankReference,
SenderAccount: deposit.SenderAccount,
Status: DirectDepositStatus(deposit.Status),
CreatedAt: deposit.CreatedAt.Time,
VerifiedBy: convertPgInt64ToPtr(deposit.VerifiedBy),
VerificationNotes: deposit.VerificationNotes.String,
VerifiedAt: convertPgTimeToPtr(deposit.VerifiedAt),
}
}
func ConvertCreateDirectDeposit(deposit CreateDirectDeposit) dbgen.CreateDirectDepositParams {
return dbgen.CreateDirectDepositParams{
CustomerID: deposit.CustomerID,
WalletID: deposit.WalletID,
Amount: pgtype.Numeric{Int: big.NewInt(int64(deposit.Amount)), Valid: true},
BankReference: deposit.BankReference,
SenderAccount: deposit.SenderAccount,
Status: string(deposit.Status),
}
}
func ConvertUpdateDirectDeposit(deposit UpdateDirectDeposit) dbgen.UpdateDirectDepositParams {
return dbgen.UpdateDirectDepositParams{
ID: deposit.ID,
Status: string(deposit.Status),
VerifiedBy: pgtype.Int8{Int64: deposit.VerifiedBy, Valid: true},
VerificationNotes: pgtype.Text{String: deposit.VerificationNotes, Valid: deposit.VerificationNotes != ""},
VerifiedAt: pgtype.Timestamp{Time: deposit.VerifiedAt, Valid: true},
}
}
func convertPgInt64ToPtr(i pgtype.Int8) *int64 {
if i.Valid {
return &i.Int64
}
return nil
}
func convertPgTimeToPtr(t pgtype.Timestamp) *time.Time {
if t.Valid {
return &t.Time
}
return nil
}

View File

@ -1,51 +0,0 @@
package domain
import (
"time"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
)
type DisabledOdd struct {
ID int64
OddMarketID int64
RawOddID int64
EventID int64
CompanyID int64
CreatedAt time.Time
}
type CreateDisabledOdd struct {
OddMarketID int64
RawOddID int64
EventID int64
CompanyID int64
}
func ConvertCreateDisabledOdd(odd CreateDisabledOdd) dbgen.InsertDisabledOddsParams {
return dbgen.InsertDisabledOddsParams{
OddsMarketID: odd.OddMarketID,
EventID: odd.EventID,
CompanyID: odd.CompanyID,
RawOddID: odd.RawOddID,
}
}
func ConvertDBDisabledOdd(dbDisabledOdd dbgen.DisabledOdd) DisabledOdd {
return DisabledOdd{
ID: dbDisabledOdd.ID,
OddMarketID: dbDisabledOdd.OddsMarketID,
RawOddID: dbDisabledOdd.RawOddID,
EventID: dbDisabledOdd.EventID,
CompanyID: dbDisabledOdd.CompanyID,
CreatedAt: dbDisabledOdd.CreatedAt.Time,
}
}
func ConvertDisabledOdds(list []dbgen.DisabledOdd) []DisabledOdd {
result := make([]DisabledOdd, 0, len(list))
for _, item := range list {
result = append(result, ConvertDBDisabledOdd(item))
}
return result
}

View File

@ -1,6 +1,11 @@
package domain
import "time"
import (
"time"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/jackc/pgx/v5/pgtype"
)
type Raffle struct {
ID int32
@ -83,3 +88,62 @@ type UpdateRaffleParams struct {
Name string `json:"name" validate:"required_without_all=ExpiresAt"`
ExpiresAt *time.Time `json:"expires_at" validate:"required_without_all=Name"`
}
func ConvertRaffleOutcome(raffle dbgen.Raffle) Raffle {
return Raffle{
ID: raffle.ID,
CompanyID: raffle.CompanyID,
Name: raffle.Name,
CreatedAt: raffle.CreatedAt.Time,
ExpiresAt: raffle.ExpiresAt.Time,
TicketLimit: raffle.TicketLimit,
Type: raffle.Type,
Status: raffle.Status,
}
}
func ConvertRaffleTicketOutcome(raffle dbgen.RaffleTicket) RaffleTicket {
return RaffleTicket{
ID: raffle.ID,
RaffleID: raffle.RaffleID,
UserID: raffle.UserID,
IsActive: raffle.IsActive.Bool,
}
}
func ConvertJoinedRaffleTicketOutcome(raffle dbgen.GetUserRaffleTicketsRow) RaffleTicketRes {
return RaffleTicketRes{
TicketID: raffle.TicketID,
UserID: raffle.UserID,
Name: raffle.Name,
Type: raffle.Type,
ExpiresAt: raffle.ExpiresAt.Time,
Status: raffle.Status,
}
}
func ConvertCreateRaffle(raffle CreateRaffle) dbgen.CreateRaffleParams {
return dbgen.CreateRaffleParams{
CompanyID: raffle.CompanyID,
Name: raffle.Name,
ExpiresAt: pgtype.Timestamp{
Time: *raffle.ExpiresAt,
Valid: true,
},
TicketLimit: raffle.TicketLimit,
Type: raffle.Type,
}
}
func ConvertRaffleStanding(raffleStanding dbgen.GetRaffleStandingRow) RaffleStanding {
return RaffleStanding{
UserID: raffleStanding.UserID,
RaffleID: raffleStanding.RaffleID,
FirstName: raffleStanding.FirstName,
LastName: raffleStanding.LastName,
PhoneNumber: raffleStanding.PhoneNumber.String,
Email: raffleStanding.Email.String,
TicketCount: raffleStanding.TicketCount,
}
}

View File

@ -1,6 +1,10 @@
package domain
import "time"
import (
"time"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
)
type ShopTransactionType int
@ -191,3 +195,121 @@ func ConvertShopTransactionDetail(transaction ShopTransactionDetail) ShopTransac
type UpdateTransactionVerifiedReq struct {
Verified bool `json:"verified" example:"true"`
}
func ConvertDBShopTransaction(transaction dbgen.ShopTransaction) ShopTransaction {
return ShopTransaction{
ID: transaction.ID,
Amount: Currency(transaction.Amount),
BranchID: transaction.BranchID,
UserID: transaction.UserID,
Type: ShopTransactionType(transaction.Type),
PaymentOption: PaymentOption(transaction.PaymentOption),
FullName: transaction.FullName,
PhoneNumber: transaction.PhoneNumber,
BankCode: ValidString{
Value: transaction.BankCode.String,
Valid: transaction.BankCode.Valid,
},
BeneficiaryName: ValidString{
Value: transaction.BeneficiaryName.String,
Valid: transaction.BeneficiaryName.Valid,
},
AccountName: ValidString{
Value: transaction.AccountName.String,
Valid: transaction.AccountName.Valid,
},
AccountNumber: ValidString{
Value: transaction.AccountName.String,
Valid: transaction.AccountNumber.Valid,
},
ReferenceNumber: ValidString{
Value: transaction.ReferenceNumber.String,
Valid: transaction.ReferenceNumber.Valid,
},
ApprovedBy: ValidInt64{
Value: transaction.ApprovedBy.Int64,
Valid: transaction.ApprovedBy.Valid,
},
CreatedAt: transaction.CreatedAt.Time,
UpdatedAt: transaction.UpdatedAt.Time,
Verified: transaction.Verified,
CompanyID: transaction.CompanyID,
}
}
func ConvertDBShopTransactionDetail(transaction dbgen.ShopTransactionDetail) ShopTransactionDetail {
return ShopTransactionDetail{
ID: transaction.ID,
Amount: Currency(transaction.Amount),
BranchID: transaction.BranchID,
UserID: transaction.UserID,
CreatorFirstName: transaction.CreatorFirstName.String,
CreatorLastName: transaction.CreatorLastName.String,
CreatorPhoneNumber: transaction.CreatorPhoneNumber.String,
Type: ShopTransactionType(transaction.Type),
PaymentOption: PaymentOption(transaction.PaymentOption),
FullName: transaction.FullName,
PhoneNumber: transaction.PhoneNumber,
BankCode: ValidString{
Value: transaction.BankCode.String,
Valid: transaction.BankCode.Valid,
},
BeneficiaryName: ValidString{
Value: transaction.BeneficiaryName.String,
Valid: transaction.BeneficiaryName.Valid,
},
AccountName: ValidString{
Value: transaction.AccountName.String,
Valid: transaction.AccountName.Valid,
},
AccountNumber: ValidString{
Value: transaction.AccountName.String,
Valid: transaction.AccountNumber.Valid,
},
ReferenceNumber: ValidString{
Value: transaction.ReferenceNumber.String,
Valid: transaction.ReferenceNumber.Valid,
},
ApprovedBy: ValidInt64{
Value: transaction.ApprovedBy.Int64,
Valid: transaction.ApprovedBy.Valid,
},
ApproverFirstName: ValidString{
Value: transaction.ApproverFirstName.String,
Valid: transaction.ApproverFirstName.Valid,
},
ApproverLastName: ValidString{
Value: transaction.ApproverLastName.String,
Valid: transaction.ApproverLastName.Valid,
},
ApproverPhoneNumber: ValidString{
Value: transaction.ApproverPhoneNumber.String,
Valid: transaction.ApproverPhoneNumber.Valid,
},
CreatedAt: transaction.CreatedAt.Time,
UpdatedAt: transaction.UpdatedAt.Time,
Verified: transaction.Verified,
CompanyID: transaction.CompanyID,
BranchName: transaction.BranchName.String,
BranchLocation: transaction.BranchLocation.String,
}
}
func ConvertCreateShopTransaction(transaction CreateShopTransaction) dbgen.CreateShopTransactionParams {
return dbgen.CreateShopTransactionParams{
Amount: int64(transaction.Amount),
BranchID: transaction.BranchID,
UserID: transaction.UserID,
Type: int64(transaction.Type),
PaymentOption: int64(transaction.PaymentOption),
FullName: transaction.FullName,
PhoneNumber: transaction.PhoneNumber,
CompanyID: transaction.CompanyID,
BankCode: transaction.BankCode.ToPG(),
BeneficiaryName: transaction.BeneficiaryName.ToPG(),
AccountName: transaction.AccountName.ToPG(),
AccountNumber: transaction.AccountNumber.ToPG(),
ReferenceNumber: transaction.ReferenceNumber.ToPG(),
}
}

View File

@ -1,6 +1,11 @@
package domain
import "time"
import (
"time"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/jackc/pgx/v5/pgtype"
)
type TicketOutcome struct {
ID int64 `json:"id" example:"1"`
@ -89,3 +94,72 @@ type TicketRes struct {
type TicketFilter struct {
CompanyID ValidInt64
}
func ConvertDBTicket(ticket dbgen.Ticket) Ticket {
return Ticket{
ID: ticket.ID,
Amount: Currency(ticket.Amount),
TotalOdds: ticket.TotalOdds,
CompanyID: ticket.CompanyID,
}
}
func ConvertDBTicketOutcomes(ticket dbgen.TicketWithOutcome) GetTicket {
var outcomes []TicketOutcome = make([]TicketOutcome, 0, len(ticket.Outcomes))
for _, outcome := range ticket.Outcomes {
outcomes = append(outcomes, TicketOutcome{
ID: outcome.ID,
TicketID: outcome.TicketID,
EventID: outcome.EventID,
OddID: outcome.OddID,
HomeTeamName: outcome.HomeTeamName,
AwayTeamName: outcome.AwayTeamName,
MarketID: outcome.MarketID,
MarketName: outcome.MarketName,
Odd: outcome.Odd,
OddName: outcome.OddName,
OddHeader: outcome.OddHeader,
OddHandicap: outcome.OddHandicap,
Status: OutcomeStatus(outcome.Status),
Expires: outcome.Expires.Time,
})
}
return GetTicket{
ID: ticket.ID,
CompanyID: ticket.CompanyID,
Amount: Currency(ticket.Amount),
TotalOdds: ticket.TotalOdds,
Outcomes: outcomes,
}
}
func ConvertDBCreateTicketOutcome(ticketOutcome CreateTicketOutcome) dbgen.CreateTicketOutcomeParams {
return dbgen.CreateTicketOutcomeParams{
TicketID: ticketOutcome.TicketID,
EventID: ticketOutcome.EventID,
OddID: ticketOutcome.OddID,
HomeTeamName: ticketOutcome.HomeTeamName,
AwayTeamName: ticketOutcome.AwayTeamName,
MarketID: ticketOutcome.MarketID,
MarketName: ticketOutcome.MarketName,
Odd: ticketOutcome.Odd,
OddName: ticketOutcome.OddName,
OddHeader: ticketOutcome.OddHeader,
OddHandicap: ticketOutcome.OddHandicap,
Expires: pgtype.Timestamp{
Time: ticketOutcome.Expires,
Valid: true,
},
}
}
func ConvertCreateTicket(ticket CreateTicket) dbgen.CreateTicketParams {
return dbgen.CreateTicketParams{
Amount: int64(ticket.Amount),
TotalOdds: ticket.TotalOdds,
Ip: ticket.IP,
CompanyID: ticket.CompanyID,
}
}

View File

@ -1,6 +1,11 @@
package domain
import "time"
import (
"time"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/jackc/pgx/v5/pgtype"
)
type TransferType string
@ -112,3 +117,82 @@ type TransferStats struct {
TotalWithdraws int64
TotalWalletToWallet int64
}
func ConvertDBTransferDetail(transfer dbgen.WalletTransferDetail) TransferDetail {
return TransferDetail{
ID: transfer.ID,
Amount: Currency(transfer.Amount.Int64),
Type: TransferType(transfer.Type.String),
Verified: transfer.Verified.Bool,
Message: transfer.Message,
ReceiverWalletID: ValidInt64{
Value: transfer.ReceiverWalletID.Int64,
Valid: transfer.ReceiverWalletID.Valid,
},
SenderWalletID: ValidInt64{
Value: transfer.SenderWalletID.Int64,
Valid: transfer.SenderWalletID.Valid,
},
DepositorID: ValidInt64{
Value: transfer.CashierID.Int64,
Valid: transfer.CashierID.Valid,
},
DepositorFirstName: transfer.FirstName.String,
DepositorLastName: transfer.LastName.String,
DepositorPhoneNumber: transfer.PhoneNumber.String,
PaymentMethod: PaymentMethod(transfer.PaymentMethod.String),
ReferenceNumber: transfer.ReferenceNumber,
SessionID: transfer.SessionID.String,
Status: transfer.Status.String,
CreatedAt: transfer.CreatedAt.Time,
UpdatedAt: transfer.UpdatedAt.Time,
}
}
func ConvertDBTransfer(transfer dbgen.WalletTransfer) Transfer {
return Transfer{
ID: transfer.ID,
Amount: Currency(transfer.Amount.Int64),
Type: TransferType(transfer.Type.String),
Verified: transfer.Verified.Bool,
Message: transfer.Message,
ReceiverWalletID: ValidInt64{
Value: transfer.ReceiverWalletID.Int64,
Valid: transfer.ReceiverWalletID.Valid,
},
SenderWalletID: ValidInt64{
Value: transfer.SenderWalletID.Int64,
Valid: transfer.SenderWalletID.Valid,
},
DepositorID: ValidInt64{
Value: transfer.CashierID.Int64,
Valid: transfer.CashierID.Valid,
},
PaymentMethod: PaymentMethod(transfer.PaymentMethod.String),
ReferenceNumber: transfer.ReferenceNumber,
SessionID: transfer.SessionID.String,
Status: transfer.Status.String,
CreatedAt: transfer.CreatedAt.Time,
UpdatedAt: transfer.UpdatedAt.Time,
}
}
func ConvertCreateTransfer(transfer CreateTransfer) dbgen.CreateTransferParams {
return dbgen.CreateTransferParams{
Message: transfer.Message,
Amount: pgtype.Int8{Int64: int64(transfer.Amount), Valid: true},
Type: pgtype.Text{String: string(transfer.Type), Valid: true},
ReceiverWalletID: transfer.ReceiverWalletID.ToPG(),
SenderWalletID: transfer.SenderWalletID.ToPG(),
CashierID: transfer.CashierID.ToPG(),
ReferenceNumber: string(transfer.ReferenceNumber),
SessionID: pgtype.Text{
String: transfer.SessionID,
Valid: true,
},
PaymentMethod: pgtype.Text{String: string(transfer.PaymentMethod), Valid: true},
Verified: pgtype.Bool{
Bool: transfer.Verified,
Valid: true,
},
}
}

View File

@ -3,6 +3,8 @@ package domain
import (
"errors"
"time"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
)
var (
@ -89,57 +91,64 @@ const (
CompanyWalletType WalletType = "company_wallet"
)
// domain/wallet.go
type DirectDepositStatus string
const (
DepositStatusPending DirectDepositStatus = "pending"
DepositStatusCompleted DirectDepositStatus = "completed"
DepositStatusRejected DirectDepositStatus = "rejected"
)
type DirectDeposit struct {
ID int64 `json:"id"`
CustomerID int64 `json:"customer_id"`
WalletID int64 `json:"wallet_id"`
Wallet Wallet `json:"wallet"`
Amount Currency `json:"amount"`
BankReference string `json:"bank_reference"`
SenderAccount string `json:"sender_account"`
Status DirectDepositStatus `json:"status"`
CreatedAt time.Time `json:"created_at"`
VerifiedBy *int64 `json:"verified_by"`
VerificationNotes string `json:"verification_notes"`
VerifiedAt *time.Time `json:"verified_at"`
func ConvertDBWallet(wallet dbgen.Wallet) Wallet {
return Wallet{
ID: wallet.ID,
Balance: Currency(wallet.Balance),
IsWithdraw: wallet.IsWithdraw,
IsBettable: wallet.IsBettable,
IsTransferable: wallet.IsTransferable,
IsActive: wallet.IsActive,
UserID: wallet.UserID,
Type: WalletType(wallet.Type),
UpdatedAt: wallet.UpdatedAt.Time,
CreatedAt: wallet.CreatedAt.Time,
}
}
type CreateDirectDeposit struct {
CustomerID int64
WalletID int64
Amount Currency
BankReference string
SenderAccount string
Status DirectDepositStatus
func ConvertCreateWallet(wallet CreateWallet) dbgen.CreateWalletParams {
return dbgen.CreateWalletParams{
IsWithdraw: wallet.IsWithdraw,
IsBettable: wallet.IsBettable,
IsTransferable: wallet.IsTransferable,
UserID: wallet.UserID,
Type: string(wallet.Type),
}
}
type UpdateDirectDeposit struct {
ID int64
Status DirectDepositStatus
VerifiedBy int64
VerificationNotes string
VerifiedAt time.Time
func ConvertDBCustomerWallet(customerWallet dbgen.CustomerWallet) CustomerWallet {
return CustomerWallet{
ID: customerWallet.ID,
RegularID: customerWallet.RegularWalletID,
StaticID: customerWallet.StaticWalletID,
CustomerID: customerWallet.CustomerID,
}
}
func ConvertCreateCustomerWallet(customerWallet CreateCustomerWallet) dbgen.CreateCustomerWalletParams {
return dbgen.CreateCustomerWalletParams{
CustomerID: customerWallet.CustomerID,
RegularWalletID: customerWallet.RegularWalletID,
StaticWalletID: customerWallet.StaticWalletID,
}
}
type DirectDepositRequest struct {
CustomerID int64 `json:"customer_id" binding:"required"`
Amount Currency `json:"amount" binding:"required,gt=0"`
BankReference string `json:"bank_reference" binding:"required"`
SenderAccount string `json:"sender_account" binding:"required"`
func ConvertDBGetCustomerWallet(customerWallet dbgen.CustomerWalletDetail) GetCustomerWallet {
return GetCustomerWallet{
ID: customerWallet.ID,
RegularID: customerWallet.RegularID,
RegularBalance: Currency(customerWallet.RegularBalance),
StaticID: customerWallet.StaticID,
StaticBalance: Currency(customerWallet.StaticBalance),
CustomerID: customerWallet.CustomerID,
RegularIsActive: customerWallet.RegularIsActive,
StaticIsActive: customerWallet.StaticIsActive,
RegularUpdatedAt: customerWallet.RegularUpdatedAt.Time,
StaticUpdatedAt: customerWallet.StaticUpdatedAt.Time,
CreatedAt: customerWallet.CreatedAt.Time,
FirstName: customerWallet.FirstName,
LastName: customerWallet.LastName,
PhoneNumber: customerWallet.PhoneNumber.String,
}
}
type VerifyDirectDepositRequest struct {
DepositID int64 `json:"deposit_id" binding:"required"`
IsVerified bool `json:"is_verified" binding:"required"`
Notes string `json:"notes"`
}

View File

@ -1,4 +1,4 @@
package authentication
package ports
import (
"context"
@ -6,9 +6,6 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type UserStore interface {
GetUserByEmailPhone(ctx context.Context, email, phone string, companyID domain.ValidInt64) (domain.User, error)
}
type TokenStore interface {
CreateRefreshToken(ctx context.Context, rt domain.RefreshToken) error
GetRefreshToken(ctx context.Context, token string) (domain.RefreshToken, error)

View File

@ -1,9 +1,7 @@
package bet
package ports
import (
"context"
"time"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
@ -51,3 +49,5 @@ type BetStore interface {
GetBetsForCashback(ctx context.Context) ([]domain.GetBet, error)
UpdateBetWithCashback(ctx context.Context, betID int64, cashbackStatus bool) error
}

View File

@ -1,4 +1,5 @@
package bonus
package ports
import (
"context"

View File

@ -1,4 +1,4 @@
package branch
package ports
import (
"context"

View File

@ -1,4 +1,4 @@
package company
package ports
import (
"context"
@ -16,7 +16,11 @@ type CompanyStore interface {
DeleteCompany(ctx context.Context, id int64) error
GetCompanyCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error)
}
type CompanyStatStore interface {
UpdateCompanyStats(ctx context.Context) error
GetCompanyStatByID(ctx context.Context, companyID int64) ([]domain.CompanyStat, error)
GetCompanyStatsByInterval(ctx context.Context, filter domain.CompanyStatFilter) ([]domain.CompanyStat, error)
}

View File

@ -1,4 +1,4 @@
package event
package ports
import (
"context"
@ -7,24 +7,33 @@ import (
)
type EventStore interface {
// FetchLiveEvents(ctx context.Context) error
FetchUpcomingEvents(ctx context.Context) error
SaveEvent(ctx context.Context, e domain.CreateEvent) error
GetAllEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error)
GetEventByID(ctx context.Context, ID int64) (domain.BaseEvent, error)
// GetAndStoreMatchResult(ctx context.Context, eventID int64) error
UpdateFinalScore(ctx context.Context, eventID int64, fullScore string, status domain.EventStatus) error
UpdateEventStatus(ctx context.Context, eventID int64, status domain.EventStatus) error
IsEventMonitored(ctx context.Context, eventID int64) (bool, error)
UpdateEventMonitored(ctx context.Context, eventID int64, IsMonitored bool) error
GetSportAndLeagueIDs(ctx context.Context, eventID int64) ([]int64, error)
GetLiveEventIDs(ctx context.Context) ([]int64, error)
GetEventBySourceID(ctx context.Context, id string, source domain.EventSource) (domain.BaseEvent, error)
DeleteEvent(ctx context.Context, eventID int64) error
// Event Settings Views
GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error)
GetEventWithSettingByID(ctx context.Context, ID int64, companyID int64) (domain.EventWithSettings, error)
UpdateTenantEventSettings(ctx context.Context, event domain.UpdateTenantEventSettings) error
UpdateGlobalEventSettings(ctx context.Context, event domain.UpdateGlobalEventSettings) error
}
// Stats
type EventHistoryStore interface {
InsertEventHistory(ctx context.Context, eventHistory domain.CreateEventHistory) (domain.EventHistory, error)
GetAllEventHistory(ctx context.Context, filter domain.EventHistoryFilter) ([]domain.EventHistory, error)
GetInitialEventPerDay(ctx context.Context, filter domain.EventHistoryFilter) ([]domain.EventHistory, error)
}
type EventStatStore interface {
GetTotalEventStats(ctx context.Context, filter domain.EventStatsFilter) (domain.EventStats, error)
GetTotalEventStatsByInterval(ctx context.Context, filter domain.EventStatsByIntervalFilter) ([]domain.EventStatsByInterval, error)
UpdateEventBetStats(ctx context.Context) error

View File

@ -1,4 +1,4 @@
package league
package ports
import (
"context"

View File

@ -1,23 +1,20 @@
package notificationservice
package ports
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/gorilla/websocket"
)
type NotificationStore interface {
SendNotification(ctx context.Context, notification *domain.Notification) error
MarkAsRead(ctx context.Context, notificationID string, recipientID int64) error
GetUserNotifications(ctx context.Context, recipientID int64, limit, offset int) ([]domain.Notification, int64, error)
ConnectWebSocket(ctx context.Context, recipientID int64, c *websocket.Conn) error
DisconnectWebSocket(recipientID int64)
SendSMS(ctx context.Context, recipientID int64, message string) error
SendEmail(ctx context.Context, recipientID int64, subject, message string) error
ListRecipientIDs(ctx context.Context, receiver domain.NotificationRecieverSide) ([]int64, error) // New method
CountUnreadNotifications(ctx context.Context, recipient_id int64) (int64, error)
GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error)
GetNotificationCounts(ctx context.Context, filter domain.ReportFilter) (total, read, unread int64, err error)
CreateNotification(ctx context.Context, notification *domain.Notification) (*domain.Notification, error)
UpdateNotificationStatus(ctx context.Context, id, status string, isRead bool, metadata []byte) (*domain.Notification, error)
ListFailedNotifications(ctx context.Context, limit int) ([]domain.Notification, error)
DeleteOldNotifications(ctx context.Context) error
}

31
internal/ports/odds.go Normal file
View File

@ -0,0 +1,31 @@
package ports
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type OddStore interface {
SaveOddMarket(ctx context.Context, m domain.CreateOddMarket) error
GetAllOdds(ctx context.Context, filter domain.OddMarketFilter) ([]domain.OddMarket, error)
GetAllOddsWithSettings(ctx context.Context, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error)
GetOddByID(ctx context.Context, id int64) (domain.OddMarket, error)
GetOddsByMarketID(ctx context.Context, marketID int64, eventID int64) (domain.OddMarket, error)
GetOddsWithSettingsByMarketID(ctx context.Context, marketID int64, eventID int64, companyID int64) (domain.OddMarketWithSettings, error)
GetOddsByEventID(ctx context.Context, eventID int64, filter domain.OddMarketWithEventFilter) ([]domain.OddMarket, error)
GetOddsWithSettingsByEventID(ctx context.Context, eventID int64, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error)
DeleteOddsForEvent(ctx context.Context, eventID int64) error
// Settings
SaveOddsSetting(ctx context.Context, odd domain.CreateOddMarketSettings) error
UpdateGlobalOddsSetting(ctx context.Context, odd domain.UpdateGlobalOddMarketSettings) error
GetOddsWithSettingsByID(ctx context.Context, ID int64, companyID int64) (domain.OddMarketWithSettings, error)
DeleteAllCompanyOddsSetting(ctx context.Context, companyID int64) error
DeleteCompanyOddsSettingByOddMarketID(ctx context.Context, companyID int64, oddMarketID int64) error
// Odd History
InsertOddHistory(ctx context.Context, odd domain.CreateOddHistory) (domain.OddHistory, error)
GetAllOddHistory(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error)
GetInitialOddPerDay(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error)
}

View File

@ -1,4 +1,4 @@
package raffle
package ports
import (
"context"

View File

@ -0,0 +1,19 @@
package ports
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type ReferralStore interface {
CreateReferralCode(ctx context.Context, referralCode domain.CreateReferralCode) (domain.ReferralCode, error)
CreateUserReferral(ctx context.Context, referral domain.CreateUserReferrals) (domain.UserReferral, error)
GetReferralCodesByUser(ctx context.Context, userID int64) ([]domain.ReferralCode, error)
GetReferralCode(ctx context.Context, code string) (domain.ReferralCode, error)
UpdateReferralCode(ctx context.Context, referral domain.UpdateReferralCode) error
GetReferralStats(ctx context.Context, userID int64, companyID int64) (domain.ReferralStats, error)
GetUserReferral(ctx context.Context, referredID int64) (domain.UserReferral, error)
GetUserReferralsByCode(ctx context.Context, code string) ([]domain.UserReferral, error)
GetUserReferralCount(ctx context.Context, referrerID int64) (int64, error)
}

44
internal/ports/report.go Normal file
View File

@ -0,0 +1,44 @@
package ports
import (
"context"
"time"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type ReportStore interface {
// GetDashboardSummary(ctx context.Context, filter domain.ReportFilter) (domain.DashboardSummary, error)
// GetBetAnalysis(ctx context.Context, filter domain.ReportFilter) ([]domain.BetAnalysis, error)
// GetCustomerActivity(ctx context.Context, filter domain.ReportFilter) ([]domain.CustomerActivity, error)
// GetBranchPerformance(ctx context.Context, filter domain.ReportFilter) ([]domain.BranchPerformance, error)
// GetSportPerformance(ctx context.Context, filter domain.ReportFilter) ([]domain.SportPerformance, error)
// GetNotificationReport(ctx context.Context, filter domain.ReportFilter) (domain.NotificationReport, error)
// GetCashierPerformance(ctx context.Context, filter domain.ReportFilter) ([]domain.CashierPerformance, error)
// GetCompanyPerformance(ctx context.Context, filter domain.ReportFilter) ([]domain.CompanyPerformance, error)
CreateReportRequest(ctx context.Context, report domain.CreateReportRequest) (domain.ReportRequest, error)
GetAllReportRequests(ctx context.Context, filter domain.ReportRequestFilter) ([]domain.ReportRequestDetail, int64, error)
GetReportRequestByRequestedByID(ctx context.Context, requestedBy int64, filter domain.ReportRequestFilter) ([]domain.ReportRequestDetail, error)
GetReportRequestByID(ctx context.Context, ID int64) (domain.ReportRequestDetail, error)
UpdateReportRequest(ctx context.Context, report domain.UpdateRequestRequest) error
}
// TODO: Move the code to new Report Store using report requests
// Auto-generated reports should also use a report request (but with no requested_by param)
type OldReportRepository interface {
GenerateReport(timeFrame domain.ReportTimeFrame, start, end time.Time) (*domain.Report, error)
SaveReport(report *domain.Report) error
FindReportsByTimeFrame(timeFrame domain.ReportTimeFrame, limit int) ([]*domain.Report, error)
GetTotalCashOutInRange(ctx context.Context, from, to time.Time) (float64, error)
GetTotalCashMadeInRange(ctx context.Context, from, to time.Time) (float64, error)
GetTotalCashBacksInRange(ctx context.Context, from, to time.Time) (float64, error)
GetTotalBetsMadeInRange(ctx context.Context, from, to time.Time) (int64, error)
GetVirtualGameSummaryInRange(ctx context.Context, from, to time.Time) ([]dbgen.GetVirtualGameSummaryInRangeRow, error)
GetAllTicketsInRange(ctx context.Context, from, to time.Time) (dbgen.GetAllTicketsInRangeRow, error)
GetWalletTransactionsInRange(ctx context.Context, from, to time.Time) ([]dbgen.GetWalletTransactionsInRangeRow, error)
// GetCompanyWiseReport(ctx context.Context, from, to time.Time) ([]dbgen.GetCompanyWiseReportRow, error)
// GetBranchWiseReport(ctx context.Context, from, to time.Time) ([]dbgen.GetBranchWiseReportRow, error)
}

View File

@ -1,4 +1,4 @@
package result
package ports
import (
"context"
@ -6,11 +6,6 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type ResultService interface {
FetchAndProcessResults(ctx context.Context) error
FetchAndStoreResult(ctx context.Context, eventID string) error
}
type ResultLogStore interface {
CreateResultLog(ctx context.Context, result domain.CreateResultLog) (domain.ResultLog, error)
GetAllResultLog(ctx context.Context, filter domain.ResultLogFilter) ([]domain.ResultLog, error)

View File

@ -1,4 +1,4 @@
package settings
package ports
import (
"context"

View File

@ -1,4 +1,4 @@
package ticket
package ports
import (
"context"

View File

@ -1,8 +1,7 @@
package transaction
package ports
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)

View File

@ -1,4 +1,4 @@
package user
package ports
import (
"context"
@ -24,6 +24,7 @@ type UserStore interface {
GetUserByPhone(ctx context.Context, phoneNum string, companyID domain.ValidInt64) (domain.User, error)
SearchUserByNameOrPhone(ctx context.Context, searchString string, role *domain.Role, companyID domain.ValidInt64) ([]domain.User, error)
UpdatePassword(ctx context.Context, identifier string, password []byte, usedOtpId int64, companyId int64) error
GetUserByEmailPhone(ctx context.Context, email, phone string, companyID domain.ValidInt64) (domain.User, error)
GetCustomerCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error)
GetCustomerDetails(ctx context.Context, filter domain.ReportFilter) (map[int64]domain.CustomerDetail, error)

View File

@ -1,4 +1,4 @@
package wallet
package ports
import (
"context"

View File

@ -7,49 +7,13 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
"github.com/jackc/pgx/v5/pgtype"
)
func (s *Store) GetUserByEmailPhone(ctx context.Context, email, phone string, companyID domain.ValidInt64) (domain.User, error) {
user, err := s.queries.GetUserByEmailPhone(ctx, dbgen.GetUserByEmailPhoneParams{
Email: pgtype.Text{
String: email,
Valid: true,
},
PhoneNumber: pgtype.Text{
String: phone,
Valid: true,
},
CompanyID: companyID.ToPG(),
})
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return domain.User{}, authentication.ErrUserNotFound
}
return domain.User{}, err
}
return domain.User{
ID: user.ID,
FirstName: user.FirstName,
LastName: user.LastName,
Email: user.Email.String,
PhoneNumber: user.PhoneNumber.String,
Password: user.Password,
Role: domain.Role(user.Role),
EmailVerified: user.EmailVerified,
PhoneVerified: user.PhoneVerified,
CreatedAt: user.CreatedAt.Time,
UpdatedAt: user.UpdatedAt.Time,
SuspendedAt: user.SuspendedAt.Time,
Suspended: user.Suspended,
CompanyID: domain.ValidInt64{
Value: user.CompanyID.Int64,
Valid: user.CompanyID.Valid,
},
}, nil
}
// Interface for creating new token store
func NewTokenStore(s *Store) ports.TokenStore { return s }
func (s *Store) CreateRefreshToken(ctx context.Context, rt domain.RefreshToken) error {
return s.queries.CreateRefreshToken(ctx, dbgen.CreateRefreshTokenParams{

View File

@ -3,28 +3,22 @@ package repository
import (
"context"
"fmt"
"log/slog"
"time"
// "fmt"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgtype"
"go.uber.org/zap"
)
var (
logger *slog.Logger
mongoLogger *zap.Logger
)
// Interface for creating new bet store
func NewBetStore(s *Store) ports.BetStore { return s }
func (s *Store) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) {
newBet, err := s.queries.CreateBet(ctx, domain.ConvertCreateBet(bet))
if err != nil {
fmt.Println("We are here")
logger.Error("Failed to create bet", slog.String("error", err.Error()), slog.Any("bet", bet))
return domain.Bet{}, err
}
return domain.ConvertDBBet(newBet), err
@ -432,7 +426,7 @@ func (s *Store) UpdateBetOutcomeStatusForOddId(ctx context.Context, oddID int64,
return result, nil
}
func (s *Store) BulkUpdateBetOutcomeStatusForOddIds(ctx context.Context, oddID []int64, status domain.OutcomeStatus) (error) {
func (s *Store) BulkUpdateBetOutcomeStatusForOddIds(ctx context.Context, oddID []int64, status domain.OutcomeStatus) error {
err := s.queries.BulkUpdateBetOutcomeStatusByOddIDs(ctx, dbgen.BulkUpdateBetOutcomeStatusByOddIDsParams{
Status: int32(status),
OddIds: oddID,

View File

@ -5,8 +5,12 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
// Interface for creating new bonus store
func NewBonusStore(s *Store) ports.BonusStore { return s }
func (s *Store) CreateUserBonus(ctx context.Context, bonus domain.CreateBonus) (domain.UserBonus, error) {
newBonus, err := s.queries.CreateUserBonus(ctx, domain.ConvertCreateBonus(bonus))

View File

@ -6,9 +6,13 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5/pgtype"
)
// Interface for creating new branch store
func NewBranchStore(s *Store) ports.BranchStore { return s }
func (s *Store) CreateBranch(ctx context.Context, branch domain.CreateBranch) (domain.Branch, error) {
dbBranch, err := s.queries.CreateBranch(ctx, domain.ConvertCreateBranch(branch))

View File

@ -5,9 +5,13 @@ import (
"fmt"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5/pgtype"
)
// Interface for creating new company store
func NewCompanyStore(s *Store) ports.CompanyStore { return s }
func (s *Store) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) {
dbCompany, err := s.queries.CreateCompany(ctx, domain.ConvertCreateCompany(company))
@ -81,8 +85,6 @@ func (s *Store) DeleteCompany(ctx context.Context, id int64) error {
return s.queries.DeleteCompany(ctx, id)
}
func (s *Store) GetCompanyCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) {
query := `SELECT
COUNT(*) as total,

View File

@ -5,8 +5,12 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
// Interface for creating new company stats store
func NewCompanyStatStore(s *Store) ports.CompanyStatStore { return s }
func (s *Store) UpdateCompanyStats(ctx context.Context) error {
return s.queries.UpdateCompanyStats(ctx)
}

View File

@ -2,71 +2,21 @@ package repository
import (
"context"
"math/big"
"time"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/jackc/pgx/v5/pgtype"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
func convertDBDirectDeposit(deposit dbgen.DirectDeposit) domain.DirectDeposit {
return domain.DirectDeposit{
ID: deposit.ID,
CustomerID: deposit.CustomerID,
WalletID: deposit.WalletID,
Amount: domain.Currency(deposit.Amount.Int.Int64()),
BankReference: deposit.BankReference,
SenderAccount: deposit.SenderAccount,
Status: domain.DirectDepositStatus(deposit.Status),
CreatedAt: deposit.CreatedAt.Time,
VerifiedBy: convertPgInt64ToPtr(deposit.VerifiedBy),
VerificationNotes: deposit.VerificationNotes.String,
VerifiedAt: convertPgTimeToPtr(deposit.VerifiedAt),
}
}
// Interface for creating new wallet store
func NewDirectDepositStore(s *Store) ports.DirectDepositStore { return s }
func convertCreateDirectDeposit(deposit domain.CreateDirectDeposit) dbgen.CreateDirectDepositParams {
return dbgen.CreateDirectDepositParams{
CustomerID: deposit.CustomerID,
WalletID: deposit.WalletID,
Amount: pgtype.Numeric{Int: big.NewInt(int64(deposit.Amount)), Valid: true},
BankReference: deposit.BankReference,
SenderAccount: deposit.SenderAccount,
Status: string(deposit.Status),
}
}
func convertUpdateDirectDeposit(deposit domain.UpdateDirectDeposit) dbgen.UpdateDirectDepositParams {
return dbgen.UpdateDirectDepositParams{
ID: deposit.ID,
Status: string(deposit.Status),
VerifiedBy: pgtype.Int8{Int64: deposit.VerifiedBy, Valid: true},
VerificationNotes: pgtype.Text{String: deposit.VerificationNotes, Valid: deposit.VerificationNotes != ""},
VerifiedAt: pgtype.Timestamp{Time: deposit.VerifiedAt, Valid: true},
}
}
func convertPgInt64ToPtr(i pgtype.Int8) *int64 {
if i.Valid {
return &i.Int64
}
return nil
}
func convertPgTimeToPtr(t pgtype.Timestamp) *time.Time {
if t.Valid {
return &t.Time
}
return nil
}
func (s *Store) CreateDirectDeposit(ctx context.Context, deposit domain.CreateDirectDeposit) (domain.DirectDeposit, error) {
newDeposit, err := s.queries.CreateDirectDeposit(ctx, convertCreateDirectDeposit(deposit))
newDeposit, err := s.queries.CreateDirectDeposit(ctx, domain.ConvertCreateDirectDeposit(deposit))
if err != nil {
return domain.DirectDeposit{}, err
}
return convertDBDirectDeposit(newDeposit), nil
return domain.ConvertDBDirectDeposit(newDeposit), nil
}
func (s *Store) GetDirectDeposit(ctx context.Context, id int64) (domain.DirectDeposit, error) {
@ -74,15 +24,15 @@ func (s *Store) GetDirectDeposit(ctx context.Context, id int64) (domain.DirectDe
if err != nil {
return domain.DirectDeposit{}, err
}
return convertDBDirectDeposit(deposit), nil
return domain.ConvertDBDirectDeposit(deposit), nil
}
func (s *Store) UpdateDirectDeposit(ctx context.Context, deposit domain.UpdateDirectDeposit) (domain.DirectDeposit, error) {
updatedDeposit, err := s.queries.UpdateDirectDeposit(ctx, convertUpdateDirectDeposit(deposit))
updatedDeposit, err := s.queries.UpdateDirectDeposit(ctx, domain.ConvertUpdateDirectDeposit(deposit))
if err != nil {
return domain.DirectDeposit{}, err
}
return convertDBDirectDeposit(updatedDeposit), nil
return domain.ConvertDBDirectDeposit(updatedDeposit), nil
}
func (s *Store) GetDirectDepositsByStatus(ctx context.Context, status domain.DirectDepositStatus) ([]domain.DirectDeposit, error) {
@ -93,7 +43,7 @@ func (s *Store) GetDirectDepositsByStatus(ctx context.Context, status domain.Dir
result := make([]domain.DirectDeposit, 0, len(deposits))
for _, deposit := range deposits {
result = append(result, convertDBDirectDeposit(deposit))
result = append(result, domain.ConvertDBDirectDeposit(deposit))
}
return result, nil
}
@ -106,7 +56,7 @@ func (s *Store) GetCustomerDirectDeposits(ctx context.Context, customerID int64)
result := make([]domain.DirectDeposit, 0, len(deposits))
for _, deposit := range deposits {
result = append(result, convertDBDirectDeposit(deposit))
result = append(result, domain.ConvertDBDirectDeposit(deposit))
}
return result, nil
}

View File

@ -1,68 +0,0 @@
package repository
import (
"context"
"fmt"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
func (s *Store) InsertDisabledOdd(ctx context.Context, odd domain.CreateDisabledOdd) (domain.DisabledOdd, error) {
dbDisabledOdd, err := s.queries.InsertDisabledOdds(ctx, domain.ConvertCreateDisabledOdd(odd))
if err != nil {
return domain.DisabledOdd{}, fmt.Errorf("InsertDisabledOdd failed: %w", err)
}
return domain.ConvertDBDisabledOdd(dbDisabledOdd), nil
}
func (s *Store) GetAllDisabledOdds(ctx context.Context) ([]domain.DisabledOdd, error) {
dbDisabledOdds, err := s.queries.GetAllDisabledOdds(ctx)
if err != nil {
return nil, fmt.Errorf("GetAllDisabledOdds failed: %w", err)
}
return domain.ConvertDisabledOdds(dbDisabledOdds), nil
}
func (s *Store) GetDisabledOddByRawOddID(ctx context.Context, rawOddID int64) (domain.DisabledOdd, error) {
dbDisabledOdd, err := s.queries.GetDisabledOddByRawOddID(ctx, rawOddID)
if err != nil {
return domain.DisabledOdd{}, fmt.Errorf("GetDisabledOddByRawOddID failed: %w", err)
}
return domain.ConvertDBDisabledOdd(dbDisabledOdd), nil
}
func (s *Store) GetDisabledOddByID(ctx context.Context, id int64) (domain.DisabledOdd, error) {
dbDisabledOdd, err := s.queries.GetDisabledOddByID(ctx, id)
if err != nil {
return domain.DisabledOdd{}, fmt.Errorf("GetDisabledOddByID failed: %w", err)
}
return domain.ConvertDBDisabledOdd(dbDisabledOdd), nil
}
func (s *Store) DeleteDisabledOddsByID(ctx context.Context, id int64) error {
err := s.queries.DeleteDisabledOddsByID(ctx, id)
if err != nil {
return fmt.Errorf("DeleteDisabledOddsByID failed: %w", err)
}
return nil
}
func (s *Store) DeleteDisabledOddsByRawOddID(ctx context.Context, id int64) error {
err := s.queries.DeleteDisabledOddsByRawOddID(ctx, id)
if err != nil {
return fmt.Errorf("DeleteDisabledOddsByRawOddID failed: %w", err)
}
return nil
}

View File

@ -6,11 +6,15 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/jackc/pgx/v5/pgtype"
)
// Interface for creating new event store
func NewEventStore(s *Store) ports.EventStore { return s }
func (s *Store) SaveEvent(ctx context.Context, e domain.CreateEvent) error {
return s.queries.InsertEvent(ctx, domain.ConvertCreateEvent(e))
}

View File

@ -6,8 +6,12 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
// Interface for creating new event history store
func NewEventHistoryStore(s *Store) ports.EventHistoryStore { return s }
func (s *Store) InsertEventHistory(ctx context.Context, eventHistory domain.CreateEventHistory) (domain.EventHistory, error) {
dbEventHistory, err := s.queries.InsertEventHistory(ctx, domain.ConvertCreateEventHistory(eventHistory))

View File

@ -5,8 +5,12 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
// Interface for creating new event stats store
func NewEventStatStore(s *Store) ports.EventStatStore { return s }
func (s *Store) GetTotalEventStats(ctx context.Context, filter domain.EventStatsFilter) (domain.EventStats, error) {
stats, err := s.queries.GetTotalEventStats(ctx, dbgen.GetTotalEventStatsParams{
LeagueID: filter.LeagueID.ToPG(),

View File

@ -5,9 +5,13 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5/pgtype"
)
// Interface for creating new league store
func NewLeagueStore(s *Store) ports.LeagueStore { return s }
func (s *Store) SaveLeague(ctx context.Context, league domain.CreateLeague) error {
return s.queries.InsertLeague(ctx, domain.ConvertCreateLeague(league))
}
@ -16,7 +20,7 @@ func (s *Store) SaveLeagueSettings(ctx context.Context, leagueSettings domain.Cr
return s.queries.SaveLeagueSettings(ctx, domain.ConvertCreateLeagueSettings(leagueSettings))
}
func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague,int64, error) {
func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, int64, error) {
l, err := s.queries.GetAllLeagues(ctx, dbgen.GetAllLeaguesParams{
Query: filter.Query.ToPG(),
CountryCode: filter.CountryCode.ToPG(),

View File

@ -7,38 +7,13 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/gorilla/websocket"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5/pgtype"
)
type NotificationRepository interface {
CreateNotification(ctx context.Context, notification *domain.Notification) (*domain.Notification, error)
UpdateNotificationStatus(ctx context.Context, id, status string, isRead bool, metadata []byte) (*domain.Notification, error)
GetUserNotifications(ctx context.Context, recipientID int64, limit, offset int) ([]domain.Notification, int64, error)
ListFailedNotifications(ctx context.Context, limit int) ([]domain.Notification, error)
ListRecipientIDs(ctx context.Context, receiver domain.NotificationRecieverSide) ([]int64, error)
CountUnreadNotifications(ctx context.Context, recipient_id int64) (int64, error)
GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error)
GetNotificationCounts(ctx context.Context, filter domain.ReportFilter) (total, read, unread int64, err error)
DeleteOldNotifications(ctx context.Context) error
}
func NewNotificationStore(s *Store) ports.NotificationStore { return s }
type Repository struct {
store *Store
}
func NewNotificationRepository(store *Store) NotificationRepository {
return &Repository{store: store}
}
func (s *Store) ConnectWebSocket(ctx context.Context, recipientID int64, c *websocket.Conn) error {
return nil
}
func (s *Store) DisconnectWebSocket(recipientID int64) {
}
func (r *Repository) CreateNotification(ctx context.Context, notification *domain.Notification) (*domain.Notification, error) {
func (r *Store) CreateNotification(ctx context.Context, notification *domain.Notification) (*domain.Notification, error) {
var errorSeverity pgtype.Text
if notification.ErrorSeverity != "" {
errorSeverity.String = string(notification.ErrorSeverity)
@ -75,7 +50,7 @@ func (r *Repository) CreateNotification(ctx context.Context, notification *domai
Metadata: notification.Metadata,
}
dbNotification, err := r.store.queries.CreateNotification(ctx, params)
dbNotification, err := r.queries.CreateNotification(ctx, params)
if err != nil {
return nil, err
}
@ -83,7 +58,7 @@ func (r *Repository) CreateNotification(ctx context.Context, notification *domai
return r.mapDBToDomain(&dbNotification), nil
}
func (r *Repository) UpdateNotificationStatus(ctx context.Context, id, status string, isRead bool, metadata []byte) (*domain.Notification, error) {
func (r *Store) UpdateNotificationStatus(ctx context.Context, id, status string, isRead bool, metadata []byte) (*domain.Notification, error) {
params := dbgen.UpdateNotificationStatusParams{
ID: id,
DeliveryStatus: status,
@ -91,7 +66,7 @@ func (r *Repository) UpdateNotificationStatus(ctx context.Context, id, status st
Metadata: metadata,
}
dbNotification, err := r.store.queries.UpdateNotificationStatus(ctx, params)
dbNotification, err := r.queries.UpdateNotificationStatus(ctx, params)
if err != nil {
return nil, err
}
@ -99,19 +74,19 @@ func (r *Repository) UpdateNotificationStatus(ctx context.Context, id, status st
return r.mapDBToDomain(&dbNotification), nil
}
func (r *Repository) GetUserNotifications(ctx context.Context, recipientID int64, limit, offset int) ([]domain.Notification, int64, error) {
func (r *Store) GetUserNotifications(ctx context.Context, recipientID int64, limit, offset int) ([]domain.Notification, int64, error) {
params := dbgen.GetUserNotificationsParams{
RecipientID: recipientID,
Limit: int32(limit),
Offset: int32(offset),
}
dbNotifications, err := r.store.queries.GetUserNotifications(ctx, params)
dbNotifications, err := r.queries.GetUserNotifications(ctx, params)
if err != nil {
return nil, 0, err
}
total, err := r.store.queries.GetUserNotificationCount(ctx, recipientID)
total, err := r.queries.GetUserNotificationCount(ctx, recipientID)
if err != nil {
return nil, 0, err
@ -126,9 +101,9 @@ func (r *Repository) GetUserNotifications(ctx context.Context, recipientID int64
return result, total, nil
}
func (r *Repository) GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error) {
func (r *Store) GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error) {
dbNotifications, err := r.store.queries.GetAllNotifications(ctx, dbgen.GetAllNotificationsParams{
dbNotifications, err := r.queries.GetAllNotifications(ctx, dbgen.GetAllNotificationsParams{
Limit: int32(limit),
Offset: int32(offset),
})
@ -144,8 +119,8 @@ func (r *Repository) GetAllNotifications(ctx context.Context, limit, offset int)
return result, nil
}
func (r *Repository) ListFailedNotifications(ctx context.Context, limit int) ([]domain.Notification, error) {
dbNotifications, err := r.store.queries.ListFailedNotifications(ctx, int32(limit))
func (r *Store) ListFailedNotifications(ctx context.Context, limit int) ([]domain.Notification, error) {
dbNotifications, err := r.queries.ListFailedNotifications(ctx, int32(limit))
if err != nil {
return nil, err
}
@ -159,15 +134,15 @@ func (r *Repository) ListFailedNotifications(ctx context.Context, limit int) ([]
return result, nil
}
func (r *Repository) ListRecipientIDs(ctx context.Context, receiver domain.NotificationRecieverSide) ([]int64, error) {
return r.store.queries.ListRecipientIDsByReceiver(ctx, string(receiver))
func (r *Store) ListRecipientIDs(ctx context.Context, receiver domain.NotificationRecieverSide) ([]int64, error) {
return r.queries.ListRecipientIDsByReceiver(ctx, string(receiver))
}
func (s *Repository) DeleteOldNotifications(ctx context.Context) error {
return s.store.queries.DeleteOldNotifications(ctx)
func (s *Store) DeleteOldNotifications(ctx context.Context) error {
return s.queries.DeleteOldNotifications(ctx)
}
func (r *Repository) mapDBToDomain(dbNotif *dbgen.Notification) *domain.Notification {
func (r *Store) mapDBToDomain(dbNotif *dbgen.Notification) *domain.Notification {
var errorSeverity domain.NotificationErrorSeverity
if dbNotif.ErrorSeverity.Valid {
errorSeverity = domain.NotificationErrorSeverity(dbNotif.ErrorSeverity.String)
@ -225,12 +200,12 @@ func unmarshalPayload(data []byte) (domain.NotificationPayload, error) {
return payload, nil
}
func (r *Repository) CountUnreadNotifications(ctx context.Context, recipient_id int64) (int64, error) {
return r.store.queries.CountUnreadNotifications(ctx, recipient_id)
func (r *Store) CountUnreadNotifications(ctx context.Context, recipient_id int64) (int64, error) {
return r.queries.CountUnreadNotifications(ctx, recipient_id)
}
func (r *Repository) GetNotificationCounts(ctx context.Context, filter domain.ReportFilter) (total, read, unread int64, err error) {
rows, err := r.store.queries.GetNotificationCounts(ctx)
func (r *Store) GetNotificationCounts(ctx context.Context, filter domain.ReportFilter) (total, read, unread int64, err error) {
rows, err := r.queries.GetNotificationCounts(ctx)
if err != nil {
return 0, 0, 0, fmt.Errorf("failed to get notification counts: %w", err)
}
@ -326,14 +301,6 @@ func (s *Store) GetNotificationCountsByType(ctx context.Context, filter domain.R
return counts, nil
}
func (s *Store) CountUnreadNotifications(ctx context.Context, userID int64) (int64, error) {
count, err := s.queries.CountUnreadNotifications(ctx, userID)
if err != nil {
return 0, err
}
return count, nil
}
// func (s *Store) GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error) {
// dbNotifications, err := s.queries.GetAllNotifications(ctx, dbgen.GetAllNotificationsParams{
// Limit: int32(limit),

View File

@ -9,9 +9,13 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5/pgtype"
)
// Interface for creating new event store
func NewOddStore(s *Store) ports.OddStore { return s }
func (s *Store) SaveOddMarket(ctx context.Context, m domain.CreateOddMarket) error {
if len(m.Odds) == 0 {
return nil

View File

@ -1,16 +1,22 @@
package repository
import (
// "context"
// "fmt"
// "time"
"context"
"fmt"
"time"
// dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// "github.com/jackc/pgx/v5/pgtype"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/jackc/pgx/v5/pgtype"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
type ReportRepository interface {
// Interface for creating new old repository repo interface
// We need to have an external definition of the repository or else we can't reuse the interface
func NewOldRepositoryStore(s *Store) ports.OldReportRepository { return s }
// type ReportRepository interface {
// GenerateReport(timeFrame domain.ReportTimeFrame, start, end time.Time) (*domain.Report, error)
// SaveReport(report *domain.Report) error
// FindReportsByTimeFrame(timeFrame domain.ReportTimeFrame, limit int) ([]*domain.Report, error)
@ -24,211 +30,211 @@ type ReportRepository interface {
// GetWalletTransactionsInRange(ctx context.Context, from, to time.Time) ([]dbgen.GetWalletTransactionsInRangeRow, error)
// GetCompanyWiseReport(ctx context.Context, from, to time.Time) ([]dbgen.GetCompanyWiseReportRow, error)
// GetBranchWiseReport(ctx context.Context, from, to time.Time) ([]dbgen.GetBranchWiseReportRow, error)
// }
// type ReportRepo struct {
// store *Store
// }
// func NewReportRepo(store *Store) ReportRepository {
// return &ReportRepo{store: store}
// }
func (s *Store) GenerateReport(timeFrame domain.ReportTimeFrame, start, end time.Time) (*domain.Report, error) {
// Implement SQL queries to calculate metrics
var report domain.Report
// Total Bets
err := s.conn.QueryRow(
context.Background(),
`SELECT COUNT(*) FROM bets
WHERE created_at BETWEEN $1 AND $2`, start, end).Scan(&report.TotalBets)
if err != nil {
return nil, err
}
// Total Cash In
err = s.conn.QueryRow(
context.Background(),
`SELECT COALESCE(SUM(amount), 0) FROM transactions
WHERE type = 'stake' AND created_at BETWEEN $1 AND $2`, start, end).Scan(&report.TotalCashIn)
if err != nil {
return nil, err
}
// Similar queries for Cash Out and Cash Back...
report.TimeFrame = timeFrame
report.PeriodStart = start
report.PeriodEnd = end
report.GeneratedAt = time.Now()
return &report, nil
}
type ReportRepo struct {
store *Store
func (s *Store) SaveReport(report *domain.Report) error {
_, err := s.conn.Exec(
context.Background(),
`INSERT INTO reports
(id, time_frame, period_start, period_end, total_bets, total_cash_in, total_cash_out, total_cash_back, generated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
report.ID, report.TimeFrame, report.PeriodStart, report.PeriodEnd,
report.TotalBets, report.TotalCashIn, report.TotalCashOut, report.TotalCashBack, report.GeneratedAt)
return err
}
func NewReportRepo(store *Store) ReportRepository {
return &ReportRepo{store: store}
func (s *Store) FindReportsByTimeFrame(timeFrame domain.ReportTimeFrame, limit int) ([]*domain.Report, error) {
rows, err := s.conn.Query(
context.Background(),
`SELECT id, time_frame, period_start, period_end, total_bets,
total_cash_in, total_cash_out, total_cash_back, generated_at
FROM reports
WHERE time_frame = $1
ORDER BY generated_at DESC
LIMIT $2`,
timeFrame, limit)
if err != nil {
return nil, err
}
defer rows.Close()
var reports []*domain.Report
for rows.Next() {
var report domain.Report
err := rows.Scan(
&report.ID,
&report.TimeFrame,
&report.PeriodStart,
&report.PeriodEnd,
&report.TotalBets,
&report.TotalCashIn,
&report.TotalCashOut,
&report.TotalCashBack,
&report.GeneratedAt,
)
if err != nil {
return nil, err
}
reports = append(reports, &report)
}
if err := rows.Err(); err != nil {
return nil, err
}
return reports, nil
}
// func (r *ReportRepo) GenerateReport(timeFrame domain.ReportTimeFrame, start, end time.Time) (*domain.Report, error) {
// // Implement SQL queries to calculate metrics
// var report domain.Report
func (s *Store) GetTotalBetsMadeInRange(ctx context.Context, from, to time.Time) (int64, error) {
params := dbgen.GetTotalBetsMadeInRangeParams{
From: ToPgTimestamp(from),
To: ToPgTimestamp(to),
}
return s.queries.GetTotalBetsMadeInRange(ctx, params)
}
// // Total Bets
// err := r.store.conn.QueryRow(
// context.Background(),
// `SELECT COUNT(*) FROM bets
// WHERE created_at BETWEEN $1 AND $2`, start, end).Scan(&report.TotalBets)
// if err != nil {
// return nil, err
// }
func (s *Store) GetTotalCashBacksInRange(ctx context.Context, from, to time.Time) (float64, error) {
params := dbgen.GetTotalCashBacksInRangeParams{
From: ToPgTimestamp(from),
To: ToPgTimestamp(to),
}
value, err := s.queries.GetTotalCashBacksInRange(ctx, params)
if err != nil {
return 0, err
}
return parseFloat(value)
}
// // Total Cash In
// err = r.store.conn.QueryRow(
// context.Background(),
// `SELECT COALESCE(SUM(amount), 0) FROM transactions
// WHERE type = 'stake' AND created_at BETWEEN $1 AND $2`, start, end).Scan(&report.TotalCashIn)
// if err != nil {
// return nil, err
// }
func (s *Store) GetTotalCashMadeInRange(ctx context.Context, from, to time.Time) (float64, error) {
params := dbgen.GetTotalCashMadeInRangeParams{
From: ToPgTimestamp(from),
To: ToPgTimestamp(to),
}
value, err := s.queries.GetTotalCashMadeInRange(ctx, params)
if err != nil {
return 0, err
}
return parseFloat(value)
}
// // Similar queries for Cash Out and Cash Back...
func (s *Store) GetTotalCashOutInRange(ctx context.Context, from, to time.Time) (float64, error) {
params := dbgen.GetTotalCashOutInRangeParams{
From: ToPgTimestamp(from),
To: ToPgTimestamp(to),
}
value, err := s.queries.GetTotalCashOutInRange(ctx, params)
if err != nil {
return 0, err
}
return parseFloat(value)
}
// report.TimeFrame = timeFrame
// report.PeriodStart = start
// report.PeriodEnd = end
// report.GeneratedAt = time.Now()
func (s *Store) GetWalletTransactionsInRange(ctx context.Context, from, to time.Time) ([]dbgen.GetWalletTransactionsInRangeRow, error) {
params := dbgen.GetWalletTransactionsInRangeParams{
CreatedAt: ToPgTimestamp(from),
CreatedAt_2: ToPgTimestamp(to),
}
return s.queries.GetWalletTransactionsInRange(ctx, params)
}
// return &report, nil
// }
func (s *Store) GetAllTicketsInRange(ctx context.Context, from, to time.Time) (dbgen.GetAllTicketsInRangeRow, error) {
params := dbgen.GetAllTicketsInRangeParams{
CreatedAt: ToPgTimestamp(from),
CreatedAt_2: ToPgTimestamp(to),
}
return s.queries.GetAllTicketsInRange(ctx, params)
}
// func (r *ReportRepo) SaveReport(report *domain.Report) error {
// _, err := r.store.conn.Exec(
// context.Background(),
// `INSERT INTO reports
// (id, time_frame, period_start, period_end, total_bets, total_cash_in, total_cash_out, total_cash_back, generated_at)
// VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
// report.ID, report.TimeFrame, report.PeriodStart, report.PeriodEnd,
// report.TotalBets, report.TotalCashIn, report.TotalCashOut, report.TotalCashBack, report.GeneratedAt)
// return err
// }
func (s *Store) GetVirtualGameSummaryInRange(ctx context.Context, from, to time.Time) ([]dbgen.GetVirtualGameSummaryInRangeRow, error) {
params := dbgen.GetVirtualGameSummaryInRangeParams{
CreatedAt: ToPgTimestamptz(from),
CreatedAt_2: ToPgTimestamptz(to),
}
return s.queries.GetVirtualGameSummaryInRange(ctx, params)
}
// func (r *ReportRepo) FindReportsByTimeFrame(timeFrame domain.ReportTimeFrame, limit int) ([]*domain.Report, error) {
// rows, err := r.store.conn.Query(
// context.Background(),
// `SELECT id, time_frame, period_start, period_end, total_bets,
// total_cash_in, total_cash_out, total_cash_back, generated_at
// FROM reports
// WHERE time_frame = $1
// ORDER BY generated_at DESC
// LIMIT $2`,
// timeFrame, limit)
// if err != nil {
// return nil, err
// }
// defer rows.Close()
func ToPgTimestamp(t time.Time) pgtype.Timestamp {
return pgtype.Timestamp{Time: t, Valid: true}
}
// var reports []*domain.Report
// for rows.Next() {
// var report domain.Report
// err := rows.Scan(
// &report.ID,
// &report.TimeFrame,
// &report.PeriodStart,
// &report.PeriodEnd,
// &report.TotalBets,
// &report.TotalCashIn,
// &report.TotalCashOut,
// &report.TotalCashBack,
// &report.GeneratedAt,
// )
// if err != nil {
// return nil, err
// }
// reports = append(reports, &report)
// }
func ToPgTimestamptz(t time.Time) pgtype.Timestamptz {
return pgtype.Timestamptz{Time: t, Valid: true}
}
// if err := rows.Err(); err != nil {
// return nil, err
// }
func parseFloat(value interface{}) (float64, error) {
switch v := value.(type) {
case float64:
return v, nil
case int64:
return float64(v), nil
case pgtype.Numeric:
if !v.Valid {
return 0, nil
}
f, err := v.Float64Value()
if err != nil {
return 0, fmt.Errorf("failed to convert pgtype.Numeric to float64: %w", err)
}
return f.Float64, nil
case nil:
return 0, nil
default:
return 0, fmt.Errorf("unexpected type %T for value: %+v", v, v)
}
}
// return reports, nil
// }
// func (r *ReportRepo) GetTotalBetsMadeInRange(ctx context.Context, from, to time.Time) (int64, error) {
// params := dbgen.GetTotalBetsMadeInRangeParams{
// From: ToPgTimestamp(from),
// To: ToPgTimestamp(to),
// }
// return r.store.queries.GetTotalBetsMadeInRange(ctx, params)
// }
// func (r *ReportRepo) GetTotalCashBacksInRange(ctx context.Context, from, to time.Time) (float64, error) {
// params := dbgen.GetTotalCashBacksInRangeParams{
// From: ToPgTimestamp(from),
// To: ToPgTimestamp(to),
// }
// value, err := r.store.queries.GetTotalCashBacksInRange(ctx, params)
// if err != nil {
// return 0, err
// }
// return parseFloat(value)
// }
// func (r *ReportRepo) GetTotalCashMadeInRange(ctx context.Context, from, to time.Time) (float64, error) {
// params := dbgen.GetTotalCashMadeInRangeParams{
// From: ToPgTimestamp(from),
// To: ToPgTimestamp(to),
// }
// value, err := r.store.queries.GetTotalCashMadeInRange(ctx, params)
// if err != nil {
// return 0, err
// }
// return parseFloat(value)
// }
// func (r *ReportRepo) GetTotalCashOutInRange(ctx context.Context, from, to time.Time) (float64, error) {
// params := dbgen.GetTotalCashOutInRangeParams{
// From: ToPgTimestamp(from),
// To: ToPgTimestamp(to),
// }
// value, err := r.store.queries.GetTotalCashOutInRange(ctx, params)
// if err != nil {
// return 0, err
// }
// return parseFloat(value)
// }
// func (r *ReportRepo) GetWalletTransactionsInRange(ctx context.Context, from, to time.Time) ([]dbgen.GetWalletTransactionsInRangeRow, error) {
// params := dbgen.GetWalletTransactionsInRangeParams{
// CreatedAt: ToPgTimestamp(from),
// CreatedAt_2: ToPgTimestamp(to),
// }
// return r.store.queries.GetWalletTransactionsInRange(ctx, params)
// }
// func (r *ReportRepo) GetAllTicketsInRange(ctx context.Context, from, to time.Time) (dbgen.GetAllTicketsInRangeRow, error) {
// params := dbgen.GetAllTicketsInRangeParams{
// CreatedAt: ToPgTimestamp(from),
// CreatedAt_2: ToPgTimestamp(to),
// }
// return r.store.queries.GetAllTicketsInRange(ctx, params)
// }
// func (r *ReportRepo) GetVirtualGameSummaryInRange(ctx context.Context, from, to time.Time) ([]dbgen.GetVirtualGameSummaryInRangeRow, error) {
// params := dbgen.GetVirtualGameSummaryInRangeParams{
// CreatedAt: ToPgTimestamptz(from),
// CreatedAt_2: ToPgTimestamptz(to),
// }
// return r.store.queries.GetVirtualGameSummaryInRange(ctx, params)
// }
// func ToPgTimestamp(t time.Time) pgtype.Timestamp {
// return pgtype.Timestamp{Time: t, Valid: true}
// }
// func ToPgTimestamptz(t time.Time) pgtype.Timestamptz {
// return pgtype.Timestamptz{Time: t, Valid: true}
// }
// func parseFloat(value interface{}) (float64, error) {
// switch v := value.(type) {
// case float64:
// return v, nil
// case int64:
// return float64(v), nil
// case pgtype.Numeric:
// if !v.Valid {
// return 0, nil
// }
// f, err := v.Float64Value()
// if err != nil {
// return 0, fmt.Errorf("failed to convert pgtype.Numeric to float64: %w", err)
// }
// return f.Float64, nil
// case nil:
// return 0, nil
// default:
// return 0, fmt.Errorf("unexpected type %T for value: %+v", v, v)
// }
// }
// func (r *ReportRepo) GetCompanyWiseReport(ctx context.Context, from, to time.Time) ([]dbgen.GetCompanyWiseReportRow, error) {
// func (s *Store) GetCompanyWiseReport(ctx context.Context, from, to time.Time) ([]dbgen.GetCompanyWiseReportRow, error) {
// params := dbgen.GetCompanyWiseReportParams{
// From: ToPgTimestamp(from),
// To: ToPgTimestamp(to),
// }
// return r.store.queries.GetCompanyWiseReport(ctx, params)
// return s.queries.GetCompanyWiseReport(ctx, params)
// }
// func (r *ReportRepo) GetBranchWiseReport(ctx context.Context, from, to time.Time) ([]dbgen.GetBranchWiseReportRow, error) {
// func (s *Store) GetBranchWiseReport(ctx context.Context, from, to time.Time) ([]dbgen.GetBranchWiseReportRow, error) {
// params := dbgen.GetBranchWiseReportParams{
// From: ToPgTimestamp(from),
// To: ToPgTimestamp(to),
// }
// return r.store.queries.GetBranchWiseReport(ctx, params)
// return s.queries.GetBranchWiseReport(ctx, params)
// }

View File

@ -7,9 +7,13 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5/pgtype"
)
// Interface for creating new otp store
func NewOTPStore(s *Store) ports.OtpStore { return s }
func (s *Store) CreateOtp(ctx context.Context, otp domain.Otp) error {
return s.queries.CreateOtp(ctx, dbgen.CreateOtpParams{
SentTo: otp.SentTo,

View File

@ -5,74 +5,20 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5/pgtype"
)
func convertRaffleOutcome(raffle dbgen.Raffle) domain.Raffle {
return domain.Raffle{
ID: raffle.ID,
CompanyID: raffle.CompanyID,
Name: raffle.Name,
CreatedAt: raffle.CreatedAt.Time,
ExpiresAt: raffle.ExpiresAt.Time,
TicketLimit: raffle.TicketLimit,
Type: raffle.Type,
Status: raffle.Status,
}
}
func convertRaffleTicketOutcome(raffle dbgen.RaffleTicket) domain.RaffleTicket {
return domain.RaffleTicket{
ID: raffle.ID,
RaffleID: raffle.RaffleID,
UserID: raffle.UserID,
IsActive: raffle.IsActive.Bool,
}
}
func convertJoinedRaffleTicketOutcome(raffle dbgen.GetUserRaffleTicketsRow) domain.RaffleTicketRes {
return domain.RaffleTicketRes{
TicketID: raffle.TicketID,
UserID: raffle.UserID,
Name: raffle.Name,
Type: raffle.Type,
ExpiresAt: raffle.ExpiresAt.Time,
Status: raffle.Status,
}
}
func convertCreateRaffle(raffle domain.CreateRaffle) dbgen.CreateRaffleParams {
return dbgen.CreateRaffleParams{
CompanyID: raffle.CompanyID,
Name: raffle.Name,
ExpiresAt: pgtype.Timestamp{
Time: *raffle.ExpiresAt,
Valid: true,
},
TicketLimit: raffle.TicketLimit,
Type: raffle.Type,
}
}
func convertRaffleStanding(raffleStanding dbgen.GetRaffleStandingRow) domain.RaffleStanding {
return domain.RaffleStanding{
UserID: raffleStanding.UserID,
RaffleID: raffleStanding.RaffleID,
FirstName: raffleStanding.FirstName,
LastName: raffleStanding.LastName,
PhoneNumber: raffleStanding.PhoneNumber.String,
Email: raffleStanding.Email.String,
TicketCount: raffleStanding.TicketCount,
}
}
// Interface for creating new raffle store
func NewRaffleStore(s *Store) ports.RaffleStore { return s }
func (s *Store) CreateRaffle(ctx context.Context, raffle domain.CreateRaffle) (domain.Raffle, error) {
raffleRes, err := s.queries.CreateRaffle(ctx, convertCreateRaffle(raffle))
raffleRes, err := s.queries.CreateRaffle(ctx, domain.ConvertCreateRaffle(raffle))
if err != nil {
return domain.Raffle{}, err
}
return convertRaffleOutcome(raffleRes), nil
return domain.ConvertRaffleOutcome(raffleRes), nil
}
func (s *Store) DeleteRaffle(ctx context.Context, raffleID int32) (domain.Raffle, error) {
@ -81,7 +27,7 @@ func (s *Store) DeleteRaffle(ctx context.Context, raffleID int32) (domain.Raffle
return domain.Raffle{}, err
}
return convertRaffleOutcome(raffleRes), nil
return domain.ConvertRaffleOutcome(raffleRes), nil
}
func (s *Store) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]dbgen.Raffle, error) {
@ -102,7 +48,7 @@ func (s *Store) CreateRaffleTicket(ctx context.Context, raffleTicketParams domai
return domain.RaffleTicket{}, err
}
return convertRaffleTicketOutcome(raffleTicket), nil
return domain.ConvertRaffleTicketOutcome(raffleTicket), nil
}
func (s *Store) GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error) {
@ -113,7 +59,7 @@ func (s *Store) GetUserRaffleTickets(ctx context.Context, userID int32) ([]domai
res := []domain.RaffleTicketRes{}
for _, raffle := range raffleTickets {
res = append(res, convertJoinedRaffleTicketOutcome(raffle))
res = append(res, domain.ConvertJoinedRaffleTicketOutcome(raffle))
}
return res, nil
@ -152,7 +98,7 @@ func (s *Store) GetRaffleStanding(ctx context.Context, raffleID, limit int32) ([
res := []domain.RaffleStanding{}
for _, standing := range raffleStanding {
res = append(res, convertRaffleStanding(standing))
res = append(res, domain.ConvertRaffleStanding(standing))
}
return res, nil

View File

@ -5,30 +5,14 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
type ReferralRepository interface {
CreateReferralCode(ctx context.Context, referralCode domain.CreateReferralCode) (domain.ReferralCode, error)
CreateUserReferral(ctx context.Context, referral domain.CreateUserReferrals) (domain.UserReferral, error)
GetReferralCodesByUser(ctx context.Context, userID int64) ([]domain.ReferralCode, error)
GetReferralCode(ctx context.Context, code string) (domain.ReferralCode, error)
UpdateReferralCode(ctx context.Context, referral domain.UpdateReferralCode) error
GetReferralStats(ctx context.Context, userID int64, companyID int64) (domain.ReferralStats, error)
GetUserReferral(ctx context.Context, referredID int64) (domain.UserReferral, error)
GetUserReferralsByCode(ctx context.Context, code string) ([]domain.UserReferral, error)
GetUserReferralCount(ctx context.Context, referrerID int64) (int64, error)
}
// Interface for creating new referral store
func NewReferralStore(s *Store) ports.ReferralStore { return s }
type ReferralRepo struct {
store *Store
}
func NewReferralRepository(store *Store) ReferralRepository {
return &ReferralRepo{store: store}
}
func (r *ReferralRepo) CreateReferralCode(ctx context.Context, referralCode domain.CreateReferralCode) (domain.ReferralCode, error) {
newReferralCode, err := r.store.queries.CreateReferralCode(ctx, domain.ConvertCreateReferralCode(referralCode))
func (s *Store) CreateReferralCode(ctx context.Context, referralCode domain.CreateReferralCode) (domain.ReferralCode, error) {
newReferralCode, err := s.queries.CreateReferralCode(ctx, domain.ConvertCreateReferralCode(referralCode))
if err != nil {
return domain.ReferralCode{}, err
@ -36,8 +20,8 @@ func (r *ReferralRepo) CreateReferralCode(ctx context.Context, referralCode doma
return domain.ConvertDBReferralCode(newReferralCode), nil
}
func (r *ReferralRepo) CreateUserReferral(ctx context.Context, referral domain.CreateUserReferrals) (domain.UserReferral, error) {
newReferral, err := r.store.queries.CreateUserReferral(ctx, domain.ConvertCreateUserReferral(referral))
func (s *Store) CreateUserReferral(ctx context.Context, referral domain.CreateUserReferrals) (domain.UserReferral, error) {
newReferral, err := s.queries.CreateUserReferral(ctx, domain.ConvertCreateUserReferral(referral))
if err != nil {
return domain.UserReferral{}, err
@ -46,8 +30,8 @@ func (r *ReferralRepo) CreateUserReferral(ctx context.Context, referral domain.C
return domain.ConvertDBUserReferral(newReferral), nil
}
func (r *ReferralRepo) GetReferralCodesByUser(ctx context.Context, userID int64) ([]domain.ReferralCode, error) {
codes, err := r.store.queries.GetReferralCodeByUser(ctx, userID)
func (s *Store) GetReferralCodesByUser(ctx context.Context, userID int64) ([]domain.ReferralCode, error) {
codes, err := s.queries.GetReferralCodeByUser(ctx, userID)
if err != nil {
return nil, err
@ -56,8 +40,8 @@ func (r *ReferralRepo) GetReferralCodesByUser(ctx context.Context, userID int64)
return domain.ConvertDBReferralCodes(codes), nil
}
func (r *ReferralRepo) GetReferralCode(ctx context.Context, code string) (domain.ReferralCode, error) {
referralCode, err := r.store.queries.GetReferralCode(ctx, code)
func (s *Store) GetReferralCode(ctx context.Context, code string) (domain.ReferralCode, error) {
referralCode, err := s.queries.GetReferralCode(ctx, code)
if err != nil {
return domain.ReferralCode{}, err
@ -66,8 +50,8 @@ func (r *ReferralRepo) GetReferralCode(ctx context.Context, code string) (domain
return domain.ConvertDBReferralCode(referralCode), nil
}
func (r *ReferralRepo) UpdateReferralCode(ctx context.Context, referral domain.UpdateReferralCode) error {
err := r.store.queries.UpdateReferralCode(ctx, domain.ConvertUpdateReferralCode(referral))
func (s *Store) UpdateReferralCode(ctx context.Context, referral domain.UpdateReferralCode) error {
err := s.queries.UpdateReferralCode(ctx, domain.ConvertUpdateReferralCode(referral))
if err != nil {
return err
@ -76,8 +60,8 @@ func (r *ReferralRepo) UpdateReferralCode(ctx context.Context, referral domain.U
return nil
}
func (r *ReferralRepo) GetReferralStats(ctx context.Context, userID int64, companyID int64) (domain.ReferralStats, error) {
stats, err := r.store.queries.GetReferralStats(ctx, dbgen.GetReferralStatsParams{
func (s *Store) GetReferralStats(ctx context.Context, userID int64, companyID int64) (domain.ReferralStats, error) {
stats, err := s.queries.GetReferralStats(ctx, dbgen.GetReferralStatsParams{
ReferrerID: userID,
CompanyID: companyID,
})
@ -88,16 +72,16 @@ func (r *ReferralRepo) GetReferralStats(ctx context.Context, userID int64, compa
return domain.ConvertDBReferralStats(stats), nil
}
func (r *ReferralRepo) GetUserReferral(ctx context.Context, referredID int64) (domain.UserReferral, error) {
dbReferral, err := r.store.queries.GetUserReferral(ctx, referredID)
func (s *Store) GetUserReferral(ctx context.Context, referredID int64) (domain.UserReferral, error) {
dbReferral, err := s.queries.GetUserReferral(ctx, referredID)
if err != nil {
return domain.UserReferral{}, err
}
return domain.ConvertDBUserReferral(dbReferral), nil
}
func (r *ReferralRepo) GetUserReferralsByCode(ctx context.Context, code string) ([]domain.UserReferral, error) {
dbReferrals, err := r.store.queries.GetUserReferralsByCode(ctx, code)
func (s *Store) GetUserReferralsByCode(ctx context.Context, code string) ([]domain.UserReferral, error) {
dbReferrals, err := s.queries.GetUserReferralsByCode(ctx, code)
if err != nil {
return nil, err
@ -106,80 +90,10 @@ func (r *ReferralRepo) GetUserReferralsByCode(ctx context.Context, code string)
return domain.ConvertDBUserReferrals(dbReferrals), nil
}
func (r *ReferralRepo) GetUserReferralCount(ctx context.Context, referrerID int64) (int64, error) {
count, err := r.store.queries.GetUserReferralsCount(ctx, referrerID)
func (s *Store) GetUserReferralCount(ctx context.Context, referrerID int64) (int64, error) {
count, err := s.queries.GetUserReferralsCount(ctx, referrerID)
if err != nil {
return 0, err
}
return count, nil
}
// func (r *ReferralRepo) mapToDomainReferral(dbRef *dbgen.Referral) *domain.Referral {
// var referredID *int64
// if dbRef.ReferredID.Valid {
// referredID = &dbRef.ReferredID.Int64
// }
// rewardAmount := 0.0
// if dbRef.RewardAmount.Valid {
// if f8, err := dbRef.RewardAmount.Float64Value(); err == nil {
// rewardAmount = f8.Float64
// }
// }
// cashbackAmount := 0.0
// if dbRef.CashbackAmount.Valid {
// if f8, err := dbRef.CashbackAmount.Float64Value(); err == nil {
// cashbackAmount = f8.Float64
// }
// }
// return &domain.Referral{
// ID: dbRef.ID,
// ReferralCode: dbRef.ReferralCode,
// ReferrerID: dbRef.ReferrerID,
// ReferredID: referredID,
// Status: domain.ReferralStatus(dbRef.Status),
// RewardAmount: rewardAmount,
// CashbackAmount: cashbackAmount,
// CreatedAt: dbRef.CreatedAt.Time,
// UpdatedAt: dbRef.UpdatedAt.Time,
// ExpiresAt: dbRef.ExpiresAt.Time,
// }
// }
// func (r *ReferralRepo) mapToDomainSettings(dbSettings *dbgen.ReferralSetting) *domain.ReferralSettings {
// rewardAmount := 0.0
// if dbSettings.ReferralRewardAmount.Valid {
// if f8, err := dbSettings.ReferralRewardAmount.Float64Value(); err == nil {
// rewardAmount = f8.Float64
// }
// }
// cashbackPercentage := 0.0
// if dbSettings.CashbackPercentage.Valid {
// if f8, err := dbSettings.CashbackPercentage.Float64Value(); err == nil {
// cashbackPercentage = f8.Float64
// }
// }
// betReferralBonusPercentage := 0.0
// if dbSettings.BetReferralBonusPercentage.Valid {
// if f8, err := dbSettings.BetReferralBonusPercentage.Float64Value(); err == nil {
// betReferralBonusPercentage = f8.Float64
// }
// }
// return &domain.ReferralSettings{
// ID: dbSettings.ID,
// ReferralRewardAmount: rewardAmount,
// CashbackPercentage: cashbackPercentage,
// BetReferralBonusPercentage: betReferralBonusPercentage, // New field
// MaxReferrals: dbSettings.MaxReferrals,
// ExpiresAfterDays: dbSettings.ExpiresAfterDays,
// UpdatedBy: dbSettings.UpdatedBy,
// CreatedAt: dbSettings.CreatedAt.Time,
// UpdatedAt: dbSettings.UpdatedAt.Time,
// Version: dbSettings.Version,
// }
// }

View File

@ -6,11 +6,14 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5/pgtype"
)
func (s *Store) CreateReportRequest(ctx context.Context, report domain.CreateReportRequest) (domain.ReportRequest, error) {
// Interface for ReportStore
func NewReportStore(s *Store) ports.ReportStore { return s }
func (s *Store) CreateReportRequest(ctx context.Context, report domain.CreateReportRequest) (domain.ReportRequest, error) {
reportMetadata, err := report.Metadata.ToPG()
if err != nil {
return domain.ReportRequest{}, err

View File

@ -5,9 +5,14 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5/pgtype"
)
// Interface for creating new result log store
func NewResultLogStore(s *Store) ports.ResultLogStore { return s }
func (s *Store) CreateResultLog(ctx context.Context, result domain.CreateResultLog) (domain.ResultLog, error) {
dbResult, err := s.queries.CreateResultLog(ctx, domain.ConvertCreateResultLog(result))
if err != nil {

View File

@ -5,9 +5,13 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"go.uber.org/zap"
)
// Interface for creating new setting store
func NewSettingStore(s *Store) ports.SettingStore { return s }
func (s *Store) GetGlobalSettingList(ctx context.Context) (domain.SettingList, error) {
settings, err := s.queries.GetGlobalSettings(ctx)
if err != nil {

View File

@ -6,133 +6,20 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5/pgtype"
)
func convertDBShopTransaction(transaction dbgen.ShopTransaction) domain.ShopTransaction {
return domain.ShopTransaction{
ID: transaction.ID,
Amount: domain.Currency(transaction.Amount),
BranchID: transaction.BranchID,
UserID: transaction.UserID,
Type: domain.ShopTransactionType(transaction.Type),
PaymentOption: domain.PaymentOption(transaction.PaymentOption),
FullName: transaction.FullName,
PhoneNumber: transaction.PhoneNumber,
BankCode: domain.ValidString{
Value: transaction.BankCode.String,
Valid: transaction.BankCode.Valid,
},
BeneficiaryName: domain.ValidString{
Value: transaction.BeneficiaryName.String,
Valid: transaction.BeneficiaryName.Valid,
},
AccountName: domain.ValidString{
Value: transaction.AccountName.String,
Valid: transaction.AccountName.Valid,
},
AccountNumber: domain.ValidString{
Value: transaction.AccountName.String,
Valid: transaction.AccountNumber.Valid,
},
ReferenceNumber: domain.ValidString{
Value: transaction.ReferenceNumber.String,
Valid: transaction.ReferenceNumber.Valid,
},
ApprovedBy: domain.ValidInt64{
Value: transaction.ApprovedBy.Int64,
Valid: transaction.ApprovedBy.Valid,
},
CreatedAt: transaction.CreatedAt.Time,
UpdatedAt: transaction.UpdatedAt.Time,
Verified: transaction.Verified,
CompanyID: transaction.CompanyID,
}
}
func convertDBShopTransactionDetail(transaction dbgen.ShopTransactionDetail) domain.ShopTransactionDetail {
return domain.ShopTransactionDetail{
ID: transaction.ID,
Amount: domain.Currency(transaction.Amount),
BranchID: transaction.BranchID,
UserID: transaction.UserID,
CreatorFirstName: transaction.CreatorFirstName.String,
CreatorLastName: transaction.CreatorLastName.String,
CreatorPhoneNumber: transaction.CreatorPhoneNumber.String,
Type: domain.ShopTransactionType(transaction.Type),
PaymentOption: domain.PaymentOption(transaction.PaymentOption),
FullName: transaction.FullName,
PhoneNumber: transaction.PhoneNumber,
BankCode: domain.ValidString{
Value: transaction.BankCode.String,
Valid: transaction.BankCode.Valid,
},
BeneficiaryName: domain.ValidString{
Value: transaction.BeneficiaryName.String,
Valid: transaction.BeneficiaryName.Valid,
},
AccountName: domain.ValidString{
Value: transaction.AccountName.String,
Valid: transaction.AccountName.Valid,
},
AccountNumber: domain.ValidString{
Value: transaction.AccountName.String,
Valid: transaction.AccountNumber.Valid,
},
ReferenceNumber: domain.ValidString{
Value: transaction.ReferenceNumber.String,
Valid: transaction.ReferenceNumber.Valid,
},
ApprovedBy: domain.ValidInt64{
Value: transaction.ApprovedBy.Int64,
Valid: transaction.ApprovedBy.Valid,
},
ApproverFirstName: domain.ValidString{
Value: transaction.ApproverFirstName.String,
Valid: transaction.ApproverFirstName.Valid,
},
ApproverLastName: domain.ValidString{
Value: transaction.ApproverLastName.String,
Valid: transaction.ApproverLastName.Valid,
},
ApproverPhoneNumber: domain.ValidString{
Value: transaction.ApproverPhoneNumber.String,
Valid: transaction.ApproverPhoneNumber.Valid,
},
CreatedAt: transaction.CreatedAt.Time,
UpdatedAt: transaction.UpdatedAt.Time,
Verified: transaction.Verified,
CompanyID: transaction.CompanyID,
BranchName: transaction.BranchName.String,
BranchLocation: transaction.BranchLocation.String,
}
}
func convertCreateShopTransaction(transaction domain.CreateShopTransaction) dbgen.CreateShopTransactionParams {
return dbgen.CreateShopTransactionParams{
Amount: int64(transaction.Amount),
BranchID: transaction.BranchID,
UserID: transaction.UserID,
Type: int64(transaction.Type),
PaymentOption: int64(transaction.PaymentOption),
FullName: transaction.FullName,
PhoneNumber: transaction.PhoneNumber,
CompanyID: transaction.CompanyID,
BankCode: pgtype.Text{String: transaction.BankCode.Value, Valid: transaction.BankCode.Valid},
BeneficiaryName: pgtype.Text{String: transaction.BeneficiaryName.Value, Valid: transaction.BeneficiaryName.Valid},
AccountName: pgtype.Text{String: transaction.AccountName.Value, Valid: transaction.AccountName.Valid},
AccountNumber: pgtype.Text{String: transaction.AccountNumber.Value, Valid: transaction.AccountNumber.Valid},
ReferenceNumber: pgtype.Text{String: transaction.ReferenceNumber.Value, Valid: transaction.ReferenceNumber.Valid},
}
}
// Interface for creating new shop transaction store
func NewTransactionStore(s *Store) ports.TransactionStore { return s }
func (s *Store) CreateShopTransaction(ctx context.Context, transaction domain.CreateShopTransaction) (domain.ShopTransaction, error) {
newTransaction, err := s.queries.CreateShopTransaction(ctx, convertCreateShopTransaction(transaction))
newTransaction, err := s.queries.CreateShopTransaction(ctx, domain.ConvertCreateShopTransaction(transaction))
if err != nil {
return domain.ShopTransaction{}, err
}
return convertDBShopTransaction(newTransaction), err
return domain.ConvertDBShopTransaction(newTransaction), err
}
func (s *Store) GetShopTransactionByID(ctx context.Context, id int64) (domain.ShopTransactionDetail, error) {
@ -141,35 +28,17 @@ func (s *Store) GetShopTransactionByID(ctx context.Context, id int64) (domain.Sh
return domain.ShopTransactionDetail{}, err
}
return convertDBShopTransactionDetail(transaction), nil
return domain.ConvertDBShopTransactionDetail(transaction), nil
}
func (s *Store) GetAllShopTransactions(ctx context.Context, filter domain.ShopTransactionFilter) ([]domain.ShopTransactionDetail, error) {
transaction, err := s.queries.GetAllShopTransactions(ctx, dbgen.GetAllShopTransactionsParams{
BranchID: pgtype.Int8{
Int64: filter.BranchID.Value,
Valid: filter.BranchID.Valid,
},
CompanyID: pgtype.Int8{
Int64: filter.CompanyID.Value,
Valid: filter.CompanyID.Valid,
},
UserID: pgtype.Int8{
Int64: filter.UserID.Value,
Valid: filter.UserID.Valid,
},
Query: pgtype.Text{
String: filter.Query.Value,
Valid: filter.Query.Valid,
},
CreatedBefore: pgtype.Timestamp{
Time: filter.CreatedBefore.Value,
Valid: filter.CreatedBefore.Valid,
},
CreatedAfter: pgtype.Timestamp{
Time: filter.CreatedAfter.Value,
Valid: filter.CreatedAfter.Valid,
},
BranchID: filter.BranchID.ToPG(),
CompanyID: filter.CompanyID.ToPG(),
UserID: filter.UserID.ToPG(),
Query: filter.Query.ToPG(),
CreatedBefore: filter.CreatedBefore.ToPG(),
CreatedAfter: filter.CreatedAfter.ToPG(),
})
if err != nil {
@ -178,7 +47,7 @@ func (s *Store) GetAllShopTransactions(ctx context.Context, filter domain.ShopTr
var result []domain.ShopTransactionDetail = make([]domain.ShopTransactionDetail, 0, len(transaction))
for _, tAction := range transaction {
result = append(result, convertDBShopTransactionDetail(tAction))
result = append(result, domain.ConvertDBShopTransactionDetail(tAction))
}
return result, nil
}
@ -191,7 +60,7 @@ func (s *Store) GetShopTransactionByBranch(ctx context.Context, id int64) ([]dom
var result []domain.ShopTransactionDetail = make([]domain.ShopTransactionDetail, 0, len(transaction))
for _, ticket := range transaction {
result = append(result, convertDBShopTransactionDetail(ticket))
result = append(result, domain.ConvertDBShopTransactionDetail(ticket))
}
return result, nil
}
@ -208,7 +77,6 @@ func (s *Store) UpdateShopTransactionVerified(ctx context.Context, id int64, ver
return err
}
// GetTransactionTotals returns total deposits and withdrawals
func (s *Store) GetTransactionTotals(ctx context.Context, filter domain.ReportFilter) (deposits, withdrawals domain.Currency, err error) {
query := `SELECT

View File

@ -5,85 +5,19 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/jackc/pgx/v5/pgtype"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
func convertDBTicket(ticket dbgen.Ticket) domain.Ticket {
return domain.Ticket{
ID: ticket.ID,
Amount: domain.Currency(ticket.Amount),
TotalOdds: ticket.TotalOdds,
CompanyID: ticket.CompanyID,
}
}
func convertDBTicketOutcomes(ticket dbgen.TicketWithOutcome) domain.GetTicket {
var outcomes []domain.TicketOutcome = make([]domain.TicketOutcome, 0, len(ticket.Outcomes))
for _, outcome := range ticket.Outcomes {
outcomes = append(outcomes, domain.TicketOutcome{
ID: outcome.ID,
TicketID: outcome.TicketID,
EventID: outcome.EventID,
OddID: outcome.OddID,
HomeTeamName: outcome.HomeTeamName,
AwayTeamName: outcome.AwayTeamName,
MarketID: outcome.MarketID,
MarketName: outcome.MarketName,
Odd: outcome.Odd,
OddName: outcome.OddName,
OddHeader: outcome.OddHeader,
OddHandicap: outcome.OddHandicap,
Status: domain.OutcomeStatus(outcome.Status),
Expires: outcome.Expires.Time,
})
}
return domain.GetTicket{
ID: ticket.ID,
CompanyID: ticket.CompanyID,
Amount: domain.Currency(ticket.Amount),
TotalOdds: ticket.TotalOdds,
Outcomes: outcomes,
}
}
func convertDBCreateTicketOutcome(ticketOutcome domain.CreateTicketOutcome) dbgen.CreateTicketOutcomeParams {
return dbgen.CreateTicketOutcomeParams{
TicketID: ticketOutcome.TicketID,
EventID: ticketOutcome.EventID,
OddID: ticketOutcome.OddID,
HomeTeamName: ticketOutcome.HomeTeamName,
AwayTeamName: ticketOutcome.AwayTeamName,
MarketID: ticketOutcome.MarketID,
MarketName: ticketOutcome.MarketName,
Odd: ticketOutcome.Odd,
OddName: ticketOutcome.OddName,
OddHeader: ticketOutcome.OddHeader,
OddHandicap: ticketOutcome.OddHandicap,
Expires: pgtype.Timestamp{
Time: ticketOutcome.Expires,
Valid: true,
},
}
}
func convertCreateTicket(ticket domain.CreateTicket) dbgen.CreateTicketParams {
return dbgen.CreateTicketParams{
Amount: int64(ticket.Amount),
TotalOdds: ticket.TotalOdds,
Ip: ticket.IP,
CompanyID: ticket.CompanyID,
}
}
// Interface for creating new user store
func NewTicketStore(s *Store) ports.TicketStore { return s }
func (s *Store) CreateTicket(ctx context.Context, ticket domain.CreateTicket) (domain.Ticket, error) {
newTicket, err := s.queries.CreateTicket(ctx, convertCreateTicket(ticket))
newTicket, err := s.queries.CreateTicket(ctx, domain.ConvertCreateTicket(ticket))
if err != nil {
return domain.Ticket{}, err
}
return convertDBTicket(newTicket), err
return domain.ConvertDBTicket(newTicket), err
}
@ -91,7 +25,7 @@ func (s *Store) CreateTicketOutcome(ctx context.Context, outcomes []domain.Creat
var dbParams []dbgen.CreateTicketOutcomeParams = make([]dbgen.CreateTicketOutcomeParams, 0, len(outcomes))
for _, outcome := range outcomes {
dbParams = append(dbParams, convertDBCreateTicketOutcome(outcome))
dbParams = append(dbParams, domain.ConvertDBCreateTicketOutcome(outcome))
}
rows, err := s.queries.CreateTicketOutcome(ctx, dbParams)
@ -110,7 +44,7 @@ func (s *Store) GetTicketByID(ctx context.Context, id int64) (domain.GetTicket,
return domain.GetTicket{}, err
}
return convertDBTicketOutcomes(ticket), nil
return domain.ConvertDBTicketOutcomes(ticket), nil
}
func (s *Store) GetAllTickets(ctx context.Context, filter domain.TicketFilter) ([]domain.GetTicket, error) {
@ -121,7 +55,7 @@ func (s *Store) GetAllTickets(ctx context.Context, filter domain.TicketFilter) (
var result []domain.GetTicket = make([]domain.GetTicket, 0, len(tickets))
for _, ticket := range tickets {
result = append(result, convertDBTicketOutcomes(ticket))
result = append(result, domain.ConvertDBTicketOutcomes(ticket))
}
return result, nil

View File

@ -5,104 +5,19 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/jackc/pgx/v5/pgtype"
)
func convertDBTransferDetail(transfer dbgen.WalletTransferDetail) domain.TransferDetail {
return domain.TransferDetail{
ID: transfer.ID,
Amount: domain.Currency(transfer.Amount.Int64),
Type: domain.TransferType(transfer.Type.String),
Verified: transfer.Verified.Bool,
Message: transfer.Message,
ReceiverWalletID: domain.ValidInt64{
Value: transfer.ReceiverWalletID.Int64,
Valid: transfer.ReceiverWalletID.Valid,
},
SenderWalletID: domain.ValidInt64{
Value: transfer.SenderWalletID.Int64,
Valid: transfer.SenderWalletID.Valid,
},
DepositorID: domain.ValidInt64{
Value: transfer.CashierID.Int64,
Valid: transfer.CashierID.Valid,
},
DepositorFirstName: transfer.FirstName.String,
DepositorLastName: transfer.LastName.String,
DepositorPhoneNumber: transfer.PhoneNumber.String,
PaymentMethod: domain.PaymentMethod(transfer.PaymentMethod.String),
ReferenceNumber: transfer.ReferenceNumber,
SessionID: transfer.SessionID.String,
Status: transfer.Status.String,
CreatedAt: transfer.CreatedAt.Time,
UpdatedAt: transfer.UpdatedAt.Time,
}
}
func convertDBTransfer(transfer dbgen.WalletTransfer) domain.Transfer {
return domain.Transfer{
ID: transfer.ID,
Amount: domain.Currency(transfer.Amount.Int64),
Type: domain.TransferType(transfer.Type.String),
Verified: transfer.Verified.Bool,
Message: transfer.Message,
ReceiverWalletID: domain.ValidInt64{
Value: transfer.ReceiverWalletID.Int64,
Valid: transfer.ReceiverWalletID.Valid,
},
SenderWalletID: domain.ValidInt64{
Value: transfer.SenderWalletID.Int64,
Valid: transfer.SenderWalletID.Valid,
},
DepositorID: domain.ValidInt64{
Value: transfer.CashierID.Int64,
Valid: transfer.CashierID.Valid,
},
PaymentMethod: domain.PaymentMethod(transfer.PaymentMethod.String),
ReferenceNumber: transfer.ReferenceNumber,
SessionID: transfer.SessionID.String,
Status: transfer.Status.String,
CreatedAt: transfer.CreatedAt.Time,
UpdatedAt: transfer.UpdatedAt.Time,
}
}
func convertCreateTransfer(transfer domain.CreateTransfer) dbgen.CreateTransferParams {
return dbgen.CreateTransferParams{
Message: transfer.Message,
Amount: pgtype.Int8{Int64: int64(transfer.Amount), Valid: true},
Type: pgtype.Text{String: string(transfer.Type), Valid: true},
ReceiverWalletID: pgtype.Int8{
Int64: transfer.ReceiverWalletID.Value,
Valid: transfer.ReceiverWalletID.Valid,
},
SenderWalletID: pgtype.Int8{
Int64: transfer.SenderWalletID.Value,
Valid: transfer.SenderWalletID.Valid,
},
CashierID: pgtype.Int8{
Int64: transfer.CashierID.Value,
Valid: transfer.CashierID.Valid,
},
ReferenceNumber: string(transfer.ReferenceNumber),
SessionID: pgtype.Text{
String: transfer.SessionID,
Valid: true,
},
PaymentMethod: pgtype.Text{String: string(transfer.PaymentMethod), Valid: true},
Verified: pgtype.Bool{
Bool: transfer.Verified,
Valid: true,
},
}
}
// Interface for creating new transfer store
func NewTransferStore(s *Store) ports.TransferStore { return s }
func (s *Store) CreateTransfer(ctx context.Context, transfer domain.CreateTransfer) (domain.Transfer, error) {
newTransfer, err := s.queries.CreateTransfer(ctx, convertCreateTransfer(transfer))
newTransfer, err := s.queries.CreateTransfer(ctx, domain.ConvertCreateTransfer(transfer))
if err != nil {
return domain.Transfer{}, err
}
return convertDBTransfer(newTransfer), nil
return domain.ConvertDBTransfer(newTransfer), nil
}
func (s *Store) GetAllTransfers(ctx context.Context) ([]domain.TransferDetail, error) {
@ -113,7 +28,7 @@ func (s *Store) GetAllTransfers(ctx context.Context) ([]domain.TransferDetail, e
var result []domain.TransferDetail = make([]domain.TransferDetail, 0, len(transfers))
for _, transfer := range transfers {
result = append(result, convertDBTransferDetail(transfer))
result = append(result, domain.ConvertDBTransferDetail(transfer))
}
return result, nil
}
@ -127,7 +42,7 @@ func (s *Store) GetTransfersByWallet(ctx context.Context, walletID int64) ([]dom
var result []domain.TransferDetail = make([]domain.TransferDetail, 0, len(transfers))
for _, transfer := range transfers {
result = append(result, convertDBTransferDetail(transfer))
result = append(result, domain.ConvertDBTransferDetail(transfer))
}
return result, nil
}
@ -137,7 +52,7 @@ func (s *Store) GetTransferByReference(ctx context.Context, reference string) (d
if err != nil {
return domain.TransferDetail{}, nil
}
return convertDBTransferDetail(transfer), nil
return domain.ConvertDBTransferDetail(transfer), nil
}
func (s *Store) GetTransferByID(ctx context.Context, id int64) (domain.TransferDetail, error) {
@ -145,7 +60,7 @@ func (s *Store) GetTransferByID(ctx context.Context, id int64) (domain.TransferD
if err != nil {
return domain.TransferDetail{}, nil
}
return convertDBTransferDetail(transfer), nil
return domain.ConvertDBTransferDetail(transfer), nil
}
func (s *Store) GetTransferStats(ctx context.Context, walletID int64) (domain.TransferStats, error) {

View File

@ -9,10 +9,15 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgtype"
)
// Interface for creating new user store
func NewUserStore(s *Store) ports.UserStore { return s }
func (s *Store) CreateUser(ctx context.Context, user domain.User, usedOtpId int64, is_company bool) (domain.User, error) {
err := s.queries.MarkOtpAsUsed(ctx, dbgen.MarkOtpAsUsedParams{
ID: usedOtpId,
@ -529,6 +534,46 @@ func (s *Store) GetAdminByCompanyID(ctx context.Context, companyID int64) (domai
}, nil
}
func (s *Store) GetUserByEmailPhone(ctx context.Context, email, phone string, companyID domain.ValidInt64) (domain.User, error) {
user, err := s.queries.GetUserByEmailPhone(ctx, dbgen.GetUserByEmailPhoneParams{
Email: pgtype.Text{
String: email,
Valid: true,
},
PhoneNumber: pgtype.Text{
String: phone,
Valid: true,
},
CompanyID: companyID.ToPG(),
})
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return domain.User{}, authentication.ErrUserNotFound
}
return domain.User{}, err
}
return domain.User{
ID: user.ID,
FirstName: user.FirstName,
LastName: user.LastName,
Email: user.Email.String,
PhoneNumber: user.PhoneNumber.String,
Password: user.Password,
Role: domain.Role(user.Role),
EmailVerified: user.EmailVerified,
PhoneVerified: user.PhoneVerified,
CreatedAt: user.CreatedAt.Time,
UpdatedAt: user.UpdatedAt.Time,
SuspendedAt: user.SuspendedAt.Time,
Suspended: user.Suspended,
CompanyID: domain.ValidInt64{
Value: user.CompanyID.Int64,
Valid: user.CompanyID.Valid,
},
}, nil
}
// GetCustomerCounts returns total and active customer counts
func (s *Store) GetCustomerCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) {
query := `SELECT

View File

@ -6,86 +6,31 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
func convertDBWallet(wallet dbgen.Wallet) domain.Wallet {
return domain.Wallet{
ID: wallet.ID,
Balance: domain.Currency(wallet.Balance),
IsWithdraw: wallet.IsWithdraw,
IsBettable: wallet.IsBettable,
IsTransferable: wallet.IsTransferable,
IsActive: wallet.IsActive,
UserID: wallet.UserID,
Type: domain.WalletType(wallet.Type),
UpdatedAt: wallet.UpdatedAt.Time,
CreatedAt: wallet.CreatedAt.Time,
}
}
// Interface for creating new wallet store
func NewWalletStore(s *Store) ports.WalletStore { return s }
func convertCreateWallet(wallet domain.CreateWallet) dbgen.CreateWalletParams {
return dbgen.CreateWalletParams{
IsWithdraw: wallet.IsWithdraw,
IsBettable: wallet.IsBettable,
IsTransferable: wallet.IsTransferable,
UserID: wallet.UserID,
Type: string(wallet.Type),
}
}
func convertDBCustomerWallet(customerWallet dbgen.CustomerWallet) domain.CustomerWallet {
return domain.CustomerWallet{
ID: customerWallet.ID,
RegularID: customerWallet.RegularWalletID,
StaticID: customerWallet.StaticWalletID,
CustomerID: customerWallet.CustomerID,
}
}
func convertCreateCustomerWallet(customerWallet domain.CreateCustomerWallet) dbgen.CreateCustomerWalletParams {
return dbgen.CreateCustomerWalletParams{
CustomerID: customerWallet.CustomerID,
RegularWalletID: customerWallet.RegularWalletID,
StaticWalletID: customerWallet.StaticWalletID,
}
}
func convertDBGetCustomerWallet(customerWallet dbgen.CustomerWalletDetail) domain.GetCustomerWallet {
return domain.GetCustomerWallet{
ID: customerWallet.ID,
RegularID: customerWallet.RegularID,
RegularBalance: domain.Currency(customerWallet.RegularBalance),
StaticID: customerWallet.StaticID,
StaticBalance: domain.Currency(customerWallet.StaticBalance),
CustomerID: customerWallet.CustomerID,
RegularIsActive: customerWallet.RegularIsActive,
StaticIsActive: customerWallet.StaticIsActive,
RegularUpdatedAt: customerWallet.RegularUpdatedAt.Time,
StaticUpdatedAt: customerWallet.StaticUpdatedAt.Time,
CreatedAt: customerWallet.CreatedAt.Time,
FirstName: customerWallet.FirstName,
LastName: customerWallet.LastName,
PhoneNumber: customerWallet.PhoneNumber.String,
}
}
func (s *Store) CreateWallet(ctx context.Context, wallet domain.CreateWallet) (domain.Wallet, error) {
newWallet, err := s.queries.CreateWallet(ctx, convertCreateWallet(wallet))
newWallet, err := s.queries.CreateWallet(ctx, domain.ConvertCreateWallet(wallet))
if err != nil {
if IsUniqueViolation(err) {
return domain.Wallet{}, domain.ErrWalletIDDuplicate
}
return domain.Wallet{}, err
}
return convertDBWallet(newWallet), nil
return domain.ConvertDBWallet(newWallet), nil
}
func (s *Store) CreateCustomerWallet(ctx context.Context, customerWallet domain.CreateCustomerWallet) (domain.CustomerWallet, error) {
newCustomerWallet, err := s.queries.CreateCustomerWallet(ctx, convertCreateCustomerWallet(customerWallet))
newCustomerWallet, err := s.queries.CreateCustomerWallet(ctx, domain.ConvertCreateCustomerWallet(customerWallet))
if err != nil {
return domain.CustomerWallet{}, err
}
return convertDBCustomerWallet(newCustomerWallet), nil
return domain.ConvertDBCustomerWallet(newCustomerWallet), nil
}
func (s *Store) GetWalletByID(ctx context.Context, id int64) (domain.Wallet, error) {
@ -94,7 +39,7 @@ func (s *Store) GetWalletByID(ctx context.Context, id int64) (domain.Wallet, err
if err != nil {
return domain.Wallet{}, err
}
return convertDBWallet(wallet), nil
return domain.ConvertDBWallet(wallet), nil
}
func (s *Store) GetAllWallets(ctx context.Context) ([]domain.Wallet, error) {
@ -106,7 +51,7 @@ func (s *Store) GetAllWallets(ctx context.Context) ([]domain.Wallet, error) {
var result []domain.Wallet = make([]domain.Wallet, 0, len(wallets))
for _, wallet := range wallets {
result = append(result, convertDBWallet(wallet))
result = append(result, domain.ConvertDBWallet(wallet))
}
return result, nil
}
@ -120,7 +65,7 @@ func (s *Store) GetWalletsByUser(ctx context.Context, userID int64) ([]domain.Wa
var result []domain.Wallet = make([]domain.Wallet, 0, len(wallets))
for _, wallet := range wallets {
result = append(result, convertDBWallet(wallet))
result = append(result, domain.ConvertDBWallet(wallet))
}
return result, nil
}
@ -133,7 +78,7 @@ func (s *Store) GetAllCustomerWallets(ctx context.Context) ([]domain.GetCustomer
var result []domain.GetCustomerWallet = make([]domain.GetCustomerWallet, 0, len(customerWallets))
for _, wallet := range customerWallets {
result = append(result, convertDBGetCustomerWallet(wallet))
result = append(result, domain.ConvertDBGetCustomerWallet(wallet))
}
return result, nil
}
@ -144,7 +89,7 @@ func (s *Store) GetCustomerWallet(ctx context.Context, customerID int64) (domain
if err != nil {
return domain.GetCustomerWallet{}, err
}
return convertDBGetCustomerWallet(customerWallet), nil
return domain.ConvertDBGetCustomerWallet(customerWallet), nil
}
func (s *Store) GetAllBranchWallets(ctx context.Context) ([]domain.BranchWallet, error) {

View File

@ -11,18 +11,19 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
"github.com/google/uuid"
)
type ArifpayService struct {
cfg *config.Config
transferStore wallet.TransferStore
transferStore ports.TransferStore
walletSvc *wallet.Service
httpClient *http.Client
}
func NewArifpayService(cfg *config.Config, transferStore wallet.TransferStore, walletSvc *wallet.Service, httpClient *http.Client) *ArifpayService {
func NewArifpayService(cfg *config.Config, transferStore ports.TransferStore, walletSvc *wallet.Service, httpClient *http.Client) *ArifpayService {
return &ArifpayService{
cfg: cfg,
transferStore: transferStore,

View File

@ -0,0 +1,17 @@
package authentication
// import (
// "context"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// )
// type UserStore interface {
// GetUserByEmailPhone(ctx context.Context, email, phone string, companyID domain.ValidInt64) (domain.User, error)
// }
// type TokenStore interface {
// CreateRefreshToken(ctx context.Context, rt domain.RefreshToken) error
// GetRefreshToken(ctx context.Context, token string) (domain.RefreshToken, error)
// GetRefreshTokenByUserID(ctx context.Context, id int64) (domain.RefreshToken, error)
// RevokeRefreshToken(ctx context.Context, token string) error
// }

View File

@ -1,5 +1,7 @@
package authentication
import "github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
// type EmailPhone struct {
// Email ValidString
// PhoneNumber ValidString
@ -14,12 +16,12 @@ type Tokens struct {
RefreshToken string
}
type Service struct {
userStore UserStore
tokenStore TokenStore
userStore ports.UserStore
tokenStore ports.TokenStore
RefreshExpiry int
}
func NewService(userStore UserStore, tokenStore TokenStore, RefreshExpiry int) *Service {
func NewService(userStore ports.UserStore, tokenStore ports.TokenStore, RefreshExpiry int) *Service {
return &Service{
userStore: userStore,
tokenStore: tokenStore,

View File

@ -0,0 +1,53 @@
package bet
// import (
// "context"
// "time"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// )
// type BetStore interface {
// CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error)
// CreateBetOutcome(ctx context.Context, outcomes []domain.CreateBetOutcome) (int64, error)
// CreateFlag(ctx context.Context, flag domain.CreateFlagReq) (domain.Flag, error)
// GetBetByID(ctx context.Context, id int64) (domain.GetBet, error)
// GetAllBets(ctx context.Context, filter domain.BetFilter) ([]domain.GetBet, int64, error)
// GetBetByUserID(ctx context.Context, UserID int64) ([]domain.GetBet, error)
// GetBetByFastCode(ctx context.Context, fastcode string) (domain.GetBet, error)
// GetBetOutcomeViewByEventID(ctx context.Context, eventID int64, filter domain.BetOutcomeViewFilter) ([]domain.BetOutcomeViewRes, int64, error)
// GetBetOutcomeByEventID(ctx context.Context, eventID int64, is_filtered bool) ([]domain.BetOutcome, error)
// GetBetOutcomeByBetID(ctx context.Context, betID int64) ([]domain.BetOutcome, error)
// GetBetOutcomeCountByOddID(ctx context.Context, oddID int64) (int64, error)
// GetBetCountByUserID(ctx context.Context, userID int64, outcomesHash string) (int64, error)
// GetBetCountByOutcomesHash(ctx context.Context, outcomesHash string) (int64, error)
// UpdateCashOut(ctx context.Context, id int64, cashedOut bool) error
// UpdateStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error
// UpdateBetOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) (domain.BetOutcome, error)
// UpdateBetOutcomeStatusByBetID(ctx context.Context, id int64, status domain.OutcomeStatus) (domain.BetOutcome, error)
// UpdateBetOutcomeStatusForEvent(ctx context.Context, eventID int64, status domain.OutcomeStatus) ([]domain.BetOutcome, error)
// UpdateBetOutcomeStatusForOddId(ctx context.Context, oddID int64, status domain.OutcomeStatus) ([]domain.BetOutcome, error)
// BulkUpdateBetOutcomeStatusForOddIds(ctx context.Context, oddID []int64, status domain.OutcomeStatus) error
// GetBetSummary(ctx context.Context, filter domain.ReportFilter) (
// totalStakes domain.Currency,
// totalBets int64,
// activeBets int64,
// totalWins int64,
// totalLosses int64,
// winBalance domain.Currency,
// err error,
// )
// GetBetStats(ctx context.Context, filter domain.ReportFilter) ([]domain.BetStat, error)
// GetSportPopularity(ctx context.Context, filter domain.ReportFilter) (map[time.Time]string, error)
// GetMarketPopularity(ctx context.Context, filter domain.ReportFilter) (map[time.Time]string, error)
// GetExtremeValues(ctx context.Context, filter domain.ReportFilter) (map[time.Time]domain.ExtremeValues, error)
// GetCustomerBetActivity(ctx context.Context, filter domain.ReportFilter) ([]domain.CustomerBetActivity, error)
// GetCustomerPreferences(ctx context.Context, filter domain.ReportFilter) (map[int64]domain.CustomerPreferences, error)
// GetBranchBetActivity(ctx context.Context, filter domain.ReportFilter) ([]domain.BranchBetActivity, error)
// GetSportBetActivity(ctx context.Context, filter domain.ReportFilter) ([]domain.SportBetActivity, error)
// GetSportDetails(ctx context.Context, filter domain.ReportFilter) (map[string]string, error)
// GetSportMarketPopularity(ctx context.Context, filter domain.ReportFilter) (map[string]string, error)
// GetBetsForCashback(ctx context.Context) ([]domain.GetBet, error)
// UpdateBetWithCashback(ctx context.Context, betID int64, cashbackStatus bool) error
// }

View File

@ -19,6 +19,7 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/pkgs/helpers"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
@ -53,7 +54,7 @@ var (
)
type Service struct {
betStore BetStore
betStore ports.BetStore
eventSvc *event.Service
prematchSvc odds.ServiceImpl
walletSvc wallet.Service
@ -67,7 +68,7 @@ type Service struct {
}
func NewService(
betStore BetStore,
betStore ports.BetStore,
eventSvc *event.Service,
prematchSvc odds.ServiceImpl,
walletSvc wallet.Service,

View File

@ -0,0 +1,17 @@
package bonus
// import (
// "context"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// )
// type BonusStore interface {
// CreateUserBonus(ctx context.Context, bonus domain.CreateBonus) (domain.UserBonus, error)
// GetAllUserBonuses(ctx context.Context, filter domain.BonusFilter) ([]domain.UserBonus, error)
// GetBonusCount(ctx context.Context, filter domain.BonusFilter) (int64, error)
// GetBonusByID(ctx context.Context, bonusID int64) (domain.UserBonus, error)
// GetBonusStats(ctx context.Context, filter domain.BonusFilter) (domain.BonusStats, error)
// UpdateUserBonus(ctx context.Context, bonusID int64, IsClaimed bool) error
// DeleteUserBonus(ctx context.Context, bonusID int64) error
// }

View File

@ -8,6 +8,7 @@ import (
"time"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/settings"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
@ -15,14 +16,20 @@ import (
)
type Service struct {
bonusStore BonusStore
bonusStore ports.BonusStore
walletSvc *wallet.Service
settingSvc *settings.Service
notificationSvc *notificationservice.Service
mongoLogger *zap.Logger
}
func NewService(bonusStore BonusStore, walletSvc *wallet.Service, settingSvc *settings.Service, notificationSvc *notificationservice.Service, mongoLogger *zap.Logger) *Service {
func NewService(
bonusStore ports.BonusStore,
walletSvc *wallet.Service,
settingSvc *settings.Service,
notificationSvc *notificationservice.Service,
mongoLogger *zap.Logger,
) *Service {
return &Service{
bonusStore: bonusStore,
walletSvc: walletSvc,

View File

@ -0,0 +1,34 @@
package branch
// import (
// "context"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// )
// type BranchStore interface {
// CreateBranch(ctx context.Context, branch domain.CreateBranch) (domain.Branch, error)
// GetBranchByID(ctx context.Context, id int64) (domain.BranchDetail, error)
// GetBranchByManagerID(ctx context.Context, branchManagerID int64) ([]domain.BranchDetail, error)
// GetBranchByCompanyID(ctx context.Context, companyID int64) ([]domain.BranchDetail, error)
// GetAllBranches(ctx context.Context, filter domain.BranchFilter) ([]domain.BranchDetail, error)
// SearchBranchByName(ctx context.Context, name string, companyID domain.ValidInt64) ([]domain.BranchDetail, error)
// UpdateBranch(ctx context.Context, branch domain.UpdateBranch) (domain.Branch, error)
// DeleteBranch(ctx context.Context, id int64) error
// CreateBranchOperation(ctx context.Context, branchOperation domain.CreateBranchOperation) error
// CreateSupportedOperation(ctx context.Context, supportedOperation domain.CreateSupportedOperation) (domain.SupportedOperation, error)
// GetAllSupportedOperations(ctx context.Context) ([]domain.SupportedOperation, error)
// GetBranchOperations(ctx context.Context, branchID int64) ([]domain.BranchOperation, error)
// DeleteBranchOperation(ctx context.Context, branchID int64, operationID int64) error
// CreateBranchCashier(ctx context.Context, branchID int64, userID int64) error
// GetBranchByCashier(ctx context.Context, userID int64) (domain.Branch, error)
// DeleteBranchCashier(ctx context.Context, userID int64) error
// GetBranchCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error)
// GetBranchDetails(ctx context.Context, filter domain.ReportFilter) (map[int64]domain.BranchDetail, error)
// GetAllCompaniesBranch(ctx context.Context) ([]domain.Company, error)
// GetBranchesByCompany(ctx context.Context, companyID int64) ([]domain.Branch, error)
// GetAllBranchLocations(ctx context.Context, query domain.ValidString) ([]domain.BranchLocation, error)
// }

View File

@ -1,16 +1,17 @@
package branch
package branch
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
type Service struct {
branchStore BranchStore
branchStore ports.BranchStore
}
func NewService(branchStore BranchStore) *Service {
func NewService(branchStore ports.BranchStore) *Service {
return &Service{
branchStore: branchStore,
}
@ -78,4 +79,3 @@ func (s *Service) GetAllCompaniesBranch(ctx context.Context) ([]domain.Company,
func (s *Service) GetBranchesByCompany(ctx context.Context, companyID int64) ([]domain.Branch, error) {
return s.branchStore.GetBranchesByCompany(ctx, companyID)
}

View File

@ -9,23 +9,24 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
"github.com/google/uuid"
)
type Service struct {
transferStore wallet.TransferStore
transferStore ports.TransferStore
walletStore wallet.Service
userStore user.UserStore
userStore ports.UserStore
cfg *config.Config
chapaClient *Client
}
func NewService(
transferStore wallet.TransferStore,
transferStore ports.TransferStore,
walletStore wallet.Service,
userStore user.UserStore,
userStore ports.UserStore,
cfg *config.Config,
chapaClient *Client,

View File

@ -0,0 +1,23 @@
package company
// import (
// "context"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// )
// type CompanyStore interface {
// CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error)
// GetAllCompanies(ctx context.Context, filter domain.CompanyFilter) ([]domain.GetCompany, error)
// SearchCompanyByName(ctx context.Context, name string) ([]domain.GetCompany, error)
// GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error)
// GetCompanyBySlug(ctx context.Context, slug string) (domain.Company, error)
// UpdateCompany(ctx context.Context, company domain.UpdateCompany) error
// DeleteCompany(ctx context.Context, id int64) error
// GetCompanyCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error)
// UpdateCompanyStats(ctx context.Context) error
// GetCompanyStatByID(ctx context.Context, companyID int64) ([]domain.CompanyStat, error)
// GetCompanyStatsByInterval(ctx context.Context, filter domain.CompanyStatFilter) ([]domain.CompanyStat, error)
// }

View File

@ -4,13 +4,14 @@ import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
type Service struct {
companyStore CompanyStore
companyStore ports.CompanyStore
}
func NewService(companyStore CompanyStore) *Service {
func NewService(companyStore ports.CompanyStore) *Service {
return &Service{
companyStore: companyStore,
}

View File

@ -0,0 +1,29 @@
package event
// import (
// "context"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// )
// type EventStore interface {
// FetchUpcomingEvents(ctx context.Context) error
// GetAllEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error)
// GetEventByID(ctx context.Context, ID int64) (domain.BaseEvent, error)
// UpdateFinalScore(ctx context.Context, eventID int64, fullScore string, status domain.EventStatus) error
// UpdateEventStatus(ctx context.Context, eventID int64, status domain.EventStatus) error
// IsEventMonitored(ctx context.Context, eventID int64) (bool, error)
// UpdateEventMonitored(ctx context.Context, eventID int64, IsMonitored bool) error
// GetSportAndLeagueIDs(ctx context.Context, eventID int64) ([]int64, error)
// // Event Settings Views
// GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error)
// GetEventWithSettingByID(ctx context.Context, ID int64, companyID int64) (domain.EventWithSettings, error)
// UpdateTenantEventSettings(ctx context.Context, event domain.UpdateTenantEventSettings) error
// UpdateGlobalEventSettings(ctx context.Context, event domain.UpdateGlobalEventSettings) error
// // Stats
// GetTotalEventStats(ctx context.Context, filter domain.EventStatsFilter) (domain.EventStats, error)
// GetTotalEventStatsByInterval(ctx context.Context, filter domain.EventStatsByIntervalFilter) ([]domain.EventStatsByInterval, error)
// UpdateEventBetStats(ctx context.Context) error
// }

View File

@ -14,27 +14,41 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/league"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/settings"
"go.uber.org/zap"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
)
type Service struct {
token string
store *repository.Store
settingSvc *settings.Service
mongoLogger *zap.Logger
cfg *config.Config
token string
eventStore ports.EventStore
eventHistoryStore ports.EventHistoryStore
leagueSvc league.Service
settingSvc *settings.Service
mongoLogger *zap.Logger
cfg *config.Config
}
func New(token string, store *repository.Store, settingSvc *settings.Service, mongoLogger *zap.Logger, cfg *config.Config) *Service {
func New(
token string,
eventStore ports.EventStore,
eventHistoryStore ports.EventHistoryStore,
leagueSvc league.Service,
settingSvc *settings.Service,
mongoLogger *zap.Logger,
cfg *config.Config,
) *Service {
return &Service{
token: token,
store: store,
settingSvc: settingSvc,
mongoLogger: mongoLogger,
cfg: cfg,
token: token,
eventStore: eventStore,
eventHistoryStore: eventHistoryStore,
leagueSvc: leagueSvc,
settingSvc: settingSvc,
mongoLogger: mongoLogger,
cfg: cfg,
}
}
@ -93,7 +107,7 @@ func New(token string, store *repository.Store, settingSvc *settings.Service, mo
// }
// for _, event := range events {
// if err := s.store.SaveEvent(ctx, event); err != nil {
// if err := s.eventStore.SaveEvent(ctx, event); err != nil {
// fmt.Printf("Could not store live event [id=%s]: %v\n", event.ID, err)
// }
// }
@ -299,7 +313,7 @@ func (s *Service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
// no this its fine to keep it here
// but change the league id to bet365 id later
//Automatically feature the league if its in the list
err = s.store.SaveLeague(ctx, domain.CreateLeague{
err = s.leagueSvc.SaveLeague(ctx, domain.CreateLeague{
ID: leagueID,
Name: ev.League.Name,
DefaultIsActive: true,
@ -313,7 +327,7 @@ func (s *Service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
}
// Since the system is multi-vendor now, no events are going to be skipped
// if supported, err := s.store.CheckLeagueSupport(ctx, leagueID); !supported || err != nil {
// if supported, err := s.eventStore.CheckLeagueSupport(ctx, leagueID); !supported || err != nil {
// dataLogger.Warn(
// "Skipping league",
// zap.Bool("is_supported", supported),
@ -356,7 +370,7 @@ func (s *Service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
dataLogger.Info("event history has been recorded")
}
err = s.store.SaveEvent(ctx, event)
err = s.eventStore.SaveEvent(ctx, event)
if err != nil {
dataLogger.Error("failed to save upcoming event", zap.Error(err))
}
@ -401,7 +415,7 @@ func (s *Service) CheckAndInsertEventHistory(ctx context.Context, newEvent domai
zap.Int32("sport_id", newEvent.SportID),
)
oldEvent, err := s.store.GetEventBySourceID(ctx, newEvent.SourceEventID, newEvent.Source)
oldEvent, err := s.eventStore.GetEventBySourceID(ctx, newEvent.SourceEventID, newEvent.Source)
if err != nil {
return false, err
@ -412,7 +426,7 @@ func (s *Service) CheckAndInsertEventHistory(ctx context.Context, newEvent domai
}
if oldEvent.Status != newEvent.Status {
_, err := s.store.InsertEventHistory(ctx, domain.CreateEventHistory{
_, err := s.eventHistoryStore.InsertEventHistory(ctx, domain.CreateEventHistory{
EventID: oldEvent.ID,
Status: string(newEvent.Status),
})
@ -462,27 +476,35 @@ func convertInt64(num string) int64 {
return 0
}
func (s *Service) GetAllEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error) {
return s.store.GetAllEvents(ctx, filter)
return s.eventStore.GetAllEvents(ctx, filter)
}
func (s *Service) GetEventByID(ctx context.Context, ID int64) (domain.BaseEvent, error) {
return s.store.GetEventByID(ctx, ID)
return s.eventStore.GetEventByID(ctx, ID)
}
func (s *Service) UpdateFinalScore(ctx context.Context, eventID int64, fullScore string, status domain.EventStatus) error {
return s.store.UpdateFinalScore(ctx, eventID, fullScore, status)
return s.eventStore.UpdateFinalScore(ctx, eventID, fullScore, status)
}
func (s *Service) UpdateEventStatus(ctx context.Context, eventID int64, status domain.EventStatus) error {
return s.store.UpdateEventStatus(ctx, eventID, status)
return s.eventStore.UpdateEventStatus(ctx, eventID, status)
}
func (s *Service) IsEventMonitored(ctx context.Context, eventID int64) (bool, error) {
return s.store.IsEventMonitored(ctx, eventID)
return s.eventStore.IsEventMonitored(ctx, eventID)
}
func (s *Service) UpdateEventMonitored(ctx context.Context, eventID int64, IsMonitored bool) error {
return s.store.UpdateEventMonitored(ctx, eventID, IsMonitored)
return s.eventStore.UpdateEventMonitored(ctx, eventID, IsMonitored)
}
func (s *Service) GetSportAndLeagueIDs(ctx context.Context, eventID int64) ([]int64, error) {
return s.store.GetSportAndLeagueIDs(ctx, eventID)
return s.eventStore.GetSportAndLeagueIDs(ctx, eventID)
}
func (s *Service) DeleteEvent(ctx context.Context, eventID int64) error {
return s.eventStore.DeleteEvent(ctx, eventID)
}
func (s *Service) GetEventBySourceID(ctx context.Context, id string, source domain.EventSource) (domain.BaseEvent, error) {
return s.eventStore.GetEventBySourceID(ctx, id, source)
}

View File

@ -7,16 +7,16 @@ import (
)
func (s *Service) GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error) {
return s.store.GetEventsWithSettings(ctx, companyID, filter)
return s.eventStore.GetEventsWithSettings(ctx, companyID, filter)
}
func (s *Service) GetEventWithSettingByID(ctx context.Context, ID int64, companyID int64) (domain.EventWithSettings, error) {
return s.store.GetEventWithSettingByID(ctx, ID, companyID)
return s.eventStore.GetEventWithSettingByID(ctx, ID, companyID)
}
func (s *Service) UpdateTenantEventSettings(ctx context.Context, event domain.UpdateTenantEventSettings) error {
return s.store.UpdateTenantEventSettings(ctx, event)
return s.eventStore.UpdateTenantEventSettings(ctx, event)
}
func (s *Service) UpdateGlobalEventSettings(ctx context.Context, event domain.UpdateGlobalEventSettings) error {
return s.store.UpdateGlobalEventSettings(ctx, event)
return s.eventStore.UpdateGlobalEventSettings(ctx, event)
}

View File

@ -0,0 +1,17 @@
package league
// import (
// "context"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// )
// type LeagueStore interface {
// SaveLeague(ctx context.Context, league domain.CreateLeague) error
// SaveLeagueSettings(ctx context.Context, leagueSettings domain.CreateLeagueSettings) error
// GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, int64, error)
// GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, int64, error)
// CheckLeagueSupport(ctx context.Context, leagueID int64, companyID int64) (bool, error)
// UpdateLeague(ctx context.Context, league domain.UpdateLeague) error
// UpdateGlobalLeagueSettings(ctx context.Context, league domain.UpdateGlobalLeagueSettings) error
// }

View File

@ -4,14 +4,15 @@ import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
type Service struct {
store *repository.Store
store ports.LeagueStore
}
func New(store *repository.Store) *Service {
func New(store ports.LeagueStore) *Service {
return &Service{
store: store,
}

View File

@ -0,0 +1,23 @@
package notificationservice
// import (
// "context"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// "github.com/gorilla/websocket"
// )
// type NotificationStore interface {
// SendNotification(ctx context.Context, notification *domain.Notification) error
// MarkAsRead(ctx context.Context, notificationID string, recipientID int64) error
// GetUserNotifications(ctx context.Context, recipientID int64, limit, offset int) ([]domain.Notification, int64, error)
// ConnectWebSocket(ctx context.Context, recipientID int64, c *websocket.Conn) error
// DisconnectWebSocket(recipientID int64)
// SendSMS(ctx context.Context, recipientID int64, message string) error
// SendEmail(ctx context.Context, recipientID int64, subject, message string) error
// ListRecipientIDs(ctx context.Context, receiver domain.NotificationRecieverSide) ([]int64, error) // New method
// CountUnreadNotifications(ctx context.Context, recipient_id int64) (int64, error)
// GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error)
// GetNotificationCounts(ctx context.Context, filter domain.ReportFilter) (total, read, unread int64, err error)
// }

View File

@ -11,9 +11,9 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/pkgs/helpers"
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/messenger"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
// "github.com/segmentio/kafka-go"
@ -27,20 +27,20 @@ import (
)
type Service struct {
repo repository.NotificationRepository
Hub *ws.NotificationHub
notificationStore NotificationStore
connections sync.Map
notificationCh chan *domain.Notification
stopCh chan struct{}
config *config.Config
userSvc *user.Service
messengerSvc *messenger.Service
mongoLogger *zap.Logger
logger *slog.Logger
store ports.NotificationStore
Hub *ws.NotificationHub
connections sync.Map
notificationCh chan *domain.Notification
stopCh chan struct{}
config *config.Config
userSvc *user.Service
messengerSvc *messenger.Service
mongoLogger *zap.Logger
logger *slog.Logger
}
func New(repo repository.NotificationRepository,
func New(
store ports.NotificationStore,
mongoLogger *zap.Logger,
logger *slog.Logger,
cfg *config.Config,
@ -50,7 +50,7 @@ func New(repo repository.NotificationRepository,
hub := ws.NewNotificationHub()
svc := &Service{
repo: repo,
store: store,
Hub: hub,
mongoLogger: mongoLogger,
logger: logger,
@ -95,7 +95,7 @@ func (s *Service) SendNotification(ctx context.Context, notification *domain.Not
notification.Timestamp = time.Now()
notification.DeliveryStatus = domain.DeliveryStatusPending
created, err := s.repo.CreateNotification(ctx, notification)
created, err := s.store.CreateNotification(ctx, notification)
if err != nil {
s.mongoLogger.Error("[NotificationSvc.SendNotification] Failed to create notification",
zap.String("id", notification.ID),
@ -129,7 +129,7 @@ func (s *Service) SendNotification(ctx context.Context, notification *domain.Not
func (s *Service) MarkAsRead(ctx context.Context, notificationIDs []string, recipientID int64) error {
for _, notificationID := range notificationIDs {
_, err := s.repo.UpdateNotificationStatus(ctx, notificationID, string(domain.DeliveryStatusSent), true, nil)
_, err := s.store.UpdateNotificationStatus(ctx, notificationID, string(domain.DeliveryStatusSent), true, nil)
if err != nil {
s.mongoLogger.Error("[NotificationSvc.MarkAsRead] Failed to mark notification as read",
zap.String("notificationID", notificationID),
@ -140,7 +140,7 @@ func (s *Service) MarkAsRead(ctx context.Context, notificationIDs []string, reci
return err
}
// count, err := s.repo.CountUnreadNotifications(ctx, recipientID)
// count, err := s.store.CountUnreadNotifications(ctx, recipientID)
// if err != nil {
// s.logger.Error("[NotificationSvc.MarkAsRead] Failed to count unread notifications", "recipientID", recipientID, "error", err)
// return err
@ -165,7 +165,7 @@ func (s *Service) MarkAsRead(ctx context.Context, notificationIDs []string, reci
}
func (s *Service) GetUserNotifications(ctx context.Context, recipientID int64, limit, offset int) ([]domain.Notification, int64, error) {
notifications, total, err := s.repo.GetUserNotifications(ctx, recipientID, limit, offset)
notifications, total, err := s.store.GetUserNotifications(ctx, recipientID, limit, offset)
if err != nil {
s.mongoLogger.Error("[NotificationSvc.GetUserNotifications] Failed to list notifications",
zap.Int64("recipientID", recipientID),
@ -186,7 +186,7 @@ func (s *Service) GetUserNotifications(ctx context.Context, recipientID int64, l
}
func (s *Service) GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error) {
notifications, err := s.repo.GetAllNotifications(ctx, limit, offset)
notifications, err := s.store.GetAllNotifications(ctx, limit, offset)
if err != nil {
s.mongoLogger.Error("[NotificationSvc.ListNotifications] Failed to get all notifications",
zap.Int("limit", limit),
@ -282,7 +282,7 @@ func (s *Service) startWorker() {
}
func (s *Service) ListRecipientIDs(ctx context.Context, receiver domain.NotificationRecieverSide) ([]int64, error) {
return s.repo.ListRecipientIDs(ctx, receiver)
return s.store.ListRecipientIDs(ctx, receiver)
}
func (s *Service) handleNotification(notification *domain.Notification) {
@ -314,7 +314,7 @@ func (s *Service) handleNotification(notification *domain.Notification) {
}
}
if _, err := s.repo.UpdateNotificationStatus(ctx, notification.ID, string(notification.DeliveryStatus), notification.IsRead, notification.Metadata); err != nil {
if _, err := s.store.UpdateNotificationStatus(ctx, notification.ID, string(notification.DeliveryStatus), notification.IsRead, notification.Metadata); err != nil {
s.mongoLogger.Error("[NotificationSvc.HandleNotification] Failed to update notification status",
zap.String("id", notification.ID),
zap.Error(err),
@ -404,7 +404,7 @@ func (s *Service) startRetryWorker() {
func (s *Service) retryFailedNotifications() {
ctx := context.Background()
failedNotifications, err := s.repo.ListFailedNotifications(ctx, 100)
failedNotifications, err := s.store.ListFailedNotifications(ctx, 100)
if err != nil {
s.mongoLogger.Error("[NotificationSvc.RetryFailedNotifications] Failed to list failed notifications",
zap.Error(err),
@ -422,7 +422,7 @@ func (s *Service) retryFailedNotifications() {
case domain.DeliveryChannelSMS:
if err := s.SendNotificationSMS(ctx, notification.RecipientID, notification.Payload.Message); err == nil {
notification.DeliveryStatus = domain.DeliveryStatusSent
if _, err := s.repo.UpdateNotificationStatus(ctx, notification.ID, string(notification.DeliveryStatus), notification.IsRead, notification.Metadata); err != nil {
if _, err := s.store.UpdateNotificationStatus(ctx, notification.ID, string(notification.DeliveryStatus), notification.IsRead, notification.Metadata); err != nil {
s.mongoLogger.Error("[NotificationSvc.RetryFailedNotifications] Failed to update after retry",
zap.String("id", notification.ID),
zap.Error(err),
@ -440,7 +440,7 @@ func (s *Service) retryFailedNotifications() {
case domain.DeliveryChannelEmail:
if err := s.SendNotificationEmail(ctx, notification.RecipientID, notification.Payload.Message, notification.Payload.Headline); err == nil {
notification.DeliveryStatus = domain.DeliveryStatusSent
if _, err := s.repo.UpdateNotificationStatus(ctx, notification.ID, string(notification.DeliveryStatus), notification.IsRead, notification.Metadata); err != nil {
if _, err := s.store.UpdateNotificationStatus(ctx, notification.ID, string(notification.DeliveryStatus), notification.IsRead, notification.Metadata); err != nil {
s.mongoLogger.Error("[NotificationSvc.RetryFailedNotifications] Failed to update after retry",
zap.String("id", notification.ID),
zap.Error(err),
@ -467,15 +467,15 @@ func (s *Service) retryFailedNotifications() {
}
func (s *Service) CountUnreadNotifications(ctx context.Context, recipient_id int64) (int64, error) {
return s.repo.CountUnreadNotifications(ctx, recipient_id)
return s.store.CountUnreadNotifications(ctx, recipient_id)
}
func (s *Service) DeleteOldNotifications(ctx context.Context) error {
return s.repo.DeleteOldNotifications(ctx)
return s.store.DeleteOldNotifications(ctx)
}
// func (s *Service) GetNotificationCounts(ctx context.Context, filter domain.ReportFilter) (total, read, unread int64, err error){
// return s.repo.Get(ctx, filter)
// return s.store.Get(ctx, filter)
// }
// func (s *Service) RunRedisSubscriber(ctx context.Context) {

View File

@ -1,28 +0,0 @@
package odds
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
func (s *ServiceImpl) InsertDisabledOdd(ctx context.Context, odd domain.CreateDisabledOdd) (domain.DisabledOdd, error) {
return s.store.InsertDisabledOdd(ctx, odd)
}
func (s *ServiceImpl) GetAllDisabledOdds(ctx context.Context) ([]domain.DisabledOdd, error) {
return s.store.GetAllDisabledOdds(ctx)
}
func (s *ServiceImpl) GetDisabledOddByRawOddID(ctx context.Context, rawOddID int64) (domain.DisabledOdd, error) {
return s.store.GetDisabledOddByRawOddID(ctx, rawOddID)
}
func (s *ServiceImpl) GetDisabledOddByID(ctx context.Context, id int64) (domain.DisabledOdd, error) {
return s.store.GetDisabledOddByID(ctx, id)
}
func (s *ServiceImpl) DeleteDisabledOddsByID(ctx context.Context, id int64) error {
return s.store.DeleteDisabledOddsByID(ctx, id)
}
func (s *ServiceImpl) DeleteDisabledOddsByRawOddID(ctx context.Context, id int64) error {
return s.store.DeleteDisabledOddsByRawOddID(ctx, id)
}

View File

@ -15,13 +15,14 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"go.uber.org/zap"
)
type ServiceImpl struct {
store *repository.Store
store ports.OddStore
config *config.Config
eventSvc *event.Service
logger *slog.Logger
@ -29,7 +30,7 @@ type ServiceImpl struct {
client *http.Client
}
func New(store *repository.Store, cfg *config.Config, eventSvc *event.Service, logger *slog.Logger, mongoLogger *zap.Logger) *ServiceImpl {
func New(store ports.OddStore, cfg *config.Config, eventSvc *event.Service, logger *slog.Logger, mongoLogger *zap.Logger) *ServiceImpl {
return &ServiceImpl{
store: store,
config: cfg,

View File

@ -0,0 +1,27 @@
package raffle
// import (
// "context"
// dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// )
// type RaffleStore interface {
// CreateRaffle(ctx context.Context, raffle domain.CreateRaffle) (domain.Raffle, error)
// AddSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) error
// DeleteRaffle(ctx context.Context, raffleID int32) (domain.Raffle, error)
// GetRafflesOfCompany(ctx context.Context, companyID int32) ([]dbgen.Raffle, error)
// GetRaffleStanding(ctx context.Context, raffleID, limit int32) ([]domain.RaffleStanding, error)
// CreateRaffleWinner(ctx context.Context, raffleWinnerParams domain.RaffleWinnerParams) error
// SetRaffleComplete(ctx context.Context, raffleID int32) error
// CheckValidSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) (bool, error)
// CheckSportRaffleHasFilter(ctx context.Context, raffleID int32) (bool, error)
// CreateRaffleTicket(ctx context.Context, raffleTicketParams domain.CreateRaffleTicket) (domain.RaffleTicket, error)
// GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error)
// SuspendRaffleTicket(ctx context.Context, raffleTicketID int32) error
// UnSuspendRaffleTicket(ctx context.Context, raffleID int32) error
// GetRaffleTicketCount(ctx context.Context, raffleID, userID int32) (int64, error)
// GetRaffleTicketLimit(ctx context.Context, raffleID int32) (int32, error)
// }

View File

@ -5,13 +5,14 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
type Service struct {
raffleStore RaffleStore
raffleStore ports.RaffleStore
}
func NewService(raffleStore RaffleStore) *Service {
func NewService(raffleStore ports.RaffleStore) *Service {
return &Service{
raffleStore: raffleStore,
}

View File

@ -0,0 +1,17 @@
package referralservice
// import (
// "context"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// )
// type ReferralStore interface {
// GenerateReferralCode() (string, error)
// CreateReferral(ctx context.Context, userID int64, companyID int64) error
// ProcessReferral(ctx context.Context, referredPhone, referralCode string, companyID int64) error
// ProcessDepositBonus(ctx context.Context, userPhone string, amount float64) error
// ProcessBetReferral(ctx context.Context, userId int64, betAmount float64) error
// GetReferralStats(ctx context.Context, userID int64, companyID int64) (*domain.ReferralStats, error)
// GetReferralCountByID(ctx context.Context, referrerID int64) (int64, error)
// }

View File

@ -1,17 +0,0 @@
package referralservice
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type ReferralStore interface {
GenerateReferralCode() (string, error)
CreateReferral(ctx context.Context, userID int64, companyID int64) error
ProcessReferral(ctx context.Context, referredPhone, referralCode string, companyID int64) error
ProcessDepositBonus(ctx context.Context, userPhone string, amount float64) error
ProcessBetReferral(ctx context.Context, userId int64, betAmount float64) error
GetReferralStats(ctx context.Context, userID int64, companyID int64) (*domain.ReferralStats, error)
GetReferralCountByID(ctx context.Context, referrerID int64) (int64, error)
}

View File

@ -10,14 +10,15 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/settings"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
"go.uber.org/zap"
)
type Service struct {
repo repository.ReferralRepository
repo ports.ReferralStore
walletSvc wallet.Service
settingSvc settings.Service
config *config.Config
@ -25,7 +26,14 @@ type Service struct {
mongoLogger *zap.Logger
}
func New(repo repository.ReferralRepository, walletSvc wallet.Service, settingSvc settings.Service, cfg *config.Config, logger *slog.Logger, mongoLogger *zap.Logger) *Service {
func New(
repo ports.ReferralStore,
walletSvc wallet.Service,
settingSvc settings.Service,
cfg *config.Config,
logger *slog.Logger,
mongoLogger *zap.Logger,
) *Service {
return &Service{
repo: repo,
walletSvc: walletSvc,

View File

@ -29,7 +29,7 @@ func (s *Service) GenerateEventIntervalReport(ctx context.Context, request domai
return "", ErrInvalidInterval
}
stats, err := s.eventSvc.GetTotalEventStatsByInterval(ctx, domain.EventStatsByIntervalFilter{
stats, err := s.statService.GetTotalEventStatsByInterval(ctx, domain.EventStatsByIntervalFilter{
Interval: domain.ValidDateInterval{
Value: interval,
Valid: true,

View File

@ -6,19 +6,23 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type ReportStore interface {
type ReportService interface {
registerGenerators()
GetDashboardSummary(ctx context.Context, filter domain.ReportFilter) (domain.DashboardSummary, error)
GetBetAnalysis(ctx context.Context, filter domain.ReportFilter) ([]domain.BetAnalysis, error)
GetCustomerActivity(ctx context.Context, filter domain.ReportFilter) ([]domain.CustomerActivity, error)
GetBranchPerformance(ctx context.Context, filter domain.ReportFilter) ([]domain.BranchPerformance, error)
GetSportPerformance(ctx context.Context, filter domain.ReportFilter) ([]domain.SportPerformance, error)
// GetNotificationReport(ctx context.Context, filter domain.ReportFilter) (domain.NotificationReport, error)
// GetCashierPerformance(ctx context.Context, filter domain.ReportFilter) ([]domain.CashierPerformance, error)
// GetCompanyPerformance(ctx context.Context, filter domain.ReportFilter) ([]domain.CompanyPerformance, error)
// GenerateReport(ctx context.Context, from, to time.Time) error
// fetchReportData(ctx context.Context, from, to time.Time)
CreateReportRequest(ctx context.Context, report domain.CreateReportRequest) (domain.ReportRequest, error)
GetAllReportRequests(ctx context.Context, filter domain.ReportRequestFilter) ([]domain.ReportRequestDetail, int64, error)
GetReportRequestByRequestedByID(ctx context.Context, requestedBy int64, filter domain.ReportRequestFilter) ([]domain.ReportRequestDetail, error)
GetReportRequestByID(ctx context.Context, ID int64) (domain.ReportRequestDetail, error)
UpdateReportRequest(ctx context.Context, report domain.UpdateRequestRequest) error
WriteCSV(rows [][]string, filePrefix string) (string, error)
CheckAndFetchReportFile(ctx context.Context, ID int64) (string, error)
ProcessReportRequests(ctx context.Context) error
processSingleReportRequest(ctx context.Context, req domain.ReportRequestDetail) error
GenerateEventIntervalReport(ctx context.Context, request domain.ReportRequestDetail) (string, error)
}

View File

@ -52,25 +52,19 @@ func (s *Service) processSingleReportRequest(ctx context.Context, req domain.Rep
)
}()
switch req.Type {
case domain.EventIntervalReportRequest:
if req.Metadata.Interval == nil {
gen, ok := s.generators[req.Type]
if !ok {
status = domain.RejectReportRequest
rejectReason = fmt.Sprintf("unsupported report type: %s", req.Type)
s.mongoLogger.Warn("unsupported report type", zap.String("type", string(req.Type)))
} else {
fp, err := gen(ctx, req)
if err != nil {
status = domain.RejectReportRequest
rejectReason = "invalid interval provided"
break
}
fp, genErr := s.GenerateEventIntervalReport(ctx, req)
if genErr != nil {
status = domain.RejectReportRequest
rejectReason = fmt.Sprintf("failed to generate report: %v", genErr)
rejectReason = fmt.Sprintf("failed to generate report: %v", err)
} else {
filePath = fp
}
default:
status = domain.RejectReportRequest
rejectReason = fmt.Sprintf("unsupported report type: %s", req.Type)
}
update := domain.UpdateRequestRequest{
@ -90,6 +84,7 @@ func (s *Service) processSingleReportRequest(ctx context.Context, req domain.Rep
}
if err := s.UpdateReportRequest(ctx, update); err != nil {
s.mongoLogger.Error("failed to update report request", zap.Int64("id", req.ID), zap.Error(err))
return fmt.Errorf("failed to update report request: %w", err)
}

View File

@ -2,10 +2,10 @@ package report
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
func (s *Service) CreateReportRequest(ctx context.Context, report domain.CreateReportRequest) (domain.ReportRequest, error) {
return s.store.CreateReportRequest(ctx, report)
}

View File

@ -14,19 +14,14 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/stats"
"go.uber.org/zap"
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/transaction"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
// virtualgameservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
)
var (
@ -35,43 +30,42 @@ var (
)
type Service struct {
store *repository.Store
betStore bet.BetStore
walletStore wallet.WalletStore
transactionStore transaction.TransactionStore
branchStore branch.BranchStore
userStore user.UserStore
repo repository.ReportRepository
companyStore company.CompanyStore
store ports.ReportStore
betStore ports.BetStore
walletStore ports.WalletStore
transactionStore ports.TransactionStore
branchStore ports.BranchStore
userStore ports.UserStore
repo ports.OldReportRepository
companyStore ports.CompanyStore
notificationStore ports.NotificationStore
virtulaGamesStore repository.VirtualGameRepository
notificationStore repository.NotificationRepository
notificationSvc *notificationservice.Service
eventSvc *event.Service
companySvc *company.Service
statService *stats.Service
logger *slog.Logger
mongoLogger *zap.Logger
cfg *config.Config
generators map[domain.ReportRequestType]ReportGeneratorFunc
}
func NewService(
store *repository.Store,
betStore bet.BetStore,
walletStore wallet.WalletStore,
transactionStore transaction.TransactionStore,
branchStore branch.BranchStore,
userStore user.UserStore,
repo repository.ReportRepository,
companyStore company.CompanyStore,
store ports.ReportStore,
betStore ports.BetStore,
walletStore ports.WalletStore,
transactionStore ports.TransactionStore,
branchStore ports.BranchStore,
userStore ports.UserStore,
repo ports.OldReportRepository,
companyStore ports.CompanyStore,
virtulaGamesStore repository.VirtualGameRepository,
notificationStore repository.NotificationRepository,
notificationStore ports.NotificationStore,
notificationSvc *notificationservice.Service,
eventSvc *event.Service,
companySvc *company.Service,
statService *stats.Service,
logger *slog.Logger,
mongoLogger *zap.Logger,
cfg *config.Config,
) *Service {
return &Service{
) ReportService {
s := &Service{
store: store,
betStore: betStore,
walletStore: walletStore,
@ -83,12 +77,28 @@ func NewService(
virtulaGamesStore: virtulaGamesStore,
notificationStore: notificationStore,
notificationSvc: notificationSvc,
eventSvc: eventSvc,
companySvc: companySvc,
statService: statService,
logger: logger,
mongoLogger: mongoLogger,
cfg: cfg,
}
// Initialize the report generators
s.registerGenerators()
return s
}
// This registers all the report generators to make the processing cleaner and easier
// A report generator is a function (ReportGeneratorFunc) which takes a ReportRequestType and returns the path to file
type ReportGeneratorFunc func(ctx context.Context, req domain.ReportRequestDetail) (string, error)
func (s *Service) registerGenerators() {
s.generators = map[domain.ReportRequestType]ReportGeneratorFunc{
domain.EventIntervalReportRequest: s.GenerateEventIntervalReport,
// domain.CompanySummaryReportRequest: s.GenerateCompanySummaryReport,
// domain.BranchPerformanceReportRequest: s.GenerateBranchPerformanceReport,
}
}
// GetDashboardSummary returns comprehensive dashboard metrics
@ -480,7 +490,7 @@ func (s *Service) GetSportPerformance(ctx context.Context, filter domain.ReportF
return performances, nil
}
// func (s *Service) GenerateReport(ctx context.Context, from, to time.Time) error {
// func (s *service) GenerateReport(ctx context.Context, from, to time.Time) error {
// // Hardcoded output directory
// outputDir := "reports"
@ -630,7 +640,7 @@ func (s *Service) GetSportPerformance(ctx context.Context, filter domain.ReportF
// return nil
// }
// func (s *Service) fetchReportData(ctx context.Context, from, to time.Time) (
// func (s *service) fetchReportData(ctx context.Context, from, to time.Time) (
// []domain.CompanyReport, map[int64][]domain.BranchReport, error,
// ) {
// // --- company level ---

View File

@ -0,0 +1,11 @@
package result
import (
"context"
)
type ResultService interface {
FetchAndProcessResults(ctx context.Context) error
FetchAndStoreResult(ctx context.Context, eventID string) error
}

View File

@ -13,7 +13,7 @@ import (
func (s *Service) CheckAndSendResultNotifications(ctx context.Context, createdAfter time.Time) error {
resultLog, err := s.repo.GetAllResultLog(ctx, domain.ResultLogFilter{
resultLog, err := s.resultLogStore.GetAllResultLog(ctx, domain.ResultLogFilter{
CreatedAfter: domain.ValidTime{
Value: createdAfter,
Valid: true,

View File

@ -13,7 +13,8 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/league"
@ -25,7 +26,7 @@ import (
)
type Service struct {
repo *repository.Store
resultLogStore ports.ResultLogStore
config *config.Config
logger *slog.Logger
mongoLogger *zap.Logger
@ -40,7 +41,7 @@ type Service struct {
}
func NewService(
repo *repository.Store,
resultLogStore ports.ResultLogStore,
cfg *config.Config,
logger *slog.Logger,
mongoLogger *zap.Logger,
@ -53,7 +54,7 @@ func NewService(
userSvc user.Service,
) *Service {
return &Service{
repo: repo,
resultLogStore: resultLogStore,
config: cfg,
logger: logger,
mongoLogger: mongoLogger,
@ -74,7 +75,7 @@ var (
func (s *Service) UpdateResultForOutcomes(ctx context.Context, eventID int64, resultRes json.RawMessage, sportID int64) error {
// TODO: Optimize this since there could be many outcomes with the same event_id and market_id that could be updated the same time
outcomes, err := s.repo.GetBetOutcomeByEventID(ctx, eventID, true)
outcomes, err := s.betSvc.GetBetOutcomeByEventID(ctx, eventID, true)
logger := s.mongoLogger.With(
zap.Int64("eventID", eventID),
zap.Int64("sportID", sportID),
@ -138,7 +139,7 @@ func (s *Service) UpdateResultForOutcomes(ctx context.Context, eventID int64, re
}
func (s *Service) GetTotalBetsForEvents(ctx context.Context, eventID int64) (map[int64]int64, error) {
outcomes, err := s.repo.GetBetOutcomeByEventID(ctx, eventID, false)
outcomes, err := s.betSvc.GetBetOutcomeByEventID(ctx, eventID, false)
if err != nil {
s.mongoLogger.Error(
@ -231,7 +232,7 @@ func (s *Service) RefundAllOutcomes(ctx context.Context, eventID int64) (map[int
func (s *Service) FetchB365ResultAndUpdateBets(ctx context.Context) error {
// TODO: Optimize this because there could be many bet outcomes for the same odd
// Take market id and match result as param and update all the bet outcomes at the same time
events, _, err := s.repo.GetAllEvents(ctx, domain.EventFilter{
events, _, err := s.eventSvc.GetAllEvents(ctx, domain.EventFilter{
LastStartTime: domain.ValidTime{
Value: time.Now(),
Valid: true,
@ -318,12 +319,12 @@ func (s *Service) FetchB365ResultAndUpdateBets(ctx context.Context) error {
commonRespLogger.Error("Failed to refund all outcomes", zap.Error(err))
continue
}
err = s.repo.DeleteEvent(ctx, event.ID)
err = s.eventSvc.DeleteEvent(ctx, event.ID)
if err != nil {
commonRespLogger.Error("Failed to remove event", zap.Error(err))
continue
}
err = s.repo.DeleteOddsForEvent(ctx, event.ID)
err = s.oddSvc.DeleteOddsForEvent(ctx, event.ID)
if err != nil {
commonRespLogger.Error("Failed to remove odds for event", zap.Error(err))
continue
@ -370,12 +371,12 @@ func (s *Service) FetchB365ResultAndUpdateBets(ctx context.Context) error {
if err != nil {
commonRespLogger.Error("Error while updating result for event", zap.Error(err))
}
err = s.repo.DeleteEvent(ctx, event.ID)
err = s.eventSvc.DeleteEvent(ctx, event.ID)
if err != nil {
commonRespLogger.Error("Failed to remove event", zap.Error(err))
continue
}
err = s.repo.DeleteOddsForEvent(ctx, event.ID)
err = s.oddSvc.DeleteOddsForEvent(ctx, event.ID)
if err != nil {
commonRespLogger.Error("Failed to remove odds for event", zap.Error(err))
continue
@ -407,12 +408,12 @@ func (s *Service) FetchB365ResultAndUpdateBets(ctx context.Context) error {
commonRespLogger.Error("Failed to refund outcomes", zap.Error(err))
}
err = s.repo.DeleteEvent(ctx, event.ID)
err = s.eventSvc.DeleteEvent(ctx, event.ID)
if err != nil {
commonRespLogger.Error("Failed to remove event", zap.Error(err))
continue
}
err = s.repo.DeleteOddsForEvent(ctx, event.ID)
err = s.oddSvc.DeleteOddsForEvent(ctx, event.ID)
if err != nil {
commonRespLogger.Error("Failed to remove odds for event", zap.Error(err))
continue
@ -428,7 +429,7 @@ func (s *Service) FetchB365ResultAndUpdateBets(ctx context.Context) error {
}
// This will be used to send daily notifications, since events will be removed
_, err = s.repo.CreateResultLog(ctx, resultLog)
_, err = s.resultLogStore.CreateResultLog(ctx, resultLog)
if err != nil {
s.mongoLogger.Warn(
"Failed to store result log",
@ -457,7 +458,7 @@ func (s *Service) FetchB365ResultAndUpdateBets(ctx context.Context) error {
}
func (s *Service) CheckAndUpdateExpiredB365Events(ctx context.Context) (int64, error) {
events, _, err := s.repo.GetAllEvents(ctx, domain.EventFilter{
events, _, err := s.eventSvc.GetAllEvents(ctx, domain.EventFilter{
LastStartTime: domain.ValidTime{
Value: time.Now(),
Valid: true,

View File

@ -11,6 +11,7 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
"github.com/google/uuid"
)
@ -22,11 +23,11 @@ import (
type SantimPayService struct {
client SantimPayClient
cfg *config.Config
transferStore wallet.TransferStore
transferStore ports.TransferStore
walletSvc *wallet.Service
}
func NewSantimPayService(client SantimPayClient, cfg *config.Config, transferStore wallet.TransferStore, walletSvc *wallet.Service) *SantimPayService {
func NewSantimPayService(client SantimPayClient, cfg *config.Config, transferStore ports.TransferStore, walletSvc *wallet.Service) *SantimPayService {
return &SantimPayService{
client: client,
cfg: cfg,

View File

@ -0,0 +1,24 @@
package settings
// import (
// "context"
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
// )
// type SettingStore interface {
// GetGlobalSettingList(ctx context.Context) (domain.SettingList, error)
// GetGlobalSettings(ctx context.Context) ([]domain.Setting, error)
// GetGlobalSetting(ctx context.Context, key string) (domain.Setting, error)
// UpdateGlobalSetting(ctx context.Context, key, value string) error
// UpdateGlobalSettingList(ctx context.Context, settingList domain.ValidSettingList) error
// InsertCompanySetting(ctx context.Context, key, value string, companyID int64) error
// InsertCompanySettingList(ctx context.Context, settingList domain.ValidSettingList, companyID int64) error
// GetAllCompanySettings(ctx context.Context) ([]domain.CompanySetting, error)
// GetCompanySettingsByKey(ctx context.Context, key string) ([]domain.CompanySetting, error)
// GetOverrideSettings(ctx context.Context, companyID int64) ([]domain.Setting, error)
// GetOverrideSettingsList(ctx context.Context, companyID int64) (domain.SettingList, error)
// DeleteCompanySetting(ctx context.Context, companyID int64, key string) error
// DeleteAllCompanySetting(ctx context.Context, companyID int64) error
// }

View File

@ -4,13 +4,14 @@ import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
)
type Service struct {
settingStore SettingStore
settingStore ports.SettingStore
}
func NewService(settingStore SettingStore) *Service {
func NewService(settingStore ports.SettingStore) *Service {
return &Service{
settingStore: settingStore,
}

View File

@ -1,19 +1,16 @@
package company
package stats
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
func (s *Service) UpdateCompanyStats(ctx context.Context) error {
return s.companyStore.UpdateCompanyStats(ctx);
return s.UpdateCompanyStats(ctx)
}
func (s *Service) GetCompanyStatByID(ctx context.Context, companyID int64) ([]domain.CompanyStat, error) {
return s.companyStore.GetCompanyStatByID(ctx, companyID);
return s.GetCompanyStatByID(ctx, companyID)
}
func (s *Service) GetCompanyStatsByInterval(ctx context.Context, filter domain.CompanyStatFilter) ([]domain.CompanyStat, error) {
return s.companyStore.GetCompanyStatsByInterval(ctx, filter)
return s.GetCompanyStatsByInterval(ctx, filter)
}

View File

@ -1,4 +1,4 @@
package event
package stats
import (
"context"
@ -7,13 +7,12 @@ import (
)
func (s *Service) GetTotalEventStats(ctx context.Context, filter domain.EventStatsFilter) (domain.EventStats, error) {
return s.store.GetTotalEventStats(ctx, filter)
return s.eventStatStore.GetTotalEventStats(ctx, filter)
}
func (s *Service) GetTotalEventStatsByInterval(ctx context.Context, filter domain.EventStatsByIntervalFilter) ([]domain.EventStatsByInterval, error) {
return s.store.GetTotalEventStatsByInterval(ctx, filter)
return s.eventStatStore.GetTotalEventStatsByInterval(ctx, filter)
}
func (s *Service) UpdateEventBetStats(ctx context.Context) error {
return s.store.UpdateEventBetStats(ctx)
return s.eventStatStore.UpdateEventBetStats(ctx)
}

View File

@ -0,0 +1,15 @@
package stats
import "github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
type Service struct {
companyStatStore ports.CompanyStatStore
eventStatStore ports.EventStatStore
}
func NewService(companyStatStore ports.CompanyStatStore, eventStatStore ports.EventStatStore) *Service {
return &Service{
companyStatStore: companyStatStore,
eventStatStore: eventStatStore,
}
}

View File

@ -23,6 +23,7 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
)
@ -31,11 +32,11 @@ import (
type TelebirrService struct {
// client TelebirrClient
cfg *config.Config
transferStore wallet.TransferStore
transferStore ports.TransferStore
walletSvc *wallet.Service
}
func NewTelebirrService(cfg *config.Config, transferStore wallet.TransferStore, walletSvc *wallet.Service) *TelebirrService {
func NewTelebirrService(cfg *config.Config, transferStore ports.TransferStore, walletSvc *wallet.Service) *TelebirrService {
return &TelebirrService{
cfg: cfg,
transferStore: transferStore,

View File

@ -0,0 +1,2 @@
package ticket

Some files were not shown because too many files have changed in this diff Show More