diff --git a/.vscode/settings.json b/.vscode/settings.json index aa78ae8..e995121 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "cSpell.words": [ "Cashout", "narg", + "notificationservice", "sqlc" ] } \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go index a6fa58d..d09e049 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -123,7 +123,7 @@ func main() { 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, logger, domain.MongoDBLogger) + betSvc := bet.NewService(store, eventSvc, *oddsSvc, *walletSvc, *branchSvc, *settingSvc, notificationSvc, logger, domain.MongoDBLogger) resultSvc := result.NewService(store, cfg, logger, *betSvc, *oddsSvc, eventSvc, leagueSvc, notificationSvc) bonusSvc := bonus.NewService(store) referalRepo := repository.NewReferralRepository(store) diff --git a/db/migrations/000001_fortune.up.sql b/db/migrations/000001_fortune.up.sql index b435356..bd2cac2 100644 --- a/db/migrations/000001_fortune.up.sql +++ b/db/migrations/000001_fortune.up.sql @@ -45,23 +45,13 @@ CREATE TABLE IF NOT EXISTS bets ( amount BIGINT NOT NULL, total_odds REAL NOT NULL, status INT NOT NULL, - full_name VARCHAR(255) NOT NULL, - phone_number VARCHAR(255) NOT NULL, - company_id BIGINT, - branch_id BIGINT, - user_id BIGINT, - cashed_out BOOLEAN DEFAULT FALSE NOT NULL, - cashout_id VARCHAR(255) NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + user_id BIGINT NOT NULL, is_shop_bet BOOLEAN NOT NULL, + cashed_out BOOLEAN NOT NULL DEFAULT false, outcomes_hash TEXT NOT NULL, fast_code VARCHAR(10) NOT NULL, - UNIQUE(cashout_id), - CHECK ( - user_id IS NOT NULL - OR branch_id IS NOT NULL - ) + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS tickets ( id BIGSERIAL PRIMARY KEY, @@ -260,7 +250,8 @@ CREATE TABLE events ( is_live BOOLEAN, status TEXT, fetched_at TIMESTAMP DEFAULT now(), - source TEXT DEFAULT 'b365api' + source TEXT DEFAULT 'b365api', + flagged BOOLEAN NOT NULL DEFAULT false ); CREATE TABLE odds ( id SERIAL PRIMARY KEY, @@ -347,10 +338,16 @@ CREATE TABLE IF NOT EXISTS supported_operations ( ); CREATE VIEW bet_with_outcomes AS SELECT bets.*, + CONCAT(users.first_name, ' ', users.last_name) AS full_name, + users.phone_number, JSON_AGG(bet_outcomes.*) AS outcomes FROM bets LEFT JOIN bet_outcomes ON bets.id = bet_outcomes.bet_id -GROUP BY bets.id; + LEFT JOIN users ON bets.user_id = users.id +GROUP BY bets.id, + users.first_name, + users.last_name, + users.phone_number; CREATE VIEW ticket_with_outcomes AS SELECT tickets.*, JSON_AGG(ticket_outcomes.*) AS outcomes @@ -438,8 +435,7 @@ ADD CONSTRAINT unique_email UNIQUE (email), ALTER TABLE refresh_tokens ADD CONSTRAINT fk_refresh_tokens_users FOREIGN KEY (user_id) REFERENCES users(id); ALTER TABLE bets -ADD CONSTRAINT fk_bets_users FOREIGN KEY (user_id) REFERENCES users(id), - ADD CONSTRAINT fk_bets_branches FOREIGN KEY (branch_id) REFERENCES branches(id); +ADD CONSTRAINT fk_bets_users FOREIGN KEY (user_id) REFERENCES users(id); ALTER TABLE wallets ADD CONSTRAINT fk_wallets_users FOREIGN KEY (user_id) REFERENCES users(id), ADD COLUMN currency VARCHAR(3) NOT NULL DEFAULT 'ETB'; @@ -494,7 +490,7 @@ VALUES ( 'Doe', 'john.doe@example.com', NULL, - crypt('password123', gen_salt('bf'))::bytea, + crypt('password@123', gen_salt('bf'))::bytea, 'customer', TRUE, FALSE, diff --git a/db/migrations/000008_issue_reporting.up.sql b/db/migrations/000008_issue_reporting.up.sql index 53ad252..1b140f4 100644 --- a/db/migrations/000008_issue_reporting.up.sql +++ b/db/migrations/000008_issue_reporting.up.sql @@ -1,12 +1,14 @@ CREATE TABLE IF NOT EXISTS reported_issues ( id BIGSERIAL PRIMARY KEY, - customer_id BIGINT NOT NULL, + user_id BIGINT NOT NULL REFERENCES users(id), + user_role VARCHAR(255) NOT NULL, subject TEXT NOT NULL, description TEXT NOT NULL, - issue_type TEXT NOT NULL, -- e.g., "deposit", "withdrawal", "bet", "technical" - status TEXT NOT NULL DEFAULT 'pending', -- pending, in_progress, resolved, rejected + issue_type TEXT NOT NULL, + -- e.g., "deposit", "withdrawal", "bet", "technical" + status TEXT NOT NULL DEFAULT 'pending', + -- pending, in_progress, resolved, rejected metadata JSONB, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -); - +); \ No newline at end of file diff --git a/db/query/bet.sql b/db/query/bet.sql index bdd6f23..8f23a9c 100644 --- a/db/query/bet.sql +++ b/db/query/bet.sql @@ -3,17 +3,12 @@ INSERT INTO bets ( amount, total_odds, status, - full_name, - phone_number, - branch_id, user_id, is_shop_bet, - cashout_id, - company_id, outcomes_hash, fast_code ) -VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) +VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *; -- name: CreateBetOutcome :copyfrom INSERT INTO bet_outcomes ( @@ -50,14 +45,6 @@ VALUES ( SELECT * FROM bet_with_outcomes wHERE ( - branch_id = sqlc.narg('branch_id') - OR sqlc.narg('branch_id') IS NULL - ) - AND ( - company_id = sqlc.narg('company_id') - OR sqlc.narg('company_id') IS NULL - ) - AND ( user_id = sqlc.narg('user_id') OR sqlc.narg('user_id') IS NULL ) @@ -65,6 +52,10 @@ wHERE ( is_shop_bet = sqlc.narg('is_shop_bet') OR sqlc.narg('is_shop_bet') IS NULL ) + AND ( + cashed_out = sqlc.narg('cashed_out') + OR sqlc.narg('cashed_out') IS NULL + ) AND ( full_name ILIKE '%' || sqlc.narg('query') || '%' OR phone_number ILIKE '%' || sqlc.narg('query') || '%' @@ -82,14 +73,6 @@ wHERE ( SELECT * FROM bet_with_outcomes WHERE id = $1; --- name: GetBetByCashoutID :one -SELECT * -FROM bet_with_outcomes -WHERE cashout_id = $1; --- name: GetBetByBranchID :many -SELECT * -FROM bet_with_outcomes -WHERE branch_id = $1; -- name: GetBetByUserID :many SELECT * FROM bet_with_outcomes diff --git a/db/query/events.sql b/db/query/events.sql index 6056738..42cc85e 100644 --- a/db/query/events.sql +++ b/db/query/events.sql @@ -126,45 +126,14 @@ SELECT id FROM events WHERE is_live = true; -- name: GetAllUpcomingEvents :many -SELECT id, - sport_id, - match_name, - home_team, - away_team, - home_team_id, - away_team_id, - home_kit_image, - away_kit_image, - league_id, - league_name, - league_cc, - start_time, - is_live, - status, - source, - fetched_at +SELECT * FROM events WHERE start_time > now() AND is_live = false AND status = 'upcoming' ORDER BY start_time ASC; -- name: GetExpiredUpcomingEvents :many -SELECT events.id, - events.sport_id, - events.match_name, - events.home_team, - events.away_team, - events.home_team_id, - events.away_team_id, - events.home_kit_image, - events.away_kit_image, - events.league_id, - events.league_name, - events.start_time, - events.is_live, - events.status, - events.source, - events.fetched_at, +SELECT events.*, leagues.country_code as league_cc FROM events LEFT JOIN leagues ON leagues.id = league_id @@ -201,22 +170,7 @@ WHERE is_live = false OR sqlc.narg('country_code') IS NULL ); -- name: GetPaginatedUpcomingEvents :many -SELECT events.id, - events.sport_id, - events.match_name, - events.home_team, - events.away_team, - events.home_team_id, - events.away_team_id, - events.home_kit_image, - events.away_kit_image, - events.league_id, - events.league_name, - events.start_time, - events.is_live, - events.status, - events.source, - events.fetched_at, +SELECT events.*, leagues.country_code as league_cc FROM events LEFT JOIN leagues ON leagues.id = league_id @@ -246,23 +200,7 @@ WHERE start_time > now() ORDER BY start_time ASC LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset'); -- name: GetUpcomingByID :one -SELECT id, - sport_id, - match_name, - home_team, - away_team, - home_team_id, - away_team_id, - home_kit_image, - away_kit_image, - league_id, - league_name, - league_cc, - start_time, - is_live, - status, - source, - fetched_at +SELECT * FROM events WHERE id = $1 AND is_live = false @@ -271,9 +209,12 @@ LIMIT 1; -- name: UpdateMatchResult :exec UPDATE events SET score = $1, - status = $2, - fetched_at = NOW() + status = $2 WHERE id = $3; +-- name: UpdateFlagged :exec +UPDATE events +SET flagged = $1 +WHERE id = $2; -- name: DeleteEvent :exec DELETE FROM events WHERE id = $1; \ No newline at end of file diff --git a/db/query/issue_reporting.sql b/db/query/issue_reporting.sql index 31ea229..1906ffe 100644 --- a/db/query/issue_reporting.sql +++ b/db/query/issue_reporting.sql @@ -1,32 +1,37 @@ -- name: CreateReportedIssue :one INSERT INTO reported_issues ( - customer_id, subject, description, issue_type, metadata -) VALUES ( - $1, $2, $3, $4, $5 -) + user_id, + user_role, + subject, + description, + issue_type, + metadata + ) +VALUES ($1, $2, $3, $4, $5, $6) RETURNING *; - -- name: ListReportedIssues :many -SELECT * FROM reported_issues +SELECT * +FROM reported_issues ORDER BY created_at DESC LIMIT $1 OFFSET $2; - --- name: ListReportedIssuesByCustomer :many -SELECT * FROM reported_issues -WHERE customer_id = $1 +-- name: ListReportedIssuesByUser :many +SELECT * +FROM reported_issues +WHERE user_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3; - -- name: CountReportedIssues :one -SELECT COUNT(*) FROM reported_issues; - --- name: CountReportedIssuesByCustomer :one -SELECT COUNT(*) FROM reported_issues WHERE customer_id = $1; - +SELECT COUNT(*) +FROM reported_issues; +-- name: CountReportedIssuesByUser :one +SELECT COUNT(*) +FROM reported_issues +WHERE user_id = $1; -- name: UpdateReportedIssueStatus :exec UPDATE reported_issues -SET status = $2, updated_at = NOW() +SET status = $2, + updated_at = NOW() WHERE id = $1; - -- name: DeleteReportedIssue :exec -DELETE FROM reported_issues WHERE id = $1; +DELETE FROM reported_issues +WHERE id = $1; \ No newline at end of file diff --git a/db/query/report.sql b/db/query/report.sql index 24677c1..dee35de 100644 --- a/db/query/report.sql +++ b/db/query/report.sql @@ -17,28 +17,60 @@ FROM bets WHERE created_at BETWEEN sqlc.arg('from') AND sqlc.arg('to') AND status = 5; -- name: GetCompanyWiseReport :many -SELECT - b.company_id, - c.name AS company_name, - COUNT(*) AS total_bets, - COALESCE(SUM(b.amount), 0) AS total_cash_made, - COALESCE(SUM(CASE WHEN b.cashed_out THEN b.amount ELSE 0 END), 0) AS total_cash_out, - COALESCE(SUM(CASE WHEN b.status = 5 THEN b.amount ELSE 0 END), 0) AS total_cash_backs -FROM bets b -JOIN companies c ON b.company_id = c.id +SELECT b.company_id, + c.name AS company_name, + COUNT(*) AS total_bets, + COALESCE(SUM(b.amount), 0) AS total_cash_made, + COALESCE( + SUM( + CASE + WHEN b.cashed_out THEN b.amount + ELSE 0 + END + ), + 0 + ) AS total_cash_out, + COALESCE( + SUM( + CASE + WHEN b.status = 5 THEN b.amount + ELSE 0 + END + ), + 0 + ) AS total_cash_backs +FROM shop_bet_detail b + JOIN companies c ON b.company_id = c.id WHERE b.created_at BETWEEN sqlc.arg('from') AND sqlc.arg('to') -GROUP BY b.company_id, c.name; +GROUP BY b.company_id, + c.name; -- name: GetBranchWiseReport :many -SELECT - b.branch_id, - br.name AS branch_name, - br.company_id, - COUNT(*) AS total_bets, - COALESCE(SUM(b.amount), 0) AS total_cash_made, - COALESCE(SUM(CASE WHEN b.cashed_out THEN b.amount ELSE 0 END), 0) AS total_cash_out, - COALESCE(SUM(CASE WHEN b.status = 5 THEN b.amount ELSE 0 END), 0) AS total_cash_backs -FROM bets b -JOIN branches br ON b.branch_id = br.id +SELECT b.branch_id, + br.name AS branch_name, + br.company_id, + COUNT(*) AS total_bets, + COALESCE(SUM(b.amount), 0) AS total_cash_made, + COALESCE( + SUM( + CASE + WHEN b.cashed_out THEN b.amount + ELSE 0 + END + ), + 0 + ) AS total_cash_out, + COALESCE( + SUM( + CASE + WHEN b.status = 5 THEN b.amount + ELSE 0 + END + ), + 0 + ) AS total_cash_backs +FROM shop_bet_detail b + JOIN branches br ON b.branch_id = br.id WHERE b.created_at BETWEEN sqlc.arg('from') AND sqlc.arg('to') -GROUP BY b.branch_id, br.name, br.company_id; - +GROUP BY b.branch_id, + br.name, + br.company_id; \ No newline at end of file diff --git a/gen/db/bet.sql.go b/gen/db/bet.sql.go index 00b4bad..cc2c933 100644 --- a/gen/db/bet.sql.go +++ b/gen/db/bet.sql.go @@ -16,33 +16,23 @@ INSERT INTO bets ( amount, total_odds, status, - full_name, - phone_number, - branch_id, user_id, is_shop_bet, - cashout_id, - company_id, outcomes_hash, fast_code ) -VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) -RETURNING id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes_hash, fast_code +VALUES ($1, $2, $3, $4, $5, $6, $7) +RETURNING id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, created_at, updated_at ` type CreateBetParams struct { - Amount int64 `json:"amount"` - TotalOdds float32 `json:"total_odds"` - Status int32 `json:"status"` - FullName string `json:"full_name"` - PhoneNumber string `json:"phone_number"` - BranchID pgtype.Int8 `json:"branch_id"` - UserID pgtype.Int8 `json:"user_id"` - IsShopBet bool `json:"is_shop_bet"` - CashoutID string `json:"cashout_id"` - CompanyID pgtype.Int8 `json:"company_id"` - OutcomesHash string `json:"outcomes_hash"` - FastCode string `json:"fast_code"` + Amount int64 `json:"amount"` + TotalOdds float32 `json:"total_odds"` + Status int32 `json:"status"` + UserID int64 `json:"user_id"` + IsShopBet bool `json:"is_shop_bet"` + OutcomesHash string `json:"outcomes_hash"` + FastCode string `json:"fast_code"` } func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, error) { @@ -50,13 +40,8 @@ func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, erro arg.Amount, arg.TotalOdds, arg.Status, - arg.FullName, - arg.PhoneNumber, - arg.BranchID, arg.UserID, arg.IsShopBet, - arg.CashoutID, - arg.CompanyID, arg.OutcomesHash, arg.FastCode, ) @@ -66,18 +51,13 @@ func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, erro &i.Amount, &i.TotalOdds, &i.Status, - &i.FullName, - &i.PhoneNumber, - &i.CompanyID, - &i.BranchID, &i.UserID, - &i.CashedOut, - &i.CashoutID, - &i.CreatedAt, - &i.UpdatedAt, &i.IsShopBet, + &i.CashedOut, &i.OutcomesHash, &i.FastCode, + &i.CreatedAt, + &i.UpdatedAt, ) return i, err } @@ -119,44 +99,39 @@ func (q *Queries) DeleteBetOutcome(ctx context.Context, betID int64) error { } const GetAllBets = `-- name: GetAllBets :many -SELECT id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes_hash, fast_code, outcomes +SELECT id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, created_at, updated_at, full_name, phone_number, outcomes FROM bet_with_outcomes wHERE ( - branch_id = $1 + user_id = $1 OR $1 IS NULL ) AND ( - company_id = $2 + is_shop_bet = $2 OR $2 IS NULL ) AND ( - user_id = $3 + cashed_out = $3 OR $3 IS NULL ) AND ( - is_shop_bet = $4 + full_name ILIKE '%' || $4 || '%' + OR phone_number ILIKE '%' || $4 || '%' OR $4 IS NULL ) AND ( - full_name ILIKE '%' || $5 || '%' - OR phone_number ILIKE '%' || $5 || '%' + created_at > $5 OR $5 IS NULL ) AND ( - created_at > $6 + created_at < $6 OR $6 IS NULL ) - AND ( - created_at < $7 - OR $7 IS NULL - ) ` type GetAllBetsParams struct { - BranchID pgtype.Int8 `json:"branch_id"` - CompanyID pgtype.Int8 `json:"company_id"` UserID pgtype.Int8 `json:"user_id"` IsShopBet pgtype.Bool `json:"is_shop_bet"` + CashedOut pgtype.Bool `json:"cashed_out"` Query pgtype.Text `json:"query"` CreatedBefore pgtype.Timestamp `json:"created_before"` CreatedAfter pgtype.Timestamp `json:"created_after"` @@ -164,10 +139,9 @@ type GetAllBetsParams struct { func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWithOutcome, error) { rows, err := q.db.Query(ctx, GetAllBets, - arg.BranchID, - arg.CompanyID, arg.UserID, arg.IsShopBet, + arg.CashedOut, arg.Query, arg.CreatedBefore, arg.CreatedAfter, @@ -184,18 +158,15 @@ func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWi &i.Amount, &i.TotalOdds, &i.Status, - &i.FullName, - &i.PhoneNumber, - &i.CompanyID, - &i.BranchID, &i.UserID, - &i.CashedOut, - &i.CashoutID, - &i.CreatedAt, - &i.UpdatedAt, &i.IsShopBet, + &i.CashedOut, &i.OutcomesHash, &i.FastCode, + &i.CreatedAt, + &i.UpdatedAt, + &i.FullName, + &i.PhoneNumber, &i.Outcomes, ); err != nil { return nil, err @@ -208,83 +179,8 @@ func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWi return items, nil } -const GetBetByBranchID = `-- name: GetBetByBranchID :many -SELECT id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes_hash, fast_code, outcomes -FROM bet_with_outcomes -WHERE branch_id = $1 -` - -func (q *Queries) GetBetByBranchID(ctx context.Context, branchID pgtype.Int8) ([]BetWithOutcome, error) { - rows, err := q.db.Query(ctx, GetBetByBranchID, branchID) - if err != nil { - return nil, err - } - defer rows.Close() - var items []BetWithOutcome - for rows.Next() { - var i BetWithOutcome - if err := rows.Scan( - &i.ID, - &i.Amount, - &i.TotalOdds, - &i.Status, - &i.FullName, - &i.PhoneNumber, - &i.CompanyID, - &i.BranchID, - &i.UserID, - &i.CashedOut, - &i.CashoutID, - &i.CreatedAt, - &i.UpdatedAt, - &i.IsShopBet, - &i.OutcomesHash, - &i.FastCode, - &i.Outcomes, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const GetBetByCashoutID = `-- name: GetBetByCashoutID :one -SELECT id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes_hash, fast_code, outcomes -FROM bet_with_outcomes -WHERE cashout_id = $1 -` - -func (q *Queries) GetBetByCashoutID(ctx context.Context, cashoutID string) (BetWithOutcome, error) { - row := q.db.QueryRow(ctx, GetBetByCashoutID, cashoutID) - var i BetWithOutcome - err := row.Scan( - &i.ID, - &i.Amount, - &i.TotalOdds, - &i.Status, - &i.FullName, - &i.PhoneNumber, - &i.CompanyID, - &i.BranchID, - &i.UserID, - &i.CashedOut, - &i.CashoutID, - &i.CreatedAt, - &i.UpdatedAt, - &i.IsShopBet, - &i.OutcomesHash, - &i.FastCode, - &i.Outcomes, - ) - return i, err -} - const GetBetByFastCode = `-- name: GetBetByFastCode :one -SELECT id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes_hash, fast_code, outcomes +SELECT id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, created_at, updated_at, full_name, phone_number, outcomes FROM bet_with_outcomes WHERE fast_code = $1 LIMIT 1 @@ -298,25 +194,22 @@ func (q *Queries) GetBetByFastCode(ctx context.Context, fastCode string) (BetWit &i.Amount, &i.TotalOdds, &i.Status, - &i.FullName, - &i.PhoneNumber, - &i.CompanyID, - &i.BranchID, &i.UserID, - &i.CashedOut, - &i.CashoutID, - &i.CreatedAt, - &i.UpdatedAt, &i.IsShopBet, + &i.CashedOut, &i.OutcomesHash, &i.FastCode, + &i.CreatedAt, + &i.UpdatedAt, + &i.FullName, + &i.PhoneNumber, &i.Outcomes, ) return i, err } const GetBetByID = `-- name: GetBetByID :one -SELECT id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes_hash, fast_code, outcomes +SELECT id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, created_at, updated_at, full_name, phone_number, outcomes FROM bet_with_outcomes WHERE id = $1 ` @@ -329,30 +222,27 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, err &i.Amount, &i.TotalOdds, &i.Status, - &i.FullName, - &i.PhoneNumber, - &i.CompanyID, - &i.BranchID, &i.UserID, - &i.CashedOut, - &i.CashoutID, - &i.CreatedAt, - &i.UpdatedAt, &i.IsShopBet, + &i.CashedOut, &i.OutcomesHash, &i.FastCode, + &i.CreatedAt, + &i.UpdatedAt, + &i.FullName, + &i.PhoneNumber, &i.Outcomes, ) return i, err } const GetBetByUserID = `-- name: GetBetByUserID :many -SELECT id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes_hash, fast_code, outcomes +SELECT id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, created_at, updated_at, full_name, phone_number, outcomes FROM bet_with_outcomes WHERE user_id = $1 ` -func (q *Queries) GetBetByUserID(ctx context.Context, userID pgtype.Int8) ([]BetWithOutcome, error) { +func (q *Queries) GetBetByUserID(ctx context.Context, userID int64) ([]BetWithOutcome, error) { rows, err := q.db.Query(ctx, GetBetByUserID, userID) if err != nil { return nil, err @@ -366,18 +256,15 @@ func (q *Queries) GetBetByUserID(ctx context.Context, userID pgtype.Int8) ([]Bet &i.Amount, &i.TotalOdds, &i.Status, - &i.FullName, - &i.PhoneNumber, - &i.CompanyID, - &i.BranchID, &i.UserID, - &i.CashedOut, - &i.CashoutID, - &i.CreatedAt, - &i.UpdatedAt, &i.IsShopBet, + &i.CashedOut, &i.OutcomesHash, &i.FastCode, + &i.CreatedAt, + &i.UpdatedAt, + &i.FullName, + &i.PhoneNumber, &i.Outcomes, ); err != nil { return nil, err @@ -393,13 +280,13 @@ func (q *Queries) GetBetByUserID(ctx context.Context, userID pgtype.Int8) ([]Bet const GetBetCount = `-- name: GetBetCount :one SELECT COUNT(*) FROM bets -where user_id = $1 +WHERE user_id = $1 AND outcomes_hash = $2 ` type GetBetCountParams struct { - UserID pgtype.Int8 `json:"user_id"` - OutcomesHash string `json:"outcomes_hash"` + UserID int64 `json:"user_id"` + OutcomesHash string `json:"outcomes_hash"` } func (q *Queries) GetBetCount(ctx context.Context, arg GetBetCountParams) (int64, error) { diff --git a/gen/db/events.sql.go b/gen/db/events.sql.go index bd84b8d..18cc922 100644 --- a/gen/db/events.sql.go +++ b/gen/db/events.sql.go @@ -22,23 +22,7 @@ func (q *Queries) DeleteEvent(ctx context.Context, id string) error { } const GetAllUpcomingEvents = `-- name: GetAllUpcomingEvents :many -SELECT id, - sport_id, - match_name, - home_team, - away_team, - home_team_id, - away_team_id, - home_kit_image, - away_kit_image, - league_id, - league_name, - league_cc, - start_time, - is_live, - status, - source, - fetched_at +SELECT id, sport_id, match_name, home_team, away_team, home_team_id, away_team_id, home_kit_image, away_kit_image, league_id, league_name, league_cc, start_time, score, match_minute, timer_status, added_time, match_period, is_live, status, fetched_at, source, flagged FROM events WHERE start_time > now() AND is_live = false @@ -46,35 +30,15 @@ WHERE start_time > now() ORDER BY start_time ASC ` -type GetAllUpcomingEventsRow struct { - ID string `json:"id"` - SportID pgtype.Int4 `json:"sport_id"` - MatchName pgtype.Text `json:"match_name"` - HomeTeam pgtype.Text `json:"home_team"` - AwayTeam pgtype.Text `json:"away_team"` - HomeTeamID pgtype.Int4 `json:"home_team_id"` - AwayTeamID pgtype.Int4 `json:"away_team_id"` - HomeKitImage pgtype.Text `json:"home_kit_image"` - AwayKitImage pgtype.Text `json:"away_kit_image"` - LeagueID pgtype.Int4 `json:"league_id"` - LeagueName pgtype.Text `json:"league_name"` - LeagueCc pgtype.Text `json:"league_cc"` - StartTime pgtype.Timestamp `json:"start_time"` - IsLive pgtype.Bool `json:"is_live"` - Status pgtype.Text `json:"status"` - Source pgtype.Text `json:"source"` - FetchedAt pgtype.Timestamp `json:"fetched_at"` -} - -func (q *Queries) GetAllUpcomingEvents(ctx context.Context) ([]GetAllUpcomingEventsRow, error) { +func (q *Queries) GetAllUpcomingEvents(ctx context.Context) ([]Event, error) { rows, err := q.db.Query(ctx, GetAllUpcomingEvents) if err != nil { return nil, err } defer rows.Close() - var items []GetAllUpcomingEventsRow + var items []Event for rows.Next() { - var i GetAllUpcomingEventsRow + var i Event if err := rows.Scan( &i.ID, &i.SportID, @@ -89,10 +53,16 @@ func (q *Queries) GetAllUpcomingEvents(ctx context.Context) ([]GetAllUpcomingEve &i.LeagueName, &i.LeagueCc, &i.StartTime, + &i.Score, + &i.MatchMinute, + &i.TimerStatus, + &i.AddedTime, + &i.MatchPeriod, &i.IsLive, &i.Status, - &i.Source, &i.FetchedAt, + &i.Source, + &i.Flagged, ); err != nil { return nil, err } @@ -105,22 +75,7 @@ func (q *Queries) GetAllUpcomingEvents(ctx context.Context) ([]GetAllUpcomingEve } const GetExpiredUpcomingEvents = `-- name: GetExpiredUpcomingEvents :many -SELECT events.id, - events.sport_id, - events.match_name, - events.home_team, - events.away_team, - events.home_team_id, - events.away_team_id, - events.home_kit_image, - events.away_kit_image, - events.league_id, - events.league_name, - events.start_time, - events.is_live, - events.status, - events.source, - events.fetched_at, +SELECT events.id, events.sport_id, events.match_name, events.home_team, events.away_team, events.home_team_id, events.away_team_id, events.home_kit_image, events.away_kit_image, events.league_id, events.league_name, events.league_cc, events.start_time, events.score, events.match_minute, events.timer_status, events.added_time, events.match_period, events.is_live, events.status, events.fetched_at, events.source, events.flagged, leagues.country_code as league_cc FROM events LEFT JOIN leagues ON leagues.id = league_id @@ -144,12 +99,19 @@ type GetExpiredUpcomingEventsRow struct { AwayKitImage pgtype.Text `json:"away_kit_image"` LeagueID pgtype.Int4 `json:"league_id"` LeagueName pgtype.Text `json:"league_name"` + LeagueCc pgtype.Text `json:"league_cc"` StartTime pgtype.Timestamp `json:"start_time"` + Score pgtype.Text `json:"score"` + MatchMinute pgtype.Int4 `json:"match_minute"` + TimerStatus pgtype.Text `json:"timer_status"` + AddedTime pgtype.Int4 `json:"added_time"` + MatchPeriod pgtype.Int4 `json:"match_period"` IsLive pgtype.Bool `json:"is_live"` Status pgtype.Text `json:"status"` - Source pgtype.Text `json:"source"` FetchedAt pgtype.Timestamp `json:"fetched_at"` - LeagueCc pgtype.Text `json:"league_cc"` + Source pgtype.Text `json:"source"` + Flagged bool `json:"flagged"` + LeagueCc_2 pgtype.Text `json:"league_cc_2"` } func (q *Queries) GetExpiredUpcomingEvents(ctx context.Context, status pgtype.Text) ([]GetExpiredUpcomingEventsRow, error) { @@ -173,12 +135,19 @@ func (q *Queries) GetExpiredUpcomingEvents(ctx context.Context, status pgtype.Te &i.AwayKitImage, &i.LeagueID, &i.LeagueName, + &i.LeagueCc, &i.StartTime, + &i.Score, + &i.MatchMinute, + &i.TimerStatus, + &i.AddedTime, + &i.MatchPeriod, &i.IsLive, &i.Status, - &i.Source, &i.FetchedAt, - &i.LeagueCc, + &i.Source, + &i.Flagged, + &i.LeagueCc_2, ); err != nil { return nil, err } @@ -191,22 +160,7 @@ func (q *Queries) GetExpiredUpcomingEvents(ctx context.Context, status pgtype.Te } const GetPaginatedUpcomingEvents = `-- name: GetPaginatedUpcomingEvents :many -SELECT events.id, - events.sport_id, - events.match_name, - events.home_team, - events.away_team, - events.home_team_id, - events.away_team_id, - events.home_kit_image, - events.away_kit_image, - events.league_id, - events.league_name, - events.start_time, - events.is_live, - events.status, - events.source, - events.fetched_at, +SELECT events.id, events.sport_id, events.match_name, events.home_team, events.away_team, events.home_team_id, events.away_team_id, events.home_kit_image, events.away_kit_image, events.league_id, events.league_name, events.league_cc, events.start_time, events.score, events.match_minute, events.timer_status, events.added_time, events.match_period, events.is_live, events.status, events.fetched_at, events.source, events.flagged, leagues.country_code as league_cc FROM events LEFT JOIN leagues ON leagues.id = league_id @@ -259,12 +213,19 @@ type GetPaginatedUpcomingEventsRow struct { AwayKitImage pgtype.Text `json:"away_kit_image"` LeagueID pgtype.Int4 `json:"league_id"` LeagueName pgtype.Text `json:"league_name"` + LeagueCc pgtype.Text `json:"league_cc"` StartTime pgtype.Timestamp `json:"start_time"` + Score pgtype.Text `json:"score"` + MatchMinute pgtype.Int4 `json:"match_minute"` + TimerStatus pgtype.Text `json:"timer_status"` + AddedTime pgtype.Int4 `json:"added_time"` + MatchPeriod pgtype.Int4 `json:"match_period"` IsLive pgtype.Bool `json:"is_live"` Status pgtype.Text `json:"status"` - Source pgtype.Text `json:"source"` FetchedAt pgtype.Timestamp `json:"fetched_at"` - LeagueCc pgtype.Text `json:"league_cc"` + Source pgtype.Text `json:"source"` + Flagged bool `json:"flagged"` + LeagueCc_2 pgtype.Text `json:"league_cc_2"` } func (q *Queries) GetPaginatedUpcomingEvents(ctx context.Context, arg GetPaginatedUpcomingEventsParams) ([]GetPaginatedUpcomingEventsRow, error) { @@ -296,12 +257,19 @@ func (q *Queries) GetPaginatedUpcomingEvents(ctx context.Context, arg GetPaginat &i.AwayKitImage, &i.LeagueID, &i.LeagueName, + &i.LeagueCc, &i.StartTime, + &i.Score, + &i.MatchMinute, + &i.TimerStatus, + &i.AddedTime, + &i.MatchPeriod, &i.IsLive, &i.Status, - &i.Source, &i.FetchedAt, - &i.LeagueCc, + &i.Source, + &i.Flagged, + &i.LeagueCc_2, ); err != nil { return nil, err } @@ -363,23 +331,7 @@ func (q *Queries) GetTotalEvents(ctx context.Context, arg GetTotalEventsParams) } const GetUpcomingByID = `-- name: GetUpcomingByID :one -SELECT id, - sport_id, - match_name, - home_team, - away_team, - home_team_id, - away_team_id, - home_kit_image, - away_kit_image, - league_id, - league_name, - league_cc, - start_time, - is_live, - status, - source, - fetched_at +SELECT id, sport_id, match_name, home_team, away_team, home_team_id, away_team_id, home_kit_image, away_kit_image, league_id, league_name, league_cc, start_time, score, match_minute, timer_status, added_time, match_period, is_live, status, fetched_at, source, flagged FROM events WHERE id = $1 AND is_live = false @@ -387,29 +339,9 @@ WHERE id = $1 LIMIT 1 ` -type GetUpcomingByIDRow struct { - ID string `json:"id"` - SportID pgtype.Int4 `json:"sport_id"` - MatchName pgtype.Text `json:"match_name"` - HomeTeam pgtype.Text `json:"home_team"` - AwayTeam pgtype.Text `json:"away_team"` - HomeTeamID pgtype.Int4 `json:"home_team_id"` - AwayTeamID pgtype.Int4 `json:"away_team_id"` - HomeKitImage pgtype.Text `json:"home_kit_image"` - AwayKitImage pgtype.Text `json:"away_kit_image"` - LeagueID pgtype.Int4 `json:"league_id"` - LeagueName pgtype.Text `json:"league_name"` - LeagueCc pgtype.Text `json:"league_cc"` - StartTime pgtype.Timestamp `json:"start_time"` - IsLive pgtype.Bool `json:"is_live"` - Status pgtype.Text `json:"status"` - Source pgtype.Text `json:"source"` - FetchedAt pgtype.Timestamp `json:"fetched_at"` -} - -func (q *Queries) GetUpcomingByID(ctx context.Context, id string) (GetUpcomingByIDRow, error) { +func (q *Queries) GetUpcomingByID(ctx context.Context, id string) (Event, error) { row := q.db.QueryRow(ctx, GetUpcomingByID, id) - var i GetUpcomingByIDRow + var i Event err := row.Scan( &i.ID, &i.SportID, @@ -424,10 +356,16 @@ func (q *Queries) GetUpcomingByID(ctx context.Context, id string) (GetUpcomingBy &i.LeagueName, &i.LeagueCc, &i.StartTime, + &i.Score, + &i.MatchMinute, + &i.TimerStatus, + &i.AddedTime, + &i.MatchPeriod, &i.IsLive, &i.Status, - &i.Source, &i.FetchedAt, + &i.Source, + &i.Flagged, ) return i, err } @@ -673,11 +611,26 @@ func (q *Queries) ListLiveEvents(ctx context.Context) ([]string, error) { return items, nil } +const UpdateFlagged = `-- name: UpdateFlagged :exec +UPDATE events +SET flagged = $1 +WHERE id = $2 +` + +type UpdateFlaggedParams struct { + Flagged bool `json:"flagged"` + ID string `json:"id"` +} + +func (q *Queries) UpdateFlagged(ctx context.Context, arg UpdateFlaggedParams) error { + _, err := q.db.Exec(ctx, UpdateFlagged, arg.Flagged, arg.ID) + return err +} + const UpdateMatchResult = `-- name: UpdateMatchResult :exec UPDATE events SET score = $1, - status = $2, - fetched_at = NOW() + status = $2 WHERE id = $3 ` diff --git a/gen/db/issue_reporting.sql.go b/gen/db/issue_reporting.sql.go index c737b9e..7fcb4af 100644 --- a/gen/db/issue_reporting.sql.go +++ b/gen/db/issue_reporting.sql.go @@ -10,7 +10,8 @@ import ( ) const CountReportedIssues = `-- name: CountReportedIssues :one -SELECT COUNT(*) FROM reported_issues +SELECT COUNT(*) +FROM reported_issues ` func (q *Queries) CountReportedIssues(ctx context.Context) (int64, error) { @@ -20,12 +21,14 @@ func (q *Queries) CountReportedIssues(ctx context.Context) (int64, error) { return count, err } -const CountReportedIssuesByCustomer = `-- name: CountReportedIssuesByCustomer :one -SELECT COUNT(*) FROM reported_issues WHERE customer_id = $1 +const CountReportedIssuesByUser = `-- name: CountReportedIssuesByUser :one +SELECT COUNT(*) +FROM reported_issues +WHERE user_id = $1 ` -func (q *Queries) CountReportedIssuesByCustomer(ctx context.Context, customerID int64) (int64, error) { - row := q.db.QueryRow(ctx, CountReportedIssuesByCustomer, customerID) +func (q *Queries) CountReportedIssuesByUser(ctx context.Context, userID int64) (int64, error) { + row := q.db.QueryRow(ctx, CountReportedIssuesByUser, userID) var count int64 err := row.Scan(&count) return count, err @@ -33,15 +36,20 @@ func (q *Queries) CountReportedIssuesByCustomer(ctx context.Context, customerID const CreateReportedIssue = `-- name: CreateReportedIssue :one INSERT INTO reported_issues ( - customer_id, subject, description, issue_type, metadata -) VALUES ( - $1, $2, $3, $4, $5 -) -RETURNING id, customer_id, subject, description, issue_type, status, metadata, created_at, updated_at + user_id, + user_role, + subject, + description, + issue_type, + metadata + ) +VALUES ($1, $2, $3, $4, $5, $6) +RETURNING id, user_id, user_role, subject, description, issue_type, status, metadata, created_at, updated_at ` type CreateReportedIssueParams struct { - CustomerID int64 `json:"customer_id"` + UserID int64 `json:"user_id"` + UserRole string `json:"user_role"` Subject string `json:"subject"` Description string `json:"description"` IssueType string `json:"issue_type"` @@ -50,7 +58,8 @@ type CreateReportedIssueParams struct { func (q *Queries) CreateReportedIssue(ctx context.Context, arg CreateReportedIssueParams) (ReportedIssue, error) { row := q.db.QueryRow(ctx, CreateReportedIssue, - arg.CustomerID, + arg.UserID, + arg.UserRole, arg.Subject, arg.Description, arg.IssueType, @@ -59,7 +68,8 @@ func (q *Queries) CreateReportedIssue(ctx context.Context, arg CreateReportedIss var i ReportedIssue err := row.Scan( &i.ID, - &i.CustomerID, + &i.UserID, + &i.UserRole, &i.Subject, &i.Description, &i.IssueType, @@ -72,7 +82,8 @@ func (q *Queries) CreateReportedIssue(ctx context.Context, arg CreateReportedIss } const DeleteReportedIssue = `-- name: DeleteReportedIssue :exec -DELETE FROM reported_issues WHERE id = $1 +DELETE FROM reported_issues +WHERE id = $1 ` func (q *Queries) DeleteReportedIssue(ctx context.Context, id int64) error { @@ -81,7 +92,8 @@ func (q *Queries) DeleteReportedIssue(ctx context.Context, id int64) error { } const ListReportedIssues = `-- name: ListReportedIssues :many -SELECT id, customer_id, subject, description, issue_type, status, metadata, created_at, updated_at FROM reported_issues +SELECT id, user_id, user_role, subject, description, issue_type, status, metadata, created_at, updated_at +FROM reported_issues ORDER BY created_at DESC LIMIT $1 OFFSET $2 ` @@ -102,7 +114,8 @@ func (q *Queries) ListReportedIssues(ctx context.Context, arg ListReportedIssues var i ReportedIssue if err := rows.Scan( &i.ID, - &i.CustomerID, + &i.UserID, + &i.UserRole, &i.Subject, &i.Description, &i.IssueType, @@ -121,21 +134,22 @@ func (q *Queries) ListReportedIssues(ctx context.Context, arg ListReportedIssues return items, nil } -const ListReportedIssuesByCustomer = `-- name: ListReportedIssuesByCustomer :many -SELECT id, customer_id, subject, description, issue_type, status, metadata, created_at, updated_at FROM reported_issues -WHERE customer_id = $1 +const ListReportedIssuesByUser = `-- name: ListReportedIssuesByUser :many +SELECT id, user_id, user_role, subject, description, issue_type, status, metadata, created_at, updated_at +FROM reported_issues +WHERE user_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3 ` -type ListReportedIssuesByCustomerParams struct { - CustomerID int64 `json:"customer_id"` - Limit int32 `json:"limit"` - Offset int32 `json:"offset"` +type ListReportedIssuesByUserParams struct { + UserID int64 `json:"user_id"` + Limit int32 `json:"limit"` + Offset int32 `json:"offset"` } -func (q *Queries) ListReportedIssuesByCustomer(ctx context.Context, arg ListReportedIssuesByCustomerParams) ([]ReportedIssue, error) { - rows, err := q.db.Query(ctx, ListReportedIssuesByCustomer, arg.CustomerID, arg.Limit, arg.Offset) +func (q *Queries) ListReportedIssuesByUser(ctx context.Context, arg ListReportedIssuesByUserParams) ([]ReportedIssue, error) { + rows, err := q.db.Query(ctx, ListReportedIssuesByUser, arg.UserID, arg.Limit, arg.Offset) if err != nil { return nil, err } @@ -145,7 +159,8 @@ func (q *Queries) ListReportedIssuesByCustomer(ctx context.Context, arg ListRepo var i ReportedIssue if err := rows.Scan( &i.ID, - &i.CustomerID, + &i.UserID, + &i.UserRole, &i.Subject, &i.Description, &i.IssueType, @@ -166,7 +181,8 @@ func (q *Queries) ListReportedIssuesByCustomer(ctx context.Context, arg ListRepo const UpdateReportedIssueStatus = `-- name: UpdateReportedIssueStatus :exec UPDATE reported_issues -SET status = $2, updated_at = NOW() +SET status = $2, + updated_at = NOW() WHERE id = $1 ` diff --git a/gen/db/models.go b/gen/db/models.go index e378fe5..0f3912b 100644 --- a/gen/db/models.go +++ b/gen/db/models.go @@ -78,18 +78,13 @@ type Bet struct { Amount int64 `json:"amount"` TotalOdds float32 `json:"total_odds"` Status int32 `json:"status"` - FullName string `json:"full_name"` - PhoneNumber string `json:"phone_number"` - CompanyID pgtype.Int8 `json:"company_id"` - BranchID pgtype.Int8 `json:"branch_id"` - UserID pgtype.Int8 `json:"user_id"` - CashedOut bool `json:"cashed_out"` - CashoutID string `json:"cashout_id"` - CreatedAt pgtype.Timestamp `json:"created_at"` - UpdatedAt pgtype.Timestamp `json:"updated_at"` + UserID int64 `json:"user_id"` IsShopBet bool `json:"is_shop_bet"` + CashedOut bool `json:"cashed_out"` OutcomesHash string `json:"outcomes_hash"` FastCode string `json:"fast_code"` + CreatedAt pgtype.Timestamp `json:"created_at"` + UpdatedAt pgtype.Timestamp `json:"updated_at"` } type BetOutcome struct { @@ -115,18 +110,15 @@ type BetWithOutcome struct { Amount int64 `json:"amount"` TotalOdds float32 `json:"total_odds"` Status int32 `json:"status"` - FullName string `json:"full_name"` - PhoneNumber string `json:"phone_number"` - CompanyID pgtype.Int8 `json:"company_id"` - BranchID pgtype.Int8 `json:"branch_id"` - UserID pgtype.Int8 `json:"user_id"` - CashedOut bool `json:"cashed_out"` - CashoutID string `json:"cashout_id"` - CreatedAt pgtype.Timestamp `json:"created_at"` - UpdatedAt pgtype.Timestamp `json:"updated_at"` + UserID int64 `json:"user_id"` IsShopBet bool `json:"is_shop_bet"` + CashedOut bool `json:"cashed_out"` OutcomesHash string `json:"outcomes_hash"` FastCode string `json:"fast_code"` + CreatedAt pgtype.Timestamp `json:"created_at"` + UpdatedAt pgtype.Timestamp `json:"updated_at"` + FullName interface{} `json:"full_name"` + PhoneNumber pgtype.Text `json:"phone_number"` Outcomes []BetOutcome `json:"outcomes"` } @@ -252,6 +244,7 @@ type Event struct { Status pgtype.Text `json:"status"` FetchedAt pgtype.Timestamp `json:"fetched_at"` Source pgtype.Text `json:"source"` + Flagged bool `json:"flagged"` } type ExchangeRate struct { @@ -366,7 +359,8 @@ type RefreshToken struct { type ReportedIssue struct { ID int64 `json:"id"` - CustomerID int64 `json:"customer_id"` + UserID int64 `json:"user_id"` + UserRole string `json:"user_role"` Subject string `json:"subject"` Description string `json:"description"` IssueType string `json:"issue_type"` diff --git a/gen/db/report.sql.go b/gen/db/report.sql.go index 7040673..cb1bb6f 100644 --- a/gen/db/report.sql.go +++ b/gen/db/report.sql.go @@ -12,18 +12,35 @@ import ( ) const GetBranchWiseReport = `-- name: GetBranchWiseReport :many -SELECT - b.branch_id, - br.name AS branch_name, - br.company_id, - COUNT(*) AS total_bets, - COALESCE(SUM(b.amount), 0) AS total_cash_made, - COALESCE(SUM(CASE WHEN b.cashed_out THEN b.amount ELSE 0 END), 0) AS total_cash_out, - COALESCE(SUM(CASE WHEN b.status = 5 THEN b.amount ELSE 0 END), 0) AS total_cash_backs -FROM bets b -JOIN branches br ON b.branch_id = br.id +SELECT b.branch_id, + br.name AS branch_name, + br.company_id, + COUNT(*) AS total_bets, + COALESCE(SUM(b.amount), 0) AS total_cash_made, + COALESCE( + SUM( + CASE + WHEN b.cashed_out THEN b.amount + ELSE 0 + END + ), + 0 + ) AS total_cash_out, + COALESCE( + SUM( + CASE + WHEN b.status = 5 THEN b.amount + ELSE 0 + END + ), + 0 + ) AS total_cash_backs +FROM shop_bet_detail b + JOIN branches br ON b.branch_id = br.id WHERE b.created_at BETWEEN $1 AND $2 -GROUP BY b.branch_id, br.name, br.company_id +GROUP BY b.branch_id, + br.name, + br.company_id ` type GetBranchWiseReportParams struct { @@ -32,7 +49,7 @@ type GetBranchWiseReportParams struct { } type GetBranchWiseReportRow struct { - BranchID pgtype.Int8 `json:"branch_id"` + BranchID int64 `json:"branch_id"` BranchName string `json:"branch_name"` CompanyID int64 `json:"company_id"` TotalBets int64 `json:"total_bets"` @@ -70,17 +87,33 @@ func (q *Queries) GetBranchWiseReport(ctx context.Context, arg GetBranchWiseRepo } const GetCompanyWiseReport = `-- name: GetCompanyWiseReport :many -SELECT - b.company_id, - c.name AS company_name, - COUNT(*) AS total_bets, - COALESCE(SUM(b.amount), 0) AS total_cash_made, - COALESCE(SUM(CASE WHEN b.cashed_out THEN b.amount ELSE 0 END), 0) AS total_cash_out, - COALESCE(SUM(CASE WHEN b.status = 5 THEN b.amount ELSE 0 END), 0) AS total_cash_backs -FROM bets b -JOIN companies c ON b.company_id = c.id +SELECT b.company_id, + c.name AS company_name, + COUNT(*) AS total_bets, + COALESCE(SUM(b.amount), 0) AS total_cash_made, + COALESCE( + SUM( + CASE + WHEN b.cashed_out THEN b.amount + ELSE 0 + END + ), + 0 + ) AS total_cash_out, + COALESCE( + SUM( + CASE + WHEN b.status = 5 THEN b.amount + ELSE 0 + END + ), + 0 + ) AS total_cash_backs +FROM shop_bet_detail b + JOIN companies c ON b.company_id = c.id WHERE b.created_at BETWEEN $1 AND $2 -GROUP BY b.company_id, c.name +GROUP BY b.company_id, + c.name ` type GetCompanyWiseReportParams struct { @@ -89,7 +122,7 @@ type GetCompanyWiseReportParams struct { } type GetCompanyWiseReportRow struct { - CompanyID pgtype.Int8 `json:"company_id"` + CompanyID int64 `json:"company_id"` CompanyName string `json:"company_name"` TotalBets int64 `json:"total_bets"` TotalCashMade interface{} `json:"total_cash_made"` diff --git a/internal/domain/bet.go b/internal/domain/bet.go index 6d1dc28..cb48793 100644 --- a/internal/domain/bet.go +++ b/internal/domain/bet.go @@ -38,29 +38,23 @@ type CreateBetOutcome struct { Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"` } -// If it is a ShopBet then UserID will be the cashier -// If it is a DigitalBet then UserID will be the user and the branchID will be 0 or nil +// If it is a ShopBet then UserID and Fullname will be the cashier +// If it is a DigitalBet then UserID and Fullname will be the user type Bet struct { - ID int64 - Amount Currency - TotalOdds float32 - Status OutcomeStatus - FullName string - PhoneNumber string - BranchID ValidInt64 // Can Be Nullable - CompanyID ValidInt64 // Can Be Nullable - UserID ValidInt64 // Can Be Nullable - IsShopBet bool - CashedOut bool - CashoutID string - FastCode string - CreatedAt time.Time + ID int64 + Amount Currency + TotalOdds float32 + Status OutcomeStatus + UserID int64 + IsShopBet bool + CashedOut bool + FastCode string + CreatedAt time.Time } type BetFilter struct { - BranchID ValidInt64 // Can Be Nullable - CompanyID ValidInt64 // Can Be Nullable - UserID ValidInt64 // Can Be Nullable + UserID ValidInt64 + CashedOut ValidBool IsShopBet ValidBool Query ValidString CreatedBefore ValidTime @@ -74,12 +68,9 @@ type GetBet struct { Status OutcomeStatus FullName string PhoneNumber string - BranchID ValidInt64 // Can Be Nullable - CompanyID ValidInt64 // Can Be Nullable - UserID ValidInt64 // Can Be Nullable + UserID int64 IsShopBet bool CashedOut bool - CashoutID string Outcomes []BetOutcome FastCode string CreatedAt time.Time @@ -89,13 +80,8 @@ type CreateBet struct { Amount Currency TotalOdds float32 Status OutcomeStatus - FullName string - PhoneNumber string - CompanyID ValidInt64 // Can Be Nullable - BranchID ValidInt64 // Can Be Nullable - UserID ValidInt64 // Can Be Nullable + UserID int64 IsShopBet bool - CashoutID string OutcomesHash string FastCode string } @@ -107,11 +93,8 @@ type CreateBetOutcomeReq struct { } type CreateBetReq struct { - Outcomes []CreateBetOutcomeReq `json:"outcomes"` - Amount float32 `json:"amount" example:"100.0"` - FullName string `json:"full_name" example:"John"` - PhoneNumber string `json:"phone_number" example:"1234567890"` - BranchID *int64 `json:"branch_id,omitempty" example:"1"` + Outcomes []CreateBetOutcomeReq `json:"outcomes"` + Amount float32 `json:"amount" example:"100.0"` } type RandomBetReq struct { @@ -124,28 +107,22 @@ type CreateBetRes struct { Amount float32 `json:"amount" example:"100.0"` TotalOdds float32 `json:"total_odds" example:"4.22"` Status OutcomeStatus `json:"status" example:"1"` - FullName string `json:"full_name" example:"John"` - PhoneNumber string `json:"phone_number" example:"1234567890"` - BranchID int64 `json:"branch_id" example:"2"` UserID int64 `json:"user_id" example:"2"` IsShopBet bool `json:"is_shop_bet" example:"false"` CreatedNumber int64 `json:"created_number" example:"2"` - CashedID string `json:"cashed_id" example:"21234"` } type BetRes struct { - ID int64 `json:"id" example:"1"` - Outcomes []BetOutcome `json:"outcomes"` - Amount float32 `json:"amount" example:"100.0"` - TotalOdds float32 `json:"total_odds" example:"4.22"` - Status OutcomeStatus `json:"status" example:"1"` - FullName string `json:"full_name" example:"John"` - PhoneNumber string `json:"phone_number" example:"1234567890"` - BranchID int64 `json:"branch_id" example:"2"` - UserID int64 `json:"user_id" example:"2"` - IsShopBet bool `json:"is_shop_bet" example:"false"` - CashedOut bool `json:"cashed_out" example:"false"` - CashedID string `json:"cashed_id" example:"21234"` - CreatedAt time.Time `json:"created_at" example:"2025-04-08T12:00:00Z"` + ID int64 `json:"id" example:"1"` + Outcomes []BetOutcome `json:"outcomes"` + Amount float32 `json:"amount" example:"100.0"` + TotalOdds float32 `json:"total_odds" example:"4.22"` + Status OutcomeStatus `json:"status" example:"1"` + Fullname string `json:"full_name" example:"John Smith"` + UserID int64 `json:"user_id" example:"2"` + IsShopBet bool `json:"is_shop_bet" example:"false"` + CashedOut bool `json:"cashed_out" example:"false"` + CreatedAt time.Time `json:"created_at" example:"2025-04-08T12:00:00Z"` + FastCode string `json:"fast_code"` } func ConvertCreateBet(bet Bet, createdNumber int64) CreateBetRes { @@ -154,29 +131,23 @@ func ConvertCreateBet(bet Bet, createdNumber int64) CreateBetRes { Amount: bet.Amount.Float32(), TotalOdds: bet.TotalOdds, Status: bet.Status, - FullName: bet.FullName, - PhoneNumber: bet.PhoneNumber, - BranchID: bet.BranchID.Value, - UserID: bet.UserID.Value, + UserID: bet.UserID, CreatedNumber: createdNumber, - CashedID: bet.CashoutID, } } func ConvertBet(bet GetBet) BetRes { return BetRes{ - ID: bet.ID, - Amount: bet.Amount.Float32(), - TotalOdds: bet.TotalOdds, - Status: bet.Status, - FullName: bet.FullName, - PhoneNumber: bet.PhoneNumber, - BranchID: bet.BranchID.Value, - UserID: bet.UserID.Value, - Outcomes: bet.Outcomes, - IsShopBet: bet.IsShopBet, - CashedOut: bet.CashedOut, - CashedID: bet.CashoutID, - CreatedAt: bet.CreatedAt, + ID: bet.ID, + Amount: bet.Amount.Float32(), + TotalOdds: bet.TotalOdds, + Status: bet.Status, + Fullname: bet.FullName, + UserID: bet.UserID, + Outcomes: bet.Outcomes, + IsShopBet: bet.IsShopBet, + CashedOut: bet.CashedOut, + CreatedAt: bet.CreatedAt, + FastCode: bet.FastCode, } } diff --git a/internal/domain/event.go b/internal/domain/event.go index fd041a7..874cbaa 100644 --- a/internal/domain/event.go +++ b/internal/domain/event.go @@ -101,6 +101,7 @@ type UpcomingEvent struct { StartTime time.Time `json:"start_time"` // Converted from "time" field in UNIX format Source string `json:"source"` // bet api provider (bet365, betfair) Status EventStatus `json:"status"` //Match Status for event + Flagged bool `json:"flagged"` //Whether the event is flagged or not } type MatchResult struct { EventID string diff --git a/internal/domain/issue_reporting.go b/internal/domain/issue_reporting.go index 1f55aee..59400d3 100644 --- a/internal/domain/issue_reporting.go +++ b/internal/domain/issue_reporting.go @@ -2,14 +2,51 @@ package domain import "time" +type ReportedIssueType string + +var ( + ISSUE_TYPE_DEPOSIT ReportedIssueType = "deposit" + ISSUE_TYPE_WITHDRAWAL ReportedIssueType = "withdrawal" + ISSUE_TYPE_BET ReportedIssueType = "bet" + ISSUE_TYPE_CASHOUT ReportedIssueType = "cashout" + ISSUE_TYPE_ODDS ReportedIssueType = "odds" + ISSUE_TYPE_EVENTS ReportedIssueType = "events" + ISSUE_TYPE_BRANCH ReportedIssueType = "branch" + ISSUE_TYPE_USER ReportedIssueType = "branch" + ISSUE_TYPE_LOGIN ReportedIssueType = "login" + ISSUE_TYPE_REGISTER ReportedIssueType = "register" + ISSUE_TYPE_RESET_PASSWORD ReportedIssueType = "reset_password" + ISSUE_TYPE_WALLET ReportedIssueType = "wallet" + ISSUE_TYPE_VIRTUAL ReportedIssueType = "virtual games" + ISSUE_TYPE_OTHER ReportedIssueType = "other" +) + +type ReportedIssueStatus string + +var ( + ISSUE_STATUS_PENDING ReportedIssueStatus = "pending" + ISSUE_STATUS_IN_PROGRESS ReportedIssueStatus = "in_progress" + ISSUE_STATUS_RESOLVED ReportedIssueStatus = "resolved" + ISSUE_STATUS_REJECTED ReportedIssueStatus = "rejected" +) + type ReportedIssue struct { ID int64 `json:"id"` - CustomerID int64 `json:"customer_id"` + UserID int64 `json:"user_id"` + UserRole Role `json:"user_role"` Subject string `json:"subject"` Description string `json:"description"` - IssueType string `json:"issue_type"` - Status string `json:"status"` + IssueType ReportedIssueType `json:"issue_type"` + Status ReportedIssueStatus `json:"status"` Metadata map[string]interface{} `json:"metadata,omitempty"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } + +type ReportedIssueReq struct { + ID int64 `json:"id"` + Subject string `json:"subject"` + Description string `json:"description"` + IssueType ReportedIssueType `json:"issue_type"` + Metadata map[string]interface{} `json:"metadata,omitempty"` +} diff --git a/internal/repository/bet.go b/internal/repository/bet.go index 05ea998..fe9f1db 100644 --- a/internal/repository/bet.go +++ b/internal/repository/bet.go @@ -21,27 +21,14 @@ var ( func convertDBBet(bet dbgen.Bet) domain.Bet { return domain.Bet{ - ID: bet.ID, - Amount: domain.Currency(bet.Amount), - TotalOdds: bet.TotalOdds, - Status: domain.OutcomeStatus(bet.Status), - FullName: bet.FullName, - PhoneNumber: bet.PhoneNumber, - BranchID: domain.ValidInt64{ - Value: bet.BranchID.Int64, - Valid: bet.BranchID.Valid, - }, - CompanyID: domain.ValidInt64{ - Value: bet.CompanyID.Int64, - Valid: bet.CompanyID.Valid, - }, - UserID: domain.ValidInt64{ - Value: bet.UserID.Int64, - Valid: bet.UserID.Valid, - }, + ID: bet.ID, + Amount: domain.Currency(bet.Amount), + TotalOdds: bet.TotalOdds, + Status: domain.OutcomeStatus(bet.Status), + UserID: bet.UserID, IsShopBet: bet.IsShopBet, CashedOut: bet.CashedOut, - CashoutID: bet.CashoutID, + FastCode: bet.FastCode, CreatedAt: bet.CreatedAt.Time, } } @@ -78,21 +65,14 @@ func convertDBBetWithOutcomes(bet dbgen.BetWithOutcome) domain.GetBet { Amount: domain.Currency(bet.Amount), TotalOdds: bet.TotalOdds, Status: domain.OutcomeStatus(bet.Status), - FullName: bet.FullName, - PhoneNumber: bet.PhoneNumber, - BranchID: domain.ValidInt64{ - Value: bet.BranchID.Int64, - Valid: bet.BranchID.Valid, - }, - UserID: domain.ValidInt64{ - Value: bet.UserID.Int64, - Valid: bet.UserID.Valid, - }, - IsShopBet: bet.IsShopBet, - CashedOut: bet.CashedOut, - CashoutID: bet.CashoutID, - Outcomes: outcomes, - CreatedAt: bet.CreatedAt.Time, + FullName: bet.FullName.(string), + PhoneNumber: bet.PhoneNumber.String, + UserID: bet.UserID, + IsShopBet: bet.IsShopBet, + CashedOut: bet.CashedOut, + Outcomes: outcomes, + FastCode: bet.FastCode, + CreatedAt: bet.CreatedAt.Time, } } @@ -119,22 +99,11 @@ func convertDBCreateBetOutcome(betOutcome domain.CreateBetOutcome) dbgen.CreateB func convertCreateBet(bet domain.CreateBet) dbgen.CreateBetParams { return dbgen.CreateBetParams{ - Amount: int64(bet.Amount), - TotalOdds: bet.TotalOdds, - Status: int32(bet.Status), - FullName: bet.FullName, - PhoneNumber: bet.PhoneNumber, - - BranchID: pgtype.Int8{ - Int64: bet.BranchID.Value, - Valid: bet.BranchID.Valid, - }, - UserID: pgtype.Int8{ - Int64: bet.UserID.Value, - Valid: bet.UserID.Valid, - }, + Amount: int64(bet.Amount), + TotalOdds: bet.TotalOdds, + Status: int32(bet.Status), + UserID: bet.UserID, IsShopBet: bet.IsShopBet, - CashoutID: bet.CashoutID, OutcomesHash: bet.OutcomesHash, FastCode: bet.FastCode, } @@ -184,33 +153,16 @@ func (s *Store) GetBetByID(ctx context.Context, id int64) (domain.GetBet, error) return convertDBBetWithOutcomes(bet), nil } -func (s *Store) GetBetByCashoutID(ctx context.Context, id string) (domain.GetBet, error) { - bet, err := s.queries.GetBetByCashoutID(ctx, id) - if err != nil { - domain.MongoDBLogger.Error("failed to get bet by cashout ID", - zap.String("cashout_id", id), - zap.Error(err), - ) - return domain.GetBet{}, err - } - - return convertDBBetWithOutcomes(bet), nil -} - func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]domain.GetBet, error) { bets, err := s.queries.GetAllBets(ctx, dbgen.GetAllBetsParams{ - 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, }, + CashedOut: pgtype.Bool{ + Bool: filter.CashedOut.Value, + Valid: filter.CashedOut.Valid, + }, IsShopBet: pgtype.Bool{ Bool: filter.IsShopBet.Value, Valid: filter.IsShopBet.Valid, @@ -244,32 +196,8 @@ func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]doma return result, nil } -func (s *Store) GetBetByBranchID(ctx context.Context, BranchID int64) ([]domain.GetBet, error) { - bets, err := s.queries.GetBetByBranchID(ctx, pgtype.Int8{ - Int64: BranchID, - Valid: true, - }) - if err != nil { - domain.MongoDBLogger.Error("failed to get bets by branch ID", - zap.Int64("branch_id", BranchID), - zap.Error(err), - ) - return nil, err - } - - var result []domain.GetBet = make([]domain.GetBet, 0, len(bets)) - for _, bet := range bets { - result = append(result, convertDBBetWithOutcomes(bet)) - } - - return result, nil -} - func (s *Store) GetBetByUserID(ctx context.Context, UserID int64) ([]domain.GetBet, error) { - bets, err := s.queries.GetBetByUserID(ctx, pgtype.Int8{ - Int64: UserID, - Valid: true, - }) + bets, err := s.queries.GetBetByUserID(ctx, UserID) if err != nil { return nil, err @@ -295,7 +223,7 @@ func (s *Store) GetBetByFastCode(ctx context.Context, fastcode string) (domain.G func (s *Store) GetBetCount(ctx context.Context, UserID int64, outcomesHash string) (int64, error) { count, err := s.queries.GetBetCount(ctx, dbgen.GetBetCountParams{ - UserID: pgtype.Int8{Int64: UserID, Valid: true}, + UserID: UserID, OutcomesHash: outcomesHash, }) @@ -462,21 +390,21 @@ func (s *Store) GetBetSummary(ctx context.Context, filter domain.ReportFilter) ( argPos := 1 // Add filters if provided - if filter.CompanyID.Valid { - query += fmt.Sprintf(" WHERE company_id = $%d", argPos) - args = append(args, filter.CompanyID.Value) - argPos++ - } - if filter.BranchID.Valid { - query += fmt.Sprintf(" AND %sbranch_id = $%d", func() string { - if len(args) == 0 { - return " WHERE " - } - return " AND " - }(), argPos) - args = append(args, filter.BranchID.Value) - argPos++ - } + // if filter.CompanyID.Valid { + // query += fmt.Sprintf(" WHERE company_id = $%d", argPos) + // args = append(args, filter.CompanyID.Value) + // argPos++ + // } + // if filter.BranchID.Valid { + // query += fmt.Sprintf(" AND %sbranch_id = $%d", func() string { + // if len(args) == 0 { + // return " WHERE " + // } + // return " AND " + // }(), argPos) + // args = append(args, filter.BranchID.Value) + // argPos++ + // } if filter.UserID.Valid { query += fmt.Sprintf(" AND %suser_id = $%d", func() string { if len(args) == 0 { diff --git a/internal/repository/event.go b/internal/repository/event.go index 219c915..674c51a 100644 --- a/internal/repository/event.go +++ b/internal/repository/event.go @@ -180,6 +180,7 @@ func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.Ev StartTime: e.StartTime.Time.UTC(), Source: e.Source.String, Status: domain.EventStatus(e.Status.String), + } } totalCount, err := s.queries.GetTotalEvents(ctx, dbgen.GetTotalEventsParams{ @@ -268,6 +269,14 @@ func (s *Store) UpdateEventStatus(ctx context.Context, eventID string, status do } + +func (s *Store) UpdateFlagged(ctx context.Context, eventID string, flagged bool) error { + return s.queries.UpdateFlagged(ctx, dbgen.UpdateFlaggedParams{ + ID: eventID, + Flagged: flagged, + }) +} + func (s *Store) DeleteEvent(ctx context.Context, eventID string) error { err := s.queries.DeleteEvent(ctx, eventID) if err != nil { diff --git a/internal/repository/issue_reporting.go b/internal/repository/issue_reporting.go index 01687f3..5c6054c 100644 --- a/internal/repository/issue_reporting.go +++ b/internal/repository/issue_reporting.go @@ -9,9 +9,9 @@ import ( type ReportedIssueRepository interface { CreateReportedIssue(ctx context.Context, arg dbgen.CreateReportedIssueParams) (dbgen.ReportedIssue, error) ListReportedIssues(ctx context.Context, limit, offset int32) ([]dbgen.ReportedIssue, error) - ListReportedIssuesByCustomer(ctx context.Context, customerID int64, limit, offset int32) ([]dbgen.ReportedIssue, error) + ListReportedIssuesByUser(ctx context.Context, userID int64, limit, offset int32) ([]dbgen.ReportedIssue, error) CountReportedIssues(ctx context.Context) (int64, error) - CountReportedIssuesByCustomer(ctx context.Context, customerID int64) (int64, error) + CountReportedIssuesByUser(ctx context.Context, userID int64) (int64, error) UpdateReportedIssueStatus(ctx context.Context, id int64, status string) error DeleteReportedIssue(ctx context.Context, id int64) error } @@ -36,21 +36,21 @@ func (s *ReportedIssueRepo) ListReportedIssues(ctx context.Context, limit, offse return s.store.queries.ListReportedIssues(ctx, params) } -func (s *ReportedIssueRepo) ListReportedIssuesByCustomer(ctx context.Context, customerID int64, limit, offset int32) ([]dbgen.ReportedIssue, error) { - params := dbgen.ListReportedIssuesByCustomerParams{ - CustomerID: customerID, - Limit: limit, - Offset: offset, +func (s *ReportedIssueRepo) ListReportedIssuesByUser(ctx context.Context, userID int64, limit, offset int32) ([]dbgen.ReportedIssue, error) { + params := dbgen.ListReportedIssuesByUserParams{ + UserID: userID, + Limit: limit, + Offset: offset, } - return s.store.queries.ListReportedIssuesByCustomer(ctx, params) + return s.store.queries.ListReportedIssuesByUser(ctx, params) } func (s *ReportedIssueRepo) CountReportedIssues(ctx context.Context) (int64, error) { return s.store.queries.CountReportedIssues(ctx) } -func (s *ReportedIssueRepo) CountReportedIssuesByCustomer(ctx context.Context, customerID int64) (int64, error) { - return s.store.queries.CountReportedIssuesByCustomer(ctx, customerID) +func (s *ReportedIssueRepo) CountReportedIssuesByUser(ctx context.Context, userID int64) (int64, error) { + return s.store.queries.CountReportedIssuesByUser(ctx, userID) } func (s *ReportedIssueRepo) UpdateReportedIssueStatus(ctx context.Context, id int64, status string) error { diff --git a/internal/services/bet/service.go b/internal/services/bet/service.go index e3444a3..8e0df56 100644 --- a/internal/services/bet/service.go +++ b/internal/services/bet/service.go @@ -20,7 +20,9 @@ import ( "github.com/SamuelTariku/FortuneBet-Backend/internal/pkgs/helpers" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event" + notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notfication" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds" + "github.com/SamuelTariku/FortuneBet-Backend/internal/services/settings" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet" "go.uber.org/zap" ) @@ -36,16 +38,21 @@ var ( ErrBranchIDRequired = errors.New("Branch ID required for this role") ErrOutcomeLimit = errors.New("Too many outcomes on a single bet") ErrTotalBalanceNotEnough = errors.New("Total Wallet balance is insufficient to create bet") + + ErrInvalidAmount = errors.New("Invalid amount") + ErrBetAmountTooHigh = errors.New("Cannot create a bet with an amount above limit") ) type Service struct { - betStore BetStore - eventSvc event.Service - prematchSvc odds.ServiceImpl - walletSvc wallet.Service - branchSvc branch.Service - logger *slog.Logger - mongoLogger *zap.Logger + betStore BetStore + eventSvc event.Service + prematchSvc odds.ServiceImpl + walletSvc wallet.Service + branchSvc branch.Service + settingSvc settings.Service + notificationSvc *notificationservice.Service + logger *slog.Logger + mongoLogger *zap.Logger } func NewService( @@ -54,17 +61,21 @@ func NewService( prematchSvc odds.ServiceImpl, walletSvc wallet.Service, branchSvc branch.Service, + settingSvc settings.Service, + notificationSvc *notificationservice.Service, logger *slog.Logger, mongoLogger *zap.Logger, ) *Service { return &Service{ - betStore: betStore, - eventSvc: eventSvc, - prematchSvc: prematchSvc, - walletSvc: walletSvc, - branchSvc: branchSvc, - logger: logger, - mongoLogger: mongoLogger, + betStore: betStore, + eventSvc: eventSvc, + prematchSvc: prematchSvc, + walletSvc: walletSvc, + branchSvc: branchSvc, + settingSvc: settingSvc, + notificationSvc: notificationSvc, + logger: logger, + mongoLogger: mongoLogger, } } @@ -196,7 +207,17 @@ func (s *Service) GenerateBetOutcome(ctx context.Context, eventID int64, marketI } func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID int64, role domain.Role) (domain.CreateBetRes, error) { - if len(req.Outcomes) > 30 { + settingsList, err := s.settingSvc.GetSettingList(ctx) + + if req.Amount < 1 { + return domain.CreateBetRes{}, ErrInvalidAmount + } + + if req.Amount > settingsList.BetAmountLimit.Float32() { + return domain.CreateBetRes{}, ErrInvalidAmount + } + + if len(req.Outcomes) > int(settingsList.MaxNumberOfOutcomes) { s.mongoLogger.Error("too many outcomes", zap.Int("count", len(req.Outcomes)), zap.Int64("user_id", userID), @@ -237,7 +258,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID return domain.CreateBetRes{}, err } if count >= 2 { - return domain.CreateBetRes{}, fmt.Errorf("bet already pleaced twice") + return domain.CreateBetRes{}, fmt.Errorf("bet already placed twice") } cashoutID, err := s.GenerateCashoutID() diff --git a/internal/services/event/port.go b/internal/services/event/port.go index c548a32..fafb8e8 100644 --- a/internal/services/event/port.go +++ b/internal/services/event/port.go @@ -16,4 +16,5 @@ type Service interface { // GetAndStoreMatchResult(ctx context.Context, eventID string) error UpdateFinalScore(ctx context.Context, eventID, fullScore string, status domain.EventStatus) error UpdateEventStatus(ctx context.Context, eventID string, status domain.EventStatus) error + UpdateFlagged(ctx context.Context, eventID string, flagged bool) error } diff --git a/internal/services/event/service.go b/internal/services/event/service.go index d09f7e9..7315b45 100644 --- a/internal/services/event/service.go +++ b/internal/services/event/service.go @@ -369,6 +369,10 @@ func (s *service) UpdateEventStatus(ctx context.Context, eventID string, status return s.store.UpdateEventStatus(ctx, eventID, status) } +func (s *service) UpdateFlagged(ctx context.Context, eventID string, flagged bool) error { + return s.store.UpdateFlagged(ctx, eventID, flagged) +} + // func (s *service) GetAndStoreMatchResult(ctx context.Context, eventID string) error { // url := fmt.Sprintf("https://api.b365api.com/v1/bet365/result?token=%s&event_id=%s", s.token, eventID) diff --git a/internal/services/issue_reporting/service.go b/internal/services/issue_reporting/service.go index 88aba2f..83c79a8 100644 --- a/internal/services/issue_reporting/service.go +++ b/internal/services/issue_reporting/service.go @@ -17,15 +17,19 @@ func New(repo repository.ReportedIssueRepository) *Service { return &Service{repo: repo} } -func (s *Service) CreateReportedIssue(ctx context.Context, issue domain.ReportedIssue) (domain.ReportedIssue, error) { +func (s *Service) CreateReportedIssue(ctx context.Context, issue domain.ReportedIssueReq, userID int64, role domain.Role) (domain.ReportedIssue, error) { + + // metadata, err := json.Marshal(issue.Metadata) + // if err != nil { + // return domain.ReportedIssue{}, err + // } params := dbgen.CreateReportedIssueParams{ - // Map fields from domain.ReportedIssue to dbgen.CreateReportedIssueParams here. - // Example: - // Title: issue.Title, - // Description: issue.Description, - // CustomerID: issue.CustomerID, - // Status: issue.Status, - // Add other fields as necessary. + UserID: userID, + UserRole: string(role), + Subject: issue.Subject, + Description: issue.Description, + IssueType: string(issue.IssueType), + // Metadata: metadata, } dbIssue, err := s.repo.CreateReportedIssue(ctx, params) if err != nil { @@ -36,17 +40,20 @@ func (s *Service) CreateReportedIssue(ctx context.Context, issue domain.Reported ID: dbIssue.ID, Subject: dbIssue.Subject, Description: dbIssue.Description, - CustomerID: dbIssue.CustomerID, - Status: dbIssue.Status, + UserID: dbIssue.UserID, + UserRole: domain.Role(dbIssue.UserRole), + Status: domain.ReportedIssueStatus(dbIssue.Status), + IssueType: domain.ReportedIssueType(dbIssue.IssueType), CreatedAt: dbIssue.CreatedAt.Time, UpdatedAt: dbIssue.UpdatedAt.Time, + // Add other fields as necessary } return reportedIssue, nil } -func (s *Service) GetIssuesForCustomer(ctx context.Context, customerID int64, limit, offset int) ([]domain.ReportedIssue, error) { - dbIssues, err := s.repo.ListReportedIssuesByCustomer(ctx, customerID, int32(limit), int32(offset)) +func (s *Service) GetIssuesForUser(ctx context.Context, userID int64, limit, offset int) ([]domain.ReportedIssue, error) { + dbIssues, err := s.repo.ListReportedIssuesByUser(ctx, userID, int32(limit), int32(offset)) if err != nil { return nil, err } @@ -56,8 +63,10 @@ func (s *Service) GetIssuesForCustomer(ctx context.Context, customerID int64, li ID: dbIssue.ID, Subject: dbIssue.Subject, Description: dbIssue.Description, - CustomerID: dbIssue.CustomerID, - Status: dbIssue.Status, + UserID: dbIssue.UserID, + UserRole: domain.Role(dbIssue.UserRole), + Status: domain.ReportedIssueStatus(dbIssue.Status), + IssueType: domain.ReportedIssueType(dbIssue.IssueType), CreatedAt: dbIssue.CreatedAt.Time, UpdatedAt: dbIssue.UpdatedAt.Time, // Add other fields as necessary diff --git a/internal/services/ticket/service.go b/internal/services/ticket/service.go index 6a91b7d..1fd521e 100644 --- a/internal/services/ticket/service.go +++ b/internal/services/ticket/service.go @@ -25,8 +25,8 @@ var ( ErrTicketAmountTooHigh = errors.New("Cannot create a ticket with an amount above limit") ErrTicketLimitForSingleUser = errors.New("Number of Ticket Limit reached") ErrTicketWinningTooHigh = errors.New("Total Winnings over set limit") - - ErrRawOddInvalid = errors.New("Prematch Raw Odd is Invalid") + ErrInvalidAmount = errors.New("Invalid amount") + ErrRawOddInvalid = errors.New("Prematch Raw Odd is Invalid") ) type Service struct { @@ -34,7 +34,7 @@ type Service struct { eventSvc event.Service prematchSvc odds.ServiceImpl mongoLogger *zap.Logger - settingSvc settings.Service + settingSvc settings.Service notificationSvc *notificationservice.Service } @@ -51,7 +51,7 @@ func NewService( eventSvc: eventSvc, prematchSvc: prematchSvc, mongoLogger: mongoLogger, - settingSvc: settingSvc, + settingSvc: settingSvc, notificationSvc: notificationSvc, } } @@ -167,6 +167,11 @@ func (s *Service) CreateTicket(ctx context.Context, req domain.CreateTicketReq, } + + if req.Amount < 1 { + return domain.Ticket{}, 0, ErrInvalidAmount + } + // Check to see if the amount is above a set limit if req.Amount > settingsList.BetAmountLimit.Float32() { return domain.Ticket{}, 0, ErrTicketAmountTooHigh @@ -183,7 +188,6 @@ func (s *Service) CreateTicket(ctx context.Context, req domain.CreateTicketReq, // Check to see how many tickets a single anonymous user has created if count > settingsList.DailyTicketPerIP { - return domain.Ticket{}, 0, ErrTicketLimitForSingleUser } diff --git a/internal/web_server/cron.go b/internal/web_server/cron.go index 58e9e24..9658ad5 100644 --- a/internal/web_server/cron.go +++ b/internal/web_server/cron.go @@ -23,22 +23,22 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S spec string task func() }{ - { - spec: "0 0 * * * *", // Every 1 hour - task: func() { - if err := eventService.FetchUpcomingEvents(context.Background()); err != nil { - log.Printf("FetchUpcomingEvents error: %v", err) - } - }, - }, - { - spec: "0 0 * * * *", // Every 1 hour (since its takes that long to fetch all the events) - task: func() { - if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil { - log.Printf("FetchNonLiveOdds error: %v", err) - } - }, - }, + // { + // spec: "0 0 * * * *", // Every 1 hour + // task: func() { + // if err := eventService.FetchUpcomingEvents(context.Background()); err != nil { + // log.Printf("FetchUpcomingEvents error: %v", err) + // } + // }, + // }, + // { + // spec: "0 0 * * * *", // Every 1 hour (since its takes that long to fetch all the events) + // task: func() { + // if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil { + // log.Printf("FetchNonLiveOdds error: %v", err) + // } + // }, + // }, { spec: "0 */5 * * * *", // Every 5 Minutes task: func() { diff --git a/internal/web_server/handlers/prematch.go b/internal/web_server/handlers/event_handler.go similarity index 68% rename from internal/web_server/handlers/prematch.go rename to internal/web_server/handlers/event_handler.go index fbdf594..13d7bac 100644 --- a/internal/web_server/handlers/prematch.go +++ b/internal/web_server/handlers/event_handler.go @@ -10,61 +10,6 @@ import ( "github.com/gofiber/fiber/v2" ) -// GetALLPrematchOdds -// @Summary Retrieve all prematch odds -// @Description Retrieve all prematch odds from the database -// @Tags prematch -// @Accept json -// @Produce json -// @Success 200 {array} domain.Odd -// @Failure 500 {object} response.APIResponse -// @Router /odds [get] -func (h *Handler) GetALLPrematchOdds(c *fiber.Ctx) error { - - odds, err := h.prematchSvc.GetALLPrematchOdds(c.Context()) - if err != nil { - return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve all prematch odds", nil, nil) - } - - return response.WriteJSON(c, fiber.StatusOK, "All prematch odds retrieved successfully", odds, nil) - -} - -// GetRawOddsByMarketID -// @Summary Retrieve raw odds by Market ID -// @Description Retrieve raw odds records using a Market ID -// @Tags prematch -// @Accept json -// @Produce json -// @Param upcoming_id path string true "Upcoming ID" -// @Param market_id path string true "Market ID" -// @Success 200 {array} domain.RawOddsByMarketID -// @Failure 400 {object} response.APIResponse -// @Failure 500 {object} response.APIResponse -// @Router /odds/upcoming/{upcoming_id}/market/{market_id} [get] -func (h *Handler) GetRawOddsByMarketID(c *fiber.Ctx) error { - - marketID := c.Params("market_id") - upcomingID := c.Params("upcoming_id") - if marketID == "" { - return response.WriteJSON(c, fiber.StatusBadRequest, "Missing market_id", nil, nil) - } - - if upcomingID == "" { - return response.WriteJSON(c, fiber.StatusBadRequest, "Missing upcoming_id", nil, nil) - } - - rawOdds, err := h.prematchSvc.GetRawOddsByMarketID(c.Context(), marketID, upcomingID) - if err != nil { - // fmt.Printf("Failed to fetch raw odds: %v market_id:%v upcomingID:%v\n", err, marketID, upcomingID) - h.logger.Error("Failed to get raw odds by market ID", "marketID", marketID, "upcomingID", upcomingID, "error", err) - return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve raw odds", err, nil) - } - - return response.WriteJSON(c, fiber.StatusOK, "Raw odds retrieved successfully", rawOdds, nil) - -} - // @Summary Retrieve all upcoming events // @Description Retrieve all upcoming events from the database // @Tags prematch @@ -151,6 +96,10 @@ func (h *Handler) GetAllUpcomingEvents(c *fiber.Ctx) error { Value: countryCodeQuery, Valid: countryCodeQuery != "", } + + + flaggedQuery := c.Query("flagged") + if flaggedQuery != "" && events, total, err := h.eventSvc.GetPaginatedUpcomingEvents( c.Context(), domain.EventFilter{ SportID: sportID, @@ -257,44 +206,6 @@ func (h *Handler) GetUpcomingEventByID(c *fiber.Ctx) error { } -// @Summary Retrieve prematch odds by upcoming ID (FI) -// @Description Retrieve prematch odds by upcoming event ID (FI from Bet365) with optional pagination -// @Tags prematch -// @Accept json -// @Produce json -// @Param upcoming_id path string true "Upcoming Event ID (FI)" -// @Param limit query int false "Number of results to return (default: 10)" -// @Param offset query int false "Number of results to skip (default: 0)" -// @Success 200 {array} domain.Odd -// @Failure 400 {object} response.APIResponse -// @Failure 500 {object} response.APIResponse -// @Router /odds/upcoming/{upcoming_id} [get] -func (h *Handler) GetOddsByUpcomingID(c *fiber.Ctx) error { - - upcomingID := c.Params("upcoming_id") - if upcomingID == "" { - return response.WriteJSON(c, fiber.StatusBadRequest, "Missing upcoming_id", nil, nil) - } - - limit, err := strconv.Atoi(c.Query("limit", "10")) // Default limit is 10 - if err != nil || limit <= 0 { - return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid limit value", nil, nil) - } - - offset, err := strconv.Atoi(c.Query("offset", "0")) // Default offset is 0 - if err != nil || offset < 0 { - return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid offset value", nil, nil) - } - - odds, err := h.prematchSvc.GetPrematchOddsByUpcomingID(c.Context(), upcomingID) - if err != nil { - return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve prematch odds", nil, nil) - } - - return response.WriteJSON(c, fiber.StatusOK, "Prematch odds retrieved successfully", odds, nil) - -} - type UpdateEventStatusReq struct { } @@ -320,3 +231,45 @@ func (h *Handler) SetEventStatusToRemoved(c *fiber.Ctx) error { return response.WriteJSON(c, fiber.StatusOK, "Event updated successfully", nil, nil) } + +type UpdateEventFlaggedReq struct { + Flagged bool `json:"flagged" example:"true"` +} + +// UpdateEventFlagged godoc +// @Summary update the event flagged +// @Description Update the event flagged +// @Tags event +// @Accept json +// @Produce json +// @Param id path int true "Event ID" +// @Success 200 {object} response.APIResponse +// @Failure 400 {object} response.APIResponse +// @Failure 500 {object} response.APIResponse +// @Router /events/{id}/flag [put] +func (h *Handler) UpdateEventFlagged(c *fiber.Ctx) error { + eventID := c.Params("id") + + var req UpdateEventFlaggedReq + + if err := c.BodyParser(&req); err != nil { + return fiber.NewError(fiber.StatusBadRequest, err.Error()) + } + + valErrs, ok := h.validator.Validate(c, req) + if !ok { + var errMsg string + for field, msg := range valErrs { + errMsg += fmt.Sprintf("%s: %s; ", field, msg) + } + return fiber.NewError(fiber.StatusBadRequest, errMsg) + } + err := h.eventSvc.UpdateFlagged(c.Context(), eventID, req.Flagged) + + if err != nil { + h.logger.Error("Failed to update event flagged", "eventID", eventID, "error", err) + } + + return response.WriteJSON(c, fiber.StatusOK, "Event updated successfully", nil, nil) + +} diff --git a/internal/web_server/handlers/issue_reporting.go b/internal/web_server/handlers/issue_reporting.go index d49c6f5..245156b 100644 --- a/internal/web_server/handlers/issue_reporting.go +++ b/internal/web_server/handlers/issue_reporting.go @@ -19,12 +19,15 @@ import ( // @Failure 500 {object} domain.ErrorResponse // @Router /api/v1/issues [post] func (h *Handler) CreateIssue(c *fiber.Ctx) error { - var req domain.ReportedIssue + role := c.Locals("role").(domain.Role) + userID := c.Locals("user_id").(int64) + + var req domain.ReportedIssueReq if err := c.BodyParser(&req); err != nil { return fiber.NewError(fiber.StatusBadRequest, "Invalid request body") } - created, err := h.issueReportingSvc.CreateReportedIssue(c.Context(), req) + created, err := h.issueReportingSvc.CreateReportedIssue(c.Context(), req, userID, role) if err != nil { return fiber.NewError(fiber.StatusInternalServerError, err.Error()) } @@ -32,27 +35,27 @@ func (h *Handler) CreateIssue(c *fiber.Ctx) error { return c.Status(fiber.StatusCreated).JSON(created) } -// GetCustomerIssues godoc -// @Summary Get reported issues by a customer -// @Description Returns all issues reported by a specific customer +// GetUserIssues godoc +// @Summary Get reported issues by a user +// @Description Returns all issues reported by a specific user // @Tags Issues // @Produce json -// @Param customer_id path int true "Customer ID" +// @Param user_id path int true "User ID" // @Param limit query int false "Limit" // @Param offset query int false "Offset" // @Success 200 {array} domain.ReportedIssue // @Failure 400 {object} domain.ErrorResponse // @Failure 500 {object} domain.ErrorResponse -// @Router /api/v1/issues/customer/{customer_id} [get] -func (h *Handler) GetCustomerIssues(c *fiber.Ctx) error { - customerID, err := strconv.ParseInt(c.Params("customer_id"), 10, 64) +// @Router /api/v1/issues/user/{user_id} [get] +func (h *Handler) GetUserIssues(c *fiber.Ctx) error { + userID, err := strconv.ParseInt(c.Params("user_id"), 10, 64) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, "Invalid customer ID") + return fiber.NewError(fiber.StatusBadRequest, "Invalid user ID") } limit, offset := getPaginationParams(c) - issues, err := h.issueReportingSvc.GetIssuesForCustomer(c.Context(), customerID, limit, offset) + issues, err := h.issueReportingSvc.GetIssuesForUser(c.Context(), userID, limit, offset) if err != nil { return fiber.NewError(fiber.StatusInternalServerError, err.Error()) } diff --git a/internal/web_server/handlers/odd_handler.go b/internal/web_server/handlers/odd_handler.go new file mode 100644 index 0000000..397d6f2 --- /dev/null +++ b/internal/web_server/handlers/odd_handler.go @@ -0,0 +1,102 @@ +package handlers + +import ( + "strconv" + + "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" + "github.com/gofiber/fiber/v2" +) + +// GetALLPrematchOdds +// @Summary Retrieve all prematch odds +// @Description Retrieve all prematch odds from the database +// @Tags prematch +// @Accept json +// @Produce json +// @Success 200 {array} domain.Odd +// @Failure 500 {object} response.APIResponse +// @Router /odds [get] +func (h *Handler) GetALLPrematchOdds(c *fiber.Ctx) error { + + odds, err := h.prematchSvc.GetALLPrematchOdds(c.Context()) + if err != nil { + return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve all prematch odds", nil, nil) + } + + return response.WriteJSON(c, fiber.StatusOK, "All prematch odds retrieved successfully", odds, nil) + +} + +// GetRawOddsByMarketID +// @Summary Retrieve raw odds by Market ID +// @Description Retrieve raw odds records using a Market ID +// @Tags prematch +// @Accept json +// @Produce json +// @Param upcoming_id path string true "Upcoming ID" +// @Param market_id path string true "Market ID" +// @Success 200 {array} domain.RawOddsByMarketID +// @Failure 400 {object} response.APIResponse +// @Failure 500 {object} response.APIResponse +// @Router /odds/upcoming/{upcoming_id}/market/{market_id} [get] +func (h *Handler) GetRawOddsByMarketID(c *fiber.Ctx) error { + + marketID := c.Params("market_id") + upcomingID := c.Params("upcoming_id") + if marketID == "" { + return response.WriteJSON(c, fiber.StatusBadRequest, "Missing market_id", nil, nil) + } + + if upcomingID == "" { + return response.WriteJSON(c, fiber.StatusBadRequest, "Missing upcoming_id", nil, nil) + } + + rawOdds, err := h.prematchSvc.GetRawOddsByMarketID(c.Context(), marketID, upcomingID) + if err != nil { + // fmt.Printf("Failed to fetch raw odds: %v market_id:%v upcomingID:%v\n", err, marketID, upcomingID) + h.logger.Error("Failed to get raw odds by market ID", "marketID", marketID, "upcomingID", upcomingID, "error", err) + return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve raw odds", err, nil) + } + + return response.WriteJSON(c, fiber.StatusOK, "Raw odds retrieved successfully", rawOdds, nil) + +} + +// @Summary Retrieve prematch odds by upcoming ID (FI) +// @Description Retrieve prematch odds by upcoming event ID (FI from Bet365) with optional pagination +// @Tags prematch +// @Accept json +// @Produce json +// @Param upcoming_id path string true "Upcoming Event ID (FI)" +// @Param limit query int false "Number of results to return (default: 10)" +// @Param offset query int false "Number of results to skip (default: 0)" +// @Success 200 {array} domain.Odd +// @Failure 400 {object} response.APIResponse +// @Failure 500 {object} response.APIResponse +// @Router /odds/upcoming/{upcoming_id} [get] +func (h *Handler) GetOddsByUpcomingID(c *fiber.Ctx) error { + + upcomingID := c.Params("upcoming_id") + if upcomingID == "" { + return response.WriteJSON(c, fiber.StatusBadRequest, "Missing upcoming_id", nil, nil) + } + + limit, err := strconv.Atoi(c.Query("limit", "10")) // Default limit is 10 + if err != nil || limit <= 0 { + return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid limit value", nil, nil) + } + + offset, err := strconv.Atoi(c.Query("offset", "0")) // Default offset is 0 + if err != nil || offset < 0 { + return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid offset value", nil, nil) + } + + odds, err := h.prematchSvc.GetPrematchOddsByUpcomingID(c.Context(), upcomingID) + if err != nil { + return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve prematch odds", nil, nil) + } + + return response.WriteJSON(c, fiber.StatusOK, "Prematch odds retrieved successfully", odds, nil) + +} + diff --git a/internal/web_server/routes.go b/internal/web_server/routes.go index f7ac808..2cad0c2 100644 --- a/internal/web_server/routes.go +++ b/internal/web_server/routes.go @@ -61,6 +61,12 @@ func (a *App) initAppRoutes() { }) }) + group.Get("/", func(c *fiber.Ctx) error { + return c.JSON(fiber.Map{ + "message": "FortuneBet API V1 pre-alpha", + "version": "1.0dev9", + }) + }) // Auth Routes a.fiber.Post("/auth/login", h.LoginCustomer) a.fiber.Post("/auth/refresh", h.RefreshToken) @@ -146,6 +152,7 @@ func (a *App) initAppRoutes() { a.fiber.Get("/events/:id", h.GetUpcomingEventByID) a.fiber.Delete("/events/:id", a.authMiddleware, a.SuperAdminOnly, h.SetEventStatusToRemoved) a.fiber.Get("/top-leagues", h.GetTopLeagues) + a.fiber.Get("/events/:id/flag", h.UpdateEventFlagged) // Leagues a.fiber.Get("/leagues", h.GetAllLeagues) @@ -315,8 +322,8 @@ func (a *App) initAppRoutes() { group.Get("/virtual-game/favorites", a.authMiddleware, h.ListFavorites) //Issue Reporting Routes - group.Post("/issues", a.authMiddleware, a.OnlyAdminAndAbove, h.CreateIssue) - group.Get("/issues/customer/:customer_id", a.authMiddleware, a.OnlyAdminAndAbove, h.GetCustomerIssues) + group.Post("/issues", a.authMiddleware, h.CreateIssue) //anyone who has logged can report a + group.Get("/issues/customer/:customer_id", a.authMiddleware, a.OnlyAdminAndAbove, h.GetUserIssues) group.Get("/issues", a.authMiddleware, a.OnlyAdminAndAbove, h.GetAllIssues) group.Patch("/issues/:issue_id/status", a.authMiddleware, a.OnlyAdminAndAbove, h.UpdateIssueStatus) group.Delete("/issues/:issue_id", a.authMiddleware, a.OnlyAdminAndAbove, h.DeleteIssue) diff --git a/makefile b/makefile index b46d3cd..ebca4d1 100644 --- a/makefile +++ b/makefile @@ -47,6 +47,7 @@ postgres: backup: @mkdir -p backup @docker exec -t fortunebet-backend-postgres-1 pg_dumpall -c -U root | gzip > backup/dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql.gz + restore: @echo "Restoring latest backup..." gunzip -c $(file) | docker exec -i fortunebet-backend-postgres-1 psql -U root -d gh