data type and enable/disable provider fixes
This commit is contained in:
commit
3624acbacb
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,3 +9,4 @@ logs/
|
|||
app_logs/
|
||||
backup/
|
||||
reports/
|
||||
exports/
|
||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -1,8 +1,11 @@
|
|||
{
|
||||
"cSpell.words": [
|
||||
"Cashout",
|
||||
"dbgen",
|
||||
"jackc",
|
||||
"narg",
|
||||
"notificationservice",
|
||||
"pgtype",
|
||||
"sqlc"
|
||||
],
|
||||
"cSpell.enabledFileTypes": {
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ func main() {
|
|||
authSvc := authentication.NewService(store, store, cfg.RefreshExpiry)
|
||||
userSvc := user.NewService(store, store, messengerSvc, cfg)
|
||||
eventSvc := event.New(cfg.Bet365Token, store, domain.MongoDBLogger)
|
||||
oddsSvc := odds.New(store, cfg, logger, domain.MongoDBLogger)
|
||||
oddsSvc := odds.New(store, cfg, eventSvc, logger, domain.MongoDBLogger)
|
||||
notificationRepo := repository.NewNotificationRepository(store)
|
||||
virtuaGamesRepo := repository.NewVirtualGameRepository(store)
|
||||
notificationSvc := notificationservice.New(notificationRepo, domain.MongoDBLogger, logger, cfg, messengerSvc, userSvc)
|
||||
|
|
|
|||
|
|
@ -1,59 +1,222 @@
|
|||
BEGIN;
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
-- Users
|
||||
INSERT INTO users (
|
||||
id, first_name, last_name, email, phone_number, password, role,
|
||||
email_verified, phone_verified, created_at, updated_at, suspended, company_id
|
||||
) VALUES
|
||||
(1, 'John', 'Doe', 'john.doe@example.com', NULL,
|
||||
crypt('password123', gen_salt('bf'))::bytea, 'customer',
|
||||
TRUE, FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL),
|
||||
|
||||
(2, 'Test', 'Admin', 'test.admin@gmail.com', '0988554466',
|
||||
crypt('password123', gen_salt('bf'))::bytea, 'admin',
|
||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, 1),
|
||||
|
||||
(3, 'Samuel', 'Tariku', 'cybersamt@gmail.com', '0911111111',
|
||||
crypt('password@123', gen_salt('bf'))::bytea, 'super_admin',
|
||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL),
|
||||
|
||||
(4, 'Kirubel', 'Kibru', 'kirubel.jkl679@gmail.com', '0911554486',
|
||||
crypt('password@123', gen_salt('bf'))::bytea, 'super_admin',
|
||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL);
|
||||
|
||||
id,
|
||||
first_name,
|
||||
last_name,
|
||||
email,
|
||||
phone_number,
|
||||
password,
|
||||
role,
|
||||
email_verified,
|
||||
phone_verified,
|
||||
created_at,
|
||||
updated_at,
|
||||
suspended,
|
||||
company_id
|
||||
)
|
||||
VALUES (
|
||||
1,
|
||||
'John',
|
||||
'Doe',
|
||||
'john.doe@example.com',
|
||||
NULL,
|
||||
crypt('password@123', gen_salt('bf'))::bytea,
|
||||
'customer',
|
||||
TRUE,
|
||||
FALSE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP,
|
||||
FALSE,
|
||||
NULL
|
||||
),
|
||||
(
|
||||
2,
|
||||
'Test',
|
||||
'Admin',
|
||||
'test.admin@gmail.com',
|
||||
'0988554466',
|
||||
crypt('password123', gen_salt('bf'))::bytea,
|
||||
'admin',
|
||||
TRUE,
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP,
|
||||
FALSE,
|
||||
1
|
||||
),
|
||||
(
|
||||
3,
|
||||
'Samuel',
|
||||
'Tariku',
|
||||
'cybersamt@gmail.com',
|
||||
'0911111111',
|
||||
crypt('password@123', gen_salt('bf'))::bytea,
|
||||
'super_admin',
|
||||
TRUE,
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP,
|
||||
FALSE,
|
||||
NULL
|
||||
),
|
||||
(
|
||||
4,
|
||||
'Kirubel',
|
||||
'Kibru',
|
||||
'kirubel.jkl679@gmail.com',
|
||||
'0911554486',
|
||||
crypt('password@123', gen_salt('bf'))::bytea,
|
||||
'super_admin',
|
||||
TRUE,
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP,
|
||||
FALSE,
|
||||
NULL
|
||||
),
|
||||
(
|
||||
5,
|
||||
'Test',
|
||||
'Veli',
|
||||
'test.veli@example.com',
|
||||
NULL,
|
||||
crypt('password@123', gen_salt('bf'))::bytea,
|
||||
'customer',
|
||||
TRUE,
|
||||
FALSE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP,
|
||||
FALSE,
|
||||
NULL
|
||||
);
|
||||
-- Supported Operations
|
||||
INSERT INTO supported_operations (id, name, description) VALUES
|
||||
(1, 'SportBook', 'Sportbook operations'),
|
||||
(2, 'Virtual', 'Virtual operations');
|
||||
|
||||
INSERT INTO supported_operations (id, name, description)
|
||||
VALUES (1, 'SportBook', 'Sportbook operations'),
|
||||
(2, 'Virtual', 'Virtual operations');
|
||||
-- Wallets
|
||||
INSERT INTO wallets (
|
||||
id, balance, is_withdraw, is_bettable, is_transferable, user_id,
|
||||
type, currency, is_active, created_at, updated_at
|
||||
) VALUES
|
||||
(1, 10000, TRUE, TRUE, TRUE, 1, 'regular', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(2, 5000, FALSE, TRUE, TRUE, 1, 'static', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(3, 20000, TRUE, TRUE, TRUE, 2, 'company_main', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(4, 15000, TRUE, TRUE, TRUE, 2, 'branch_main', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||
|
||||
id,
|
||||
balance,
|
||||
is_withdraw,
|
||||
is_bettable,
|
||||
is_transferable,
|
||||
user_id,
|
||||
type,
|
||||
currency,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
1,
|
||||
10000,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
1,
|
||||
'regular',
|
||||
'ETB',
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
),
|
||||
(
|
||||
2,
|
||||
5000,
|
||||
FALSE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
1,
|
||||
'static',
|
||||
'ETB',
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
),
|
||||
(
|
||||
3,
|
||||
20000,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
2,
|
||||
'company_main',
|
||||
'ETB',
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
),
|
||||
(
|
||||
4,
|
||||
15000,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
2,
|
||||
'branch_main',
|
||||
'ETB',
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
);
|
||||
-- Customer Wallets
|
||||
INSERT INTO customer_wallets (id, customer_id, regular_wallet_id, static_wallet_id)
|
||||
INSERT INTO customer_wallets (
|
||||
id,
|
||||
customer_id,
|
||||
regular_wallet_id,
|
||||
static_wallet_id
|
||||
)
|
||||
VALUES (1, 1, 1, 2);
|
||||
|
||||
-- Company
|
||||
INSERT INTO companies (
|
||||
id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
||||
) VALUES
|
||||
(1, 'Test Company', 2, 3, 0.10, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||
|
||||
id,
|
||||
name,
|
||||
slug,
|
||||
admin_id,
|
||||
wallet_id,
|
||||
deducted_percentage,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
1,
|
||||
'FortuneBets',
|
||||
'fortunebets',
|
||||
2,
|
||||
3,
|
||||
0.10,
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
);
|
||||
-- Branch
|
||||
INSERT INTO branches (
|
||||
id, name, location, wallet_id, branch_manager_id, company_id,
|
||||
is_self_owned, profit_percent, is_active, created_at, updated_at
|
||||
) VALUES
|
||||
(1, 'Test Branch', 'addis_ababa', 4, 2, 1, TRUE, 0.10, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||
|
||||
id,
|
||||
name,
|
||||
location,
|
||||
wallet_id,
|
||||
branch_manager_id,
|
||||
company_id,
|
||||
is_self_owned,
|
||||
profit_percent,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
1,
|
||||
'Test Branch',
|
||||
'addis_ababa',
|
||||
4,
|
||||
2,
|
||||
1,
|
||||
TRUE,
|
||||
0.10,
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
);
|
||||
COMMIT;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ CREATE TABLE IF NOT EXISTS users (
|
|||
CHECK (
|
||||
email IS NOT NULL
|
||||
OR phone_number IS NOT NULL
|
||||
)
|
||||
),
|
||||
UNIQUE(email, company_id),
|
||||
UNIQUE (phone_number, company_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS virtual_game_providers (
|
||||
|
|
@ -30,10 +32,10 @@ CREATE TABLE IF NOT EXISTS virtual_game_providers (
|
|||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS wallets (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
balance BIGINT NOT NULL DEFAULT 0,
|
||||
currency VARCHAR(3) NOT NULL DEFAULT 'ETB',
|
||||
is_withdraw BOOLEAN NOT NULL,
|
||||
is_bettable BOOLEAN NOT NULL,
|
||||
is_transferable BOOLEAN NOT NULL,
|
||||
|
|
@ -43,7 +45,6 @@ CREATE TABLE IF NOT EXISTS wallets (
|
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE refresh_tokens (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL,
|
||||
|
|
@ -53,26 +54,6 @@ CREATE TABLE refresh_tokens (
|
|||
revoked BOOLEAN DEFAULT FALSE NOT NULL,
|
||||
CONSTRAINT unique_token UNIQUE (token)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE direct_deposits (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
customer_id BIGINT NOT NULL REFERENCES users(id),
|
||||
wallet_id BIGINT NOT NULL REFERENCES wallets(id),
|
||||
amount NUMERIC(15, 2) NOT NULL,
|
||||
bank_reference TEXT NOT NULL,
|
||||
sender_account TEXT NOT NULL,
|
||||
status TEXT NOT NULL CHECK (status IN ('pending', 'completed', 'rejected')),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
verified_by BIGINT REFERENCES users(id),
|
||||
verification_notes TEXT,
|
||||
verified_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_direct_deposits_status ON direct_deposits(status);
|
||||
CREATE INDEX idx_direct_deposits_customer ON direct_deposits(customer_id);
|
||||
CREATE INDEX idx_direct_deposits_reference ON direct_deposits(bank_reference);
|
||||
|
||||
-----
|
||||
CREATE TABLE otps (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
|
|
@ -87,6 +68,7 @@ CREATE TABLE otps (
|
|||
);
|
||||
CREATE TABLE IF NOT EXISTS bets (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
company_id BIGINT NOT NULL,
|
||||
amount BIGINT NOT NULL,
|
||||
total_odds REAL NOT NULL,
|
||||
status INT NOT NULL,
|
||||
|
|
@ -101,6 +83,7 @@ CREATE TABLE IF NOT EXISTS bets (
|
|||
);
|
||||
CREATE TABLE IF NOT EXISTS tickets (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
company_id BIGINT NOT NULL,
|
||||
amount BIGINT NOT NULL,
|
||||
total_odds REAL NOT NULL,
|
||||
IP VARCHAR(255) NOT NULL,
|
||||
|
|
@ -122,14 +105,14 @@ CREATE TABLE IF NOT EXISTS bet_outcomes (
|
|||
sport_id BIGINT NOT NULL,
|
||||
event_id BIGINT NOT null,
|
||||
odd_id BIGINT NOT NULL,
|
||||
home_team_name VARCHAR(255) NOT NULL,
|
||||
away_team_name VARCHAR(255) NOT NULL,
|
||||
home_team_name TEXT NOT NULL,
|
||||
away_team_name TEXT NOT NULL,
|
||||
market_id BIGINT NOT NULL,
|
||||
market_name VARCHAR(255) NOT NULL,
|
||||
market_name TEXT NOT NULL,
|
||||
odd REAL NOT NULL,
|
||||
odd_name VARCHAR(255) NOT NULL,
|
||||
odd_header VARCHAR(255) NOT NULL,
|
||||
odd_handicap VARCHAR(255) NOT NULL,
|
||||
odd_name TEXT NOT NULL,
|
||||
odd_header TEXT NOT NULL,
|
||||
odd_handicap TEXT NOT NULL,
|
||||
status INT NOT NULL DEFAULT 0,
|
||||
expires TIMESTAMP NOT NULL
|
||||
);
|
||||
|
|
@ -138,14 +121,14 @@ CREATE TABLE IF NOT EXISTS ticket_outcomes (
|
|||
ticket_id BIGINT NOT NULL,
|
||||
event_id BIGINT NOT null,
|
||||
odd_id BIGINT NOT NULL,
|
||||
home_team_name VARCHAR(255) NOT NULL,
|
||||
away_team_name VARCHAR(255) NOT NULL,
|
||||
home_team_name TEXT NOT NULL,
|
||||
away_team_name TEXT NOT NULL,
|
||||
market_id BIGINT NOT NULL,
|
||||
market_name VARCHAR(255) NOT NULL,
|
||||
market_name TEXT NOT NULL,
|
||||
odd REAL NOT NULL,
|
||||
odd_name VARCHAR(255) NOT NULL,
|
||||
odd_header VARCHAR(255) NOT NULL,
|
||||
odd_handicap VARCHAR(255) NOT NULL,
|
||||
odd_name TEXT NOT NULL,
|
||||
odd_header TEXT NOT NULL,
|
||||
odd_handicap TEXT NOT NULL,
|
||||
status INT NOT NULL DEFAULT 0,
|
||||
expires TIMESTAMP NOT NULL
|
||||
);
|
||||
|
|
@ -194,7 +177,7 @@ CREATE TABLE IF NOT EXISTS customer_wallets (
|
|||
CREATE TABLE IF NOT EXISTS wallet_transfer (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
amount BIGINT,
|
||||
message VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
type VARCHAR(255),
|
||||
receiver_wallet_id BIGINT,
|
||||
sender_wallet_id BIGINT,
|
||||
|
|
@ -288,54 +271,115 @@ CREATE TABLE IF NOT EXISTS branch_locations (
|
|||
);
|
||||
CREATE TABLE events (
|
||||
id TEXT PRIMARY KEY,
|
||||
sport_id INT,
|
||||
match_name TEXT,
|
||||
home_team TEXT,
|
||||
away_team TEXT,
|
||||
home_team_id INT,
|
||||
away_team_id INT,
|
||||
home_kit_image TEXT,
|
||||
away_kit_image TEXT,
|
||||
league_id INT,
|
||||
league_name TEXT,
|
||||
league_cc TEXT,
|
||||
start_time TIMESTAMP,
|
||||
sport_id INT NOT NULL,
|
||||
match_name TEXT NOT NULL,
|
||||
home_team TEXT NOT NULL,
|
||||
away_team TEXT NOT NULL,
|
||||
home_team_id BIGINT NOT NULL,
|
||||
away_team_id BIGINT NOT NULL,
|
||||
home_kit_image TEXT NOT NULL,
|
||||
away_kit_image TEXT NOT NULL,
|
||||
league_id BIGINT NOT NULL,
|
||||
league_name TEXT NOT NULL,
|
||||
start_time TIMESTAMP NOT NULL,
|
||||
score TEXT,
|
||||
match_minute INT,
|
||||
timer_status TEXT,
|
||||
added_time INT,
|
||||
match_period INT,
|
||||
is_live BOOLEAN,
|
||||
status TEXT,
|
||||
is_live BOOLEAN NOT NULL DEFAULT false,
|
||||
status TEXT NOT NULL,
|
||||
fetched_at TIMESTAMP DEFAULT now(),
|
||||
source TEXT DEFAULT 'b365api',
|
||||
is_featured BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE
|
||||
source TEXT NOT NULL DEFAULT 'b365api' CHECK (
|
||||
source IN (
|
||||
'b365api',
|
||||
'bfair',
|
||||
'1xbet',
|
||||
'bwin',
|
||||
'enetpulse'
|
||||
)
|
||||
),
|
||||
default_is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
default_is_featured BOOLEAN NOT NULL DEFAULT false,
|
||||
default_winning_upper_limit INT NOT NULL,
|
||||
is_monitored BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
UNIQUE(id, source)
|
||||
);
|
||||
CREATE TABLE odds (
|
||||
id SERIAL PRIMARY KEY,
|
||||
event_id TEXT,
|
||||
fi TEXT,
|
||||
CREATE TABLE event_history (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
event_id TEXT NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE TABLE company_event_settings (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
company_id BIGINT NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
is_active BOOLEAN,
|
||||
is_featured BOOLEAN,
|
||||
winning_upper_limit INT,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(company_id, event_id)
|
||||
);
|
||||
CREATE TABLE odds_market (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
event_id TEXT NOT NULL,
|
||||
market_type TEXT NOT NULL,
|
||||
market_name TEXT,
|
||||
market_category TEXT,
|
||||
market_id TEXT,
|
||||
name TEXT,
|
||||
handicap TEXT,
|
||||
odds_value DOUBLE PRECISION,
|
||||
section TEXT NOT NULL,
|
||||
category TEXT,
|
||||
raw_odds JSONB,
|
||||
market_name TEXT NOT NULL,
|
||||
market_category TEXT NOT NULL,
|
||||
market_id TEXT NOT NULL,
|
||||
raw_odds JSONB NOT NULL,
|
||||
default_is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
fetched_at TIMESTAMP DEFAULT now(),
|
||||
source TEXT DEFAULT 'b365api',
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
UNIQUE (market_id, name, handicap),
|
||||
UNIQUE (event_id, market_id, name, handicap),
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
UNIQUE (event_id, market_id)
|
||||
);
|
||||
CREATE TABLE odd_history (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
odds_market_id BIGINT NOT NULL REFERENCES odds_market(id),
|
||||
raw_odd_id BIGINT NOT NULL,
|
||||
market_id TEXT NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
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 TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE TABLE company_odd_settings (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
company_id BIGINT NOT NULL,
|
||||
odds_market_id BIGINT NOT NULL,
|
||||
is_active BOOLEAN,
|
||||
custom_raw_odds JSONB,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(company_id, odds_market_id)
|
||||
);
|
||||
CREATE TABLE result_log (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
status_not_finished_count INT NOT NULL,
|
||||
status_not_finished_bets INT NOT NULL,
|
||||
status_to_be_fixed_count INT NOT NULL,
|
||||
status_to_be_fixed_bets INT NOT NULL,
|
||||
status_postponed_count INT NOT NULL,
|
||||
status_postponed_bets INT NOT NULL,
|
||||
status_ended_count INT NOT NULL,
|
||||
status_ended_bets INT NOT NULL,
|
||||
status_removed_count INT NOT NULL,
|
||||
status_removed_bets INT NOT NULL,
|
||||
removed_count INT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE TABLE companies (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
slug TEXT UNIQUE NOT NULL,
|
||||
admin_id BIGINT NOT NULL,
|
||||
wallet_id BIGINT NOT NULL,
|
||||
deducted_percentage REAL NOT NULL,
|
||||
|
|
@ -350,35 +394,53 @@ CREATE TABLE companies (
|
|||
CREATE TABLE leagues (
|
||||
id BIGINT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
img TEXT,
|
||||
img_url TEXT,
|
||||
country_code TEXT,
|
||||
bet365_id INT,
|
||||
sport_id INT NOT NULL,
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
is_featured BOOLEAN DEFAULT false
|
||||
default_is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
default_is_featured BOOLEAN NOT NULL DEFAULT false
|
||||
);
|
||||
CREATE TABLE company_league_settings (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
company_id BIGINT NOT NULL,
|
||||
league_id BIGINT NOT NULL,
|
||||
is_active BOOLEAN,
|
||||
is_featured BOOLEAN,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(league_id, company_id)
|
||||
);
|
||||
CREATE TABLE teams (
|
||||
id TEXT PRIMARY KEY,
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
team_name TEXT NOT NULL,
|
||||
country TEXT,
|
||||
bet365_id INT,
|
||||
logo_url TEXT
|
||||
country_code TEXT NOT NULL,
|
||||
bet365_id BIGINT,
|
||||
img_url TEXT
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
CREATE TABLE IF NOT EXISTS global_settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
-- Tenant/Company-specific overrides
|
||||
CREATE TABLE IF NOT EXISTS company_settings (
|
||||
company_id BIGINT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
||||
key TEXT NOT NULL,
|
||||
value TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (company_id, key)
|
||||
);
|
||||
CREATE TABLE bonus (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
multiplier REAL NOT NULL,
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
balance_cap BIGINT NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE TABLE flags (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
bet_id BIGINT REFERENCES bets(id) ON DELETE CASCADE,
|
||||
odd_id BIGINT REFERENCES odds(id),
|
||||
odds_market_id BIGINT REFERENCES odds_market(id),
|
||||
reason TEXT,
|
||||
flagged_at TIMESTAMP DEFAULT NOW(),
|
||||
resolved BOOLEAN DEFAULT FALSE,
|
||||
|
|
@ -386,14 +448,30 @@ CREATE TABLE flags (
|
|||
CHECK (
|
||||
(
|
||||
bet_id IS NOT NULL
|
||||
AND odd_id IS NULL
|
||||
AND odds_market_id IS NULL
|
||||
)
|
||||
OR (
|
||||
bet_id IS NULL
|
||||
AND odd_id IS NOT NULL
|
||||
AND odds_market_id IS NOT NULL
|
||||
)
|
||||
)
|
||||
);
|
||||
CREATE TABLE direct_deposits (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
customer_id BIGINT NOT NULL REFERENCES users(id),
|
||||
wallet_id BIGINT NOT NULL REFERENCES wallets(id),
|
||||
amount NUMERIC(15, 2) NOT NULL,
|
||||
bank_reference TEXT NOT NULL,
|
||||
sender_account TEXT NOT NULL,
|
||||
status TEXT NOT NULL CHECK (status IN ('pending', 'completed', 'rejected')),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
verified_by BIGINT REFERENCES users(id),
|
||||
verification_notes TEXT,
|
||||
verified_at TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_direct_deposits_status ON direct_deposits(status);
|
||||
CREATE INDEX idx_direct_deposits_customer ON direct_deposits(customer_id);
|
||||
CREATE INDEX idx_direct_deposits_reference ON direct_deposits(bank_reference);
|
||||
-- Views
|
||||
CREATE VIEW companies_details AS
|
||||
SELECT companies.*,
|
||||
|
|
@ -512,17 +590,64 @@ SELECT sd.*,
|
|||
st.verified AS transaction_verified
|
||||
FROM shop_deposits AS sd
|
||||
JOIN shop_transactions st ON st.id = sd.shop_transaction_id;
|
||||
CREATE VIEW league_with_settings AS
|
||||
SELECT l.*,
|
||||
cls.company_id,
|
||||
COALESCE(cls.is_active, l.default_is_active) AS is_active,
|
||||
COALESCE(cls.is_featured, l.default_is_featured) AS is_featured,
|
||||
cls.updated_at
|
||||
FROM leagues l
|
||||
JOIN company_league_settings cls ON l.id = cls.league_id;
|
||||
CREATE VIEW event_with_settings AS
|
||||
SELECT e.*,
|
||||
ces.company_id,
|
||||
COALESCE(ces.is_active, e.default_is_active) AS is_active,
|
||||
COALESCE(ces.is_featured, e.default_is_featured) AS is_featured,
|
||||
COALESCE(
|
||||
ces.winning_upper_limit,
|
||||
e.default_winning_upper_limit
|
||||
) AS winning_upper_limit,
|
||||
ces.updated_at,
|
||||
l.country_code as league_cc
|
||||
FROM events e
|
||||
JOIN company_event_settings ces ON e.id = ces.event_id
|
||||
JOIN leagues l ON l.id = e.league_id;
|
||||
CREATE VIEW event_with_country AS
|
||||
SELECT events.*,
|
||||
leagues.country_code as league_cc
|
||||
FROM events
|
||||
LEFT JOIN leagues ON leagues.id = events.league_id;
|
||||
CREATE VIEW odds_market_with_settings AS
|
||||
SELECT o.id,
|
||||
o.event_id,
|
||||
o.market_type,
|
||||
o.market_name,
|
||||
o.market_category,
|
||||
o.market_id,
|
||||
o.default_is_active,
|
||||
o.fetched_at,
|
||||
o.expires_at,
|
||||
cos.company_id,
|
||||
COALESCE(cos.is_active, o.default_is_active) AS is_active,
|
||||
COALESCE(cos.custom_raw_odds, o.raw_odds) AS raw_odds,
|
||||
cos.updated_at
|
||||
FROM odds_market o
|
||||
JOIN company_odd_settings cos ON o.id = cos.odds_market_id;
|
||||
CREATE VIEW odds_market_with_event AS
|
||||
SELECT o.*,
|
||||
e.is_monitored,
|
||||
e.is_live,
|
||||
e.status,
|
||||
e.source
|
||||
FROM odds_market o
|
||||
JOIN events e ON o.event_id = e.id;
|
||||
-- Foreign Keys
|
||||
ALTER TABLE users
|
||||
ADD CONSTRAINT unique_email UNIQUE (email),
|
||||
ADD CONSTRAINT unique_phone_number UNIQUE (phone_number);
|
||||
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);
|
||||
ALTER TABLE wallets
|
||||
ADD CONSTRAINT fk_wallets_users FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
ADD COLUMN currency VARCHAR(3) NOT NULL DEFAULT 'ETB';
|
||||
ADD CONSTRAINT fk_wallets_users FOREIGN KEY (user_id) REFERENCES users(id);
|
||||
ALTER TABLE customer_wallets
|
||||
ADD CONSTRAINT fk_customer_wallets_customers FOREIGN KEY (customer_id) REFERENCES users(id),
|
||||
ADD CONSTRAINT fk_customer_wallets_regular_wallet FOREIGN KEY (regular_wallet_id) REFERENCES wallets(id),
|
||||
|
|
@ -553,3 +678,12 @@ ADD CONSTRAINT fk_branch_cashiers_users FOREIGN KEY (user_id) REFERENCES users(i
|
|||
ALTER TABLE companies
|
||||
ADD CONSTRAINT fk_companies_admin FOREIGN KEY (admin_id) REFERENCES users(id),
|
||||
ADD CONSTRAINT fk_companies_wallet FOREIGN KEY (wallet_id) REFERENCES wallets(id) ON DELETE CASCADE;
|
||||
ALTER TABLE company_league_settings
|
||||
ADD CONSTRAINT fk_league_settings_company FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||
ADD CONSTRAINT fk_league_settings_league FOREIGN KEY (league_id) REFERENCES leagues(id) ON DELETE CASCADE;
|
||||
ALTER TABLE company_event_settings
|
||||
ADD CONSTRAINT fk_event_settings_company FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||
ADD CONSTRAINT fk_event_settings_event FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE;
|
||||
ALTER TABLE company_odd_settings
|
||||
ADD CONSTRAINT fk_odds_settings_company FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||
ADD CONSTRAINT fk_odds_settings_odds_market FOREIGN KEY (odds_market_id) REFERENCES odds_market(id) ON DELETE CASCADE;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
-- Settings Initial Data
|
||||
INSERT INTO settings (key, value)
|
||||
VALUES ('sms_provider', '30'),
|
||||
INSERT INTO global_settings (key, value)
|
||||
VALUES ('sms_provider', 'afro_message'),
|
||||
('max_number_of_outcomes', '30'),
|
||||
('bet_amount_limit', '10000000'),
|
||||
('daily_ticket_limit', '50'),
|
||||
|
|
|
|||
|
|
@ -1,58 +1,218 @@
|
|||
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
-- Users
|
||||
INSERT INTO users (
|
||||
id, first_name, last_name, email, phone_number, password, role,
|
||||
email_verified, phone_verified, created_at, updated_at, suspended, company_id
|
||||
) VALUES
|
||||
(1, 'John', 'Doe', 'john.doe@example.com', NULL,
|
||||
crypt('password123', gen_salt('bf'))::bytea, 'customer',
|
||||
TRUE, FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL),
|
||||
|
||||
(2, 'Test', 'Admin', 'test.admin@gmail.com', '0988554466',
|
||||
crypt('password123', gen_salt('bf'))::bytea, 'admin',
|
||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, 1),
|
||||
|
||||
(3, 'Samuel', 'Tariku', 'cybersamt@gmail.com', '0911111111',
|
||||
crypt('password@123', gen_salt('bf'))::bytea, 'super_admin',
|
||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL),
|
||||
|
||||
(4, 'Kirubel', 'Kibru', 'kirubel.jkl679@gmail.com', '0911554486',
|
||||
crypt('password@123', gen_salt('bf'))::bytea, 'super_admin',
|
||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL);
|
||||
|
||||
id,
|
||||
first_name,
|
||||
last_name,
|
||||
email,
|
||||
phone_number,
|
||||
password,
|
||||
role,
|
||||
email_verified,
|
||||
phone_verified,
|
||||
created_at,
|
||||
updated_at,
|
||||
suspended,
|
||||
company_id
|
||||
)
|
||||
VALUES (
|
||||
1,
|
||||
'John',
|
||||
'Doe',
|
||||
'john.doe@example.com',
|
||||
NULL,
|
||||
crypt('password123', gen_salt('bf'))::bytea,
|
||||
'customer',
|
||||
TRUE,
|
||||
FALSE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP,
|
||||
FALSE,
|
||||
NULL
|
||||
),
|
||||
(
|
||||
2,
|
||||
'Test',
|
||||
'Admin',
|
||||
'test.admin@gmail.com',
|
||||
'0988554466',
|
||||
crypt('password123', gen_salt('bf'))::bytea,
|
||||
'admin',
|
||||
TRUE,
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP,
|
||||
FALSE,
|
||||
1
|
||||
),
|
||||
(
|
||||
3,
|
||||
'Samuel',
|
||||
'Tariku',
|
||||
'cybersamt@gmail.com',
|
||||
'0911111111',
|
||||
crypt('password@123', gen_salt('bf'))::bytea,
|
||||
'super_admin',
|
||||
TRUE,
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP,
|
||||
FALSE,
|
||||
NULL
|
||||
),
|
||||
(
|
||||
4,
|
||||
'Kirubel',
|
||||
'Kibru',
|
||||
'kirubel.jkl679@gmail.com',
|
||||
'0911554486',
|
||||
crypt('password@123', gen_salt('bf'))::bytea,
|
||||
'super_admin',
|
||||
TRUE,
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP,
|
||||
FALSE,
|
||||
NULL
|
||||
),
|
||||
(
|
||||
5,
|
||||
'Test',
|
||||
'Veli',
|
||||
'test.veli@example.com',
|
||||
NULL,
|
||||
crypt('password@123', gen_salt('bf'))::bytea,
|
||||
'customer',
|
||||
TRUE,
|
||||
FALSE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP,
|
||||
FALSE,
|
||||
NULL
|
||||
);
|
||||
-- Supported Operations
|
||||
INSERT INTO supported_operations (id, name, description) VALUES
|
||||
(1, 'SportBook', 'Sportbook operations'),
|
||||
(2, 'Virtual', 'Virtual operations');
|
||||
|
||||
INSERT INTO supported_operations (id, name, description)
|
||||
VALUES (1, 'SportBook', 'Sportbook operations'),
|
||||
(2, 'Virtual', 'Virtual operations');
|
||||
-- Wallets
|
||||
INSERT INTO wallets (
|
||||
id, balance, is_withdraw, is_bettable, is_transferable, user_id,
|
||||
type, currency, is_active, created_at, updated_at
|
||||
) VALUES
|
||||
(1, 10000, TRUE, TRUE, TRUE, 1, 'regular', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(2, 5000, FALSE, TRUE, TRUE, 1, 'static', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(3, 20000, TRUE, TRUE, TRUE, 2, 'company_main', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||
(4, 15000, TRUE, TRUE, TRUE, 2, 'branch_main', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||
|
||||
id,
|
||||
balance,
|
||||
is_withdraw,
|
||||
is_bettable,
|
||||
is_transferable,
|
||||
user_id,
|
||||
type,
|
||||
currency,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
1,
|
||||
10000,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
1,
|
||||
'regular',
|
||||
'ETB',
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
),
|
||||
(
|
||||
2,
|
||||
5000,
|
||||
FALSE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
1,
|
||||
'static',
|
||||
'ETB',
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
),
|
||||
(
|
||||
3,
|
||||
20000,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
2,
|
||||
'company_main',
|
||||
'ETB',
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
),
|
||||
(
|
||||
4,
|
||||
15000,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
2,
|
||||
'branch_main',
|
||||
'ETB',
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
);
|
||||
-- Customer Wallets
|
||||
INSERT INTO customer_wallets (id, customer_id, regular_wallet_id, static_wallet_id)
|
||||
INSERT INTO customer_wallets (
|
||||
id,
|
||||
customer_id,
|
||||
regular_wallet_id,
|
||||
static_wallet_id
|
||||
)
|
||||
VALUES (1, 1, 1, 2);
|
||||
|
||||
-- Company
|
||||
INSERT INTO companies (
|
||||
id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
||||
) VALUES
|
||||
(1, 'Test Company', 2, 3, 0.10, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||
|
||||
id,
|
||||
name,
|
||||
admin_id,
|
||||
wallet_id,
|
||||
deducted_percentage,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
1,
|
||||
'Test Company',
|
||||
2,
|
||||
3,
|
||||
0.10,
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
);
|
||||
-- Branch
|
||||
INSERT INTO branches (
|
||||
id, name, location, wallet_id, branch_manager_id, company_id,
|
||||
is_self_owned, profit_percent, is_active, created_at, updated_at
|
||||
) VALUES
|
||||
(1, 'Test Branch', 'addis_ababa', 4, 2, 1, TRUE, 0.10, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||
|
||||
|
||||
|
||||
id,
|
||||
name,
|
||||
location,
|
||||
wallet_id,
|
||||
branch_manager_id,
|
||||
company_id,
|
||||
is_self_owned,
|
||||
profit_percent,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
1,
|
||||
'Test Branch',
|
||||
'addis_ababa',
|
||||
4,
|
||||
2,
|
||||
1,
|
||||
TRUE,
|
||||
0.10,
|
||||
TRUE,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
);
|
||||
|
|
@ -1,12 +1,17 @@
|
|||
-- name: GetUserByEmailPhone :one
|
||||
SELECT *
|
||||
FROM users
|
||||
WHERE email = $1
|
||||
OR phone_number = $2;
|
||||
WHERE (
|
||||
email = $1
|
||||
OR phone_number = $2
|
||||
)
|
||||
AND (
|
||||
company_id = sqlc.narg('company_id')
|
||||
OR sqlc.narg('company_id') IS NULL
|
||||
);
|
||||
-- name: CreateRefreshToken :exec
|
||||
INSERT INTO refresh_tokens (user_id, token, expires_at, created_at, revoked)
|
||||
VALUES ($1, $2, $3, $4, $5);
|
||||
|
||||
-- name: GetRefreshToken :one
|
||||
SELECT *
|
||||
FROM refresh_tokens
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ INSERT INTO bets (
|
|||
user_id,
|
||||
is_shop_bet,
|
||||
outcomes_hash,
|
||||
fast_code
|
||||
fast_code,
|
||||
company_id
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||
RETURNING *;
|
||||
-- name: CreateBetOutcome :copyfrom
|
||||
INSERT INTO bet_outcomes (
|
||||
|
|
@ -52,6 +53,10 @@ wHERE (
|
|||
is_shop_bet = sqlc.narg('is_shop_bet')
|
||||
OR sqlc.narg('is_shop_bet') IS NULL
|
||||
)
|
||||
AND (
|
||||
company_id = sqlc.narg('company_id')
|
||||
OR sqlc.narg('company_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
cashed_out = sqlc.narg('cashed_out')
|
||||
OR sqlc.narg('cashed_out') IS NULL
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
-- name: CreateCompany :one
|
||||
INSERT INTO companies (
|
||||
name,
|
||||
slug,
|
||||
admin_id,
|
||||
wallet_id,
|
||||
deducted_percentage
|
||||
)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING *;
|
||||
-- name: GetAllCompanies :many
|
||||
SELECT *
|
||||
|
|
@ -29,6 +30,10 @@ WHERE (
|
|||
SELECT *
|
||||
FROM companies_details
|
||||
WHERE id = $1;
|
||||
-- name: GetCompanyIDUsingSlug :one
|
||||
SELECT id
|
||||
FROM companies
|
||||
WHERE slug = $1;
|
||||
-- name: SearchCompanyByName :many
|
||||
SELECT *
|
||||
FROM companies_details
|
||||
|
|
|
|||
35
db/query/custom_odds.sql
Normal file
35
db/query/custom_odds.sql
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
-- -- name: InsertCustomOddsMarket :one
|
||||
-- INSERT INTO custom_odds_market (
|
||||
-- odds_market_id,
|
||||
-- company_id,
|
||||
-- event_id,
|
||||
-- raw_odds
|
||||
-- )
|
||||
-- VALUES ($1, $2, $3, $4)
|
||||
-- RETURNING *;
|
||||
-- -- name: GetAllCustomOdds :many
|
||||
-- SELECT *
|
||||
-- FROM custom_odds_market
|
||||
-- WHERE (
|
||||
-- company_id = sqlc.narg('company_id')
|
||||
-- OR sqlc.narg('company_id') IS NULL
|
||||
-- );
|
||||
-- -- name: GetCustomOddByID :one
|
||||
-- SELECT *
|
||||
-- FROM custom_odds_market
|
||||
-- WHERE id = $1;
|
||||
-- -- name: GetCustomOddByOddID :one
|
||||
-- SELECT *
|
||||
-- FROM custom_odds_market
|
||||
-- WHERE odds_market_id = $1
|
||||
-- AND company_id = $2;
|
||||
-- -- name: DeleteCustomOddsByID :exec
|
||||
-- DELETE FROM custom_odds_market
|
||||
-- WHERE id = $1;
|
||||
-- -- name: DeleteCustomOddsByOddID :exec
|
||||
-- DELETE FROM custom_odds_market
|
||||
-- WHERE odds_market_id = $1
|
||||
-- AND company_id = $2;
|
||||
-- -- name: DeleteCustomOddByEventID :exec
|
||||
-- DELETE FROM custom_odds_market
|
||||
-- WHERE event_id = $1;
|
||||
26
db/query/disabled_odds.sql
Normal file
26
db/query/disabled_odds.sql
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
-- 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;
|
||||
36
db/query/event_history.sql
Normal file
36
db/query/event_history.sql
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
-- name: InsertEventHistory :one
|
||||
INSERT INTO event_history (event_id, status)
|
||||
VALUES ($1, $2)
|
||||
RETURNING *;
|
||||
-- name: GetAllEventHistory :many
|
||||
SELECT *
|
||||
FROM event_history
|
||||
WHERE (
|
||||
event_id = sqlc.narg('event_id')
|
||||
OR sqlc.narg('event_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at > sqlc.narg('created_before')
|
||||
OR sqlc.narg('created_before') IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at < sqlc.narg('created_after')
|
||||
OR sqlc.narg('created_after') IS NULL
|
||||
);
|
||||
-- name: GetInitialEventPerDay :many
|
||||
SELECT DISTINCT ON (DATE_TRUNC('day', created_at)) *
|
||||
FROM event_history
|
||||
WHERE (
|
||||
event_id = sqlc.narg('event_id')
|
||||
OR sqlc.narg('event_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at > sqlc.narg('created_before')
|
||||
OR sqlc.narg('created_before') IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at < sqlc.narg('created_after')
|
||||
OR sqlc.narg('created_after') IS NULL
|
||||
)
|
||||
ORDER BY DATE_TRUNC('day', created_at),
|
||||
created_at ASC;
|
||||
|
|
@ -11,13 +11,7 @@ INSERT INTO events (
|
|||
away_kit_image,
|
||||
league_id,
|
||||
league_name,
|
||||
league_cc,
|
||||
start_time,
|
||||
score,
|
||||
match_minute,
|
||||
timer_status,
|
||||
added_time,
|
||||
match_period,
|
||||
is_live,
|
||||
status,
|
||||
source
|
||||
|
|
@ -37,13 +31,7 @@ VALUES (
|
|||
$12,
|
||||
$13,
|
||||
$14,
|
||||
$15,
|
||||
$16,
|
||||
$17,
|
||||
$18,
|
||||
$19,
|
||||
$20,
|
||||
$21
|
||||
$15
|
||||
) ON CONFLICT (id) DO
|
||||
UPDATE
|
||||
SET sport_id = EXCLUDED.sport_id,
|
||||
|
|
@ -64,79 +52,35 @@ SET sport_id = EXCLUDED.sport_id,
|
|||
added_time = EXCLUDED.added_time,
|
||||
match_period = EXCLUDED.match_period,
|
||||
is_live = EXCLUDED.is_live,
|
||||
status = EXCLUDED.status,
|
||||
source = EXCLUDED.source,
|
||||
fetched_at = now();
|
||||
-- name: InsertUpcomingEvent :exec
|
||||
INSERT INTO events (
|
||||
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
|
||||
-- name: InsertEventSettings :exec
|
||||
INSERT INTO company_event_settings (
|
||||
company_id,
|
||||
event_id,
|
||||
is_active,
|
||||
is_featured,
|
||||
winning_upper_limit
|
||||
)
|
||||
VALUES (
|
||||
$1,
|
||||
$2,
|
||||
$3,
|
||||
$4,
|
||||
$5,
|
||||
$6,
|
||||
$7,
|
||||
$8,
|
||||
$9,
|
||||
$10,
|
||||
$11,
|
||||
$12,
|
||||
$13,
|
||||
false,
|
||||
'upcoming',
|
||||
$14
|
||||
) ON CONFLICT (id) DO
|
||||
VALUES ($1, $2, $3, $4, $5) ON CONFLICT(company_id, event_id) DO
|
||||
UPDATE
|
||||
SET sport_id = EXCLUDED.sport_id,
|
||||
match_name = EXCLUDED.match_name,
|
||||
home_team = EXCLUDED.home_team,
|
||||
away_team = EXCLUDED.away_team,
|
||||
home_team_id = EXCLUDED.home_team_id,
|
||||
away_team_id = EXCLUDED.away_team_id,
|
||||
home_kit_image = EXCLUDED.home_kit_image,
|
||||
away_kit_image = EXCLUDED.away_kit_image,
|
||||
league_id = EXCLUDED.league_id,
|
||||
league_name = EXCLUDED.league_name,
|
||||
league_cc = EXCLUDED.league_cc,
|
||||
start_time = EXCLUDED.start_time,
|
||||
is_live = false,
|
||||
status = 'upcoming',
|
||||
source = EXCLUDED.source,
|
||||
fetched_at = now();
|
||||
SET is_active = EXCLUDED.is_active,
|
||||
is_featured = EXCLUDED.is_featured,
|
||||
winning_upper_limit = EXCLUDED.winning_upper_limit;
|
||||
-- name: ListLiveEvents :many
|
||||
SELECT id
|
||||
FROM events
|
||||
FROM event_with_country
|
||||
WHERE is_live = true;
|
||||
-- name: GetAllUpcomingEvents :many
|
||||
SELECT *
|
||||
FROM events
|
||||
FROM event_with_country
|
||||
WHERE start_time > now()
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
ORDER BY start_time ASC;
|
||||
-- name: GetExpiredUpcomingEvents :many
|
||||
SELECT events.*,
|
||||
leagues.country_code as league_cc
|
||||
FROM events
|
||||
LEFT JOIN leagues ON leagues.id = league_id
|
||||
-- name: GetExpiredEvents :many
|
||||
SELECT *
|
||||
FROM event_with_country
|
||||
WHERE start_time < now()
|
||||
and (
|
||||
status = sqlc.narg('status')
|
||||
|
|
@ -145,8 +89,7 @@ WHERE start_time < now()
|
|||
ORDER BY start_time ASC;
|
||||
-- name: GetTotalEvents :one
|
||||
SELECT COUNT(*)
|
||||
FROM events
|
||||
LEFT JOIN leagues ON leagues.id = league_id
|
||||
FROM event_with_country
|
||||
WHERE is_live = false
|
||||
AND status = 'upcoming'
|
||||
AND (
|
||||
|
|
@ -154,7 +97,7 @@ WHERE is_live = false
|
|||
OR sqlc.narg('league_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
events.sport_id = sqlc.narg('sport_id')
|
||||
sport_id = sqlc.narg('sport_id')
|
||||
OR sqlc.narg('sport_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
|
|
@ -171,18 +114,12 @@ WHERE is_live = false
|
|||
OR sqlc.narg('first_start_time') IS NULL
|
||||
)
|
||||
AND (
|
||||
leagues.country_code = sqlc.narg('country_code')
|
||||
league_cc = sqlc.narg('country_code')
|
||||
OR sqlc.narg('country_code') IS NULL
|
||||
)
|
||||
AND (
|
||||
events.is_featured = sqlc.narg('is_featured')
|
||||
OR sqlc.narg('is_featured') IS NULL
|
||||
);
|
||||
-- name: GetPaginatedUpcomingEvents :many
|
||||
SELECT events.*,
|
||||
leagues.country_code as league_cc
|
||||
FROM events
|
||||
LEFT JOIN leagues ON leagues.id = league_id
|
||||
SELECT *
|
||||
FROM event_with_country
|
||||
WHERE start_time > now()
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
|
|
@ -191,7 +128,7 @@ WHERE start_time > now()
|
|||
OR sqlc.narg('league_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
events.sport_id = sqlc.narg('sport_id')
|
||||
sport_id = sqlc.narg('sport_id')
|
||||
OR sqlc.narg('sport_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
|
|
@ -208,31 +145,117 @@ WHERE start_time > now()
|
|||
OR sqlc.narg('first_start_time') IS NULL
|
||||
)
|
||||
AND (
|
||||
leagues.country_code = sqlc.narg('country_code')
|
||||
league_cc = sqlc.narg('country_code')
|
||||
OR sqlc.narg('country_code') IS NULL
|
||||
)
|
||||
ORDER BY start_time ASC
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetTotalCompanyEvents :one
|
||||
SELECT COUNT(*)
|
||||
FROM event_with_settings
|
||||
WHERE company_id = $1
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
AND (
|
||||
events.is_featured = sqlc.narg('is_featured')
|
||||
OR sqlc.narg('is_featured') IS NULL
|
||||
league_id = sqlc.narg('league_id')
|
||||
OR sqlc.narg('league_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = sqlc.narg('sport_id')
|
||||
OR sqlc.narg('sport_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
match_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||
OR league_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||
OR sqlc.narg('query') IS NULL
|
||||
)
|
||||
AND (
|
||||
start_time < sqlc.narg('last_start_time')
|
||||
OR sqlc.narg('last_start_time') IS NULL
|
||||
)
|
||||
AND (
|
||||
start_time > sqlc.narg('first_start_time')
|
||||
OR sqlc.narg('first_start_time') IS NULL
|
||||
)
|
||||
AND (
|
||||
league_cc = sqlc.narg('country_code')
|
||||
OR sqlc.narg('country_code') IS NULL
|
||||
);
|
||||
-- name: GetEventsWithSettings :many
|
||||
SELECT *
|
||||
FROM event_with_settings
|
||||
WHERE company_id = $1
|
||||
AND start_time > now()
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
AND (
|
||||
league_id = sqlc.narg('league_id')
|
||||
OR sqlc.narg('league_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = sqlc.narg('sport_id')
|
||||
OR sqlc.narg('sport_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
match_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||
OR league_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||
OR sqlc.narg('query') IS NULL
|
||||
)
|
||||
AND (
|
||||
start_time < sqlc.narg('last_start_time')
|
||||
OR sqlc.narg('last_start_time') IS NULL
|
||||
)
|
||||
AND (
|
||||
start_time > sqlc.narg('first_start_time')
|
||||
OR sqlc.narg('first_start_time') IS NULL
|
||||
)
|
||||
AND (
|
||||
league_cc = sqlc.narg('country_code')
|
||||
OR sqlc.narg('country_code') IS NULL
|
||||
)
|
||||
ORDER BY start_time ASC
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetUpcomingByID :one
|
||||
SELECT *
|
||||
FROM events
|
||||
FROM event_with_country
|
||||
WHERE id = $1
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
LIMIT 1;
|
||||
-- name: GetEventWithSettingByID :one
|
||||
SELECT *
|
||||
FROM event_with_settings
|
||||
WHERE id = $1
|
||||
AND company_id = $2
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
LIMIT 1;
|
||||
-- name: UpdateMatchResult :exec
|
||||
UPDATE events
|
||||
SET score = $1,
|
||||
status = $2
|
||||
WHERE id = $3;
|
||||
-- name: UpdateFeatured :exec
|
||||
-- name: IsEventMonitored :one
|
||||
SELECT is_monitored
|
||||
FROM events
|
||||
WHERE id = $1;
|
||||
-- name: UpdateEventMonitored :exec
|
||||
UPDATE events
|
||||
SET is_featured = $1
|
||||
SET is_monitored = $1
|
||||
WHERE id = $2;
|
||||
-- name: UpdateEventSettings :exec
|
||||
UPDATE company_event_settings
|
||||
SET is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
||||
is_featured = COALESCE(
|
||||
sqlc.narg('is_featured'),
|
||||
is_featured
|
||||
),
|
||||
winning_upper_limit = COALESCE(
|
||||
sqlc.narg('winning_upper_limit'),
|
||||
winning_upper_limit
|
||||
)
|
||||
WHERE event_id = $1
|
||||
AND company_id = $2;
|
||||
-- name: DeleteEvent :exec
|
||||
DELETE FROM events
|
||||
WHERE id = $1;
|
||||
|
|
@ -4,16 +4,55 @@ SELECT DATE_TRUNC('month', start_time) AS month,
|
|||
FROM events
|
||||
JOIN leagues ON leagues.id = events.league_id
|
||||
WHERE (
|
||||
events.is_featured = sqlc.narg('is_event_featured')
|
||||
OR sqlc.narg('is_event_featured') IS NULL
|
||||
)
|
||||
AND (
|
||||
leagues.is_featured = sqlc.narg('is_league_featured')
|
||||
OR sqlc.narg('is_league_featured') IS NULL
|
||||
)
|
||||
AND (
|
||||
events.league_id = sqlc.narg('league_id')
|
||||
OR sqlc.narg('league_id') IS NULL
|
||||
)
|
||||
GROUP BY month
|
||||
ORDER BY month;
|
||||
-- name: GetLeagueEventStat :many
|
||||
SELECT leagues.id,
|
||||
leagues.name,
|
||||
COUNT(*) AS total_events,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'pending'
|
||||
) AS pending,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'in_play'
|
||||
) AS in_play,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'to_be_fixed'
|
||||
) AS to_be_fixed,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'ended'
|
||||
) AS ended,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'postponed'
|
||||
) AS postponed,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'cancelled'
|
||||
) AS cancelled,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'walkover'
|
||||
) AS walkover,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'interrupted'
|
||||
) AS interrupted,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'abandoned'
|
||||
) AS abandoned,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'retired'
|
||||
) AS retired,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'suspended'
|
||||
) AS suspended,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'decided_by_fa'
|
||||
) AS decided_by_fa,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'removed'
|
||||
) AS removed
|
||||
FROM leagues
|
||||
JOIN events ON leagues.id = events.league_id
|
||||
GROUP BY leagues.id,
|
||||
leagues.name;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
-- name: CreateFlag :one
|
||||
INSERT INTO flags (
|
||||
bet_id,
|
||||
odd_id,
|
||||
odds_market_id,
|
||||
reason
|
||||
) VALUES (
|
||||
$1, $2, $3
|
||||
|
|
|
|||
|
|
@ -5,25 +5,28 @@ INSERT INTO leagues (
|
|||
country_code,
|
||||
bet365_id,
|
||||
sport_id,
|
||||
is_active,
|
||||
is_featured
|
||||
default_is_active,
|
||||
default_is_featured
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (id) DO
|
||||
UPDATE
|
||||
SET name = EXCLUDED.name,
|
||||
country_code = EXCLUDED.country_code,
|
||||
bet365_id = EXCLUDED.bet365_id,
|
||||
is_active = EXCLUDED.is_active,
|
||||
is_featured = EXCLUDED.is_featured,
|
||||
sport_id = EXCLUDED.sport_id;
|
||||
-- name: InsertLeagueSettings :exec
|
||||
INSERT INTO company_league_settings (
|
||||
company_id,
|
||||
league_id,
|
||||
is_active,
|
||||
is_featured
|
||||
)
|
||||
VALUES ($1, $2, $3, $4) ON CONFLICT(company_id, league_id) DO
|
||||
UPDATE
|
||||
SET is_active = EXCLUDED.is_active,
|
||||
is_featured = EXCLUDED.is_featured;
|
||||
-- name: GetAllLeagues :many
|
||||
SELECT id,
|
||||
name,
|
||||
country_code,
|
||||
bet365_id,
|
||||
is_active,
|
||||
is_featured,
|
||||
sport_id
|
||||
SELECT *
|
||||
FROM leagues
|
||||
WHERE (
|
||||
country_code = sqlc.narg('country_code')
|
||||
|
|
@ -33,6 +36,20 @@ WHERE (
|
|||
sport_id = sqlc.narg('sport_id')
|
||||
OR sqlc.narg('sport_id') IS NULL
|
||||
)
|
||||
ORDER BY name ASC
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetAllLeaguesWithSettings :many
|
||||
SELECT *
|
||||
FROM league_with_settings
|
||||
WHERE (company_id = $1)
|
||||
AND (
|
||||
country_code = sqlc.narg('country_code')
|
||||
OR sqlc.narg('country_code') IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = sqlc.narg('sport_id')
|
||||
OR sqlc.narg('sport_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
is_active = sqlc.narg('is_active')
|
||||
OR sqlc.narg('is_active') IS NULL
|
||||
|
|
@ -44,21 +61,12 @@ WHERE (
|
|||
ORDER BY is_featured DESC,
|
||||
name ASC
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetFeaturedLeagues :many
|
||||
SELECT id,
|
||||
name,
|
||||
country_code,
|
||||
bet365_id,
|
||||
is_active,
|
||||
is_featured,
|
||||
sport_id
|
||||
FROM leagues
|
||||
WHERE is_featured = true;
|
||||
-- name: CheckLeagueSupport :one
|
||||
SELECT EXISTS(
|
||||
SELECT 1
|
||||
FROM leagues
|
||||
WHERE id = $1
|
||||
FROM company_league_settings
|
||||
WHERE league_id = $1
|
||||
AND company_id = $2
|
||||
AND is_active = true
|
||||
);
|
||||
-- name: UpdateLeague :exec
|
||||
|
|
@ -66,20 +74,14 @@ UPDATE leagues
|
|||
SET name = COALESCE(sqlc.narg('name'), name),
|
||||
country_code = COALESCE(sqlc.narg('country_code'), country_code),
|
||||
bet365_id = COALESCE(sqlc.narg('bet365_id'), bet365_id),
|
||||
is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
||||
is_featured = COALESCE(sqlc.narg('is_featured'), is_featured),
|
||||
sport_id = COALESCE(sqlc.narg('sport_id'), sport_id)
|
||||
WHERE id = $1;
|
||||
-- name: UpdateLeagueByBet365ID :exec
|
||||
UPDATE leagues
|
||||
SET name = COALESCE(sqlc.narg('name'), name),
|
||||
id = COALESCE(sqlc.narg('id'), id),
|
||||
country_code = COALESCE(sqlc.narg('country_code'), country_code),
|
||||
is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
||||
is_featured = COALESCE(sqlc.narg('is_featured'), is_featured),
|
||||
sport_id = COALESCE(sqlc.narg('sport_id'), sport_id)
|
||||
WHERE bet365_id = $1;
|
||||
-- name: SetLeagueActive :exec
|
||||
UPDATE leagues
|
||||
SET is_active = $2
|
||||
WHERE id = $1;
|
||||
-- name: UpdateLeagueSettings :exec
|
||||
UPDATE company_league_settings
|
||||
SET is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
||||
is_featured = COALESCE(
|
||||
sqlc.narg('is_featured'),
|
||||
is_featured
|
||||
)
|
||||
WHERE league_id = $1
|
||||
AND company_id = $2;
|
||||
66
db/query/odd_history.sql
Normal file
66
db/query/odd_history.sql
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
-- name: InsertOddHistory :one
|
||||
INSERT INTO odd_history (
|
||||
odds_market_id,
|
||||
market_id,
|
||||
raw_odd_id,
|
||||
event_id,
|
||||
odd_value
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING *;
|
||||
-- name: GetAllOddHistory :many
|
||||
SELECT *
|
||||
FROM odd_history
|
||||
WHERE (
|
||||
odds_market_id = sqlc.narg('odd_id')
|
||||
OR sqlc.narg('odd_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
market_id = sqlc.narg('market_id')
|
||||
OR sqlc.narg('market_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
raw_odd_id = sqlc.narg('raw_odd_id')
|
||||
OR sqlc.narg('raw_odd_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
event_id = sqlc.narg('event_id')
|
||||
OR sqlc.narg('event_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at > sqlc.narg('created_before')
|
||||
OR sqlc.narg('created_before') IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at < sqlc.narg('created_after')
|
||||
OR sqlc.narg('created_after') IS NULL
|
||||
);
|
||||
-- name: GetInitialOddPerDay :many
|
||||
SELECT DISTINCT ON (DATE_TRUNC($1, created_at)) *
|
||||
FROM odd_history
|
||||
WHERE (
|
||||
odds_market_id = sqlc.narg('odd_id')
|
||||
OR sqlc.narg('odd_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
market_id = sqlc.narg('market_id')
|
||||
OR sqlc.narg('market_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
raw_odd_id = sqlc.narg('raw_odd_id')
|
||||
OR sqlc.narg('raw_odd_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
event_id = sqlc.narg('event_id')
|
||||
OR sqlc.narg('event_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at > sqlc.narg('created_before')
|
||||
OR sqlc.narg('created_before') IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at < sqlc.narg('created_after')
|
||||
OR sqlc.narg('created_after') IS NULL
|
||||
)
|
||||
ORDER BY DATE_TRUNC($1, created_at),
|
||||
created_at ASC;
|
||||
|
|
@ -1,20 +1,13 @@
|
|||
-- name: InsertNonLiveOdd :exec
|
||||
INSERT INTO odds (
|
||||
-- name: InsertOddsMarket :exec
|
||||
INSERT INTO odds_market (
|
||||
event_id,
|
||||
fi,
|
||||
market_type,
|
||||
market_name,
|
||||
market_category,
|
||||
market_id,
|
||||
name,
|
||||
handicap,
|
||||
odds_value,
|
||||
section,
|
||||
category,
|
||||
raw_odds,
|
||||
is_active,
|
||||
source,
|
||||
fetched_at
|
||||
fetched_at,
|
||||
expires_at
|
||||
)
|
||||
VALUES (
|
||||
$1,
|
||||
|
|
@ -24,95 +17,69 @@ VALUES (
|
|||
$5,
|
||||
$6,
|
||||
$7,
|
||||
$8,
|
||||
$9,
|
||||
$10,
|
||||
$11,
|
||||
$12,
|
||||
$13,
|
||||
$14,
|
||||
$15
|
||||
$8
|
||||
) ON CONFLICT (event_id, market_id) DO
|
||||
UPDATE
|
||||
SET odds_value = EXCLUDED.odds_value,
|
||||
raw_odds = EXCLUDED.raw_odds,
|
||||
market_type = EXCLUDED.market_type,
|
||||
SET market_type = EXCLUDED.market_type,
|
||||
market_name = EXCLUDED.market_name,
|
||||
market_category = EXCLUDED.market_category,
|
||||
name = EXCLUDED.name,
|
||||
handicap = EXCLUDED.handicap,
|
||||
raw_odds = EXCLUDED.raw_odds,
|
||||
fetched_at = EXCLUDED.fetched_at,
|
||||
is_active = EXCLUDED.is_active,
|
||||
source = EXCLUDED.source,
|
||||
fi = EXCLUDED.fi;
|
||||
-- name: GetPrematchOdds :many
|
||||
SELECT event_id,
|
||||
fi,
|
||||
market_type,
|
||||
market_name,
|
||||
market_category,
|
||||
market_id,
|
||||
name,
|
||||
handicap,
|
||||
odds_value,
|
||||
section,
|
||||
category,
|
||||
raw_odds,
|
||||
fetched_at,
|
||||
source,
|
||||
is_active
|
||||
FROM odds
|
||||
WHERE is_active = true
|
||||
AND source = 'bet365';
|
||||
-- name: GetALLPrematchOdds :many
|
||||
SELECT event_id,
|
||||
fi,
|
||||
market_type,
|
||||
market_name,
|
||||
market_category,
|
||||
market_id,
|
||||
name,
|
||||
handicap,
|
||||
odds_value,
|
||||
section,
|
||||
category,
|
||||
raw_odds,
|
||||
fetched_at,
|
||||
source,
|
||||
is_active
|
||||
FROM odds
|
||||
WHERE is_active = true
|
||||
AND source = 'bet365';
|
||||
-- name: GetRawOddsByMarketID :one
|
||||
SELECT id,
|
||||
market_name,
|
||||
handicap,
|
||||
raw_odds,
|
||||
fetched_at
|
||||
FROM odds
|
||||
expires_at = EXCLUDED.expires_at;
|
||||
-- name: InsertOddSettings :exec
|
||||
INSERT INTO company_odd_settings (
|
||||
company_id,
|
||||
odds_market_id,
|
||||
is_active,
|
||||
custom_raw_odds
|
||||
)
|
||||
VALUES ($1, $2, $3, $4) ON CONFLICT (company_id, odds_market_id) DO
|
||||
UPDATE
|
||||
SET is_active = EXCLUDED.is_active,
|
||||
custom_raw_odds = EXCLUDED.custom_raw_odds;
|
||||
-- name: GetAllOdds :many
|
||||
SELECT *
|
||||
FROM odds_market_with_event
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetAllOddsWithSettings :many
|
||||
SELECT *
|
||||
FROM odds_market_with_settings
|
||||
WHERE company_id = $1
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetOddsByMarketID :one
|
||||
SELECT *
|
||||
FROM odds_market_with_event
|
||||
WHERE market_id = $1
|
||||
AND fi = $2
|
||||
AND is_active = true
|
||||
AND source = 'bet365';
|
||||
-- name: GetPrematchOddsByUpcomingID :many
|
||||
SELECT o.*
|
||||
FROM odds o
|
||||
JOIN events e ON o.fi = e.id
|
||||
WHERE e.id = $1
|
||||
AND e.is_live = false
|
||||
AND e.status = 'upcoming'
|
||||
AND o.is_active = true
|
||||
AND o.source = 'bet365';
|
||||
-- name: GetPaginatedPrematchOddsByUpcomingID :many
|
||||
SELECT o.*
|
||||
FROM odds o
|
||||
JOIN events e ON o.fi = e.id
|
||||
WHERE e.id = $1
|
||||
AND e.is_live = false
|
||||
AND e.status = 'upcoming'
|
||||
AND o.is_active = true
|
||||
AND o.source = 'bet365'
|
||||
AND event_id = $2;
|
||||
-- name: GetOddsWithSettingsByMarketID :one
|
||||
SELECT *
|
||||
FROM odds_market_with_settings
|
||||
WHERE market_id = $1
|
||||
AND event_id = $2
|
||||
AND company_id = $3;
|
||||
-- name: GetOddsByEventID :many
|
||||
SELECT *
|
||||
FROM odds_market_with_event
|
||||
WHERE event_id = $1
|
||||
AND (
|
||||
is_live = sqlc.narg('is_live')
|
||||
OR sqlc.narg('is_live') IS NULL
|
||||
)
|
||||
AND (
|
||||
status = sqlc.narg('status')
|
||||
OR sqlc.narg('status') IS NULL
|
||||
)
|
||||
AND (
|
||||
source = sqlc.narg('source')
|
||||
OR sqlc.narg('source') IS NULL
|
||||
)
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetOddsWithSettingsByEventID :many
|
||||
SELECT *
|
||||
FROM odds_market_with_settings
|
||||
WHERE event_id = $1
|
||||
AND company_id = $2
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: DeleteOddsForEvent :exec
|
||||
DELETE FROM odds
|
||||
Where fi = $1;
|
||||
DELETE FROM odds_market
|
||||
Where event_id = $1;
|
||||
28
db/query/result_log.sql
Normal file
28
db/query/result_log.sql
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
-- name: CreateResultLog :one
|
||||
INSERT INTO result_log (
|
||||
status_not_finished_count,
|
||||
status_not_finished_bets,
|
||||
status_to_be_fixed_count,
|
||||
status_to_be_fixed_bets,
|
||||
status_postponed_count,
|
||||
status_postponed_bets,
|
||||
status_ended_count,
|
||||
status_ended_bets,
|
||||
status_removed_count,
|
||||
status_removed_bets,
|
||||
removed_count
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||
RETURNING *;
|
||||
-- name: GetAllResultLog :many
|
||||
SELECT *
|
||||
FROM result_log
|
||||
WHERE (
|
||||
created_at < sqlc.narg('created_before')
|
||||
OR sqlc.narg('created_before') IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at > sqlc.narg('created_after')
|
||||
OR sqlc.narg('created_after') IS NULL
|
||||
)
|
||||
ORDER BY created_at DESC;
|
||||
|
|
@ -1,13 +1,41 @@
|
|||
-- name: GetSettings :many
|
||||
-- name: GetGlobalSettings :many
|
||||
SELECT *
|
||||
FROM settings;
|
||||
-- name: GetSetting :one
|
||||
FROM global_settings;
|
||||
-- name: GetGlobalSetting :one
|
||||
SELECT *
|
||||
FROM settings
|
||||
FROM global_settings
|
||||
WHERE key = $1;
|
||||
-- name: SaveSetting :one
|
||||
INSERT INTO settings (key, value, updated_at)
|
||||
VALUES ($1, $2, CURRENT_TIMESTAMP) ON CONFLICT (key) DO
|
||||
-- name: UpdateGlobalSetting :exec
|
||||
UPDATE global_settings
|
||||
SET value = $2,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE key = $1;
|
||||
-- name: InsertCompanySetting :exec
|
||||
INSERT INTO company_settings (company_id, key, value)
|
||||
VALUES ($1, $2, $3) ON CONFLICT (company_id, key) DO
|
||||
UPDATE
|
||||
SET value = EXCLUDED.value
|
||||
RETURNING *;
|
||||
SET value = EXCLUDED.value;
|
||||
-- name: GetAllCompanySettings :many
|
||||
SELECT *
|
||||
FROM company_settings;
|
||||
-- name: GetCompanySetting :many
|
||||
SELECT *
|
||||
FROM company_settings
|
||||
WHERE company_id = $1;
|
||||
-- name: GetCompanySettingsByKey :many
|
||||
SELECT *
|
||||
FROM company_settings
|
||||
WHERE key = $1;
|
||||
-- name: GetOverrideSettings :many
|
||||
SELECT gs.*,
|
||||
COALESCE(cs.value, gs.value) AS value
|
||||
FROM global_settings gs
|
||||
LEFT JOIN company_settings cs ON cs.key = gs.key
|
||||
AND cs.company_id = $1;
|
||||
-- name: DeleteCompanySetting :exec
|
||||
DELETE FROM company_settings
|
||||
WHERE company_id = $1
|
||||
AND key = $2;
|
||||
-- name: DeleteAllCompanySetting :exec
|
||||
DELETE FROM company_settings
|
||||
WHERE company_id = $1;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
-- name: CreateTicket :one
|
||||
INSERT INTO tickets (amount, total_odds, ip)
|
||||
VALUES ($1, $2, $3)
|
||||
INSERT INTO tickets (amount, total_odds, ip, company_id)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING *;
|
||||
-- name: CreateTicketOutcome :copyfrom
|
||||
INSERT INTO ticket_outcomes (
|
||||
|
|
@ -33,7 +33,11 @@ VALUES (
|
|||
);
|
||||
-- name: GetAllTickets :many
|
||||
SELECT *
|
||||
FROM ticket_with_outcomes;
|
||||
FROM ticket_with_outcomes
|
||||
WHERE (
|
||||
company_id = sqlc.narg('company_id')
|
||||
OR sqlc.narg('company_id') IS NULL
|
||||
);
|
||||
-- name: GetTicketByID :one
|
||||
SELECT *
|
||||
FROM ticket_with_outcomes
|
||||
|
|
@ -60,6 +64,7 @@ where created_at < now() - interval '1 day';
|
|||
Delete from ticket_outcomes
|
||||
where ticket_id = $1;
|
||||
-- name: GetAllTicketsInRange :one
|
||||
SELECT COUNT(*) as total_tickets, COALESCE(SUM(amount), 0) as total_amount
|
||||
SELECT COUNT(*) as total_tickets,
|
||||
COALESCE(SUM(amount), 0) as total_amount
|
||||
FROM tickets
|
||||
WHERE created_at BETWEEN $1 AND $2;
|
||||
|
|
@ -107,18 +107,15 @@ SELECT id,
|
|||
suspended_at,
|
||||
company_id
|
||||
FROM users
|
||||
WHERE (
|
||||
first_name ILIKE '%' || $1 || '%'
|
||||
OR last_name ILIKE '%' || $1 || '%'
|
||||
OR phone_number LIKE '%' || $1 || '%'
|
||||
WHERE (company_id = $1)
|
||||
AND (
|
||||
first_name ILIKE '%' || $2 || '%'
|
||||
OR last_name ILIKE '%' || $2 || '%'
|
||||
OR phone_number LIKE '%' || $2 || '%'
|
||||
)
|
||||
AND (
|
||||
role = sqlc.narg('role')
|
||||
OR sqlc.narg('role') IS NULL
|
||||
)
|
||||
AND (
|
||||
company_id = sqlc.narg('company_id')
|
||||
OR sqlc.narg('company_id') IS NULL
|
||||
);
|
||||
-- name: UpdateUser :exec
|
||||
UPDATE users
|
||||
|
|
@ -146,12 +143,14 @@ SELECT EXISTS (
|
|||
FROM users
|
||||
WHERE users.phone_number = $1
|
||||
AND users.phone_number IS NOT NULL
|
||||
AND users.company_id = $2
|
||||
) AS phone_exists,
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM users
|
||||
WHERE users.email = $2
|
||||
WHERE users.email = $3
|
||||
AND users.email IS NOT NULL
|
||||
AND users.company_id = $2
|
||||
) AS email_exists;
|
||||
-- name: GetUserByEmail :one
|
||||
SELECT id,
|
||||
|
|
@ -168,7 +167,8 @@ SELECT id,
|
|||
suspended_at,
|
||||
company_id
|
||||
FROM users
|
||||
WHERE email = $1;
|
||||
WHERE email = $1
|
||||
AND company_id = $2;
|
||||
-- name: GetUserByPhone :one
|
||||
SELECT id,
|
||||
first_name,
|
||||
|
|
@ -184,7 +184,8 @@ SELECT id,
|
|||
suspended_at,
|
||||
company_id
|
||||
FROM users
|
||||
WHERE phone_number = $1;
|
||||
WHERE phone_number = $1
|
||||
AND company_id = $2;
|
||||
-- name: UpdatePassword :exec
|
||||
UPDATE users
|
||||
SET password = $1,
|
||||
|
|
@ -192,6 +193,7 @@ SET password = $1,
|
|||
WHERE (
|
||||
email = $2
|
||||
OR phone_number = $3
|
||||
AND company_id = $4
|
||||
);
|
||||
-- name: GetAdminByCompanyID :one
|
||||
SELECT users.*
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ services:
|
|||
retries: 5
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./exports:/exports
|
||||
|
||||
mongo:
|
||||
container_name: fortunebet-mongo
|
||||
|
|
|
|||
|
|
@ -78,17 +78,24 @@ func (q *Queries) GetRefreshTokenByUserID(ctx context.Context, userID int64) (Re
|
|||
const GetUserByEmailPhone = `-- name: GetUserByEmailPhone :one
|
||||
SELECT id, first_name, last_name, email, phone_number, role, password, email_verified, phone_verified, created_at, updated_at, company_id, suspended_at, suspended, referral_code, referred_by
|
||||
FROM users
|
||||
WHERE email = $1
|
||||
OR phone_number = $2
|
||||
WHERE (
|
||||
email = $1
|
||||
OR phone_number = $2
|
||||
)
|
||||
AND (
|
||||
company_id = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
`
|
||||
|
||||
type GetUserByEmailPhoneParams struct {
|
||||
Email pgtype.Text `json:"email"`
|
||||
PhoneNumber pgtype.Text `json:"phone_number"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetUserByEmailPhone(ctx context.Context, arg GetUserByEmailPhoneParams) (User, error) {
|
||||
row := q.db.QueryRow(ctx, GetUserByEmailPhone, arg.Email, arg.PhoneNumber)
|
||||
row := q.db.QueryRow(ctx, GetUserByEmailPhone, arg.Email, arg.PhoneNumber, arg.CompanyID)
|
||||
var i User
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
|
|
|
|||
|
|
@ -19,10 +19,11 @@ INSERT INTO bets (
|
|||
user_id,
|
||||
is_shop_bet,
|
||||
outcomes_hash,
|
||||
fast_code
|
||||
fast_code,
|
||||
company_id
|
||||
)
|
||||
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, processed, created_at, updated_at
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||
RETURNING id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateBetParams struct {
|
||||
|
|
@ -33,6 +34,7 @@ type CreateBetParams struct {
|
|||
IsShopBet bool `json:"is_shop_bet"`
|
||||
OutcomesHash string `json:"outcomes_hash"`
|
||||
FastCode string `json:"fast_code"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, error) {
|
||||
|
|
@ -44,10 +46,12 @@ func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, erro
|
|||
arg.IsShopBet,
|
||||
arg.OutcomesHash,
|
||||
arg.FastCode,
|
||||
arg.CompanyID,
|
||||
)
|
||||
var i Bet
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.Amount,
|
||||
&i.TotalOdds,
|
||||
&i.Status,
|
||||
|
|
@ -100,7 +104,7 @@ func (q *Queries) DeleteBetOutcome(ctx context.Context, betID int64) error {
|
|||
}
|
||||
|
||||
const GetAllBets = `-- name: GetAllBets :many
|
||||
SELECT id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
||||
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
||||
FROM bet_with_outcomes
|
||||
wHERE (
|
||||
user_id = $1
|
||||
|
|
@ -111,27 +115,32 @@ wHERE (
|
|||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
cashed_out = $3
|
||||
company_id = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
AND (
|
||||
full_name ILIKE '%' || $4 || '%'
|
||||
OR phone_number ILIKE '%' || $4 || '%'
|
||||
cashed_out = $4
|
||||
OR $4 IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at > $5
|
||||
full_name ILIKE '%' || $5 || '%'
|
||||
OR phone_number ILIKE '%' || $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 {
|
||||
UserID pgtype.Int8 `json:"user_id"`
|
||||
IsShopBet pgtype.Bool `json:"is_shop_bet"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
CashedOut pgtype.Bool `json:"cashed_out"`
|
||||
Query pgtype.Text `json:"query"`
|
||||
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||
|
|
@ -142,6 +151,7 @@ func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWi
|
|||
rows, err := q.db.Query(ctx, GetAllBets,
|
||||
arg.UserID,
|
||||
arg.IsShopBet,
|
||||
arg.CompanyID,
|
||||
arg.CashedOut,
|
||||
arg.Query,
|
||||
arg.CreatedBefore,
|
||||
|
|
@ -156,6 +166,7 @@ func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWi
|
|||
var i BetWithOutcome
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.Amount,
|
||||
&i.TotalOdds,
|
||||
&i.Status,
|
||||
|
|
@ -182,7 +193,7 @@ func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWi
|
|||
}
|
||||
|
||||
const GetBetByFastCode = `-- name: GetBetByFastCode :one
|
||||
SELECT id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
||||
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
||||
FROM bet_with_outcomes
|
||||
WHERE fast_code = $1
|
||||
LIMIT 1
|
||||
|
|
@ -193,6 +204,7 @@ func (q *Queries) GetBetByFastCode(ctx context.Context, fastCode string) (BetWit
|
|||
var i BetWithOutcome
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.Amount,
|
||||
&i.TotalOdds,
|
||||
&i.Status,
|
||||
|
|
@ -212,7 +224,7 @@ func (q *Queries) GetBetByFastCode(ctx context.Context, fastCode string) (BetWit
|
|||
}
|
||||
|
||||
const GetBetByID = `-- name: GetBetByID :one
|
||||
SELECT id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
||||
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
||||
FROM bet_with_outcomes
|
||||
WHERE id = $1
|
||||
`
|
||||
|
|
@ -222,6 +234,7 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, err
|
|||
var i BetWithOutcome
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.Amount,
|
||||
&i.TotalOdds,
|
||||
&i.Status,
|
||||
|
|
@ -241,7 +254,7 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, err
|
|||
}
|
||||
|
||||
const GetBetByUserID = `-- name: GetBetByUserID :many
|
||||
SELECT id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
||||
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
||||
FROM bet_with_outcomes
|
||||
WHERE user_id = $1
|
||||
`
|
||||
|
|
@ -257,6 +270,7 @@ func (q *Queries) GetBetByUserID(ctx context.Context, userID int64) ([]BetWithOu
|
|||
var i BetWithOutcome
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.Amount,
|
||||
&i.TotalOdds,
|
||||
&i.Status,
|
||||
|
|
@ -424,7 +438,7 @@ func (q *Queries) GetBetOutcomeCountByOddID(ctx context.Context, oddID int64) (i
|
|||
}
|
||||
|
||||
const GetBetsForCashback = `-- name: GetBetsForCashback :many
|
||||
SELECT id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
||||
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
||||
FROM bet_with_outcomes
|
||||
WHERE status = 2
|
||||
AND processed = false
|
||||
|
|
@ -441,6 +455,7 @@ func (q *Queries) GetBetsForCashback(ctx context.Context) ([]BetWithOutcome, err
|
|||
var i BetWithOutcome
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.Amount,
|
||||
&i.TotalOdds,
|
||||
&i.Status,
|
||||
|
|
|
|||
|
|
@ -14,16 +14,18 @@ import (
|
|||
const CreateCompany = `-- name: CreateCompany :one
|
||||
INSERT INTO companies (
|
||||
name,
|
||||
slug,
|
||||
admin_id,
|
||||
wallet_id,
|
||||
deducted_percentage
|
||||
)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateCompanyParams struct {
|
||||
Name string `json:"name"`
|
||||
Slug string `json:"slug"`
|
||||
AdminID int64 `json:"admin_id"`
|
||||
WalletID int64 `json:"wallet_id"`
|
||||
DeductedPercentage float32 `json:"deducted_percentage"`
|
||||
|
|
@ -32,6 +34,7 @@ type CreateCompanyParams struct {
|
|||
func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (Company, error) {
|
||||
row := q.db.QueryRow(ctx, CreateCompany,
|
||||
arg.Name,
|
||||
arg.Slug,
|
||||
arg.AdminID,
|
||||
arg.WalletID,
|
||||
arg.DeductedPercentage,
|
||||
|
|
@ -40,6 +43,7 @@ func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (C
|
|||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Slug,
|
||||
&i.AdminID,
|
||||
&i.WalletID,
|
||||
&i.DeductedPercentage,
|
||||
|
|
@ -61,7 +65,7 @@ func (q *Queries) DeleteCompany(ctx context.Context, id int64) error {
|
|||
}
|
||||
|
||||
const GetAllCompanies = `-- name: GetAllCompanies :many
|
||||
SELECT id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||
SELECT id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||
FROM companies_details
|
||||
WHERE (
|
||||
name ILIKE '%' || $1 || '%'
|
||||
|
|
@ -98,6 +102,7 @@ func (q *Queries) GetAllCompanies(ctx context.Context, arg GetAllCompaniesParams
|
|||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Slug,
|
||||
&i.AdminID,
|
||||
&i.WalletID,
|
||||
&i.DeductedPercentage,
|
||||
|
|
@ -121,7 +126,7 @@ func (q *Queries) GetAllCompanies(ctx context.Context, arg GetAllCompaniesParams
|
|||
}
|
||||
|
||||
const GetCompanyByID = `-- name: GetCompanyByID :one
|
||||
SELECT id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||
SELECT id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||
FROM companies_details
|
||||
WHERE id = $1
|
||||
`
|
||||
|
|
@ -132,6 +137,7 @@ func (q *Queries) GetCompanyByID(ctx context.Context, id int64) (CompaniesDetail
|
|||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Slug,
|
||||
&i.AdminID,
|
||||
&i.WalletID,
|
||||
&i.DeductedPercentage,
|
||||
|
|
@ -147,8 +153,21 @@ func (q *Queries) GetCompanyByID(ctx context.Context, id int64) (CompaniesDetail
|
|||
return i, err
|
||||
}
|
||||
|
||||
const GetCompanyIDUsingSlug = `-- name: GetCompanyIDUsingSlug :one
|
||||
SELECT id
|
||||
FROM companies
|
||||
WHERE slug = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetCompanyIDUsingSlug(ctx context.Context, slug string) (int64, error) {
|
||||
row := q.db.QueryRow(ctx, GetCompanyIDUsingSlug, slug)
|
||||
var id int64
|
||||
err := row.Scan(&id)
|
||||
return id, err
|
||||
}
|
||||
|
||||
const SearchCompanyByName = `-- name: SearchCompanyByName :many
|
||||
SELECT id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||
SELECT id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||
FROM companies_details
|
||||
WHERE name ILIKE '%' || $1 || '%'
|
||||
`
|
||||
|
|
@ -165,6 +184,7 @@ func (q *Queries) SearchCompanyByName(ctx context.Context, dollar_1 pgtype.Text)
|
|||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Slug,
|
||||
&i.AdminID,
|
||||
&i.WalletID,
|
||||
&i.DeductedPercentage,
|
||||
|
|
@ -198,7 +218,7 @@ SET name = COALESCE($2, name),
|
|||
),
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = $1
|
||||
RETURNING id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
||||
RETURNING id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
||||
`
|
||||
|
||||
type UpdateCompanyParams struct {
|
||||
|
|
@ -221,6 +241,7 @@ func (q *Queries) UpdateCompany(ctx context.Context, arg UpdateCompanyParams) (C
|
|||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Slug,
|
||||
&i.AdminID,
|
||||
&i.WalletID,
|
||||
&i.DeductedPercentage,
|
||||
|
|
|
|||
139
gen/db/disabled_odds.sql.go
Normal file
139
gen/db/disabled_odds.sql.go
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
// 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 string `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
|
||||
}
|
||||
133
gen/db/event_history.sql.go
Normal file
133
gen/db/event_history.sql.go
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
// source: event_history.sql
|
||||
|
||||
package dbgen
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const GetAllEventHistory = `-- name: GetAllEventHistory :many
|
||||
SELECT id, event_id, status, created_at
|
||||
FROM event_history
|
||||
WHERE (
|
||||
event_id = $1
|
||||
OR $1 IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at > $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at < $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
`
|
||||
|
||||
type GetAllEventHistoryParams struct {
|
||||
EventID pgtype.Text `json:"event_id"`
|
||||
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetAllEventHistory(ctx context.Context, arg GetAllEventHistoryParams) ([]EventHistory, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllEventHistory, arg.EventID, arg.CreatedBefore, arg.CreatedAfter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []EventHistory
|
||||
for rows.Next() {
|
||||
var i EventHistory
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
&i.Status,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetInitialEventPerDay = `-- name: GetInitialEventPerDay :many
|
||||
SELECT DISTINCT ON (DATE_TRUNC('day', created_at)) id, event_id, status, created_at
|
||||
FROM event_history
|
||||
WHERE (
|
||||
event_id = $1
|
||||
OR $1 IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at > $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at < $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
ORDER BY DATE_TRUNC('day', created_at),
|
||||
created_at ASC
|
||||
`
|
||||
|
||||
type GetInitialEventPerDayParams struct {
|
||||
EventID pgtype.Text `json:"event_id"`
|
||||
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetInitialEventPerDay(ctx context.Context, arg GetInitialEventPerDayParams) ([]EventHistory, error) {
|
||||
rows, err := q.db.Query(ctx, GetInitialEventPerDay, arg.EventID, arg.CreatedBefore, arg.CreatedAfter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []EventHistory
|
||||
for rows.Next() {
|
||||
var i EventHistory
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
&i.Status,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const InsertEventHistory = `-- name: InsertEventHistory :one
|
||||
INSERT INTO event_history (event_id, status)
|
||||
VALUES ($1, $2)
|
||||
RETURNING id, event_id, status, created_at
|
||||
`
|
||||
|
||||
type InsertEventHistoryParams struct {
|
||||
EventID string `json:"event_id"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
func (q *Queries) InsertEventHistory(ctx context.Context, arg InsertEventHistoryParams) (EventHistory, error) {
|
||||
row := q.db.QueryRow(ctx, InsertEventHistory, arg.EventID, arg.Status)
|
||||
var i EventHistory
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
&i.Status,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -11,40 +11,131 @@ import (
|
|||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const GetLeagueEventStat = `-- name: GetLeagueEventStat :many
|
||||
SELECT leagues.id,
|
||||
leagues.name,
|
||||
COUNT(*) AS total_events,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'pending'
|
||||
) AS pending,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'in_play'
|
||||
) AS in_play,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'to_be_fixed'
|
||||
) AS to_be_fixed,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'ended'
|
||||
) AS ended,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'postponed'
|
||||
) AS postponed,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'cancelled'
|
||||
) AS cancelled,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'walkover'
|
||||
) AS walkover,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'interrupted'
|
||||
) AS interrupted,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'abandoned'
|
||||
) AS abandoned,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'retired'
|
||||
) AS retired,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'suspended'
|
||||
) AS suspended,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'decided_by_fa'
|
||||
) AS decided_by_fa,
|
||||
COUNT(*) FILTER (
|
||||
WHERE events.status = 'removed'
|
||||
) AS removed
|
||||
FROM leagues
|
||||
JOIN events ON leagues.id = events.league_id
|
||||
GROUP BY leagues.id,
|
||||
leagues.name
|
||||
`
|
||||
|
||||
type GetLeagueEventStatRow struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
TotalEvents int64 `json:"total_events"`
|
||||
Pending int64 `json:"pending"`
|
||||
InPlay int64 `json:"in_play"`
|
||||
ToBeFixed int64 `json:"to_be_fixed"`
|
||||
Ended int64 `json:"ended"`
|
||||
Postponed int64 `json:"postponed"`
|
||||
Cancelled int64 `json:"cancelled"`
|
||||
Walkover int64 `json:"walkover"`
|
||||
Interrupted int64 `json:"interrupted"`
|
||||
Abandoned int64 `json:"abandoned"`
|
||||
Retired int64 `json:"retired"`
|
||||
Suspended int64 `json:"suspended"`
|
||||
DecidedByFa int64 `json:"decided_by_fa"`
|
||||
Removed int64 `json:"removed"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetLeagueEventStat(ctx context.Context) ([]GetLeagueEventStatRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetLeagueEventStat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetLeagueEventStatRow
|
||||
for rows.Next() {
|
||||
var i GetLeagueEventStatRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.TotalEvents,
|
||||
&i.Pending,
|
||||
&i.InPlay,
|
||||
&i.ToBeFixed,
|
||||
&i.Ended,
|
||||
&i.Postponed,
|
||||
&i.Cancelled,
|
||||
&i.Walkover,
|
||||
&i.Interrupted,
|
||||
&i.Abandoned,
|
||||
&i.Retired,
|
||||
&i.Suspended,
|
||||
&i.DecidedByFa,
|
||||
&i.Removed,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetTotalMontlyEventStat = `-- name: GetTotalMontlyEventStat :many
|
||||
SELECT DATE_TRUNC('month', start_time) AS month,
|
||||
COUNT(*) AS event_count
|
||||
FROM events
|
||||
JOIN leagues ON leagues.id = events.league_id
|
||||
WHERE (
|
||||
events.is_featured = $1
|
||||
events.league_id = $1
|
||||
OR $1 IS NULL
|
||||
)
|
||||
AND (
|
||||
leagues.is_featured = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
events.league_id = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
GROUP BY month
|
||||
ORDER BY month
|
||||
`
|
||||
|
||||
type GetTotalMontlyEventStatParams struct {
|
||||
IsEventFeatured pgtype.Bool `json:"is_event_featured"`
|
||||
IsLeagueFeatured pgtype.Bool `json:"is_league_featured"`
|
||||
LeagueID pgtype.Int4 `json:"league_id"`
|
||||
}
|
||||
|
||||
type GetTotalMontlyEventStatRow struct {
|
||||
Month pgtype.Interval `json:"month"`
|
||||
EventCount int64 `json:"event_count"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetTotalMontlyEventStat(ctx context.Context, arg GetTotalMontlyEventStatParams) ([]GetTotalMontlyEventStatRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetTotalMontlyEventStat, arg.IsEventFeatured, arg.IsLeagueFeatured, arg.LeagueID)
|
||||
func (q *Queries) GetTotalMontlyEventStat(ctx context.Context, leagueID pgtype.Int8) ([]GetTotalMontlyEventStatRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetTotalMontlyEventStat, leagueID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,26 +14,26 @@ import (
|
|||
const CreateFlag = `-- name: CreateFlag :one
|
||||
INSERT INTO flags (
|
||||
bet_id,
|
||||
odd_id,
|
||||
odds_market_id,
|
||||
reason
|
||||
) VALUES (
|
||||
$1, $2, $3
|
||||
) RETURNING id, bet_id, odd_id, reason, flagged_at, resolved
|
||||
) RETURNING id, bet_id, odds_market_id, reason, flagged_at, resolved
|
||||
`
|
||||
|
||||
type CreateFlagParams struct {
|
||||
BetID pgtype.Int8 `json:"bet_id"`
|
||||
OddID pgtype.Int8 `json:"odd_id"`
|
||||
Reason pgtype.Text `json:"reason"`
|
||||
BetID pgtype.Int8 `json:"bet_id"`
|
||||
OddsMarketID pgtype.Int8 `json:"odds_market_id"`
|
||||
Reason pgtype.Text `json:"reason"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateFlag(ctx context.Context, arg CreateFlagParams) (Flag, error) {
|
||||
row := q.db.QueryRow(ctx, CreateFlag, arg.BetID, arg.OddID, arg.Reason)
|
||||
row := q.db.QueryRow(ctx, CreateFlag, arg.BetID, arg.OddsMarketID, arg.Reason)
|
||||
var i Flag
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.BetID,
|
||||
&i.OddID,
|
||||
&i.OddsMarketID,
|
||||
&i.Reason,
|
||||
&i.FlaggedAt,
|
||||
&i.Resolved,
|
||||
|
|
|
|||
|
|
@ -14,27 +14,27 @@ import (
|
|||
const CheckLeagueSupport = `-- name: CheckLeagueSupport :one
|
||||
SELECT EXISTS(
|
||||
SELECT 1
|
||||
FROM leagues
|
||||
WHERE id = $1
|
||||
FROM company_league_settings
|
||||
WHERE league_id = $1
|
||||
AND company_id = $2
|
||||
AND is_active = true
|
||||
)
|
||||
`
|
||||
|
||||
func (q *Queries) CheckLeagueSupport(ctx context.Context, id int64) (bool, error) {
|
||||
row := q.db.QueryRow(ctx, CheckLeagueSupport, id)
|
||||
type CheckLeagueSupportParams struct {
|
||||
LeagueID int64 `json:"league_id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) CheckLeagueSupport(ctx context.Context, arg CheckLeagueSupportParams) (bool, error) {
|
||||
row := q.db.QueryRow(ctx, CheckLeagueSupport, arg.LeagueID, arg.CompanyID)
|
||||
var exists bool
|
||||
err := row.Scan(&exists)
|
||||
return exists, err
|
||||
}
|
||||
|
||||
const GetAllLeagues = `-- name: GetAllLeagues :many
|
||||
SELECT id,
|
||||
name,
|
||||
country_code,
|
||||
bet365_id,
|
||||
is_active,
|
||||
is_featured,
|
||||
sport_id
|
||||
SELECT id, name, img_url, country_code, bet365_id, sport_id, default_is_active, default_is_featured
|
||||
FROM leagues
|
||||
WHERE (
|
||||
country_code = $1
|
||||
|
|
@ -44,44 +44,21 @@ WHERE (
|
|||
sport_id = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
is_active = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
AND (
|
||||
is_featured = $4
|
||||
OR $4 IS NULL
|
||||
)
|
||||
ORDER BY is_featured DESC,
|
||||
name ASC
|
||||
LIMIT $6 OFFSET $5
|
||||
ORDER BY name ASC
|
||||
LIMIT $4 OFFSET $3
|
||||
`
|
||||
|
||||
type GetAllLeaguesParams struct {
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
SportID pgtype.Int4 `json:"sport_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
Offset pgtype.Int4 `json:"offset"`
|
||||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
||||
type GetAllLeaguesRow struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([]GetAllLeaguesRow, error) {
|
||||
func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([]League, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllLeagues,
|
||||
arg.CountryCode,
|
||||
arg.SportID,
|
||||
arg.IsActive,
|
||||
arg.IsFeatured,
|
||||
arg.Offset,
|
||||
arg.Limit,
|
||||
)
|
||||
|
|
@ -89,17 +66,18 @@ func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([
|
|||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetAllLeaguesRow
|
||||
var items []League
|
||||
for rows.Next() {
|
||||
var i GetAllLeaguesRow
|
||||
var i League
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.ImgUrl,
|
||||
&i.CountryCode,
|
||||
&i.Bet365ID,
|
||||
&i.IsActive,
|
||||
&i.IsFeatured,
|
||||
&i.SportID,
|
||||
&i.DefaultIsActive,
|
||||
&i.DefaultIsFeatured,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -111,45 +89,71 @@ func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([
|
|||
return items, nil
|
||||
}
|
||||
|
||||
const GetFeaturedLeagues = `-- name: GetFeaturedLeagues :many
|
||||
SELECT id,
|
||||
name,
|
||||
country_code,
|
||||
bet365_id,
|
||||
is_active,
|
||||
is_featured,
|
||||
sport_id
|
||||
FROM leagues
|
||||
WHERE is_featured = true
|
||||
const GetAllLeaguesWithSettings = `-- name: GetAllLeaguesWithSettings :many
|
||||
SELECT id, name, img_url, country_code, bet365_id, sport_id, default_is_active, default_is_featured, company_id, is_active, is_featured, updated_at
|
||||
FROM league_with_settings
|
||||
WHERE (company_id = $1)
|
||||
AND (
|
||||
country_code = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
AND (
|
||||
is_active = $4
|
||||
OR $4 IS NULL
|
||||
)
|
||||
AND (
|
||||
is_featured = $5
|
||||
OR $5 IS NULL
|
||||
)
|
||||
ORDER BY is_featured DESC,
|
||||
name ASC
|
||||
LIMIT $7 OFFSET $6
|
||||
`
|
||||
|
||||
type GetFeaturedLeaguesRow struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
type GetAllLeaguesWithSettingsParams struct {
|
||||
CompanyID int64 `json:"company_id"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
SportID pgtype.Int4 `json:"sport_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
Offset pgtype.Int4 `json:"offset"`
|
||||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetFeaturedLeagues(ctx context.Context) ([]GetFeaturedLeaguesRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetFeaturedLeagues)
|
||||
func (q *Queries) GetAllLeaguesWithSettings(ctx context.Context, arg GetAllLeaguesWithSettingsParams) ([]LeagueWithSetting, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllLeaguesWithSettings,
|
||||
arg.CompanyID,
|
||||
arg.CountryCode,
|
||||
arg.SportID,
|
||||
arg.IsActive,
|
||||
arg.IsFeatured,
|
||||
arg.Offset,
|
||||
arg.Limit,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetFeaturedLeaguesRow
|
||||
var items []LeagueWithSetting
|
||||
for rows.Next() {
|
||||
var i GetFeaturedLeaguesRow
|
||||
var i LeagueWithSetting
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.ImgUrl,
|
||||
&i.CountryCode,
|
||||
&i.Bet365ID,
|
||||
&i.SportID,
|
||||
&i.DefaultIsActive,
|
||||
&i.DefaultIsFeatured,
|
||||
&i.CompanyID,
|
||||
&i.IsActive,
|
||||
&i.IsFeatured,
|
||||
&i.SportID,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -168,27 +172,25 @@ INSERT INTO leagues (
|
|||
country_code,
|
||||
bet365_id,
|
||||
sport_id,
|
||||
is_active,
|
||||
is_featured
|
||||
default_is_active,
|
||||
default_is_featured
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (id) DO
|
||||
UPDATE
|
||||
SET name = EXCLUDED.name,
|
||||
country_code = EXCLUDED.country_code,
|
||||
bet365_id = EXCLUDED.bet365_id,
|
||||
is_active = EXCLUDED.is_active,
|
||||
is_featured = EXCLUDED.is_featured,
|
||||
sport_id = EXCLUDED.sport_id
|
||||
`
|
||||
|
||||
type InsertLeagueParams struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
}
|
||||
|
||||
func (q *Queries) InsertLeague(ctx context.Context, arg InsertLeagueParams) error {
|
||||
|
|
@ -198,25 +200,39 @@ func (q *Queries) InsertLeague(ctx context.Context, arg InsertLeagueParams) erro
|
|||
arg.CountryCode,
|
||||
arg.Bet365ID,
|
||||
arg.SportID,
|
||||
arg.IsActive,
|
||||
arg.IsFeatured,
|
||||
arg.DefaultIsActive,
|
||||
arg.DefaultIsFeatured,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const SetLeagueActive = `-- name: SetLeagueActive :exec
|
||||
UPDATE leagues
|
||||
SET is_active = $2
|
||||
WHERE id = $1
|
||||
const InsertLeagueSettings = `-- name: InsertLeagueSettings :exec
|
||||
INSERT INTO company_league_settings (
|
||||
company_id,
|
||||
league_id,
|
||||
is_active,
|
||||
is_featured
|
||||
)
|
||||
VALUES ($1, $2, $3, $4) ON CONFLICT(company_id, league_id) DO
|
||||
UPDATE
|
||||
SET is_active = EXCLUDED.is_active,
|
||||
is_featured = EXCLUDED.is_featured
|
||||
`
|
||||
|
||||
type SetLeagueActiveParams struct {
|
||||
ID int64 `json:"id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
type InsertLeagueSettingsParams struct {
|
||||
CompanyID int64 `json:"company_id"`
|
||||
LeagueID int64 `json:"league_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
}
|
||||
|
||||
func (q *Queries) SetLeagueActive(ctx context.Context, arg SetLeagueActiveParams) error {
|
||||
_, err := q.db.Exec(ctx, SetLeagueActive, arg.ID, arg.IsActive)
|
||||
func (q *Queries) InsertLeagueSettings(ctx context.Context, arg InsertLeagueSettingsParams) error {
|
||||
_, err := q.db.Exec(ctx, InsertLeagueSettings,
|
||||
arg.CompanyID,
|
||||
arg.LeagueID,
|
||||
arg.IsActive,
|
||||
arg.IsFeatured,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -225,9 +241,7 @@ UPDATE leagues
|
|||
SET name = COALESCE($2, name),
|
||||
country_code = COALESCE($3, country_code),
|
||||
bet365_id = COALESCE($4, bet365_id),
|
||||
is_active = COALESCE($5, is_active),
|
||||
is_featured = COALESCE($6, is_featured),
|
||||
sport_id = COALESCE($7, sport_id)
|
||||
sport_id = COALESCE($5, sport_id)
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
|
|
@ -236,8 +250,6 @@ type UpdateLeagueParams struct {
|
|||
Name pgtype.Text `json:"name"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
SportID pgtype.Int4 `json:"sport_id"`
|
||||
}
|
||||
|
||||
|
|
@ -247,43 +259,35 @@ func (q *Queries) UpdateLeague(ctx context.Context, arg UpdateLeagueParams) erro
|
|||
arg.Name,
|
||||
arg.CountryCode,
|
||||
arg.Bet365ID,
|
||||
arg.IsActive,
|
||||
arg.IsFeatured,
|
||||
arg.SportID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const UpdateLeagueByBet365ID = `-- name: UpdateLeagueByBet365ID :exec
|
||||
UPDATE leagues
|
||||
SET name = COALESCE($2, name),
|
||||
id = COALESCE($3, id),
|
||||
country_code = COALESCE($4, country_code),
|
||||
is_active = COALESCE($5, is_active),
|
||||
is_featured = COALESCE($6, is_featured),
|
||||
sport_id = COALESCE($7, sport_id)
|
||||
WHERE bet365_id = $1
|
||||
const UpdateLeagueSettings = `-- name: UpdateLeagueSettings :exec
|
||||
UPDATE company_league_settings
|
||||
SET is_active = COALESCE($3, is_active),
|
||||
is_featured = COALESCE(
|
||||
$4,
|
||||
is_featured
|
||||
)
|
||||
WHERE league_id = $1
|
||||
AND company_id = $2
|
||||
`
|
||||
|
||||
type UpdateLeagueByBet365IDParams struct {
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
Name pgtype.Text `json:"name"`
|
||||
ID pgtype.Int8 `json:"id"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
SportID pgtype.Int4 `json:"sport_id"`
|
||||
type UpdateLeagueSettingsParams struct {
|
||||
LeagueID int64 `json:"league_id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateLeagueByBet365ID(ctx context.Context, arg UpdateLeagueByBet365IDParams) error {
|
||||
_, err := q.db.Exec(ctx, UpdateLeagueByBet365ID,
|
||||
arg.Bet365ID,
|
||||
arg.Name,
|
||||
arg.ID,
|
||||
arg.CountryCode,
|
||||
func (q *Queries) UpdateLeagueSettings(ctx context.Context, arg UpdateLeagueSettingsParams) error {
|
||||
_, err := q.db.Exec(ctx, UpdateLeagueSettings,
|
||||
arg.LeagueID,
|
||||
arg.CompanyID,
|
||||
arg.IsActive,
|
||||
arg.IsFeatured,
|
||||
arg.SportID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
325
gen/db/models.go
325
gen/db/models.go
|
|
@ -75,6 +75,7 @@ type Bank struct {
|
|||
|
||||
type Bet struct {
|
||||
ID int64 `json:"id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
Amount int64 `json:"amount"`
|
||||
TotalOdds float32 `json:"total_odds"`
|
||||
Status int32 `json:"status"`
|
||||
|
|
@ -108,6 +109,7 @@ type BetOutcome struct {
|
|||
|
||||
type BetWithOutcome struct {
|
||||
ID int64 `json:"id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
Amount int64 `json:"amount"`
|
||||
TotalOdds float32 `json:"total_odds"`
|
||||
Status int32 `json:"status"`
|
||||
|
|
@ -125,8 +127,8 @@ type BetWithOutcome struct {
|
|||
}
|
||||
|
||||
type Bonu struct {
|
||||
ID int64 `json:"id"`
|
||||
Multiplier float32 `json:"multiplier"`
|
||||
ID int64 `json:"id"`
|
||||
BalanceCap int64 `json:"balance_cap"`
|
||||
}
|
||||
|
||||
|
|
@ -184,6 +186,7 @@ type BranchOperation struct {
|
|||
type CompaniesDetail struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Slug string `json:"slug"`
|
||||
AdminID int64 `json:"admin_id"`
|
||||
WalletID int64 `json:"wallet_id"`
|
||||
DeductedPercentage float32 `json:"deducted_percentage"`
|
||||
|
|
@ -200,6 +203,7 @@ type CompaniesDetail struct {
|
|||
type Company struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Slug string `json:"slug"`
|
||||
AdminID int64 `json:"admin_id"`
|
||||
WalletID int64 `json:"wallet_id"`
|
||||
DeductedPercentage float32 `json:"deducted_percentage"`
|
||||
|
|
@ -208,6 +212,42 @@ type Company struct {
|
|||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
type CompanyEventSetting struct {
|
||||
ID int64 `json:"id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
EventID string `json:"event_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
WinningUpperLimit pgtype.Int4 `json:"winning_upper_limit"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
type CompanyLeagueSetting struct {
|
||||
ID int64 `json:"id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
LeagueID int64 `json:"league_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
type CompanyOddSetting struct {
|
||||
ID int64 `json:"id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
OddsMarketID int64 `json:"odds_market_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
CustomRawOdds []byte `json:"custom_raw_odds"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
type CompanySetting struct {
|
||||
CompanyID int64 `json:"company_id"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
type CustomerWallet struct {
|
||||
ID int64 `json:"id"`
|
||||
CustomerID int64 `json:"customer_id"`
|
||||
|
|
@ -248,31 +288,111 @@ 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 string `json:"event_id"`
|
||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||
}
|
||||
|
||||
type Event 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"`
|
||||
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"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
Source pgtype.Text `json:"source"`
|
||||
IsFeatured bool `json:"is_featured"`
|
||||
IsActive bool `json:"is_active"`
|
||||
ID string `json:"id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
MatchName string `json:"match_name"`
|
||||
HomeTeam string `json:"home_team"`
|
||||
AwayTeam string `json:"away_team"`
|
||||
HomeTeamID int64 `json:"home_team_id"`
|
||||
AwayTeamID int64 `json:"away_team_id"`
|
||||
HomeKitImage string `json:"home_kit_image"`
|
||||
AwayKitImage string `json:"away_kit_image"`
|
||||
LeagueID int64 `json:"league_id"`
|
||||
LeagueName string `json:"league_name"`
|
||||
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 bool `json:"is_live"`
|
||||
Status string `json:"status"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
Source string `json:"source"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
DefaultWinningUpperLimit int32 `json:"default_winning_upper_limit"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
}
|
||||
|
||||
type EventHistory struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||
}
|
||||
|
||||
type EventWithCountry struct {
|
||||
ID string `json:"id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
MatchName string `json:"match_name"`
|
||||
HomeTeam string `json:"home_team"`
|
||||
AwayTeam string `json:"away_team"`
|
||||
HomeTeamID int64 `json:"home_team_id"`
|
||||
AwayTeamID int64 `json:"away_team_id"`
|
||||
HomeKitImage string `json:"home_kit_image"`
|
||||
AwayKitImage string `json:"away_kit_image"`
|
||||
LeagueID int64 `json:"league_id"`
|
||||
LeagueName string `json:"league_name"`
|
||||
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 bool `json:"is_live"`
|
||||
Status string `json:"status"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
Source string `json:"source"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
DefaultWinningUpperLimit int32 `json:"default_winning_upper_limit"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
LeagueCc pgtype.Text `json:"league_cc"`
|
||||
}
|
||||
|
||||
type EventWithSetting struct {
|
||||
ID string `json:"id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
MatchName string `json:"match_name"`
|
||||
HomeTeam string `json:"home_team"`
|
||||
AwayTeam string `json:"away_team"`
|
||||
HomeTeamID int64 `json:"home_team_id"`
|
||||
AwayTeamID int64 `json:"away_team_id"`
|
||||
HomeKitImage string `json:"home_kit_image"`
|
||||
AwayKitImage string `json:"away_kit_image"`
|
||||
LeagueID int64 `json:"league_id"`
|
||||
LeagueName string `json:"league_name"`
|
||||
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 bool `json:"is_live"`
|
||||
Status string `json:"status"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
Source string `json:"source"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
DefaultWinningUpperLimit int32 `json:"default_winning_upper_limit"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
IsFeatured bool `json:"is_featured"`
|
||||
WinningUpperLimit int32 `json:"winning_upper_limit"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
LeagueCc pgtype.Text `json:"league_cc"`
|
||||
}
|
||||
|
||||
type ExchangeRate struct {
|
||||
|
|
@ -292,23 +412,45 @@ type FavoriteGame struct {
|
|||
}
|
||||
|
||||
type Flag struct {
|
||||
ID int64 `json:"id"`
|
||||
BetID pgtype.Int8 `json:"bet_id"`
|
||||
OddID pgtype.Int8 `json:"odd_id"`
|
||||
Reason pgtype.Text `json:"reason"`
|
||||
FlaggedAt pgtype.Timestamp `json:"flagged_at"`
|
||||
Resolved pgtype.Bool `json:"resolved"`
|
||||
ID int64 `json:"id"`
|
||||
BetID pgtype.Int8 `json:"bet_id"`
|
||||
OddsMarketID pgtype.Int8 `json:"odds_market_id"`
|
||||
Reason pgtype.Text `json:"reason"`
|
||||
FlaggedAt pgtype.Timestamp `json:"flagged_at"`
|
||||
Resolved pgtype.Bool `json:"resolved"`
|
||||
}
|
||||
|
||||
type GlobalSetting struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
type League struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Img pgtype.Text `json:"img"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ImgUrl pgtype.Text `json:"img_url"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
}
|
||||
|
||||
type LeagueWithSetting struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ImgUrl pgtype.Text `json:"img_url"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
IsFeatured bool `json:"is_featured"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
type Notification struct {
|
||||
|
|
@ -328,23 +470,60 @@ type Notification struct {
|
|||
Metadata []byte `json:"metadata"`
|
||||
}
|
||||
|
||||
type Odd struct {
|
||||
ID int32 `json:"id"`
|
||||
EventID pgtype.Text `json:"event_id"`
|
||||
Fi pgtype.Text `json:"fi"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName pgtype.Text `json:"market_name"`
|
||||
MarketCategory pgtype.Text `json:"market_category"`
|
||||
MarketID pgtype.Text `json:"market_id"`
|
||||
Name pgtype.Text `json:"name"`
|
||||
Handicap pgtype.Text `json:"handicap"`
|
||||
OddsValue pgtype.Float8 `json:"odds_value"`
|
||||
Section string `json:"section"`
|
||||
Category pgtype.Text `json:"category"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
Source pgtype.Text `json:"source"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
type OddHistory struct {
|
||||
ID int64 `json:"id"`
|
||||
OddsMarketID int64 `json:"odds_market_id"`
|
||||
RawOddID int64 `json:"raw_odd_id"`
|
||||
MarketID string `json:"market_id"`
|
||||
EventID string `json:"event_id"`
|
||||
OddValue float64 `json:"odd_value"`
|
||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||
}
|
||||
|
||||
type OddsMarket struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName string `json:"market_name"`
|
||||
MarketCategory string `json:"market_category"`
|
||||
MarketID string `json:"market_id"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||
}
|
||||
|
||||
type OddsMarketWithEvent struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName string `json:"market_name"`
|
||||
MarketCategory string `json:"market_category"`
|
||||
MarketID string `json:"market_id"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
IsLive bool `json:"is_live"`
|
||||
Status string `json:"status"`
|
||||
Source string `json:"source"`
|
||||
}
|
||||
|
||||
type OddsMarketWithSetting struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName string `json:"market_name"`
|
||||
MarketCategory string `json:"market_category"`
|
||||
MarketID string `json:"market_id"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
type Otp struct {
|
||||
|
|
@ -422,11 +601,21 @@ type Result struct {
|
|||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
type Setting struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
type ResultLog struct {
|
||||
ID int64 `json:"id"`
|
||||
StatusNotFinishedCount int32 `json:"status_not_finished_count"`
|
||||
StatusNotFinishedBets int32 `json:"status_not_finished_bets"`
|
||||
StatusToBeFixedCount int32 `json:"status_to_be_fixed_count"`
|
||||
StatusToBeFixedBets int32 `json:"status_to_be_fixed_bets"`
|
||||
StatusPostponedCount int32 `json:"status_postponed_count"`
|
||||
StatusPostponedBets int32 `json:"status_postponed_bets"`
|
||||
StatusEndedCount int32 `json:"status_ended_count"`
|
||||
StatusEndedBets int32 `json:"status_ended_bets"`
|
||||
StatusRemovedCount int32 `json:"status_removed_count"`
|
||||
StatusRemovedBets int32 `json:"status_removed_bets"`
|
||||
RemovedCount int32 `json:"removed_count"`
|
||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
type ShopBet struct {
|
||||
|
|
@ -545,15 +734,16 @@ type SupportedOperation struct {
|
|||
}
|
||||
|
||||
type Team struct {
|
||||
ID string `json:"id"`
|
||||
TeamName string `json:"team_name"`
|
||||
Country pgtype.Text `json:"country"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
LogoUrl pgtype.Text `json:"logo_url"`
|
||||
ID int64 `json:"id"`
|
||||
TeamName string `json:"team_name"`
|
||||
CountryCode string `json:"country_code"`
|
||||
Bet365ID pgtype.Int8 `json:"bet365_id"`
|
||||
ImgUrl pgtype.Text `json:"img_url"`
|
||||
}
|
||||
|
||||
type Ticket struct {
|
||||
ID int64 `json:"id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
Amount int64 `json:"amount"`
|
||||
TotalOdds float32 `json:"total_odds"`
|
||||
Ip string `json:"ip"`
|
||||
|
|
@ -580,6 +770,7 @@ type TicketOutcome struct {
|
|||
|
||||
type TicketWithOutcome struct {
|
||||
ID int64 `json:"id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
Amount int64 `json:"amount"`
|
||||
TotalOdds float32 `json:"total_odds"`
|
||||
Ip string `json:"ip"`
|
||||
|
|
@ -695,6 +886,7 @@ type VirtualGameTransaction struct {
|
|||
type Wallet struct {
|
||||
ID int64 `json:"id"`
|
||||
Balance int64 `json:"balance"`
|
||||
Currency string `json:"currency"`
|
||||
IsWithdraw bool `json:"is_withdraw"`
|
||||
IsBettable bool `json:"is_bettable"`
|
||||
IsTransferable bool `json:"is_transferable"`
|
||||
|
|
@ -703,7 +895,6 @@ type Wallet struct {
|
|||
IsActive bool `json:"is_active"`
|
||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
Currency string `json:"currency"`
|
||||
BonusBalance pgtype.Numeric `json:"bonus_balance"`
|
||||
CashBalance pgtype.Numeric `json:"cash_balance"`
|
||||
}
|
||||
|
|
|
|||
203
gen/db/odd_history.sql.go
Normal file
203
gen/db/odd_history.sql.go
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
// source: odd_history.sql
|
||||
|
||||
package dbgen
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const GetAllOddHistory = `-- name: GetAllOddHistory :many
|
||||
SELECT id, odds_market_id, raw_odd_id, market_id, event_id, odd_value, created_at
|
||||
FROM odd_history
|
||||
WHERE (
|
||||
odds_market_id = $1
|
||||
OR $1 IS NULL
|
||||
)
|
||||
AND (
|
||||
market_id = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
raw_odd_id = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
AND (
|
||||
event_id = $4
|
||||
OR $4 IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at > $5
|
||||
OR $5 IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at < $6
|
||||
OR $6 IS NULL
|
||||
)
|
||||
`
|
||||
|
||||
type GetAllOddHistoryParams struct {
|
||||
OddID pgtype.Int8 `json:"odd_id"`
|
||||
MarketID pgtype.Text `json:"market_id"`
|
||||
RawOddID pgtype.Int8 `json:"raw_odd_id"`
|
||||
EventID pgtype.Text `json:"event_id"`
|
||||
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetAllOddHistory(ctx context.Context, arg GetAllOddHistoryParams) ([]OddHistory, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllOddHistory,
|
||||
arg.OddID,
|
||||
arg.MarketID,
|
||||
arg.RawOddID,
|
||||
arg.EventID,
|
||||
arg.CreatedBefore,
|
||||
arg.CreatedAfter,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []OddHistory
|
||||
for rows.Next() {
|
||||
var i OddHistory
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.OddsMarketID,
|
||||
&i.RawOddID,
|
||||
&i.MarketID,
|
||||
&i.EventID,
|
||||
&i.OddValue,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetInitialOddPerDay = `-- name: GetInitialOddPerDay :many
|
||||
SELECT DISTINCT ON (DATE_TRUNC($1, created_at)) id, odds_market_id, raw_odd_id, market_id, event_id, odd_value, created_at
|
||||
FROM odd_history
|
||||
WHERE (
|
||||
odds_market_id = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
market_id = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
AND (
|
||||
raw_odd_id = $4
|
||||
OR $4 IS NULL
|
||||
)
|
||||
AND (
|
||||
event_id = $5
|
||||
OR $5 IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at > $6
|
||||
OR $6 IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at < $7
|
||||
OR $7 IS NULL
|
||||
)
|
||||
ORDER BY DATE_TRUNC($1, created_at),
|
||||
created_at ASC
|
||||
`
|
||||
|
||||
type GetInitialOddPerDayParams struct {
|
||||
DateTrunc string `json:"date_trunc"`
|
||||
OddID pgtype.Int8 `json:"odd_id"`
|
||||
MarketID pgtype.Text `json:"market_id"`
|
||||
RawOddID pgtype.Int8 `json:"raw_odd_id"`
|
||||
EventID pgtype.Text `json:"event_id"`
|
||||
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetInitialOddPerDay(ctx context.Context, arg GetInitialOddPerDayParams) ([]OddHistory, error) {
|
||||
rows, err := q.db.Query(ctx, GetInitialOddPerDay,
|
||||
arg.DateTrunc,
|
||||
arg.OddID,
|
||||
arg.MarketID,
|
||||
arg.RawOddID,
|
||||
arg.EventID,
|
||||
arg.CreatedBefore,
|
||||
arg.CreatedAfter,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []OddHistory
|
||||
for rows.Next() {
|
||||
var i OddHistory
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.OddsMarketID,
|
||||
&i.RawOddID,
|
||||
&i.MarketID,
|
||||
&i.EventID,
|
||||
&i.OddValue,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const InsertOddHistory = `-- name: InsertOddHistory :one
|
||||
INSERT INTO odd_history (
|
||||
odds_market_id,
|
||||
market_id,
|
||||
raw_odd_id,
|
||||
event_id,
|
||||
odd_value
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id, odds_market_id, raw_odd_id, market_id, event_id, odd_value, created_at
|
||||
`
|
||||
|
||||
type InsertOddHistoryParams struct {
|
||||
OddsMarketID int64 `json:"odds_market_id"`
|
||||
MarketID string `json:"market_id"`
|
||||
RawOddID int64 `json:"raw_odd_id"`
|
||||
EventID string `json:"event_id"`
|
||||
OddValue float64 `json:"odd_value"`
|
||||
}
|
||||
|
||||
func (q *Queries) InsertOddHistory(ctx context.Context, arg InsertOddHistoryParams) (OddHistory, error) {
|
||||
row := q.db.QueryRow(ctx, InsertOddHistory,
|
||||
arg.OddsMarketID,
|
||||
arg.MarketID,
|
||||
arg.RawOddID,
|
||||
arg.EventID,
|
||||
arg.OddValue,
|
||||
)
|
||||
var i OddHistory
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.OddsMarketID,
|
||||
&i.RawOddID,
|
||||
&i.MarketID,
|
||||
&i.EventID,
|
||||
&i.OddValue,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
|
@ -12,134 +12,50 @@ import (
|
|||
)
|
||||
|
||||
const DeleteOddsForEvent = `-- name: DeleteOddsForEvent :exec
|
||||
DELETE FROM odds
|
||||
Where fi = $1
|
||||
DELETE FROM odds_market
|
||||
Where event_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteOddsForEvent(ctx context.Context, fi pgtype.Text) error {
|
||||
_, err := q.db.Exec(ctx, DeleteOddsForEvent, fi)
|
||||
func (q *Queries) DeleteOddsForEvent(ctx context.Context, eventID string) error {
|
||||
_, err := q.db.Exec(ctx, DeleteOddsForEvent, eventID)
|
||||
return err
|
||||
}
|
||||
|
||||
const GetALLPrematchOdds = `-- name: GetALLPrematchOdds :many
|
||||
SELECT event_id,
|
||||
fi,
|
||||
market_type,
|
||||
market_name,
|
||||
market_category,
|
||||
market_id,
|
||||
name,
|
||||
handicap,
|
||||
odds_value,
|
||||
section,
|
||||
category,
|
||||
raw_odds,
|
||||
fetched_at,
|
||||
source,
|
||||
is_active
|
||||
FROM odds
|
||||
WHERE is_active = true
|
||||
AND source = 'bet365'
|
||||
const GetAllOdds = `-- name: GetAllOdds :many
|
||||
SELECT id, event_id, market_type, market_name, market_category, market_id, raw_odds, default_is_active, fetched_at, expires_at, is_monitored, is_live, status, source
|
||||
FROM odds_market_with_event
|
||||
LIMIT $2 OFFSET $1
|
||||
`
|
||||
|
||||
type GetALLPrematchOddsRow struct {
|
||||
EventID pgtype.Text `json:"event_id"`
|
||||
Fi pgtype.Text `json:"fi"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName pgtype.Text `json:"market_name"`
|
||||
MarketCategory pgtype.Text `json:"market_category"`
|
||||
MarketID pgtype.Text `json:"market_id"`
|
||||
Name pgtype.Text `json:"name"`
|
||||
Handicap pgtype.Text `json:"handicap"`
|
||||
OddsValue pgtype.Float8 `json:"odds_value"`
|
||||
Section string `json:"section"`
|
||||
Category pgtype.Text `json:"category"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
Source pgtype.Text `json:"source"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetALLPrematchOdds(ctx context.Context) ([]GetALLPrematchOddsRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetALLPrematchOdds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetALLPrematchOddsRow
|
||||
for rows.Next() {
|
||||
var i GetALLPrematchOddsRow
|
||||
if err := rows.Scan(
|
||||
&i.EventID,
|
||||
&i.Fi,
|
||||
&i.MarketType,
|
||||
&i.MarketName,
|
||||
&i.MarketCategory,
|
||||
&i.MarketID,
|
||||
&i.Name,
|
||||
&i.Handicap,
|
||||
&i.OddsValue,
|
||||
&i.Section,
|
||||
&i.Category,
|
||||
&i.RawOdds,
|
||||
&i.FetchedAt,
|
||||
&i.Source,
|
||||
&i.IsActive,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetPaginatedPrematchOddsByUpcomingID = `-- name: GetPaginatedPrematchOddsByUpcomingID :many
|
||||
SELECT o.id, o.event_id, o.fi, o.market_type, o.market_name, o.market_category, o.market_id, o.name, o.handicap, o.odds_value, o.section, o.category, o.raw_odds, o.fetched_at, o.source, o.is_active
|
||||
FROM odds o
|
||||
JOIN events e ON o.fi = e.id
|
||||
WHERE e.id = $1
|
||||
AND e.is_live = false
|
||||
AND e.status = 'upcoming'
|
||||
AND o.is_active = true
|
||||
AND o.source = 'bet365'
|
||||
LIMIT $3 OFFSET $2
|
||||
`
|
||||
|
||||
type GetPaginatedPrematchOddsByUpcomingIDParams struct {
|
||||
ID string `json:"id"`
|
||||
type GetAllOddsParams struct {
|
||||
Offset pgtype.Int4 `json:"offset"`
|
||||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, arg GetPaginatedPrematchOddsByUpcomingIDParams) ([]Odd, error) {
|
||||
rows, err := q.db.Query(ctx, GetPaginatedPrematchOddsByUpcomingID, arg.ID, arg.Offset, arg.Limit)
|
||||
func (q *Queries) GetAllOdds(ctx context.Context, arg GetAllOddsParams) ([]OddsMarketWithEvent, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllOdds, arg.Offset, arg.Limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Odd
|
||||
var items []OddsMarketWithEvent
|
||||
for rows.Next() {
|
||||
var i Odd
|
||||
var i OddsMarketWithEvent
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
&i.Fi,
|
||||
&i.MarketType,
|
||||
&i.MarketName,
|
||||
&i.MarketCategory,
|
||||
&i.MarketID,
|
||||
&i.Name,
|
||||
&i.Handicap,
|
||||
&i.OddsValue,
|
||||
&i.Section,
|
||||
&i.Category,
|
||||
&i.RawOdds,
|
||||
&i.DefaultIsActive,
|
||||
&i.FetchedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.IsMonitored,
|
||||
&i.IsLive,
|
||||
&i.Status,
|
||||
&i.Source,
|
||||
&i.IsActive,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -151,118 +67,42 @@ func (q *Queries) GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, arg
|
|||
return items, nil
|
||||
}
|
||||
|
||||
const GetPrematchOdds = `-- name: GetPrematchOdds :many
|
||||
SELECT event_id,
|
||||
fi,
|
||||
market_type,
|
||||
market_name,
|
||||
market_category,
|
||||
market_id,
|
||||
name,
|
||||
handicap,
|
||||
odds_value,
|
||||
section,
|
||||
category,
|
||||
raw_odds,
|
||||
fetched_at,
|
||||
source,
|
||||
is_active
|
||||
FROM odds
|
||||
WHERE is_active = true
|
||||
AND source = 'bet365'
|
||||
const GetAllOddsWithSettings = `-- name: GetAllOddsWithSettings :many
|
||||
SELECT id, event_id, market_type, market_name, market_category, market_id, default_is_active, fetched_at, expires_at, company_id, is_active, raw_odds, updated_at
|
||||
FROM odds_market_with_settings
|
||||
WHERE company_id = $1
|
||||
LIMIT $3 OFFSET $2
|
||||
`
|
||||
|
||||
type GetPrematchOddsRow struct {
|
||||
EventID pgtype.Text `json:"event_id"`
|
||||
Fi pgtype.Text `json:"fi"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName pgtype.Text `json:"market_name"`
|
||||
MarketCategory pgtype.Text `json:"market_category"`
|
||||
MarketID pgtype.Text `json:"market_id"`
|
||||
Name pgtype.Text `json:"name"`
|
||||
Handicap pgtype.Text `json:"handicap"`
|
||||
OddsValue pgtype.Float8 `json:"odds_value"`
|
||||
Section string `json:"section"`
|
||||
Category pgtype.Text `json:"category"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
Source pgtype.Text `json:"source"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
type GetAllOddsWithSettingsParams struct {
|
||||
CompanyID int64 `json:"company_id"`
|
||||
Offset pgtype.Int4 `json:"offset"`
|
||||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetPrematchOdds(ctx context.Context) ([]GetPrematchOddsRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetPrematchOdds)
|
||||
func (q *Queries) GetAllOddsWithSettings(ctx context.Context, arg GetAllOddsWithSettingsParams) ([]OddsMarketWithSetting, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllOddsWithSettings, arg.CompanyID, arg.Offset, arg.Limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetPrematchOddsRow
|
||||
var items []OddsMarketWithSetting
|
||||
for rows.Next() {
|
||||
var i GetPrematchOddsRow
|
||||
if err := rows.Scan(
|
||||
&i.EventID,
|
||||
&i.Fi,
|
||||
&i.MarketType,
|
||||
&i.MarketName,
|
||||
&i.MarketCategory,
|
||||
&i.MarketID,
|
||||
&i.Name,
|
||||
&i.Handicap,
|
||||
&i.OddsValue,
|
||||
&i.Section,
|
||||
&i.Category,
|
||||
&i.RawOdds,
|
||||
&i.FetchedAt,
|
||||
&i.Source,
|
||||
&i.IsActive,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetPrematchOddsByUpcomingID = `-- name: GetPrematchOddsByUpcomingID :many
|
||||
SELECT o.id, o.event_id, o.fi, o.market_type, o.market_name, o.market_category, o.market_id, o.name, o.handicap, o.odds_value, o.section, o.category, o.raw_odds, o.fetched_at, o.source, o.is_active
|
||||
FROM odds o
|
||||
JOIN events e ON o.fi = e.id
|
||||
WHERE e.id = $1
|
||||
AND e.is_live = false
|
||||
AND e.status = 'upcoming'
|
||||
AND o.is_active = true
|
||||
AND o.source = 'bet365'
|
||||
`
|
||||
|
||||
func (q *Queries) GetPrematchOddsByUpcomingID(ctx context.Context, id string) ([]Odd, error) {
|
||||
rows, err := q.db.Query(ctx, GetPrematchOddsByUpcomingID, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Odd
|
||||
for rows.Next() {
|
||||
var i Odd
|
||||
var i OddsMarketWithSetting
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
&i.Fi,
|
||||
&i.MarketType,
|
||||
&i.MarketName,
|
||||
&i.MarketCategory,
|
||||
&i.MarketID,
|
||||
&i.Name,
|
||||
&i.Handicap,
|
||||
&i.OddsValue,
|
||||
&i.Section,
|
||||
&i.Category,
|
||||
&i.RawOdds,
|
||||
&i.DefaultIsActive,
|
||||
&i.FetchedAt,
|
||||
&i.Source,
|
||||
&i.ExpiresAt,
|
||||
&i.CompanyID,
|
||||
&i.IsActive,
|
||||
&i.RawOdds,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -274,62 +114,239 @@ func (q *Queries) GetPrematchOddsByUpcomingID(ctx context.Context, id string) ([
|
|||
return items, nil
|
||||
}
|
||||
|
||||
const GetRawOddsByMarketID = `-- name: GetRawOddsByMarketID :one
|
||||
SELECT id,
|
||||
market_name,
|
||||
handicap,
|
||||
raw_odds,
|
||||
fetched_at
|
||||
FROM odds
|
||||
const GetOddsByEventID = `-- name: GetOddsByEventID :many
|
||||
SELECT id, event_id, market_type, market_name, market_category, market_id, raw_odds, default_is_active, fetched_at, expires_at, is_monitored, is_live, status, source
|
||||
FROM odds_market_with_event
|
||||
WHERE event_id = $1
|
||||
AND (
|
||||
is_live = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
status = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
AND (
|
||||
source = $4
|
||||
OR $4 IS NULL
|
||||
)
|
||||
LIMIT $6 OFFSET $5
|
||||
`
|
||||
|
||||
type GetOddsByEventIDParams struct {
|
||||
EventID string `json:"event_id"`
|
||||
IsLive pgtype.Bool `json:"is_live"`
|
||||
Status pgtype.Text `json:"status"`
|
||||
Source pgtype.Text `json:"source"`
|
||||
Offset pgtype.Int4 `json:"offset"`
|
||||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetOddsByEventID(ctx context.Context, arg GetOddsByEventIDParams) ([]OddsMarketWithEvent, error) {
|
||||
rows, err := q.db.Query(ctx, GetOddsByEventID,
|
||||
arg.EventID,
|
||||
arg.IsLive,
|
||||
arg.Status,
|
||||
arg.Source,
|
||||
arg.Offset,
|
||||
arg.Limit,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []OddsMarketWithEvent
|
||||
for rows.Next() {
|
||||
var i OddsMarketWithEvent
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
&i.MarketType,
|
||||
&i.MarketName,
|
||||
&i.MarketCategory,
|
||||
&i.MarketID,
|
||||
&i.RawOdds,
|
||||
&i.DefaultIsActive,
|
||||
&i.FetchedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.IsMonitored,
|
||||
&i.IsLive,
|
||||
&i.Status,
|
||||
&i.Source,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetOddsByMarketID = `-- name: GetOddsByMarketID :one
|
||||
SELECT id, event_id, market_type, market_name, market_category, market_id, raw_odds, default_is_active, fetched_at, expires_at, is_monitored, is_live, status, source
|
||||
FROM odds_market_with_event
|
||||
WHERE market_id = $1
|
||||
AND fi = $2
|
||||
AND is_active = true
|
||||
AND source = 'bet365'
|
||||
AND event_id = $2
|
||||
`
|
||||
|
||||
type GetRawOddsByMarketIDParams struct {
|
||||
MarketID pgtype.Text `json:"market_id"`
|
||||
Fi pgtype.Text `json:"fi"`
|
||||
type GetOddsByMarketIDParams struct {
|
||||
MarketID string `json:"market_id"`
|
||||
EventID string `json:"event_id"`
|
||||
}
|
||||
|
||||
type GetRawOddsByMarketIDRow struct {
|
||||
ID int32 `json:"id"`
|
||||
MarketName pgtype.Text `json:"market_name"`
|
||||
Handicap pgtype.Text `json:"handicap"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetRawOddsByMarketID(ctx context.Context, arg GetRawOddsByMarketIDParams) (GetRawOddsByMarketIDRow, error) {
|
||||
row := q.db.QueryRow(ctx, GetRawOddsByMarketID, arg.MarketID, arg.Fi)
|
||||
var i GetRawOddsByMarketIDRow
|
||||
func (q *Queries) GetOddsByMarketID(ctx context.Context, arg GetOddsByMarketIDParams) (OddsMarketWithEvent, error) {
|
||||
row := q.db.QueryRow(ctx, GetOddsByMarketID, arg.MarketID, arg.EventID)
|
||||
var i OddsMarketWithEvent
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
&i.MarketType,
|
||||
&i.MarketName,
|
||||
&i.Handicap,
|
||||
&i.MarketCategory,
|
||||
&i.MarketID,
|
||||
&i.RawOdds,
|
||||
&i.DefaultIsActive,
|
||||
&i.FetchedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.IsMonitored,
|
||||
&i.IsLive,
|
||||
&i.Status,
|
||||
&i.Source,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const InsertNonLiveOdd = `-- name: InsertNonLiveOdd :exec
|
||||
INSERT INTO odds (
|
||||
const GetOddsWithSettingsByEventID = `-- name: GetOddsWithSettingsByEventID :many
|
||||
SELECT id, event_id, market_type, market_name, market_category, market_id, default_is_active, fetched_at, expires_at, company_id, is_active, raw_odds, updated_at
|
||||
FROM odds_market_with_settings
|
||||
WHERE event_id = $1
|
||||
AND company_id = $2
|
||||
LIMIT $4 OFFSET $3
|
||||
`
|
||||
|
||||
type GetOddsWithSettingsByEventIDParams struct {
|
||||
EventID string `json:"event_id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
Offset pgtype.Int4 `json:"offset"`
|
||||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetOddsWithSettingsByEventID(ctx context.Context, arg GetOddsWithSettingsByEventIDParams) ([]OddsMarketWithSetting, error) {
|
||||
rows, err := q.db.Query(ctx, GetOddsWithSettingsByEventID,
|
||||
arg.EventID,
|
||||
arg.CompanyID,
|
||||
arg.Offset,
|
||||
arg.Limit,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []OddsMarketWithSetting
|
||||
for rows.Next() {
|
||||
var i OddsMarketWithSetting
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
&i.MarketType,
|
||||
&i.MarketName,
|
||||
&i.MarketCategory,
|
||||
&i.MarketID,
|
||||
&i.DefaultIsActive,
|
||||
&i.FetchedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.CompanyID,
|
||||
&i.IsActive,
|
||||
&i.RawOdds,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetOddsWithSettingsByMarketID = `-- name: GetOddsWithSettingsByMarketID :one
|
||||
SELECT id, event_id, market_type, market_name, market_category, market_id, default_is_active, fetched_at, expires_at, company_id, is_active, raw_odds, updated_at
|
||||
FROM odds_market_with_settings
|
||||
WHERE market_id = $1
|
||||
AND event_id = $2
|
||||
AND company_id = $3
|
||||
`
|
||||
|
||||
type GetOddsWithSettingsByMarketIDParams struct {
|
||||
MarketID string `json:"market_id"`
|
||||
EventID string `json:"event_id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetOddsWithSettingsByMarketID(ctx context.Context, arg GetOddsWithSettingsByMarketIDParams) (OddsMarketWithSetting, error) {
|
||||
row := q.db.QueryRow(ctx, GetOddsWithSettingsByMarketID, arg.MarketID, arg.EventID, arg.CompanyID)
|
||||
var i OddsMarketWithSetting
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
&i.MarketType,
|
||||
&i.MarketName,
|
||||
&i.MarketCategory,
|
||||
&i.MarketID,
|
||||
&i.DefaultIsActive,
|
||||
&i.FetchedAt,
|
||||
&i.ExpiresAt,
|
||||
&i.CompanyID,
|
||||
&i.IsActive,
|
||||
&i.RawOdds,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const InsertOddSettings = `-- name: InsertOddSettings :exec
|
||||
INSERT INTO company_odd_settings (
|
||||
company_id,
|
||||
odds_market_id,
|
||||
is_active,
|
||||
custom_raw_odds
|
||||
)
|
||||
VALUES ($1, $2, $3, $4) ON CONFLICT (company_id, odds_market_id) DO
|
||||
UPDATE
|
||||
SET is_active = EXCLUDED.is_active,
|
||||
custom_raw_odds = EXCLUDED.custom_raw_odds
|
||||
`
|
||||
|
||||
type InsertOddSettingsParams struct {
|
||||
CompanyID int64 `json:"company_id"`
|
||||
OddsMarketID int64 `json:"odds_market_id"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
CustomRawOdds []byte `json:"custom_raw_odds"`
|
||||
}
|
||||
|
||||
func (q *Queries) InsertOddSettings(ctx context.Context, arg InsertOddSettingsParams) error {
|
||||
_, err := q.db.Exec(ctx, InsertOddSettings,
|
||||
arg.CompanyID,
|
||||
arg.OddsMarketID,
|
||||
arg.IsActive,
|
||||
arg.CustomRawOdds,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const InsertOddsMarket = `-- name: InsertOddsMarket :exec
|
||||
INSERT INTO odds_market (
|
||||
event_id,
|
||||
fi,
|
||||
market_type,
|
||||
market_name,
|
||||
market_category,
|
||||
market_id,
|
||||
name,
|
||||
handicap,
|
||||
odds_value,
|
||||
section,
|
||||
category,
|
||||
raw_odds,
|
||||
is_active,
|
||||
source,
|
||||
fetched_at
|
||||
fetched_at,
|
||||
expires_at
|
||||
)
|
||||
VALUES (
|
||||
$1,
|
||||
|
|
@ -339,64 +356,38 @@ VALUES (
|
|||
$5,
|
||||
$6,
|
||||
$7,
|
||||
$8,
|
||||
$9,
|
||||
$10,
|
||||
$11,
|
||||
$12,
|
||||
$13,
|
||||
$14,
|
||||
$15
|
||||
$8
|
||||
) ON CONFLICT (event_id, market_id) DO
|
||||
UPDATE
|
||||
SET odds_value = EXCLUDED.odds_value,
|
||||
raw_odds = EXCLUDED.raw_odds,
|
||||
market_type = EXCLUDED.market_type,
|
||||
SET market_type = EXCLUDED.market_type,
|
||||
market_name = EXCLUDED.market_name,
|
||||
market_category = EXCLUDED.market_category,
|
||||
name = EXCLUDED.name,
|
||||
handicap = EXCLUDED.handicap,
|
||||
raw_odds = EXCLUDED.raw_odds,
|
||||
fetched_at = EXCLUDED.fetched_at,
|
||||
is_active = EXCLUDED.is_active,
|
||||
source = EXCLUDED.source,
|
||||
fi = EXCLUDED.fi
|
||||
expires_at = EXCLUDED.expires_at
|
||||
`
|
||||
|
||||
type InsertNonLiveOddParams struct {
|
||||
EventID pgtype.Text `json:"event_id"`
|
||||
Fi pgtype.Text `json:"fi"`
|
||||
type InsertOddsMarketParams struct {
|
||||
EventID string `json:"event_id"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName pgtype.Text `json:"market_name"`
|
||||
MarketCategory pgtype.Text `json:"market_category"`
|
||||
MarketID pgtype.Text `json:"market_id"`
|
||||
Name pgtype.Text `json:"name"`
|
||||
Handicap pgtype.Text `json:"handicap"`
|
||||
OddsValue pgtype.Float8 `json:"odds_value"`
|
||||
Section string `json:"section"`
|
||||
Category pgtype.Text `json:"category"`
|
||||
MarketName string `json:"market_name"`
|
||||
MarketCategory string `json:"market_category"`
|
||||
MarketID string `json:"market_id"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
IsActive pgtype.Bool `json:"is_active"`
|
||||
Source pgtype.Text `json:"source"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) InsertNonLiveOdd(ctx context.Context, arg InsertNonLiveOddParams) error {
|
||||
_, err := q.db.Exec(ctx, InsertNonLiveOdd,
|
||||
func (q *Queries) InsertOddsMarket(ctx context.Context, arg InsertOddsMarketParams) error {
|
||||
_, err := q.db.Exec(ctx, InsertOddsMarket,
|
||||
arg.EventID,
|
||||
arg.Fi,
|
||||
arg.MarketType,
|
||||
arg.MarketName,
|
||||
arg.MarketCategory,
|
||||
arg.MarketID,
|
||||
arg.Name,
|
||||
arg.Handicap,
|
||||
arg.OddsValue,
|
||||
arg.Section,
|
||||
arg.Category,
|
||||
arg.RawOdds,
|
||||
arg.IsActive,
|
||||
arg.Source,
|
||||
arg.FetchedAt,
|
||||
arg.ExpiresAt,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
132
gen/db/result_log.sql.go
Normal file
132
gen/db/result_log.sql.go
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
// source: result_log.sql
|
||||
|
||||
package dbgen
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const CreateResultLog = `-- name: CreateResultLog :one
|
||||
INSERT INTO result_log (
|
||||
status_not_finished_count,
|
||||
status_not_finished_bets,
|
||||
status_to_be_fixed_count,
|
||||
status_to_be_fixed_bets,
|
||||
status_postponed_count,
|
||||
status_postponed_bets,
|
||||
status_ended_count,
|
||||
status_ended_bets,
|
||||
status_removed_count,
|
||||
status_removed_bets,
|
||||
removed_count
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||
RETURNING id, status_not_finished_count, status_not_finished_bets, status_to_be_fixed_count, status_to_be_fixed_bets, status_postponed_count, status_postponed_bets, status_ended_count, status_ended_bets, status_removed_count, status_removed_bets, removed_count, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateResultLogParams struct {
|
||||
StatusNotFinishedCount int32 `json:"status_not_finished_count"`
|
||||
StatusNotFinishedBets int32 `json:"status_not_finished_bets"`
|
||||
StatusToBeFixedCount int32 `json:"status_to_be_fixed_count"`
|
||||
StatusToBeFixedBets int32 `json:"status_to_be_fixed_bets"`
|
||||
StatusPostponedCount int32 `json:"status_postponed_count"`
|
||||
StatusPostponedBets int32 `json:"status_postponed_bets"`
|
||||
StatusEndedCount int32 `json:"status_ended_count"`
|
||||
StatusEndedBets int32 `json:"status_ended_bets"`
|
||||
StatusRemovedCount int32 `json:"status_removed_count"`
|
||||
StatusRemovedBets int32 `json:"status_removed_bets"`
|
||||
RemovedCount int32 `json:"removed_count"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateResultLog(ctx context.Context, arg CreateResultLogParams) (ResultLog, error) {
|
||||
row := q.db.QueryRow(ctx, CreateResultLog,
|
||||
arg.StatusNotFinishedCount,
|
||||
arg.StatusNotFinishedBets,
|
||||
arg.StatusToBeFixedCount,
|
||||
arg.StatusToBeFixedBets,
|
||||
arg.StatusPostponedCount,
|
||||
arg.StatusPostponedBets,
|
||||
arg.StatusEndedCount,
|
||||
arg.StatusEndedBets,
|
||||
arg.StatusRemovedCount,
|
||||
arg.StatusRemovedBets,
|
||||
arg.RemovedCount,
|
||||
)
|
||||
var i ResultLog
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.StatusNotFinishedCount,
|
||||
&i.StatusNotFinishedBets,
|
||||
&i.StatusToBeFixedCount,
|
||||
&i.StatusToBeFixedBets,
|
||||
&i.StatusPostponedCount,
|
||||
&i.StatusPostponedBets,
|
||||
&i.StatusEndedCount,
|
||||
&i.StatusEndedBets,
|
||||
&i.StatusRemovedCount,
|
||||
&i.StatusRemovedBets,
|
||||
&i.RemovedCount,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const GetAllResultLog = `-- name: GetAllResultLog :many
|
||||
SELECT id, status_not_finished_count, status_not_finished_bets, status_to_be_fixed_count, status_to_be_fixed_bets, status_postponed_count, status_postponed_bets, status_ended_count, status_ended_bets, status_removed_count, status_removed_bets, removed_count, created_at, updated_at
|
||||
FROM result_log
|
||||
WHERE (
|
||||
created_at < $1
|
||||
OR $1 IS NULL
|
||||
)
|
||||
AND (
|
||||
created_at > $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
ORDER BY created_at DESC
|
||||
`
|
||||
|
||||
type GetAllResultLogParams struct {
|
||||
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetAllResultLog(ctx context.Context, arg GetAllResultLogParams) ([]ResultLog, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllResultLog, arg.CreatedBefore, arg.CreatedAfter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ResultLog
|
||||
for rows.Next() {
|
||||
var i ResultLog
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.StatusNotFinishedCount,
|
||||
&i.StatusNotFinishedBets,
|
||||
&i.StatusToBeFixedCount,
|
||||
&i.StatusToBeFixedBets,
|
||||
&i.StatusPostponedCount,
|
||||
&i.StatusPostponedBets,
|
||||
&i.StatusEndedCount,
|
||||
&i.StatusEndedBets,
|
||||
&i.StatusRemovedCount,
|
||||
&i.StatusRemovedBets,
|
||||
&i.RemovedCount,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
|
@ -7,17 +7,140 @@ package dbgen
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const GetSetting = `-- name: GetSetting :one
|
||||
SELECT key, value, created_at, updated_at
|
||||
FROM settings
|
||||
const DeleteAllCompanySetting = `-- name: DeleteAllCompanySetting :exec
|
||||
DELETE FROM company_settings
|
||||
WHERE company_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteAllCompanySetting(ctx context.Context, companyID int64) error {
|
||||
_, err := q.db.Exec(ctx, DeleteAllCompanySetting, companyID)
|
||||
return err
|
||||
}
|
||||
|
||||
const DeleteCompanySetting = `-- name: DeleteCompanySetting :exec
|
||||
DELETE FROM company_settings
|
||||
WHERE company_id = $1
|
||||
AND key = $2
|
||||
`
|
||||
|
||||
type DeleteCompanySettingParams struct {
|
||||
CompanyID int64 `json:"company_id"`
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
func (q *Queries) DeleteCompanySetting(ctx context.Context, arg DeleteCompanySettingParams) error {
|
||||
_, err := q.db.Exec(ctx, DeleteCompanySetting, arg.CompanyID, arg.Key)
|
||||
return err
|
||||
}
|
||||
|
||||
const GetAllCompanySettings = `-- name: GetAllCompanySettings :many
|
||||
SELECT company_id, key, value, created_at, updated_at
|
||||
FROM company_settings
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllCompanySettings(ctx context.Context) ([]CompanySetting, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllCompanySettings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []CompanySetting
|
||||
for rows.Next() {
|
||||
var i CompanySetting
|
||||
if err := rows.Scan(
|
||||
&i.CompanyID,
|
||||
&i.Key,
|
||||
&i.Value,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetCompanySetting = `-- name: GetCompanySetting :many
|
||||
SELECT company_id, key, value, created_at, updated_at
|
||||
FROM company_settings
|
||||
WHERE company_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetCompanySetting(ctx context.Context, companyID int64) ([]CompanySetting, error) {
|
||||
rows, err := q.db.Query(ctx, GetCompanySetting, companyID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []CompanySetting
|
||||
for rows.Next() {
|
||||
var i CompanySetting
|
||||
if err := rows.Scan(
|
||||
&i.CompanyID,
|
||||
&i.Key,
|
||||
&i.Value,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetCompanySettingsByKey = `-- name: GetCompanySettingsByKey :many
|
||||
SELECT company_id, key, value, created_at, updated_at
|
||||
FROM company_settings
|
||||
WHERE key = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetSetting(ctx context.Context, key string) (Setting, error) {
|
||||
row := q.db.QueryRow(ctx, GetSetting, key)
|
||||
var i Setting
|
||||
func (q *Queries) GetCompanySettingsByKey(ctx context.Context, key string) ([]CompanySetting, error) {
|
||||
rows, err := q.db.Query(ctx, GetCompanySettingsByKey, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []CompanySetting
|
||||
for rows.Next() {
|
||||
var i CompanySetting
|
||||
if err := rows.Scan(
|
||||
&i.CompanyID,
|
||||
&i.Key,
|
||||
&i.Value,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetGlobalSetting = `-- name: GetGlobalSetting :one
|
||||
SELECT key, value, created_at, updated_at
|
||||
FROM global_settings
|
||||
WHERE key = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetGlobalSetting(ctx context.Context, key string) (GlobalSetting, error) {
|
||||
row := q.db.QueryRow(ctx, GetGlobalSetting, key)
|
||||
var i GlobalSetting
|
||||
err := row.Scan(
|
||||
&i.Key,
|
||||
&i.Value,
|
||||
|
|
@ -27,20 +150,20 @@ func (q *Queries) GetSetting(ctx context.Context, key string) (Setting, error) {
|
|||
return i, err
|
||||
}
|
||||
|
||||
const GetSettings = `-- name: GetSettings :many
|
||||
const GetGlobalSettings = `-- name: GetGlobalSettings :many
|
||||
SELECT key, value, created_at, updated_at
|
||||
FROM settings
|
||||
FROM global_settings
|
||||
`
|
||||
|
||||
func (q *Queries) GetSettings(ctx context.Context) ([]Setting, error) {
|
||||
rows, err := q.db.Query(ctx, GetSettings)
|
||||
func (q *Queries) GetGlobalSettings(ctx context.Context) ([]GlobalSetting, error) {
|
||||
rows, err := q.db.Query(ctx, GetGlobalSettings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Setting
|
||||
var items []GlobalSetting
|
||||
for rows.Next() {
|
||||
var i Setting
|
||||
var i GlobalSetting
|
||||
if err := rows.Scan(
|
||||
&i.Key,
|
||||
&i.Value,
|
||||
|
|
@ -57,27 +180,79 @@ func (q *Queries) GetSettings(ctx context.Context) ([]Setting, error) {
|
|||
return items, nil
|
||||
}
|
||||
|
||||
const SaveSetting = `-- name: SaveSetting :one
|
||||
INSERT INTO settings (key, value, updated_at)
|
||||
VALUES ($1, $2, CURRENT_TIMESTAMP) ON CONFLICT (key) DO
|
||||
UPDATE
|
||||
SET value = EXCLUDED.value
|
||||
RETURNING key, value, created_at, updated_at
|
||||
const GetOverrideSettings = `-- name: GetOverrideSettings :many
|
||||
SELECT gs.key, gs.value, gs.created_at, gs.updated_at,
|
||||
COALESCE(cs.value, gs.value) AS value
|
||||
FROM global_settings gs
|
||||
LEFT JOIN company_settings cs ON cs.key = gs.key
|
||||
AND cs.company_id = $1
|
||||
`
|
||||
|
||||
type SaveSettingParams struct {
|
||||
type GetOverrideSettingsRow struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
Value_2 string `json:"value_2"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetOverrideSettings(ctx context.Context, companyID int64) ([]GetOverrideSettingsRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetOverrideSettings, companyID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetOverrideSettingsRow
|
||||
for rows.Next() {
|
||||
var i GetOverrideSettingsRow
|
||||
if err := rows.Scan(
|
||||
&i.Key,
|
||||
&i.Value,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Value_2,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const InsertCompanySetting = `-- name: InsertCompanySetting :exec
|
||||
INSERT INTO company_settings (company_id, key, value)
|
||||
VALUES ($1, $2, $3) ON CONFLICT (company_id, key) DO
|
||||
UPDATE
|
||||
SET value = EXCLUDED.value
|
||||
`
|
||||
|
||||
type InsertCompanySettingParams struct {
|
||||
CompanyID int64 `json:"company_id"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
func (q *Queries) InsertCompanySetting(ctx context.Context, arg InsertCompanySettingParams) error {
|
||||
_, err := q.db.Exec(ctx, InsertCompanySetting, arg.CompanyID, arg.Key, arg.Value)
|
||||
return err
|
||||
}
|
||||
|
||||
const UpdateGlobalSetting = `-- name: UpdateGlobalSetting :exec
|
||||
UPDATE global_settings
|
||||
SET value = $2,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE key = $1
|
||||
`
|
||||
|
||||
type UpdateGlobalSettingParams struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
func (q *Queries) SaveSetting(ctx context.Context, arg SaveSettingParams) (Setting, error) {
|
||||
row := q.db.QueryRow(ctx, SaveSetting, arg.Key, arg.Value)
|
||||
var i Setting
|
||||
err := row.Scan(
|
||||
&i.Key,
|
||||
&i.Value,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
func (q *Queries) UpdateGlobalSetting(ctx context.Context, arg UpdateGlobalSettingParams) error {
|
||||
_, err := q.db.Exec(ctx, UpdateGlobalSetting, arg.Key, arg.Value)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,22 +25,29 @@ func (q *Queries) CountTicketByIP(ctx context.Context, ip string) (int64, error)
|
|||
}
|
||||
|
||||
const CreateTicket = `-- name: CreateTicket :one
|
||||
INSERT INTO tickets (amount, total_odds, ip)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id, amount, total_odds, ip, created_at, updated_at
|
||||
INSERT INTO tickets (amount, total_odds, ip, company_id)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id, company_id, amount, total_odds, ip, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateTicketParams struct {
|
||||
Amount int64 `json:"amount"`
|
||||
TotalOdds float32 `json:"total_odds"`
|
||||
Ip string `json:"ip"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateTicket(ctx context.Context, arg CreateTicketParams) (Ticket, error) {
|
||||
row := q.db.QueryRow(ctx, CreateTicket, arg.Amount, arg.TotalOdds, arg.Ip)
|
||||
row := q.db.QueryRow(ctx, CreateTicket,
|
||||
arg.Amount,
|
||||
arg.TotalOdds,
|
||||
arg.Ip,
|
||||
arg.CompanyID,
|
||||
)
|
||||
var i Ticket
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.Amount,
|
||||
&i.TotalOdds,
|
||||
&i.Ip,
|
||||
|
|
@ -96,12 +103,16 @@ func (q *Queries) DeleteTicketOutcome(ctx context.Context, ticketID int64) error
|
|||
}
|
||||
|
||||
const GetAllTickets = `-- name: GetAllTickets :many
|
||||
SELECT id, amount, total_odds, ip, created_at, updated_at, outcomes
|
||||
SELECT id, company_id, amount, total_odds, ip, created_at, updated_at, outcomes
|
||||
FROM ticket_with_outcomes
|
||||
WHERE (
|
||||
company_id = $1
|
||||
OR $1 IS NULL
|
||||
)
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllTickets(ctx context.Context) ([]TicketWithOutcome, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllTickets)
|
||||
func (q *Queries) GetAllTickets(ctx context.Context, companyID pgtype.Int8) ([]TicketWithOutcome, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllTickets, companyID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -111,6 +122,7 @@ func (q *Queries) GetAllTickets(ctx context.Context) ([]TicketWithOutcome, error
|
|||
var i TicketWithOutcome
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.Amount,
|
||||
&i.TotalOdds,
|
||||
&i.Ip,
|
||||
|
|
@ -129,7 +141,8 @@ func (q *Queries) GetAllTickets(ctx context.Context) ([]TicketWithOutcome, error
|
|||
}
|
||||
|
||||
const GetAllTicketsInRange = `-- name: GetAllTicketsInRange :one
|
||||
SELECT COUNT(*) as total_tickets, COALESCE(SUM(amount), 0) as total_amount
|
||||
SELECT COUNT(*) as total_tickets,
|
||||
COALESCE(SUM(amount), 0) as total_amount
|
||||
FROM tickets
|
||||
WHERE created_at BETWEEN $1 AND $2
|
||||
`
|
||||
|
|
@ -152,7 +165,7 @@ func (q *Queries) GetAllTicketsInRange(ctx context.Context, arg GetAllTicketsInR
|
|||
}
|
||||
|
||||
const GetTicketByID = `-- name: GetTicketByID :one
|
||||
SELECT id, amount, total_odds, ip, created_at, updated_at, outcomes
|
||||
SELECT id, company_id, amount, total_odds, ip, created_at, updated_at, outcomes
|
||||
FROM ticket_with_outcomes
|
||||
WHERE id = $1
|
||||
`
|
||||
|
|
@ -162,6 +175,7 @@ func (q *Queries) GetTicketByID(ctx context.Context, id int64) (TicketWithOutcom
|
|||
var i TicketWithOutcome
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.Amount,
|
||||
&i.TotalOdds,
|
||||
&i.Ip,
|
||||
|
|
|
|||
|
|
@ -17,17 +17,20 @@ SELECT EXISTS (
|
|||
FROM users
|
||||
WHERE users.phone_number = $1
|
||||
AND users.phone_number IS NOT NULL
|
||||
AND users.company_id = $2
|
||||
) AS phone_exists,
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM users
|
||||
WHERE users.email = $2
|
||||
WHERE users.email = $3
|
||||
AND users.email IS NOT NULL
|
||||
AND users.company_id = $2
|
||||
) AS email_exists
|
||||
`
|
||||
|
||||
type CheckPhoneEmailExistParams struct {
|
||||
PhoneNumber pgtype.Text `json:"phone_number"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
Email pgtype.Text `json:"email"`
|
||||
}
|
||||
|
||||
|
|
@ -37,7 +40,7 @@ type CheckPhoneEmailExistRow struct {
|
|||
}
|
||||
|
||||
func (q *Queries) CheckPhoneEmailExist(ctx context.Context, arg CheckPhoneEmailExistParams) (CheckPhoneEmailExistRow, error) {
|
||||
row := q.db.QueryRow(ctx, CheckPhoneEmailExist, arg.PhoneNumber, arg.Email)
|
||||
row := q.db.QueryRow(ctx, CheckPhoneEmailExist, arg.PhoneNumber, arg.CompanyID, arg.Email)
|
||||
var i CheckPhoneEmailExistRow
|
||||
err := row.Scan(&i.PhoneExists, &i.EmailExists)
|
||||
return i, err
|
||||
|
|
@ -339,8 +342,14 @@ SELECT id,
|
|||
company_id
|
||||
FROM users
|
||||
WHERE email = $1
|
||||
AND company_id = $2
|
||||
`
|
||||
|
||||
type GetUserByEmailParams struct {
|
||||
Email pgtype.Text `json:"email"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
}
|
||||
|
||||
type GetUserByEmailRow struct {
|
||||
ID int64 `json:"id"`
|
||||
FirstName string `json:"first_name"`
|
||||
|
|
@ -357,8 +366,8 @@ type GetUserByEmailRow struct {
|
|||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetUserByEmail(ctx context.Context, email pgtype.Text) (GetUserByEmailRow, error) {
|
||||
row := q.db.QueryRow(ctx, GetUserByEmail, email)
|
||||
func (q *Queries) GetUserByEmail(ctx context.Context, arg GetUserByEmailParams) (GetUserByEmailRow, error) {
|
||||
row := q.db.QueryRow(ctx, GetUserByEmail, arg.Email, arg.CompanyID)
|
||||
var i GetUserByEmailRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
|
|
@ -424,8 +433,14 @@ SELECT id,
|
|||
company_id
|
||||
FROM users
|
||||
WHERE phone_number = $1
|
||||
AND company_id = $2
|
||||
`
|
||||
|
||||
type GetUserByPhoneParams struct {
|
||||
PhoneNumber pgtype.Text `json:"phone_number"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
}
|
||||
|
||||
type GetUserByPhoneRow struct {
|
||||
ID int64 `json:"id"`
|
||||
FirstName string `json:"first_name"`
|
||||
|
|
@ -442,8 +457,8 @@ type GetUserByPhoneRow struct {
|
|||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetUserByPhone(ctx context.Context, phoneNumber pgtype.Text) (GetUserByPhoneRow, error) {
|
||||
row := q.db.QueryRow(ctx, GetUserByPhone, phoneNumber)
|
||||
func (q *Queries) GetUserByPhone(ctx context.Context, arg GetUserByPhoneParams) (GetUserByPhoneRow, error) {
|
||||
row := q.db.QueryRow(ctx, GetUserByPhone, arg.PhoneNumber, arg.CompanyID)
|
||||
var i GetUserByPhoneRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
|
|
@ -478,25 +493,22 @@ SELECT id,
|
|||
suspended_at,
|
||||
company_id
|
||||
FROM users
|
||||
WHERE (
|
||||
first_name ILIKE '%' || $1 || '%'
|
||||
OR last_name ILIKE '%' || $1 || '%'
|
||||
OR phone_number LIKE '%' || $1 || '%'
|
||||
WHERE (company_id = $1)
|
||||
AND (
|
||||
first_name ILIKE '%' || $2 || '%'
|
||||
OR last_name ILIKE '%' || $2 || '%'
|
||||
OR phone_number LIKE '%' || $2 || '%'
|
||||
)
|
||||
AND (
|
||||
role = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
company_id = $3
|
||||
role = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
`
|
||||
|
||||
type SearchUserByNameOrPhoneParams struct {
|
||||
Column1 pgtype.Text `json:"column_1"`
|
||||
Role pgtype.Text `json:"role"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
Column2 pgtype.Text `json:"column_2"`
|
||||
Role pgtype.Text `json:"role"`
|
||||
}
|
||||
|
||||
type SearchUserByNameOrPhoneRow struct {
|
||||
|
|
@ -516,7 +528,7 @@ type SearchUserByNameOrPhoneRow struct {
|
|||
}
|
||||
|
||||
func (q *Queries) SearchUserByNameOrPhone(ctx context.Context, arg SearchUserByNameOrPhoneParams) ([]SearchUserByNameOrPhoneRow, error) {
|
||||
rows, err := q.db.Query(ctx, SearchUserByNameOrPhone, arg.Column1, arg.Role, arg.CompanyID)
|
||||
rows, err := q.db.Query(ctx, SearchUserByNameOrPhone, arg.CompanyID, arg.Column2, arg.Role)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -575,6 +587,7 @@ SET password = $1,
|
|||
WHERE (
|
||||
email = $2
|
||||
OR phone_number = $3
|
||||
AND company_id = $4
|
||||
)
|
||||
`
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ INSERT INTO wallets (
|
|||
type
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id, balance, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, currency, bonus_balance, cash_balance
|
||||
RETURNING id, balance, currency, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, bonus_balance, cash_balance
|
||||
`
|
||||
|
||||
type CreateWalletParams struct {
|
||||
|
|
@ -73,6 +73,7 @@ func (q *Queries) CreateWallet(ctx context.Context, arg CreateWalletParams) (Wal
|
|||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Balance,
|
||||
&i.Currency,
|
||||
&i.IsWithdraw,
|
||||
&i.IsBettable,
|
||||
&i.IsTransferable,
|
||||
|
|
@ -81,7 +82,6 @@ func (q *Queries) CreateWallet(ctx context.Context, arg CreateWalletParams) (Wal
|
|||
&i.IsActive,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Currency,
|
||||
&i.BonusBalance,
|
||||
&i.CashBalance,
|
||||
)
|
||||
|
|
@ -188,7 +188,7 @@ func (q *Queries) GetAllCustomerWallet(ctx context.Context) ([]CustomerWalletDet
|
|||
}
|
||||
|
||||
const GetAllWallets = `-- name: GetAllWallets :many
|
||||
SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, currency, bonus_balance, cash_balance
|
||||
SELECT id, balance, currency, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, bonus_balance, cash_balance
|
||||
FROM wallets
|
||||
`
|
||||
|
||||
|
|
@ -204,6 +204,7 @@ func (q *Queries) GetAllWallets(ctx context.Context) ([]Wallet, error) {
|
|||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Balance,
|
||||
&i.Currency,
|
||||
&i.IsWithdraw,
|
||||
&i.IsBettable,
|
||||
&i.IsTransferable,
|
||||
|
|
@ -212,7 +213,6 @@ func (q *Queries) GetAllWallets(ctx context.Context) ([]Wallet, error) {
|
|||
&i.IsActive,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Currency,
|
||||
&i.BonusBalance,
|
||||
&i.CashBalance,
|
||||
); err != nil {
|
||||
|
|
@ -319,7 +319,7 @@ func (q *Queries) GetCustomerWallet(ctx context.Context, customerID int64) (Cust
|
|||
}
|
||||
|
||||
const GetWalletByID = `-- name: GetWalletByID :one
|
||||
SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, currency, bonus_balance, cash_balance
|
||||
SELECT id, balance, currency, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, bonus_balance, cash_balance
|
||||
FROM wallets
|
||||
WHERE id = $1
|
||||
`
|
||||
|
|
@ -330,6 +330,7 @@ func (q *Queries) GetWalletByID(ctx context.Context, id int64) (Wallet, error) {
|
|||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Balance,
|
||||
&i.Currency,
|
||||
&i.IsWithdraw,
|
||||
&i.IsBettable,
|
||||
&i.IsTransferable,
|
||||
|
|
@ -338,7 +339,6 @@ func (q *Queries) GetWalletByID(ctx context.Context, id int64) (Wallet, error) {
|
|||
&i.IsActive,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Currency,
|
||||
&i.BonusBalance,
|
||||
&i.CashBalance,
|
||||
)
|
||||
|
|
@ -346,7 +346,7 @@ func (q *Queries) GetWalletByID(ctx context.Context, id int64) (Wallet, error) {
|
|||
}
|
||||
|
||||
const GetWalletByUserID = `-- name: GetWalletByUserID :many
|
||||
SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, currency, bonus_balance, cash_balance
|
||||
SELECT id, balance, currency, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, bonus_balance, cash_balance
|
||||
FROM wallets
|
||||
WHERE user_id = $1
|
||||
`
|
||||
|
|
@ -363,6 +363,7 @@ func (q *Queries) GetWalletByUserID(ctx context.Context, userID int64) ([]Wallet
|
|||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Balance,
|
||||
&i.Currency,
|
||||
&i.IsWithdraw,
|
||||
&i.IsBettable,
|
||||
&i.IsTransferable,
|
||||
|
|
@ -371,7 +372,6 @@ func (q *Queries) GetWalletByUserID(ctx context.Context, userID int64) ([]Wallet
|
|||
&i.IsActive,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Currency,
|
||||
&i.BonusBalance,
|
||||
&i.CashBalance,
|
||||
); err != nil {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,14 @@ package domain
|
|||
|
||||
import (
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
// The Odd ID here is not the odd id from our database
|
||||
// but the raw_odd_id from the betapi.from within the raw_odds json
|
||||
// This can be refactor later
|
||||
type BetOutcome struct {
|
||||
ID int64 `json:"id" example:"1"`
|
||||
BetID int64 `json:"bet_id" example:"1"`
|
||||
|
|
@ -46,6 +52,7 @@ type Bet struct {
|
|||
TotalOdds float32
|
||||
Status OutcomeStatus
|
||||
UserID int64
|
||||
CompanyID int64
|
||||
IsShopBet bool
|
||||
CashedOut bool
|
||||
FastCode string
|
||||
|
|
@ -54,6 +61,7 @@ type Bet struct {
|
|||
|
||||
type BetFilter struct {
|
||||
UserID ValidInt64
|
||||
CompanyID ValidInt64
|
||||
CashedOut ValidBool
|
||||
IsShopBet ValidBool
|
||||
Query ValidString
|
||||
|
|
@ -78,6 +86,7 @@ type GetBet struct {
|
|||
FullName string
|
||||
PhoneNumber string
|
||||
UserID int64
|
||||
CompanyID int64
|
||||
IsShopBet bool
|
||||
CashedOut bool
|
||||
Outcomes []BetOutcome
|
||||
|
|
@ -90,6 +99,7 @@ type CreateBet struct {
|
|||
TotalOdds float32
|
||||
Status OutcomeStatus
|
||||
UserID int64
|
||||
CompanyID int64
|
||||
IsShopBet bool
|
||||
OutcomesHash string
|
||||
FastCode string
|
||||
|
|
@ -130,6 +140,7 @@ type CreateBetRes struct {
|
|||
TotalOdds float32 `json:"total_odds" example:"4.22"`
|
||||
Status OutcomeStatus `json:"status" example:"1"`
|
||||
UserID int64 `json:"user_id" example:"2"`
|
||||
CompanyID int64 `json:"company_id" example:"1"`
|
||||
IsShopBet bool `json:"is_shop_bet" example:"false"`
|
||||
CreatedNumber int64 `json:"created_number" example:"2"`
|
||||
FastCode string `json:"fast_code"`
|
||||
|
|
@ -142,19 +153,21 @@ type BetRes struct {
|
|||
Status OutcomeStatus `json:"status" example:"1"`
|
||||
Fullname string `json:"full_name" example:"John Smith"`
|
||||
UserID int64 `json:"user_id" example:"2"`
|
||||
CompanyID int64 `json:"company_id" example:"1"`
|
||||
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 {
|
||||
func ConvertCreateBetRes(bet Bet, createdNumber int64) CreateBetRes {
|
||||
return CreateBetRes{
|
||||
ID: bet.ID,
|
||||
Amount: bet.Amount.Float32(),
|
||||
TotalOdds: bet.TotalOdds,
|
||||
Status: bet.Status,
|
||||
UserID: bet.UserID,
|
||||
CompanyID: bet.CompanyID,
|
||||
CreatedNumber: createdNumber,
|
||||
IsShopBet: bet.IsShopBet,
|
||||
FastCode: bet.FastCode,
|
||||
|
|
@ -169,6 +182,7 @@ func ConvertBet(bet GetBet) BetRes {
|
|||
Status: bet.Status,
|
||||
Fullname: bet.FullName,
|
||||
UserID: bet.UserID,
|
||||
CompanyID: bet.CompanyID,
|
||||
Outcomes: bet.Outcomes,
|
||||
IsShopBet: bet.IsShopBet,
|
||||
CashedOut: bet.CashedOut,
|
||||
|
|
@ -176,3 +190,106 @@ func ConvertBet(bet GetBet) BetRes {
|
|||
FastCode: bet.FastCode,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBBet(bet dbgen.Bet) Bet {
|
||||
return Bet{
|
||||
ID: bet.ID,
|
||||
Amount: Currency(bet.Amount),
|
||||
TotalOdds: bet.TotalOdds,
|
||||
Status: OutcomeStatus(bet.Status),
|
||||
UserID: bet.UserID,
|
||||
CompanyID: bet.CompanyID,
|
||||
IsShopBet: bet.IsShopBet,
|
||||
CashedOut: bet.CashedOut,
|
||||
FastCode: bet.FastCode,
|
||||
CreatedAt: bet.CreatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBBetOutcomes(outcome dbgen.BetOutcome) BetOutcome {
|
||||
return BetOutcome{
|
||||
ID: outcome.ID,
|
||||
BetID: outcome.BetID,
|
||||
SportID: outcome.SportID,
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBBetWithOutcomes(bet dbgen.BetWithOutcome) GetBet {
|
||||
var outcomes []BetOutcome = make([]BetOutcome, 0, len(bet.Outcomes))
|
||||
|
||||
for _, outcome := range bet.Outcomes {
|
||||
outcomes = append(outcomes, ConvertDBBetOutcomes(outcome))
|
||||
}
|
||||
|
||||
return GetBet{
|
||||
ID: bet.ID,
|
||||
Amount: Currency(bet.Amount),
|
||||
TotalOdds: bet.TotalOdds,
|
||||
Status: OutcomeStatus(bet.Status),
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBFlag(flag dbgen.Flag) Flag {
|
||||
return Flag{
|
||||
ID: flag.ID,
|
||||
BetID: flag.BetID.Int64,
|
||||
OddID: flag.OddsMarketID.Int64,
|
||||
Reason: flag.Reason.String,
|
||||
FlaggedAt: flag.FlaggedAt.Time,
|
||||
Resolved: flag.Resolved.Bool,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBCreateBetOutcome(betOutcome CreateBetOutcome) dbgen.CreateBetOutcomeParams {
|
||||
return dbgen.CreateBetOutcomeParams{
|
||||
BetID: betOutcome.BetID,
|
||||
EventID: betOutcome.EventID,
|
||||
SportID: betOutcome.SportID,
|
||||
OddID: betOutcome.OddID,
|
||||
HomeTeamName: betOutcome.HomeTeamName,
|
||||
AwayTeamName: betOutcome.AwayTeamName,
|
||||
MarketID: betOutcome.MarketID,
|
||||
MarketName: betOutcome.MarketName,
|
||||
Odd: betOutcome.Odd,
|
||||
OddName: betOutcome.OddName,
|
||||
OddHeader: betOutcome.OddHeader,
|
||||
OddHandicap: betOutcome.OddHandicap,
|
||||
Expires: pgtype.Timestamp{
|
||||
Time: betOutcome.Expires,
|
||||
Valid: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCreateBet(bet CreateBet) dbgen.CreateBetParams {
|
||||
return dbgen.CreateBetParams{
|
||||
Amount: int64(bet.Amount),
|
||||
TotalOdds: bet.TotalOdds,
|
||||
Status: int32(bet.Status),
|
||||
UserID: bet.UserID,
|
||||
CompanyID: bet.CompanyID,
|
||||
IsShopBet: bet.IsShopBet,
|
||||
OutcomesHash: bet.OutcomesHash,
|
||||
FastCode: bet.FastCode,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,68 +1,11 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var MongoDBLogger *zap.Logger
|
||||
|
||||
type ValidInt64 struct {
|
||||
Value int64
|
||||
Valid bool
|
||||
}
|
||||
type ValidInt struct {
|
||||
Value int
|
||||
Valid bool
|
||||
}
|
||||
type ValidInt32 struct {
|
||||
Value int32
|
||||
Valid bool
|
||||
}
|
||||
|
||||
type ValidFloat32 struct {
|
||||
Value float32
|
||||
Valid bool
|
||||
}
|
||||
|
||||
type ValidString struct {
|
||||
Value string
|
||||
Valid bool
|
||||
}
|
||||
type ValidTime struct {
|
||||
Value time.Time
|
||||
Valid bool
|
||||
}
|
||||
type ValidBool struct {
|
||||
Value bool
|
||||
Valid bool
|
||||
}
|
||||
|
||||
type Currency int64
|
||||
|
||||
// ToCurrency converts a float32 to Currency
|
||||
func ToCurrency(f float32) Currency {
|
||||
return Currency((f * 100) + 0.5)
|
||||
}
|
||||
|
||||
// Float32 converts a Currency to float32
|
||||
func (m Currency) Float32() float32 {
|
||||
x := float32(m)
|
||||
x = x / 100
|
||||
return x
|
||||
}
|
||||
|
||||
// String returns a formatted Currency value
|
||||
func (m Currency) String() string {
|
||||
x := float32(m)
|
||||
x = x / 100
|
||||
return fmt.Sprintf("$%.2f", x)
|
||||
}
|
||||
|
||||
type ResponseWDataFactory[T any] struct {
|
||||
Data T `json:"data"`
|
||||
Response
|
||||
|
|
@ -95,73 +38,3 @@ type Pagination struct {
|
|||
|
||||
func PtrFloat64(v float64) *float64 { return &v }
|
||||
func PtrInt64(v int64) *int64 { return &v }
|
||||
|
||||
type Int64JSON int64
|
||||
|
||||
// func (i *Int64JSON) Parse() (int64, error) {
|
||||
// var asString string
|
||||
// if err := json.Unmarshal(i, &asString); err == nil {
|
||||
// // Try to parse the string to int64
|
||||
// return strconv.ParseInt(strings.TrimSpace(asString), 10, 64)
|
||||
// }
|
||||
|
||||
// var asInt int64
|
||||
// if err := json.Unmarshal(i, &asInt); err == nil {
|
||||
// return asInt, nil
|
||||
// }
|
||||
|
||||
// // Neither string nor int worked
|
||||
// return 0, fmt.Errorf("invalid int64 value: %s", string(i))
|
||||
// }
|
||||
|
||||
func (i *Int64JSON) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(data, &s); err == nil {
|
||||
// it was a string, parse it
|
||||
v, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*i = Int64JSON(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
var v int64
|
||||
if err := json.Unmarshal(data, &v); err == nil {
|
||||
*i = Int64JSON(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("invalid int64 value: %s", string(data))
|
||||
}
|
||||
|
||||
type NullableInt64JSON struct {
|
||||
Int64 int64
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (n *NullableInt64JSON) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(data, &s); err == nil {
|
||||
if s == "" {
|
||||
n.Valid = false
|
||||
return nil
|
||||
}
|
||||
v, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.Int64, n.Valid = v, true
|
||||
return nil
|
||||
}
|
||||
|
||||
var v int64
|
||||
if err := json.Unmarshal(data, &v); err == nil {
|
||||
n.Int64, n.Valid = v, true
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("invalid int64 value: %s", string(data))
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
34
internal/domain/common_log.go
Normal file
34
internal/domain/common_log.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// var BadRequestZapFields = []zap.Field{
|
||||
// zap.Int("status_code", fiber.StatusBadRequest),
|
||||
// zap.Time("timestamp", time.Now()),
|
||||
// }
|
||||
// var InternalServerErrorZapFields = []zap.Field{
|
||||
// zap.Int("status_code", fiber.StatusBadRequest),
|
||||
// zap.Time("timestamp", time.Now()),
|
||||
// }
|
||||
|
||||
var SuccessResZapFields = []zap.Field{
|
||||
zap.Int("status_code", fiber.StatusBadRequest),
|
||||
zap.Time("timestamp", time.Now()),
|
||||
}
|
||||
|
||||
// var BadRequestLogger = MongoDBLogger.With(
|
||||
// zap.Int("status_code", fiber.StatusBadRequest),
|
||||
// zap.Time("timestamp", time.Now()))
|
||||
|
||||
// var InternalServerErrorLogger = MongoDBLogger.With(
|
||||
// zap.Int("status_code", fiber.StatusInternalServerError),
|
||||
// zap.Time("timestamp", time.Now()))
|
||||
|
||||
// var SuccessResLogger = MongoDBLogger.With(
|
||||
// zap.Int("status_code", fiber.StatusOK),
|
||||
// zap.Time("timestamp", time.Now()))
|
||||
|
|
@ -11,6 +11,7 @@ import (
|
|||
type Company struct {
|
||||
ID int64
|
||||
Name string
|
||||
Slug string
|
||||
AdminID int64
|
||||
WalletID int64
|
||||
DeductedPercentage float32
|
||||
|
|
@ -27,6 +28,7 @@ type CompanyFilter struct {
|
|||
type GetCompany struct {
|
||||
ID int64
|
||||
Name string
|
||||
Slug string
|
||||
AdminID int64
|
||||
AdminFirstName string
|
||||
AdminLastName string
|
||||
|
|
@ -68,6 +70,7 @@ type UpdateCompanyReq struct {
|
|||
type CompanyRes struct {
|
||||
ID int64 `json:"id" example:"1"`
|
||||
Name string `json:"name" example:"CompanyName"`
|
||||
Slug string `json:"slug" example:"slug"`
|
||||
AdminID int64 `json:"admin_id" example:"1"`
|
||||
WalletID int64 `json:"wallet_id" example:"1"`
|
||||
DeductedPercentage float32 `json:"deducted_percentage" example:"0.1"`
|
||||
|
|
@ -77,6 +80,7 @@ type CompanyRes struct {
|
|||
type GetCompanyRes struct {
|
||||
ID int64 `json:"id" example:"1"`
|
||||
Name string `json:"name" example:"CompanyName"`
|
||||
Slug string `json:"slug" example:"slug"`
|
||||
AdminID int64 `json:"admin_id" example:"1"`
|
||||
WalletID int64 `json:"wallet_id" example:"1"`
|
||||
WalletBalance float32 `json:"balance" example:"1"`
|
||||
|
|
@ -89,20 +93,14 @@ type GetCompanyRes struct {
|
|||
}
|
||||
|
||||
func ConvertCompany(company Company) CompanyRes {
|
||||
return CompanyRes{
|
||||
ID: company.ID,
|
||||
Name: company.Name,
|
||||
AdminID: company.AdminID,
|
||||
WalletID: company.WalletID,
|
||||
IsActive: company.IsActive,
|
||||
DeductedPercentage: company.DeductedPercentage,
|
||||
}
|
||||
return CompanyRes(company)
|
||||
}
|
||||
|
||||
func ConvertGetCompany(company GetCompany) GetCompanyRes {
|
||||
return GetCompanyRes{
|
||||
ID: company.ID,
|
||||
Name: company.Name,
|
||||
Slug: company.Slug,
|
||||
AdminID: company.AdminID,
|
||||
WalletID: company.WalletID,
|
||||
WalletBalance: company.WalletBalance.Float32(),
|
||||
|
|
@ -112,13 +110,13 @@ func ConvertGetCompany(company GetCompany) GetCompanyRes {
|
|||
AdminFirstName: company.AdminFirstName,
|
||||
AdminLastName: company.AdminLastName,
|
||||
AdminPhoneNumber: company.AdminPhoneNumber,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCreateCompany(company CreateCompany) dbgen.CreateCompanyParams {
|
||||
func ConvertCreateCompany(company CreateCompany, uniqueSlug string) dbgen.CreateCompanyParams {
|
||||
return dbgen.CreateCompanyParams{
|
||||
Name: company.Name,
|
||||
Slug: uniqueSlug,
|
||||
AdminID: company.AdminID,
|
||||
WalletID: company.WalletID,
|
||||
DeductedPercentage: company.DeductedPercentage,
|
||||
|
|
@ -129,6 +127,7 @@ func ConvertDBCompany(dbCompany dbgen.Company) Company {
|
|||
return Company{
|
||||
ID: dbCompany.ID,
|
||||
Name: dbCompany.Name,
|
||||
Slug: dbCompany.Slug,
|
||||
AdminID: dbCompany.AdminID,
|
||||
WalletID: dbCompany.WalletID,
|
||||
DeductedPercentage: dbCompany.DeductedPercentage,
|
||||
|
|
@ -140,6 +139,7 @@ func ConvertDBCompanyDetails(dbCompany dbgen.CompaniesDetail) GetCompany {
|
|||
return GetCompany{
|
||||
ID: dbCompany.ID,
|
||||
Name: dbCompany.Name,
|
||||
Slug: dbCompany.Slug,
|
||||
AdminID: dbCompany.AdminID,
|
||||
WalletID: dbCompany.WalletID,
|
||||
WalletBalance: Currency(dbCompany.Balance),
|
||||
|
|
|
|||
|
|
@ -3,9 +3,28 @@ package domain
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Currency int64
|
||||
|
||||
// ToCurrency converts a float32 (like 12.34) into Currency (stored in cents).
|
||||
func ToCurrency(f float32) Currency {
|
||||
cents := math.Round(float64(f) * 100) // avoid float32 precision issues
|
||||
return Currency(int64(cents))
|
||||
}
|
||||
|
||||
// Float32 converts a Currency back into float32 (like 12.34).
|
||||
func (m Currency) Float32() float32 {
|
||||
return float32(m) / 100
|
||||
}
|
||||
|
||||
// String returns a formatted Currency value for display.
|
||||
func (m Currency) String() string {
|
||||
return fmt.Sprintf("$%.2f", m.Float32())
|
||||
}
|
||||
|
||||
type IntCurrency string
|
||||
|
||||
const (
|
||||
|
|
|
|||
69
internal/domain/custom_odds.go
Normal file
69
internal/domain/custom_odds.go
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
package domain
|
||||
|
||||
// import (
|
||||
// "encoding/json"
|
||||
// "time"
|
||||
|
||||
// dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
// )
|
||||
|
||||
// type CustomOdd struct {
|
||||
// ID int64
|
||||
// OddID int64
|
||||
// CompanyID int64
|
||||
// EventID string
|
||||
// RawOdds []json.RawMessage
|
||||
// CreatedAt time.Time
|
||||
// }
|
||||
|
||||
// type CreateCustomOdd struct {
|
||||
// OddID int64
|
||||
// CompanyID int64
|
||||
// EventID string
|
||||
// RawOdds []json.RawMessage
|
||||
// }
|
||||
|
||||
// type CustomOddFilter struct {
|
||||
// CompanyID ValidInt64
|
||||
// }
|
||||
|
||||
// func ConvertCreateCustomOdd(odd CreateCustomOdd) (dbgen.InsertCustomOddParams, error) {
|
||||
// rawOddsBytes, err := json.Marshal(odd.RawOdds)
|
||||
|
||||
// if err != nil {
|
||||
// return dbgen.InsertCustomOddParams{}, err
|
||||
// }
|
||||
// return dbgen.InsertCustomOddParams{
|
||||
// OddID: odd.OddID,
|
||||
// CompanyID: odd.CompanyID,
|
||||
// EventID: odd.EventID,
|
||||
// RawOdds: rawOddsBytes,
|
||||
// }, nil
|
||||
// }
|
||||
|
||||
// func ConvertDBCustomOdd(dbCustomOdd dbgen.CustomOdd) (CustomOdd, error) {
|
||||
// var rawOdds []json.RawMessage
|
||||
// if err := json.Unmarshal(dbCustomOdd.RawOdds, &rawOdds); err != nil {
|
||||
// return CustomOdd{}, err
|
||||
// }
|
||||
// return CustomOdd{
|
||||
// ID: dbCustomOdd.ID,
|
||||
// OddID: dbCustomOdd.OddID,
|
||||
// CompanyID: dbCustomOdd.CompanyID,
|
||||
// EventID: dbCustomOdd.EventID,
|
||||
// RawOdds: rawOdds,
|
||||
// CreatedAt: dbCustomOdd.CreatedAt.Time,
|
||||
// }, nil
|
||||
// }
|
||||
|
||||
// func ConvertDbCustomOdds(list []dbgen.CustomOdd) ([]CustomOdd, error) {
|
||||
// result := make([]CustomOdd, 0, len(list))
|
||||
// for _, item := range list {
|
||||
// convertedItem, err := ConvertDBCustomOdd(item)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// result = append(result, convertedItem)
|
||||
// }
|
||||
// return result, nil
|
||||
// }
|
||||
51
internal/domain/disabled_odds.go
Normal file
51
internal/domain/disabled_odds.go
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
)
|
||||
|
||||
type DisabledOdd struct {
|
||||
ID int64
|
||||
OddMarketID int64
|
||||
RawOddID int64
|
||||
EventID string
|
||||
CompanyID int64
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type CreateDisabledOdd struct {
|
||||
OddMarketID int64
|
||||
RawOddID int64
|
||||
EventID string
|
||||
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
|
||||
}
|
||||
|
|
@ -1,6 +1,11 @@
|
|||
package domain
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
// TODO: turn status into an enum
|
||||
// Status represents the status of an event.
|
||||
|
|
@ -35,100 +40,408 @@ const (
|
|||
STATUS_REMOVED EventStatus = "removed"
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
ID string
|
||||
SportID int32
|
||||
MatchName string
|
||||
HomeTeam string
|
||||
AwayTeam string
|
||||
HomeTeamID int32
|
||||
AwayTeamID int32
|
||||
HomeKitImage string
|
||||
AwayKitImage string
|
||||
LeagueID int32
|
||||
LeagueName string
|
||||
LeagueCC string
|
||||
StartTime string
|
||||
Score string
|
||||
MatchMinute int
|
||||
TimerStatus string
|
||||
AddedTime int
|
||||
MatchPeriod int
|
||||
IsLive bool
|
||||
Status string
|
||||
Source string
|
||||
type EventSource string
|
||||
|
||||
const (
|
||||
EVENT_SOURCE_BET365 EventSource = "b365api"
|
||||
EVENT_SOURCE_BWIN EventSource = "bwin"
|
||||
EVENT_SOURCE_BETFAIR EventSource = "bfair"
|
||||
EVENT_SOURCE_1XBET EventSource = "1xbet"
|
||||
EVENT_SOURCE_ENET EventSource = "enetpulse"
|
||||
)
|
||||
|
||||
type BaseEvent struct {
|
||||
ID string
|
||||
SportID int32
|
||||
MatchName string
|
||||
HomeTeam string
|
||||
AwayTeam string
|
||||
HomeTeamID int64
|
||||
AwayTeamID int64
|
||||
HomeTeamImage string
|
||||
AwayTeamImage string
|
||||
LeagueID int64
|
||||
LeagueName string
|
||||
LeagueCC ValidString
|
||||
StartTime time.Time
|
||||
Source EventSource
|
||||
Status EventStatus
|
||||
IsMonitored bool
|
||||
DefaultIsFeatured bool
|
||||
DefaultIsActive bool
|
||||
DefaultWinningUpperLimit int32
|
||||
Score ValidString
|
||||
MatchMinute ValidInt
|
||||
TimerStatus ValidString
|
||||
AddedTime ValidInt
|
||||
MatchPeriod ValidInt
|
||||
IsLive bool
|
||||
FetchedAt time.Time
|
||||
}
|
||||
type BaseEventRes struct {
|
||||
ID string `json:"id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
MatchName string `json:"match_name"`
|
||||
HomeTeam string `json:"home_team"`
|
||||
AwayTeam string `json:"away_team"`
|
||||
HomeTeamID int64 `json:"home_team_id"`
|
||||
AwayTeamID int64 `json:"away_team_id"`
|
||||
HomeTeamImage string `json:"home_team_image"`
|
||||
AwayTeamImage string `json:"away_team_image"`
|
||||
LeagueID int64 `json:"league_id"`
|
||||
LeagueName string `json:"league_name"`
|
||||
LeagueCC string `json:"league_cc"`
|
||||
StartTime time.Time `json:"start_time"`
|
||||
Source EventSource `json:"source"`
|
||||
Status EventStatus `json:"status"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultWinningUpperLimit int32 `json:"default_winning_upper_limit"`
|
||||
Score string `json:"score,omitempty"`
|
||||
MatchMinute int `json:"match_minute,omitempty"`
|
||||
TimerStatus string `json:"timer_status,omitempty"`
|
||||
AddedTime int `json:"added_time,omitempty"`
|
||||
MatchPeriod int `json:"match_period,omitempty"`
|
||||
IsLive bool `json:"is_live"`
|
||||
FetchedAt time.Time `json:"fetched_at"`
|
||||
}
|
||||
type EventWithSettings struct {
|
||||
ID string
|
||||
SportID int32
|
||||
MatchName string
|
||||
HomeTeam string
|
||||
AwayTeam string
|
||||
HomeTeamID int64
|
||||
AwayTeamID int64
|
||||
HomeTeamImage string
|
||||
AwayTeamImage string
|
||||
LeagueID int64
|
||||
LeagueName string
|
||||
LeagueCC ValidString
|
||||
StartTime time.Time
|
||||
Source EventSource
|
||||
Status EventStatus
|
||||
IsFeatured bool
|
||||
IsMonitored bool
|
||||
IsActive bool
|
||||
WinningUpperLimit int32
|
||||
Score ValidString
|
||||
MatchMinute ValidInt
|
||||
TimerStatus ValidString
|
||||
AddedTime ValidInt
|
||||
MatchPeriod ValidInt
|
||||
IsLive bool
|
||||
UpdatedAt time.Time
|
||||
FetchedAt time.Time
|
||||
}
|
||||
|
||||
type BetResult struct {
|
||||
Success int `json:"success"`
|
||||
Pager struct {
|
||||
Page int `json:"page"`
|
||||
PerPage int `json:"per_page"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
Results []struct {
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
League struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"league"`
|
||||
Home struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"home"`
|
||||
Away *struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"away"`
|
||||
} `json:"results"`
|
||||
type CreateEvent struct {
|
||||
ID string
|
||||
SportID int32
|
||||
MatchName string
|
||||
HomeTeam string
|
||||
AwayTeam string
|
||||
HomeTeamID int64
|
||||
AwayTeamID int64
|
||||
HomeTeamImage string
|
||||
AwayTeamImage string
|
||||
LeagueID int64
|
||||
LeagueName string
|
||||
StartTime time.Time
|
||||
IsLive bool
|
||||
Status EventStatus
|
||||
Source EventSource
|
||||
}
|
||||
|
||||
type UpcomingEvent struct {
|
||||
ID string `json:"id"` // Event ID
|
||||
SportID int32 `json:"sport_id"` // Sport ID
|
||||
MatchName string `json:"match_name"` // Match or event name
|
||||
HomeTeam string `json:"home_team"` // Home team name (if available)
|
||||
AwayTeam string `json:"away_team"` // Away team name (can be empty/null)
|
||||
HomeTeamID int32 `json:"home_team_id"` // Home team ID
|
||||
AwayTeamID int32 `json:"away_team_id"` // Away team ID (can be empty/null)
|
||||
HomeKitImage string `json:"home_kit_image"` // Kit or image for home team (optional)
|
||||
AwayKitImage string `json:"away_kit_image"` // Kit or image for away team (optional)
|
||||
LeagueID int32 `json:"league_id"` // League ID
|
||||
LeagueName string `json:"league_name"` // League name
|
||||
LeagueCC string `json:"league_cc"` // League country code
|
||||
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
|
||||
IsFeatured bool `json:"is_featured"` //Whether the event is featured or not
|
||||
IsActive bool `json:"is_active"` //Whether the event is featured or not
|
||||
}
|
||||
type MatchResult struct {
|
||||
EventID string
|
||||
FullScore string
|
||||
HalfScore string
|
||||
Status string
|
||||
Scores map[string]map[string]string
|
||||
type EventWithSettingsRes struct {
|
||||
ID string `json:"id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
MatchName string `json:"match_name"`
|
||||
HomeTeam string `json:"home_team"`
|
||||
AwayTeam string `json:"away_team"`
|
||||
HomeTeamID int64 `json:"home_team_id"`
|
||||
AwayTeamID int64 `json:"away_team_id"`
|
||||
HomeTeamImage string `json:"home_team_image"`
|
||||
AwayTeamImage string `json:"away_team_image"`
|
||||
LeagueID int64 `json:"league_id"`
|
||||
LeagueName string `json:"league_name"`
|
||||
LeagueCC string `json:"league_cc"`
|
||||
StartTime time.Time `json:"start_time"`
|
||||
Source EventSource `json:"source"`
|
||||
Status EventStatus `json:"status"`
|
||||
IsFeatured bool `json:"is_featured"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
IsActive bool `json:"is_active"`
|
||||
WinningUpperLimit int32 `json:"winning_upper_limit"`
|
||||
Score string `json:"score,omitempty"`
|
||||
MatchMinute int `json:"match_minute,omitempty"`
|
||||
TimerStatus string `json:"timer_status,omitempty"`
|
||||
AddedTime int `json:"added_time,omitempty"`
|
||||
MatchPeriod int `json:"match_period,omitempty"`
|
||||
IsLive bool `json:"is_live"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
FetchedAt time.Time `json:"fetched_at"`
|
||||
}
|
||||
|
||||
type Odds struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
MarketType string `json:"market_type"`
|
||||
Name string `json:"name"`
|
||||
HitStatus string `json:"hit_status"`
|
||||
type EventSettings struct {
|
||||
CompanyID int64
|
||||
EventID string
|
||||
IsActive ValidBool
|
||||
IsFeatured ValidBool
|
||||
WinningUpperLimit ValidInt
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type CreateEventSettings struct {
|
||||
CompanyID int64
|
||||
EventID string
|
||||
IsActive ValidBool
|
||||
IsFeatured ValidBool
|
||||
WinningUpperLimit ValidInt
|
||||
}
|
||||
|
||||
type EventFilter struct {
|
||||
Query ValidString
|
||||
SportID ValidInt32
|
||||
LeagueID ValidInt32
|
||||
LeagueID ValidInt64
|
||||
CountryCode ValidString
|
||||
FirstStartTime ValidTime
|
||||
LastStartTime ValidTime
|
||||
Limit ValidInt64
|
||||
Offset ValidInt64
|
||||
Limit ValidInt32
|
||||
Offset ValidInt32
|
||||
MatchStatus ValidString // e.g., "upcoming", "in_play", "ended"
|
||||
Featured ValidBool
|
||||
}
|
||||
|
||||
func ConvertDBEvent(event dbgen.EventWithCountry) BaseEvent {
|
||||
return BaseEvent{
|
||||
ID: event.ID,
|
||||
SportID: event.SportID,
|
||||
MatchName: event.MatchName,
|
||||
HomeTeam: event.HomeTeam,
|
||||
AwayTeam: event.AwayTeam,
|
||||
HomeTeamID: event.HomeTeamID,
|
||||
AwayTeamID: event.AwayTeamID,
|
||||
HomeTeamImage: event.HomeKitImage,
|
||||
AwayTeamImage: event.AwayKitImage,
|
||||
LeagueID: event.LeagueID,
|
||||
LeagueName: event.LeagueName,
|
||||
LeagueCC: ValidString{
|
||||
Value: event.LeagueCc.String,
|
||||
Valid: event.LeagueCc.Valid,
|
||||
},
|
||||
StartTime: event.StartTime.Time.UTC(),
|
||||
Source: EventSource(event.Source),
|
||||
Status: EventStatus(event.Status),
|
||||
DefaultIsFeatured: event.DefaultIsFeatured,
|
||||
IsMonitored: event.IsMonitored,
|
||||
DefaultIsActive: event.DefaultIsActive,
|
||||
DefaultWinningUpperLimit: event.DefaultWinningUpperLimit,
|
||||
Score: ValidString{
|
||||
Value: event.Score.String,
|
||||
Valid: event.Score.Valid,
|
||||
},
|
||||
MatchMinute: ValidInt{
|
||||
Value: int(event.MatchMinute.Int32),
|
||||
Valid: event.MatchMinute.Valid,
|
||||
},
|
||||
TimerStatus: ValidString{
|
||||
Value: event.TimerStatus.String,
|
||||
Valid: event.TimerStatus.Valid,
|
||||
},
|
||||
AddedTime: ValidInt{
|
||||
Value: int(event.AddedTime.Int32),
|
||||
Valid: event.AddedTime.Valid,
|
||||
},
|
||||
MatchPeriod: ValidInt{
|
||||
Value: int(event.MatchPeriod.Int32),
|
||||
Valid: event.MatchPeriod.Valid,
|
||||
},
|
||||
IsLive: event.IsLive,
|
||||
FetchedAt: event.FetchedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBEvents(events []dbgen.EventWithCountry) []BaseEvent {
|
||||
result := make([]BaseEvent, len(events))
|
||||
for i, e := range events {
|
||||
result[i] = ConvertDBEvent(e)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ConvertCreateEvent(e CreateEvent) dbgen.InsertEventParams {
|
||||
return dbgen.InsertEventParams{
|
||||
ID: e.ID,
|
||||
SportID: e.SportID,
|
||||
MatchName: e.MatchName,
|
||||
HomeTeam: e.HomeTeam,
|
||||
AwayTeam: e.AwayTeam,
|
||||
HomeTeamID: e.HomeTeamID,
|
||||
AwayTeamID: e.AwayTeamID,
|
||||
HomeKitImage: e.HomeTeamImage,
|
||||
AwayKitImage: e.AwayTeamImage,
|
||||
LeagueID: e.LeagueID,
|
||||
LeagueName: e.LeagueName,
|
||||
StartTime: pgtype.Timestamp{Time: e.StartTime, Valid: true},
|
||||
IsLive: e.IsLive,
|
||||
Status: string(e.Status),
|
||||
Source: string(e.Source),
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCreateEventSettings(eventSettings CreateEventSettings) dbgen.InsertEventSettingsParams {
|
||||
return dbgen.InsertEventSettingsParams{
|
||||
CompanyID: eventSettings.CompanyID,
|
||||
EventID: eventSettings.EventID,
|
||||
IsActive: eventSettings.IsActive.ToPG(),
|
||||
IsFeatured: eventSettings.IsFeatured.ToPG(),
|
||||
WinningUpperLimit: eventSettings.WinningUpperLimit.ToPG(),
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBEventWithSetting(event dbgen.EventWithSetting) EventWithSettings {
|
||||
return EventWithSettings{
|
||||
ID: event.ID,
|
||||
SportID: event.SportID,
|
||||
MatchName: event.MatchName,
|
||||
HomeTeam: event.HomeTeam,
|
||||
AwayTeam: event.AwayTeam,
|
||||
HomeTeamID: event.HomeTeamID,
|
||||
AwayTeamID: event.AwayTeamID,
|
||||
HomeTeamImage: event.HomeKitImage,
|
||||
AwayTeamImage: event.AwayKitImage,
|
||||
LeagueID: event.LeagueID,
|
||||
LeagueName: event.LeagueName,
|
||||
LeagueCC: ValidString{
|
||||
Value: event.LeagueCc.String,
|
||||
Valid: event.LeagueCc.Valid,
|
||||
},
|
||||
StartTime: event.StartTime.Time.UTC(),
|
||||
Source: EventSource(event.Source),
|
||||
Status: EventStatus(event.Status),
|
||||
IsFeatured: event.IsFeatured,
|
||||
IsMonitored: event.IsMonitored,
|
||||
IsActive: event.IsActive,
|
||||
WinningUpperLimit: event.WinningUpperLimit,
|
||||
Score: ValidString{
|
||||
Value: event.Score.String,
|
||||
Valid: event.Score.Valid,
|
||||
},
|
||||
MatchMinute: ValidInt{
|
||||
Value: int(event.MatchMinute.Int32),
|
||||
Valid: event.MatchMinute.Valid,
|
||||
},
|
||||
TimerStatus: ValidString{
|
||||
Value: event.TimerStatus.String,
|
||||
Valid: event.TimerStatus.Valid,
|
||||
},
|
||||
AddedTime: ValidInt{
|
||||
Value: int(event.AddedTime.Int32),
|
||||
Valid: event.AddedTime.Valid,
|
||||
},
|
||||
MatchPeriod: ValidInt{
|
||||
Value: int(event.MatchPeriod.Int32),
|
||||
Valid: event.MatchPeriod.Valid,
|
||||
},
|
||||
IsLive: event.IsLive,
|
||||
UpdatedAt: event.UpdatedAt.Time,
|
||||
FetchedAt: event.FetchedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBEventWithSettings(events []dbgen.EventWithSetting) []EventWithSettings {
|
||||
result := make([]EventWithSettings, len(events))
|
||||
for i, e := range events {
|
||||
result[i] = ConvertDBEventWithSetting(e)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ConvertUpdateEventSettings(event CreateEventSettings) dbgen.UpdateEventSettingsParams {
|
||||
return dbgen.UpdateEventSettingsParams{
|
||||
EventID: event.EventID,
|
||||
CompanyID: event.CompanyID,
|
||||
IsActive: event.IsActive.ToPG(),
|
||||
IsFeatured: event.IsFeatured.ToPG(),
|
||||
WinningUpperLimit: event.WinningUpperLimit.ToPG(),
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertEventRes(event BaseEvent) BaseEventRes {
|
||||
return BaseEventRes{
|
||||
ID: event.ID,
|
||||
SportID: event.SportID,
|
||||
MatchName: event.MatchName,
|
||||
HomeTeam: event.HomeTeam,
|
||||
AwayTeam: event.AwayTeam,
|
||||
HomeTeamID: event.HomeTeamID,
|
||||
AwayTeamID: event.AwayTeamID,
|
||||
HomeTeamImage: event.HomeTeamImage,
|
||||
AwayTeamImage: event.AwayTeamImage,
|
||||
LeagueID: event.LeagueID,
|
||||
LeagueName: event.LeagueName,
|
||||
LeagueCC: event.LeagueCC.Value,
|
||||
StartTime: event.StartTime.UTC(),
|
||||
Source: EventSource(event.Source),
|
||||
Status: EventStatus(event.Status),
|
||||
DefaultIsFeatured: event.DefaultIsFeatured,
|
||||
IsMonitored: event.IsMonitored,
|
||||
DefaultIsActive: event.DefaultIsActive,
|
||||
DefaultWinningUpperLimit: event.DefaultWinningUpperLimit,
|
||||
Score: event.Score.Value,
|
||||
MatchMinute: event.MatchMinute.Value,
|
||||
TimerStatus: event.TimerStatus.Value,
|
||||
AddedTime: event.AddedTime.Value,
|
||||
MatchPeriod: event.MatchPeriod.Value,
|
||||
IsLive: event.IsLive,
|
||||
FetchedAt: event.FetchedAt.UTC(),
|
||||
}
|
||||
}
|
||||
func ConvertEventResList(events []BaseEvent) []BaseEventRes {
|
||||
result := make([]BaseEventRes, 0, len(events))
|
||||
for _, event := range events {
|
||||
result = append(result, ConvertEventRes(event))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ConvertEventWitSettingRes(event EventWithSettings) EventWithSettingsRes {
|
||||
return EventWithSettingsRes{
|
||||
ID: event.ID,
|
||||
SportID: event.SportID,
|
||||
MatchName: event.MatchName,
|
||||
HomeTeam: event.HomeTeam,
|
||||
AwayTeam: event.AwayTeam,
|
||||
HomeTeamID: event.HomeTeamID,
|
||||
AwayTeamID: event.AwayTeamID,
|
||||
HomeTeamImage: event.HomeTeamImage,
|
||||
AwayTeamImage: event.AwayTeamImage,
|
||||
LeagueID: event.LeagueID,
|
||||
LeagueName: event.LeagueName,
|
||||
LeagueCC: event.LeagueCC.Value,
|
||||
StartTime: event.StartTime.UTC(),
|
||||
Source: EventSource(event.Source),
|
||||
Status: EventStatus(event.Status),
|
||||
IsFeatured: event.IsFeatured,
|
||||
IsMonitored: event.IsMonitored,
|
||||
IsActive: event.IsActive,
|
||||
WinningUpperLimit: event.WinningUpperLimit,
|
||||
Score: event.Score.Value,
|
||||
MatchMinute: event.MatchMinute.Value,
|
||||
TimerStatus: event.TimerStatus.Value,
|
||||
AddedTime: event.AddedTime.Value,
|
||||
MatchPeriod: event.MatchPeriod.Value,
|
||||
IsLive: event.IsLive,
|
||||
FetchedAt: event.FetchedAt.UTC(),
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertEventWithSettingResList(events []EventWithSettings) []EventWithSettingsRes {
|
||||
result := make([]EventWithSettingsRes, 0, len(events))
|
||||
for _, event := range events {
|
||||
result = append(result, ConvertEventWitSettingRes(event))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
|||
41
internal/domain/event_history.go
Normal file
41
internal/domain/event_history.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
)
|
||||
|
||||
type EventHistory struct {
|
||||
ID int64
|
||||
EventID string
|
||||
Status string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type CreateEventHistory struct {
|
||||
EventID string
|
||||
Status string
|
||||
}
|
||||
|
||||
type EventHistoryFilter struct {
|
||||
EventID ValidString
|
||||
CreatedBefore ValidTime
|
||||
CreatedAfter ValidTime
|
||||
}
|
||||
|
||||
func ConvertCreateEventHistory(eventHistory CreateEventHistory) dbgen.InsertEventHistoryParams {
|
||||
return dbgen.InsertEventHistoryParams{
|
||||
EventID: eventHistory.EventID,
|
||||
Status: eventHistory.Status,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBEventHistory(eventHistory dbgen.EventHistory) EventHistory {
|
||||
return EventHistory{
|
||||
ID: eventHistory.ID,
|
||||
EventID: eventHistory.EventID,
|
||||
Status: eventHistory.Status,
|
||||
CreatedAt: eventHistory.CreatedAt.Time,
|
||||
}
|
||||
}
|
||||
35
internal/domain/eventres.go
Normal file
35
internal/domain/eventres.go
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
package domain
|
||||
|
||||
type MatchResult struct {
|
||||
EventID string
|
||||
FullScore string
|
||||
HalfScore string
|
||||
Status string
|
||||
Scores map[string]map[string]string
|
||||
}
|
||||
|
||||
type B365UpcomingRes struct {
|
||||
Success int `json:"success"`
|
||||
Pager struct {
|
||||
Page int `json:"page"`
|
||||
PerPage int `json:"per_page"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
Results []struct {
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
League struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"league"`
|
||||
Home struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"home"`
|
||||
Away *struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"away"`
|
||||
} `json:"results"`
|
||||
}
|
||||
63
internal/domain/featured_leagues.go
Normal file
63
internal/domain/featured_leagues.go
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
package domain
|
||||
|
||||
// These leagues are automatically featured when the league is created
|
||||
var FeaturedLeagues = []int64{
|
||||
// Football
|
||||
10044469, // Ethiopian Premier League
|
||||
10041282, //Premier League
|
||||
10083364, //La Liga
|
||||
10041095, //German Bundesliga
|
||||
10041100, //Ligue 1
|
||||
10041809, //UEFA Champions League
|
||||
10041957, //UEFA Europa League
|
||||
10079560, //UEFA Conference League
|
||||
10050282, //UEFA Nations League
|
||||
10044685, //FIFA Club World Cup
|
||||
10050346, //UEFA Super Cup
|
||||
10081269, //CONCACAF Champions Cup
|
||||
10070189, //CONCACAF Gold Cup
|
||||
10076185, //UEFA Regions Cup
|
||||
|
||||
10067913, //Europe - World Cup Qualifying
|
||||
10040162, //Asia - World Cup Qualifying
|
||||
10067624, //South America - World Cup Qualifying
|
||||
10073057, //North & Central America - World Cup Qualifying
|
||||
|
||||
10037075, //International Match
|
||||
10077480, //Women’s International
|
||||
10037109, //Europe Friendlies
|
||||
10068837, //Euro U21
|
||||
|
||||
10041315, //Italian Serie A
|
||||
10036538, //Spain Segunda
|
||||
10047168, // US MLS
|
||||
|
||||
10043156, //England FA Cup
|
||||
10042103, //France Cup
|
||||
10041088, //Premier League 2
|
||||
10084250, //Turkiye Super League
|
||||
10041187, //Kenya Super League
|
||||
10041391, //Netherlands Eredivisie
|
||||
|
||||
// Basketball
|
||||
10041830, //NBA
|
||||
10049984, //WNBA
|
||||
10037165, //German Bundesliga
|
||||
10036608, //Italian Lega 1
|
||||
10040795, //EuroLeague
|
||||
10041534, //Basketball Africa League
|
||||
|
||||
// Ice Hockey
|
||||
10037477, //NHL
|
||||
10037447, //AHL
|
||||
10069385, //IIHF World Championship
|
||||
|
||||
// AMERICAN FOOTBALL
|
||||
10037219, //NFL
|
||||
|
||||
// BASEBALL
|
||||
10037485, // MLB
|
||||
|
||||
// VOLLEYBALL
|
||||
10069666, //FIVB Nations League
|
||||
}
|
||||
|
|
@ -1,6 +1,24 @@
|
|||
package domain
|
||||
|
||||
type League struct {
|
||||
import (
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
)
|
||||
|
||||
// The ID and the Bet365 IDs we have here are both gotten from the betapi
|
||||
type LeagueWithSettings struct {
|
||||
ID int64
|
||||
Name string
|
||||
CompanyID int64
|
||||
CountryCode ValidString
|
||||
Bet365ID ValidInt32
|
||||
SportID int32
|
||||
IsActive bool
|
||||
IsFeatured bool
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
type LeagueWithSettingsRes struct {
|
||||
ID int64 `json:"id" example:"1"`
|
||||
Name string `json:"name" example:"BPL"`
|
||||
CountryCode string `json:"cc" example:"uk"`
|
||||
|
|
@ -9,6 +27,49 @@ type League struct {
|
|||
SportID int32 `json:"sport_id" example:"1"`
|
||||
IsFeatured bool `json:"is_featured" example:"false"`
|
||||
}
|
||||
type BaseLeague struct {
|
||||
ID int64
|
||||
Name string
|
||||
CountryCode ValidString
|
||||
Bet365ID ValidInt32
|
||||
SportID int32
|
||||
DefaultIsActive bool
|
||||
DefaultIsFeatured bool
|
||||
}
|
||||
|
||||
type BaseLeagueRes struct {
|
||||
ID int64 `json:"id" example:"1"`
|
||||
Name string `json:"name" example:"BPL"`
|
||||
CountryCode string `json:"cc" example:"uk"`
|
||||
Bet365ID int32 `json:"bet365_id" example:"1121"`
|
||||
SportID int32 `json:"sport_id" example:"1"`
|
||||
DefaultIsActive bool `json:"default_is_active" example:"false"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured" example:"false"`
|
||||
}
|
||||
|
||||
type CreateLeague struct {
|
||||
ID int64
|
||||
Name string
|
||||
CountryCode ValidString
|
||||
Bet365ID ValidInt32
|
||||
SportID int32
|
||||
DefaultIsActive bool
|
||||
DefaultIsFeatured bool
|
||||
}
|
||||
|
||||
type LeagueSettings struct {
|
||||
CompanyID int64
|
||||
LeagueID int64
|
||||
IsActive ValidBool
|
||||
IsFeatured ValidBool
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
type CreateLeagueSettings struct {
|
||||
CompanyID int64
|
||||
LeagueID int64
|
||||
IsActive ValidBool
|
||||
IsFeatured ValidBool
|
||||
}
|
||||
|
||||
type UpdateLeague struct {
|
||||
ID int64 `json:"id" example:"1"`
|
||||
|
|
@ -29,64 +90,87 @@ type LeagueFilter struct {
|
|||
Offset ValidInt64
|
||||
}
|
||||
|
||||
// These leagues are automatically featured when the league is created
|
||||
var FeaturedLeagues = []int64{
|
||||
// Football
|
||||
10044469, // Ethiopian Premier League
|
||||
10041282, //Premier League
|
||||
10083364, //La Liga
|
||||
10041095, //German Bundesliga
|
||||
10041100, //Ligue 1
|
||||
10041809, //UEFA Champions League
|
||||
10041957, //UEFA Europa League
|
||||
10079560, //UEFA Conference League
|
||||
10050282, //UEFA Nations League
|
||||
10044685, //FIFA Club World Cup
|
||||
10050346, //UEFA Super Cup
|
||||
10081269, //CONCACAF Champions Cup
|
||||
10070189, //CONCACAF Gold Cup
|
||||
10076185, //UEFA Regions Cup
|
||||
|
||||
10067913, //Europe - World Cup Qualifying
|
||||
10040162, //Asia - World Cup Qualifying
|
||||
10067624, //South America - World Cup Qualifying
|
||||
10073057, //North & Central America - World Cup Qualifying
|
||||
|
||||
10037075, //International Match
|
||||
10077480, //Women’s International
|
||||
10037109, //Europe Friendlies
|
||||
10068837, //Euro U21
|
||||
|
||||
10041315, //Italian Serie A
|
||||
10036538, //Spain Segunda
|
||||
10047168, // US MLS
|
||||
|
||||
10043156, //England FA Cup
|
||||
10042103, //France Cup
|
||||
10041088, //Premier League 2
|
||||
10084250, //Turkiye Super League
|
||||
10041187, //Kenya Super League
|
||||
10041391, //Netherlands Eredivisie
|
||||
|
||||
// Basketball
|
||||
10041830, //NBA
|
||||
10049984, //WNBA
|
||||
10037165, //German Bundesliga
|
||||
10036608, //Italian Lega 1
|
||||
10040795, //EuroLeague
|
||||
10041534, //Basketball Africa League
|
||||
|
||||
// Ice Hockey
|
||||
10037477, //NHL
|
||||
10037447, //AHL
|
||||
10069385, //IIHF World Championship
|
||||
|
||||
// AMERICAN FOOTBALL
|
||||
10037219, //NFL
|
||||
|
||||
// BASEBALL
|
||||
10037485, // MLB
|
||||
|
||||
// VOLLEYBALL
|
||||
10069666, //FIVB Nations League
|
||||
func ConvertCreateLeague(league CreateLeague) dbgen.InsertLeagueParams {
|
||||
return dbgen.InsertLeagueParams{
|
||||
ID: league.ID,
|
||||
Name: league.Name,
|
||||
CountryCode: league.CountryCode.ToPG(),
|
||||
Bet365ID: league.Bet365ID.ToPG(),
|
||||
SportID: league.SportID,
|
||||
DefaultIsActive: league.DefaultIsActive,
|
||||
DefaultIsFeatured: league.DefaultIsFeatured,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCreateLeagueSettings(leagueSetting CreateLeagueSettings) dbgen.InsertLeagueSettingsParams {
|
||||
return dbgen.InsertLeagueSettingsParams{
|
||||
CompanyID: leagueSetting.CompanyID,
|
||||
LeagueID: leagueSetting.LeagueID,
|
||||
IsActive: leagueSetting.IsActive.ToPG(),
|
||||
IsFeatured: leagueSetting.IsFeatured.ToPG(),
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBBaseLeague(league dbgen.League) BaseLeague {
|
||||
return BaseLeague{
|
||||
ID: league.ID,
|
||||
Name: league.Name,
|
||||
CountryCode: ValidString{
|
||||
Value: league.CountryCode.String,
|
||||
Valid: league.CountryCode.Valid,
|
||||
},
|
||||
Bet365ID: ValidInt32{
|
||||
Value: league.Bet365ID.Int32,
|
||||
Valid: league.Bet365ID.Valid,
|
||||
},
|
||||
SportID: league.SportID,
|
||||
DefaultIsActive: league.DefaultIsActive,
|
||||
DefaultIsFeatured: league.DefaultIsFeatured,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBBaseLeagues(leagues []dbgen.League) []BaseLeague {
|
||||
result := make([]BaseLeague, len(leagues))
|
||||
for i, league := range leagues {
|
||||
result[i] = ConvertDBBaseLeague(league)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ConvertDBLeagueWithSetting(lws dbgen.LeagueWithSetting) LeagueWithSettings {
|
||||
return LeagueWithSettings{
|
||||
ID: lws.ID,
|
||||
Name: lws.Name,
|
||||
CompanyID: lws.CompanyID,
|
||||
CountryCode: ValidString{
|
||||
Value: lws.CountryCode.String,
|
||||
Valid: lws.CountryCode.Valid,
|
||||
},
|
||||
Bet365ID: ValidInt32{
|
||||
Value: lws.Bet365ID.Int32,
|
||||
Valid: lws.Bet365ID.Valid,
|
||||
},
|
||||
IsActive: lws.IsActive,
|
||||
SportID: lws.SportID,
|
||||
IsFeatured: lws.IsFeatured,
|
||||
UpdatedAt: lws.UpdatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBLeagueWithSettings(lws []dbgen.LeagueWithSetting) []LeagueWithSettings {
|
||||
result := make([]LeagueWithSettings, len(lws))
|
||||
for i, league := range lws {
|
||||
result[i] = ConvertDBLeagueWithSetting(league)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ConvertUpdateLeague(updateLeague UpdateLeague) dbgen.UpdateLeagueParams {
|
||||
return dbgen.UpdateLeagueParams{
|
||||
ID: updateLeague.ID,
|
||||
Name: updateLeague.Name.ToPG(),
|
||||
CountryCode: updateLeague.CountryCode.ToPG(),
|
||||
Bet365ID: updateLeague.Bet365ID.ToPG(),
|
||||
SportID: updateLeague.SportID.ToPG(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ type RawOdd struct {
|
|||
|
||||
// The Market ID for the json data can be either string / int which is causing problems when UnMarshalling
|
||||
type OddsMarket struct {
|
||||
ID NullableInt64JSON `json:"id"`
|
||||
ID ValidInt64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Odds []json.RawMessage `json:"odds"`
|
||||
Header string `json:"header,omitempty"`
|
||||
|
|
|
|||
|
|
@ -1,49 +1,186 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
type RawMessage interface{}
|
||||
|
||||
type Market struct {
|
||||
type CreateOddMarket struct {
|
||||
EventID string
|
||||
FI string
|
||||
MarketCategory string
|
||||
MarketType string
|
||||
MarketName string
|
||||
MarketID string
|
||||
UpdatedAt time.Time
|
||||
Odds []map[string]interface{}
|
||||
Name string
|
||||
Handicap string
|
||||
OddsVal float64
|
||||
Source string
|
||||
}
|
||||
|
||||
type Odd struct {
|
||||
EventID string `json:"event_id"`
|
||||
Fi string `json:"fi"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName string `json:"market_name"`
|
||||
MarketCategory string `json:"market_category"`
|
||||
MarketID string `json:"market_id"`
|
||||
Name string `json:"name"`
|
||||
Handicap string `json:"handicap"`
|
||||
OddsValue float64 `json:"odds_value"`
|
||||
Section string `json:"section"`
|
||||
Category string `json:"category"`
|
||||
RawOdds []RawMessage `json:"raw_odds"`
|
||||
FetchedAt time.Time `json:"fetched_at"`
|
||||
Source string `json:"source"`
|
||||
IsActive bool `json:"is_active"`
|
||||
type OddMarket struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName string `json:"market_name"`
|
||||
MarketCategory string `json:"market_category"`
|
||||
MarketID string `json:"market_id"`
|
||||
RawOdds []json.RawMessage `json:"raw_odds"`
|
||||
FetchedAt time.Time `json:"fetched_at"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
DefaultIsActive bool `json:"is_active"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
IsLive bool `json:"is_live"`
|
||||
Status EventStatus `json:"status"`
|
||||
Source EventSource `json:"source"`
|
||||
}
|
||||
type RawOddsByMarketID struct {
|
||||
ID int64 `json:"id"`
|
||||
MarketName string `json:"market_name"`
|
||||
Handicap string `json:"handicap"`
|
||||
RawOdds []RawMessage `json:"raw_odds"`
|
||||
FetchedAt time.Time `json:"fetched_at"`
|
||||
type OddMarketWithSettings struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName string `json:"market_name"`
|
||||
MarketCategory string `json:"market_category"`
|
||||
MarketID string `json:"market_id"`
|
||||
RawOdds []json.RawMessage `json:"raw_odds"`
|
||||
FetchedAt time.Time `json:"fetched_at"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
IsActive bool `json:"is_active"`
|
||||
}
|
||||
|
||||
type OddMarketSettings struct {
|
||||
CompanyID int64
|
||||
OddMarketID int64
|
||||
IsActive ValidBool
|
||||
CustomRawOdds string
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
type CreateOddMarketSettings struct {
|
||||
CompanyID int64
|
||||
OddMarketID int64
|
||||
IsActive ValidBool
|
||||
CustomRawOdds []map[string]interface{}
|
||||
}
|
||||
|
||||
// type RawOddsByMarketID struct {
|
||||
// ID int64 `json:"id"`
|
||||
// MarketName string `json:"market_name"`
|
||||
// Handicap string `json:"handicap"`
|
||||
// RawOdds []json.RawMessage `json:"raw_odds"`
|
||||
// FetchedAt time.Time `json:"fetched_at"`
|
||||
// ExpiresAt time.Time `json:"expires_at"`
|
||||
// }
|
||||
|
||||
type OddMarketFilter struct {
|
||||
Limit ValidInt32
|
||||
Offset ValidInt32
|
||||
}
|
||||
type OddMarketWithEventFilter struct {
|
||||
Limit ValidInt32
|
||||
Offset ValidInt32
|
||||
}
|
||||
|
||||
func ConvertDBOddMarket(oddMarket dbgen.OddsMarketWithEvent) (OddMarket, error) {
|
||||
var rawOdds []json.RawMessage
|
||||
if len(oddMarket.RawOdds) > 0 {
|
||||
if err := json.Unmarshal(oddMarket.RawOdds, &rawOdds); err != nil {
|
||||
return OddMarket{}, err
|
||||
}
|
||||
} else {
|
||||
rawOdds = []json.RawMessage{} // explicit empty slice
|
||||
}
|
||||
return OddMarket{
|
||||
ID: oddMarket.ID,
|
||||
EventID: oddMarket.EventID,
|
||||
MarketType: oddMarket.MarketType,
|
||||
MarketName: oddMarket.MarketName,
|
||||
MarketCategory: oddMarket.MarketCategory,
|
||||
MarketID: oddMarket.MarketID,
|
||||
RawOdds: rawOdds,
|
||||
FetchedAt: oddMarket.FetchedAt.Time,
|
||||
ExpiresAt: oddMarket.ExpiresAt.Time,
|
||||
DefaultIsActive: oddMarket.DefaultIsActive,
|
||||
IsMonitored: oddMarket.IsMonitored,
|
||||
IsLive: oddMarket.IsLive,
|
||||
Status: EventStatus(oddMarket.Status),
|
||||
Source: EventSource(oddMarket.Source),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ConvertDBOddMarkets(oddMarkets []dbgen.OddsMarketWithEvent) ([]OddMarket, error) {
|
||||
result := make([]OddMarket, len(oddMarkets))
|
||||
for i, om := range oddMarkets {
|
||||
convertedMarket, err := ConvertDBOddMarket(om)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[i] = convertedMarket
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func ConvertCreateOddMarket(oddMarket CreateOddMarket) (dbgen.InsertOddsMarketParams, error) {
|
||||
rawOddsBytes, err := json.Marshal(oddMarket.Odds)
|
||||
if err != nil {
|
||||
return dbgen.InsertOddsMarketParams{}, err
|
||||
}
|
||||
|
||||
return dbgen.InsertOddsMarketParams{
|
||||
EventID: oddMarket.EventID,
|
||||
MarketType: oddMarket.MarketType,
|
||||
MarketName: oddMarket.MarketName,
|
||||
MarketCategory: oddMarket.MarketCategory,
|
||||
MarketID: oddMarket.MarketID,
|
||||
RawOdds: rawOddsBytes,
|
||||
FetchedAt: pgtype.Timestamp{Time: time.Now(), Valid: true},
|
||||
ExpiresAt: pgtype.Timestamp{Time: (time.Now()).Add(time.Hour), Valid: true},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ConvertCreateOddMarketSetting(oms CreateOddMarketSettings) (dbgen.InsertOddSettingsParams, error) {
|
||||
rawOddsBytes, err := json.Marshal(oms.CustomRawOdds)
|
||||
if err != nil {
|
||||
return dbgen.InsertOddSettingsParams{}, err
|
||||
}
|
||||
return dbgen.InsertOddSettingsParams{
|
||||
CompanyID: oms.CompanyID,
|
||||
OddsMarketID: oms.OddMarketID,
|
||||
IsActive: oms.IsActive.ToPG(),
|
||||
CustomRawOdds: rawOddsBytes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ConvertDBOddMarketWithSetting(oms dbgen.OddsMarketWithSetting) (OddMarketWithSettings, error) {
|
||||
var rawOdds []json.RawMessage
|
||||
if len(oms.RawOdds) > 0 {
|
||||
if err := json.Unmarshal(oms.RawOdds, &rawOdds); err != nil {
|
||||
return OddMarketWithSettings{}, err
|
||||
}
|
||||
} else {
|
||||
rawOdds = []json.RawMessage{} // explicit empty slice
|
||||
}
|
||||
return OddMarketWithSettings{
|
||||
ID: oms.ID,
|
||||
EventID: oms.EventID,
|
||||
MarketType: oms.MarketType,
|
||||
MarketName: oms.MarketName,
|
||||
MarketCategory: oms.MarketCategory,
|
||||
MarketID: oms.MarketID,
|
||||
RawOdds: rawOdds,
|
||||
FetchedAt: oms.FetchedAt.Time,
|
||||
ExpiresAt: oms.ExpiresAt.Time,
|
||||
IsActive: oms.IsActive,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ConvertDBOddMarketWithSettings(oms []dbgen.OddsMarketWithSetting) ([]OddMarketWithSettings, error) {
|
||||
result := make([]OddMarketWithSettings, len(oms))
|
||||
for i, o := range oms {
|
||||
converted, err := ConvertDBOddMarketWithSetting(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[i] = converted
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
64
internal/domain/odds_history.go
Normal file
64
internal/domain/odds_history.go
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
)
|
||||
|
||||
type OddHistory struct {
|
||||
ID int64
|
||||
OddID int64
|
||||
MarketID string
|
||||
RawOddID int64
|
||||
EventID string
|
||||
OddValue float64
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type CreateOddHistory struct {
|
||||
OddID int64
|
||||
MarketID string
|
||||
RawOddID int64
|
||||
EventID string
|
||||
OddValue float64
|
||||
}
|
||||
|
||||
type OddHistoryFilter struct {
|
||||
OddID ValidInt64
|
||||
MarketID ValidString
|
||||
RawOddID ValidInt64
|
||||
EventID ValidString
|
||||
CreatedBefore ValidTime
|
||||
CreatedAfter ValidTime
|
||||
}
|
||||
|
||||
func ConvertCreateOddHistory(odd CreateOddHistory) dbgen.InsertOddHistoryParams {
|
||||
return dbgen.InsertOddHistoryParams{
|
||||
OddsMarketID: odd.OddID,
|
||||
MarketID: odd.MarketID,
|
||||
RawOddID: odd.RawOddID,
|
||||
EventID: odd.EventID,
|
||||
OddValue: odd.OddValue,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertDBOddHistory(dbOddHistory dbgen.OddHistory) OddHistory {
|
||||
return OddHistory{
|
||||
ID: dbOddHistory.ID,
|
||||
OddID: dbOddHistory.OddsMarketID,
|
||||
MarketID: dbOddHistory.MarketID,
|
||||
RawOddID: dbOddHistory.RawOddID,
|
||||
EventID: dbOddHistory.EventID,
|
||||
OddValue: dbOddHistory.OddValue,
|
||||
CreatedAt: dbOddHistory.CreatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertOddHistories(list []dbgen.OddHistory) []OddHistory {
|
||||
result := make([]OddHistory, 0, len(list))
|
||||
for _, item := range list {
|
||||
result = append(result, ConvertDBOddHistory(item))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ package domain
|
|||
|
||||
import (
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
)
|
||||
|
||||
type MarketConfig struct {
|
||||
|
|
@ -21,7 +23,7 @@ type Result struct {
|
|||
FullTimeScore string
|
||||
HalfTimeScore string
|
||||
SS string
|
||||
Scores map[string]Score
|
||||
Scores map[string]ScoreResultResponse
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
|
@ -83,22 +85,78 @@ const (
|
|||
TIME_STATUS_REMOVED TimeStatus = 99
|
||||
)
|
||||
|
||||
type ResultStatusCounts struct {
|
||||
IsNotFinished int `json:"is_not_finished"`
|
||||
IsNotFinishedBets int `json:"is_not_finished_bets"`
|
||||
IsToBeFixed int `json:"is_to_be_fixed"`
|
||||
IsToBeFixedBets int `json:"is_to_be_fixed_bets"`
|
||||
IsPostponed int `json:"is_postponed"`
|
||||
IsPostponedBets int `json:"is_postponed_bets"`
|
||||
IsEnded int `json:"is_ended"`
|
||||
IsEndedBets int `json:"is_ended_bets"`
|
||||
IsRemoved int `json:"is_removed"`
|
||||
IsRemovedBets int `json:"is_removed_bets"`
|
||||
type ResultLog struct {
|
||||
ID int64 `json:"id"`
|
||||
StatusNotFinishedCount int `json:"status_not_finished_count"`
|
||||
StatusNotFinishedBets int `json:"status_not_finished_bets"`
|
||||
StatusToBeFixedCount int `json:"status_to_be_fixed_count"`
|
||||
StatusToBeFixedBets int `json:"status_to_be_fixed_bets"`
|
||||
StatusPostponedCount int `json:"status_postponed_count"`
|
||||
StatusPostponedBets int `json:"status_postponed_bets"`
|
||||
StatusEndedCount int `json:"status_ended_count"`
|
||||
StatusEndedBets int `json:"status_ended_bets"`
|
||||
StatusRemovedCount int `json:"status_removed_count"`
|
||||
StatusRemovedBets int `json:"status_removed_bets"`
|
||||
RemovedCount int `json:"removed"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
type CreateResultLog struct {
|
||||
StatusNotFinishedCount int `json:"status_not_finished_count"`
|
||||
StatusNotFinishedBets int `json:"status_not_finished_bets"`
|
||||
StatusToBeFixedCount int `json:"status_to_be_fixed_count"`
|
||||
StatusToBeFixedBets int `json:"status_to_be_fixed_bets"`
|
||||
StatusPostponedCount int `json:"status_postponed_count"`
|
||||
StatusPostponedBets int `json:"status_postponed_bets"`
|
||||
StatusEndedCount int `json:"status_ended_count"`
|
||||
StatusEndedBets int `json:"status_ended_bets"`
|
||||
StatusRemovedCount int `json:"status_removed_count"`
|
||||
StatusRemovedBets int `json:"status_removed_bets"`
|
||||
RemovedCount int `json:"removed"`
|
||||
}
|
||||
|
||||
type ResultFilter struct {
|
||||
CreatedBefore ValidTime
|
||||
CreatedAfter ValidTime
|
||||
}
|
||||
type ResultStatusBets struct {
|
||||
IsNotFinished []int64 `json:"is_not_finished"`
|
||||
IsToBeFixed []int64 `json:"is_to_be_fixed"`
|
||||
IsPostponed []int64 `json:"is_postponed"`
|
||||
IsEnded []int64 `json:"is_ended"`
|
||||
IsRemoved []int64 `json:"is_removed"`
|
||||
StatusNotFinished []int64 `json:"status_not_finished"`
|
||||
StatusToBeFixed []int64 `json:"status_to_be_fixed"`
|
||||
StatusPostponed []int64 `json:"status_postponed"`
|
||||
StatusEnded []int64 `json:"status_ended"`
|
||||
StatusRemoved []int64 `json:"status_removed"`
|
||||
}
|
||||
|
||||
func ConvertDBResultLog(result dbgen.ResultLog) ResultLog {
|
||||
return ResultLog{
|
||||
ID: result.ID,
|
||||
StatusNotFinishedCount: int(result.StatusNotFinishedCount),
|
||||
StatusNotFinishedBets: int(result.StatusNotFinishedBets),
|
||||
StatusToBeFixedCount: int(result.StatusToBeFixedCount),
|
||||
StatusToBeFixedBets: int(result.StatusToBeFixedBets),
|
||||
StatusPostponedCount: int(result.StatusPostponedCount),
|
||||
StatusPostponedBets: int(result.StatusPostponedBets),
|
||||
StatusEndedCount: int(result.StatusEndedCount),
|
||||
StatusEndedBets: int(result.StatusEndedBets),
|
||||
StatusRemovedCount: int(result.StatusRemovedCount),
|
||||
StatusRemovedBets: int(result.StatusRemovedBets),
|
||||
RemovedCount: int(result.RemovedCount),
|
||||
CreatedAt: result.CreatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCreateResultLog(result CreateResultLog) dbgen.CreateResultLogParams {
|
||||
return dbgen.CreateResultLogParams{
|
||||
StatusNotFinishedCount: int32(result.StatusNotFinishedCount),
|
||||
StatusNotFinishedBets: int32(result.StatusNotFinishedBets),
|
||||
StatusToBeFixedCount: int32(result.StatusToBeFixedCount),
|
||||
StatusToBeFixedBets: int32(result.StatusToBeFixedBets),
|
||||
StatusPostponedCount: int32(result.StatusPostponedCount),
|
||||
StatusPostponedBets: int32(result.StatusPostponedBets),
|
||||
StatusEndedCount: int32(result.StatusEndedCount),
|
||||
StatusEndedBets: int32(result.StatusEndedBets),
|
||||
StatusRemovedCount: int32(result.StatusRemovedCount),
|
||||
StatusRemovedBets: int32(result.StatusRemovedBets),
|
||||
RemovedCount: int32(result.RemovedCount),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,47 +9,47 @@ type BaseResultResponse struct {
|
|||
Results []json.RawMessage `json:"results"`
|
||||
}
|
||||
|
||||
type LeagueRes struct {
|
||||
type LeagueResultResponse struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CC string `json:"cc"`
|
||||
}
|
||||
|
||||
type Team struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ImageID NullableInt64JSON `json:"image_id"`
|
||||
CC string `json:"cc"`
|
||||
type TeamResultResponse struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ImageID ValidInt64 `json:"image_id"`
|
||||
CC string `json:"cc"`
|
||||
}
|
||||
|
||||
type Score struct {
|
||||
type ScoreResultResponse struct {
|
||||
Home string `json:"home"`
|
||||
Away string `json:"away"`
|
||||
}
|
||||
|
||||
type CommonResultResponse struct {
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
TimeStatus NullableInt64JSON `json:"time_status"`
|
||||
League LeagueRes `json:"league"`
|
||||
Home Team `json:"home"`
|
||||
Away Team `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
TimeStatus ValidInt64 `json:"time_status"`
|
||||
League LeagueResultResponse `json:"league"`
|
||||
Home TeamResultResponse `json:"home"`
|
||||
Away TeamResultResponse `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
}
|
||||
|
||||
type FootballResultResponse struct {
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
TimeStatus string `json:"time_status"`
|
||||
League LeagueRes `json:"league"`
|
||||
Home Team `json:"home"`
|
||||
Away Team `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
TimeStatus string `json:"time_status"`
|
||||
League LeagueResultResponse `json:"league"`
|
||||
Home TeamResultResponse `json:"home"`
|
||||
Away TeamResultResponse `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
Scores struct {
|
||||
FirstHalf Score `json:"1"`
|
||||
SecondHalf Score `json:"2"`
|
||||
FirstHalf ScoreResultResponse `json:"1"`
|
||||
SecondHalf ScoreResultResponse `json:"2"`
|
||||
} `json:"scores"`
|
||||
Stats struct {
|
||||
Attacks []string `json:"attacks"`
|
||||
|
|
@ -78,21 +78,21 @@ type FootballResultResponse struct {
|
|||
}
|
||||
|
||||
type BasketballResultResponse struct {
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
TimeStatus string `json:"time_status"`
|
||||
League LeagueRes `json:"league"`
|
||||
Home Team `json:"home"`
|
||||
Away Team `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
TimeStatus string `json:"time_status"`
|
||||
League LeagueResultResponse `json:"league"`
|
||||
Home TeamResultResponse `json:"home"`
|
||||
Away TeamResultResponse `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
Scores struct {
|
||||
FirstQuarter Score `json:"1"`
|
||||
SecondQuarter Score `json:"2"`
|
||||
FirstHalf Score `json:"3"`
|
||||
ThirdQuarter Score `json:"4"`
|
||||
FourthQuarter Score `json:"5"`
|
||||
TotalScore Score `json:"7"`
|
||||
FirstQuarter ScoreResultResponse `json:"1"`
|
||||
SecondQuarter ScoreResultResponse `json:"2"`
|
||||
FirstHalf ScoreResultResponse `json:"3"`
|
||||
ThirdQuarter ScoreResultResponse `json:"4"`
|
||||
FourthQuarter ScoreResultResponse `json:"5"`
|
||||
TotalScore ScoreResultResponse `json:"7"`
|
||||
} `json:"scores"`
|
||||
Stats struct {
|
||||
TwoPoints []string `json:"2points"`
|
||||
|
|
@ -125,19 +125,19 @@ type BasketballResultResponse struct {
|
|||
Bet365ID string `json:"bet365_id"`
|
||||
}
|
||||
type IceHockeyResultResponse struct {
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
TimeStatus string `json:"time_status"`
|
||||
League LeagueRes `json:"league"`
|
||||
Home Team `json:"home"`
|
||||
Away Team `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
TimeStatus string `json:"time_status"`
|
||||
League LeagueResultResponse `json:"league"`
|
||||
Home TeamResultResponse `json:"home"`
|
||||
Away TeamResultResponse `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
Scores struct {
|
||||
FirstPeriod Score `json:"1"`
|
||||
SecondPeriod Score `json:"2"`
|
||||
ThirdPeriod Score `json:"3"`
|
||||
TotalScore Score `json:"5"`
|
||||
FirstPeriod ScoreResultResponse `json:"1"`
|
||||
SecondPeriod ScoreResultResponse `json:"2"`
|
||||
ThirdPeriod ScoreResultResponse `json:"3"`
|
||||
TotalScore ScoreResultResponse `json:"5"`
|
||||
} `json:"scores"`
|
||||
|
||||
Stats struct {
|
||||
|
|
@ -222,11 +222,11 @@ type VolleyballResultResponse struct {
|
|||
} `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
Scores struct {
|
||||
FirstSet Score `json:"1"`
|
||||
SecondSet Score `json:"2"`
|
||||
ThirdSet Score `json:"3"`
|
||||
FourthSet Score `json:"4"`
|
||||
FivethSet Score `json:"5"`
|
||||
FirstSet ScoreResultResponse `json:"1"`
|
||||
SecondSet ScoreResultResponse `json:"2"`
|
||||
ThirdSet ScoreResultResponse `json:"3"`
|
||||
FourthSet ScoreResultResponse `json:"4"`
|
||||
FivethSet ScoreResultResponse `json:"5"`
|
||||
} `json:"scores"`
|
||||
Stats struct {
|
||||
PointsWonOnServe []string `json:"points_won_on_serve"`
|
||||
|
|
@ -290,10 +290,10 @@ type FutsalResultResponse struct {
|
|||
} `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
Scores struct {
|
||||
FirstPeriod Score `json:"1"`
|
||||
SecondPeriod Score `json:"2"`
|
||||
ThirdPeriod Score `json:"3"`
|
||||
TotalScore Score `json:"4"`
|
||||
FirstPeriod ScoreResultResponse `json:"1"`
|
||||
SecondPeriod ScoreResultResponse `json:"2"`
|
||||
ThirdPeriod ScoreResultResponse `json:"3"`
|
||||
TotalScore ScoreResultResponse `json:"4"`
|
||||
} `json:"scores"`
|
||||
Events []map[string]string `json:"events"`
|
||||
InplayCreatedAt string `json:"inplay_created_at"`
|
||||
|
|
@ -327,12 +327,12 @@ type NFLResultResponse struct {
|
|||
} `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
Scores struct {
|
||||
FirstQuarter Score `json:"1"`
|
||||
SecondQuarter Score `json:"2"`
|
||||
ThirdQuarter Score `json:"3"`
|
||||
FourthQuarter Score `json:"4"`
|
||||
Overtime Score `json:"5"`
|
||||
TotalScore Score `json:"7"`
|
||||
FirstQuarter ScoreResultResponse `json:"1"`
|
||||
SecondQuarter ScoreResultResponse `json:"2"`
|
||||
ThirdQuarter ScoreResultResponse `json:"3"`
|
||||
FourthQuarter ScoreResultResponse `json:"4"`
|
||||
Overtime ScoreResultResponse `json:"5"`
|
||||
TotalScore ScoreResultResponse `json:"7"`
|
||||
} `json:"scores"`
|
||||
Stats struct {
|
||||
FirstDowns []string `json:"first_downs"`
|
||||
|
|
@ -381,9 +381,9 @@ type RugbyResultResponse struct {
|
|||
} `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
Scores struct {
|
||||
FirstHalf Score `json:"1"`
|
||||
SecondHalf Score `json:"2"`
|
||||
TotalScore Score `json:"7"`
|
||||
FirstHalf ScoreResultResponse `json:"1"`
|
||||
SecondHalf ScoreResultResponse `json:"2"`
|
||||
TotalScore ScoreResultResponse `json:"7"`
|
||||
} `json:"scores"`
|
||||
Stats struct {
|
||||
Tries []string `json:"tries"`
|
||||
|
|
@ -433,17 +433,17 @@ type BaseballResultResponse struct {
|
|||
} `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
Scores struct {
|
||||
FirstInning Score `json:"1"`
|
||||
SecondInning Score `json:"2"`
|
||||
ThirdInning Score `json:"3"`
|
||||
FourthInning Score `json:"4"`
|
||||
FifthInning Score `json:"5"`
|
||||
SixthInning Score `json:"6"`
|
||||
SeventhInning Score `json:"7"`
|
||||
EighthInning Score `json:"8"`
|
||||
NinthInning Score `json:"9"`
|
||||
ExtraInnings Score `json:"10"`
|
||||
TotalScore Score `json:"11"`
|
||||
FirstInning ScoreResultResponse `json:"1"`
|
||||
SecondInning ScoreResultResponse `json:"2"`
|
||||
ThirdInning ScoreResultResponse `json:"3"`
|
||||
FourthInning ScoreResultResponse `json:"4"`
|
||||
FifthInning ScoreResultResponse `json:"5"`
|
||||
SixthInning ScoreResultResponse `json:"6"`
|
||||
SeventhInning ScoreResultResponse `json:"7"`
|
||||
EighthInning ScoreResultResponse `json:"8"`
|
||||
NinthInning ScoreResultResponse `json:"9"`
|
||||
ExtraInnings ScoreResultResponse `json:"10"`
|
||||
TotalScore ScoreResultResponse `json:"11"`
|
||||
} `json:"scores"`
|
||||
Stats struct {
|
||||
Hits []string `json:"hits"`
|
||||
|
|
|
|||
|
|
@ -9,3 +9,12 @@ const (
|
|||
RoleCustomer Role = "customer"
|
||||
RoleCashier Role = "cashier"
|
||||
)
|
||||
|
||||
func (r Role) IsValid() bool {
|
||||
switch r {
|
||||
case RoleSuperAdmin, RoleAdmin, RoleBranchManager, RoleCustomer, RoleCashier:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
447
internal/domain/setting_list.go
Normal file
447
internal/domain/setting_list.go
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrSettingNotFound = errors.New("cannot find setting in list")
|
||||
)
|
||||
|
||||
type SettingList struct {
|
||||
SMSProvider SMSProvider `json:"sms_provider"`
|
||||
MaxNumberOfOutcomes int64 `json:"max_number_of_outcomes"`
|
||||
BetAmountLimit Currency `json:"bet_amount_limit"`
|
||||
DailyTicketPerIP int64 `json:"daily_ticket_limit"`
|
||||
TotalWinningLimit Currency `json:"total_winning_limit"`
|
||||
AmountForBetReferral Currency `json:"amount_for_bet_referral"`
|
||||
CashbackAmountCap Currency `json:"cashback_amount_cap"`
|
||||
}
|
||||
|
||||
type SettingListRes struct {
|
||||
SMSProvider SMSProvider `json:"sms_provider"`
|
||||
MaxNumberOfOutcomes int64 `json:"max_number_of_outcomes"`
|
||||
BetAmountLimit float32 `json:"bet_amount_limit"`
|
||||
DailyTicketPerIP int64 `json:"daily_ticket_limit"`
|
||||
TotalWinningLimit float32 `json:"total_winning_limit"`
|
||||
AmountForBetReferral float32 `json:"amount_for_bet_referral"`
|
||||
CashbackAmountCap float32 `json:"cashback_amount_cap"`
|
||||
}
|
||||
|
||||
type SaveSettingListReq struct {
|
||||
SMSProvider *string `json:"sms_provider,omitempty"`
|
||||
MaxNumberOfOutcomes *int64 `json:"max_number_of_outcomes,omitempty"`
|
||||
BetAmountLimit *float32 `json:"bet_amount_limit,omitempty"`
|
||||
DailyTicketPerIP *int64 `json:"daily_ticket_limit,omitempty"`
|
||||
TotalWinningLimit *float32 `json:"total_winning_limit,omitempty"`
|
||||
AmountForBetReferral *float32 `json:"amount_for_bet_referral,omitempty"`
|
||||
CashbackAmountCap *float32 `json:"cashback_amount_cap,omitempty"`
|
||||
}
|
||||
|
||||
func ConvertSaveSettingListReq(settings SaveSettingListReq) ValidSettingList {
|
||||
return ValidSettingList{
|
||||
SMSProvider: ConvertStringPtr(settings.SMSProvider),
|
||||
MaxNumberOfOutcomes: ConvertInt64Ptr(settings.MaxNumberOfOutcomes),
|
||||
BetAmountLimit: ConvertFloat32PtrToCurrency(settings.BetAmountLimit),
|
||||
DailyTicketPerIP: ConvertInt64Ptr(settings.DailyTicketPerIP),
|
||||
TotalWinningLimit: ConvertFloat32PtrToCurrency(settings.TotalWinningLimit),
|
||||
AmountForBetReferral: ConvertFloat32PtrToCurrency(settings.AmountForBetReferral),
|
||||
CashbackAmountCap: ConvertFloat32PtrToCurrency(settings.CashbackAmountCap),
|
||||
}
|
||||
}
|
||||
|
||||
type ValidSettingList struct {
|
||||
SMSProvider ValidString
|
||||
MaxNumberOfOutcomes ValidInt64
|
||||
BetAmountLimit ValidCurrency
|
||||
DailyTicketPerIP ValidInt64
|
||||
TotalWinningLimit ValidCurrency
|
||||
AmountForBetReferral ValidCurrency
|
||||
CashbackAmountCap ValidCurrency
|
||||
}
|
||||
|
||||
// Always make sure to run the validation before converting this
|
||||
func (vsl *ValidSettingList) ToSettingList() SettingList {
|
||||
return SettingList{
|
||||
SMSProvider: SMSProvider(vsl.SMSProvider.Value),
|
||||
MaxNumberOfOutcomes: vsl.MaxNumberOfOutcomes.Value,
|
||||
BetAmountLimit: Currency(vsl.BetAmountLimit.Value),
|
||||
DailyTicketPerIP: vsl.DailyTicketPerIP.Value,
|
||||
TotalWinningLimit: Currency(vsl.TotalWinningLimit.Value),
|
||||
AmountForBetReferral: Currency(vsl.AmountForBetReferral.Value),
|
||||
CashbackAmountCap: Currency(vsl.CashbackAmountCap.Value),
|
||||
}
|
||||
}
|
||||
|
||||
// Custom Validations for non-generic types
|
||||
func (vsl *ValidSettingList) CustomValidationSettings() error {
|
||||
if !SMSProvider(vsl.SMSProvider.Value).IsValid() {
|
||||
return fmt.Errorf("sms provider invalid")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) GetInt64SettingsMap() map[string]*ValidInt64 {
|
||||
return map[string]*ValidInt64{
|
||||
"max_number_of_outcomes": &vsl.MaxNumberOfOutcomes,
|
||||
"daily_ticket_limit": &vsl.DailyTicketPerIP,
|
||||
}
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) GetCurrencySettingsMap() map[string]*ValidCurrency {
|
||||
return map[string]*ValidCurrency{
|
||||
"bet_amount_limit": &vsl.BetAmountLimit,
|
||||
"total_winnings_limit": &vsl.TotalWinningLimit,
|
||||
"amount_for_bet_referral": &vsl.AmountForBetReferral,
|
||||
"cashback_amount_cap": &vsl.CashbackAmountCap,
|
||||
}
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) GetStringSettingsMap() map[string]*ValidString {
|
||||
return map[string]*ValidString{
|
||||
"sms_provider": &vsl.SMSProvider,
|
||||
}
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) GetBoolSettingsMap() map[string]*ValidBool {
|
||||
return map[string]*ValidBool{}
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) GetFloat32SettingsMap() map[string]*ValidFloat32 {
|
||||
return map[string]*ValidFloat32{}
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) GetTimeSettingsMap() map[string]*ValidTime {
|
||||
return map[string]*ValidTime{}
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) GetTotalSettings() int {
|
||||
return len(vsl.GetInt64SettingsMap()) +
|
||||
len(vsl.GetCurrencySettingsMap()) +
|
||||
len(vsl.GetStringSettingsMap()) +
|
||||
len(vsl.GetBoolSettingsMap()) +
|
||||
len(vsl.GetFloat32SettingsMap()) +
|
||||
len(vsl.GetTimeSettingsMap())
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) GetAllValid() map[string]*bool {
|
||||
|
||||
settingValid := make(map[string]*bool)
|
||||
|
||||
for key, setting := range vsl.GetInt64SettingsMap() {
|
||||
settingValid[key] = &(*setting).Valid
|
||||
}
|
||||
for key, setting := range vsl.GetCurrencySettingsMap() {
|
||||
settingValid[key] = &(*setting).Valid
|
||||
}
|
||||
for key, setting := range vsl.GetStringSettingsMap() {
|
||||
settingValid[key] = &(*setting).Valid
|
||||
}
|
||||
for key, setting := range vsl.GetBoolSettingsMap() {
|
||||
settingValid[key] = &(*setting).Valid
|
||||
}
|
||||
for key, setting := range vsl.GetFloat32SettingsMap() {
|
||||
settingValid[key] = &(*setting).Valid
|
||||
}
|
||||
for key, setting := range vsl.GetTimeSettingsMap() {
|
||||
settingValid[key] = &(*setting).Valid
|
||||
}
|
||||
|
||||
return settingValid
|
||||
}
|
||||
|
||||
func setValidSetting[T any](settings map[string]*T, searchKey string, setVal T) error {
|
||||
for key, setting := range settings {
|
||||
if key == searchKey {
|
||||
*setting = setVal
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return ErrSettingNotFound
|
||||
}
|
||||
func (vsl *ValidSettingList) SetInt64Setting(searchKey string, searchVal string) error {
|
||||
value, err := strconv.ParseInt(searchVal, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setValidSetting(vsl.GetInt64SettingsMap(), searchKey, ValidInt64{Value: value, Valid: true})
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) SetCurrencySetting(searchKey string, searchVal string) error {
|
||||
value, err := strconv.ParseInt(searchVal, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setValidSetting(vsl.GetCurrencySettingsMap(), searchKey, ValidCurrency{Value: Currency(value), Valid: true})
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) SetStringSetting(searchKey string, searchVal string) error {
|
||||
return setValidSetting(vsl.GetStringSettingsMap(), searchKey, ValidString{Value: searchVal, Valid: true})
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) SetBoolSetting(searchKey string, searchVal string) error {
|
||||
value, err := strconv.ParseBool(searchVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setValidSetting(vsl.GetBoolSettingsMap(), searchKey, ValidBool{Value: value, Valid: true})
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) SetFloat32Setting(searchKey string, searchVal string) error {
|
||||
value, err := strconv.ParseFloat(searchVal, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setValidSetting(vsl.GetFloat32SettingsMap(), searchKey, ValidFloat32{Value: float32(value), Valid: true})
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) SetTimeSetting(searchKey string, searchVal string) error {
|
||||
value, err := time.Parse(time.RFC3339, searchVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setValidSetting(vsl.GetTimeSettingsMap(), searchKey, ValidTime{Value: value, Valid: true})
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) SetSetting(searchKey string, searchVal string) error {
|
||||
setters := []func(string, string) error{
|
||||
vsl.SetInt64Setting,
|
||||
vsl.SetCurrencySetting,
|
||||
vsl.SetStringSetting,
|
||||
vsl.SetBoolSetting,
|
||||
vsl.SetFloat32Setting,
|
||||
vsl.SetTimeSetting,
|
||||
}
|
||||
|
||||
for _, setter := range setters {
|
||||
if err := setter(searchKey, searchVal); err != nil {
|
||||
if err == ErrSettingNotFound {
|
||||
continue // not this setter, try the next
|
||||
}
|
||||
return fmt.Errorf("error while processing setting %q: %w", searchKey, err)
|
||||
}
|
||||
return nil // successfully set
|
||||
}
|
||||
|
||||
// If we get here, none of the setters matched
|
||||
return ErrSettingNotFound
|
||||
}
|
||||
|
||||
func convertValidSettings[T any](
|
||||
settings map[string]*T,
|
||||
isValid func(*T) bool,
|
||||
toString func(*T) string,
|
||||
) []Setting {
|
||||
result := make([]Setting, 0, len(settings))
|
||||
for key, s := range settings {
|
||||
if isValid(s) {
|
||||
result = append(result, Setting{
|
||||
Key: key,
|
||||
Value: toString(s),
|
||||
})
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ConvertInt64Settings() []Setting {
|
||||
return convertValidSettings(
|
||||
vsl.GetInt64SettingsMap(),
|
||||
func(s *ValidInt64) bool { return s.Valid },
|
||||
func(s *ValidInt64) string { return strconv.FormatInt(s.Value, 10) },
|
||||
)
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ConvertCurrencySettings() []Setting {
|
||||
return convertValidSettings(
|
||||
vsl.GetCurrencySettingsMap(),
|
||||
func(s *ValidCurrency) bool { return s.Valid },
|
||||
func(s *ValidCurrency) string { return strconv.FormatInt(int64(s.Value), 10) },
|
||||
)
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ConvertStringSettings() []Setting {
|
||||
return convertValidSettings(
|
||||
vsl.GetStringSettingsMap(),
|
||||
func(s *ValidString) bool { return s.Valid },
|
||||
func(s *ValidString) string { return s.Value },
|
||||
)
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ConvertBoolSettings() []Setting {
|
||||
return convertValidSettings(
|
||||
vsl.GetBoolSettingsMap(),
|
||||
func(s *ValidBool) bool { return s.Valid },
|
||||
func(s *ValidBool) string { return strconv.FormatBool(s.Value) },
|
||||
)
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ConvertFloat32Settings() []Setting {
|
||||
return convertValidSettings(
|
||||
vsl.GetFloat32SettingsMap(),
|
||||
func(s *ValidFloat32) bool { return s.Valid },
|
||||
func(s *ValidFloat32) string { return strconv.FormatFloat(float64(s.Value), 'f', -1, 32) },
|
||||
)
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ConvertTimeSettings() []Setting {
|
||||
return convertValidSettings(
|
||||
vsl.GetTimeSettingsMap(),
|
||||
func(s *ValidTime) bool { return s.Valid },
|
||||
func(s *ValidTime) string { return s.Value.Format(time.RFC3339) },
|
||||
)
|
||||
}
|
||||
|
||||
func validateSettings[T any](
|
||||
settings map[string]*T,
|
||||
customValidator func(*T) bool,
|
||||
) error {
|
||||
var errs []string
|
||||
for key, s := range settings {
|
||||
if !customValidator(s) {
|
||||
errs = append(errs, fmt.Sprintf("%v is invalid", key))
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
return errors.New(strings.Join(errs, "; "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ValidateInt64Settings() error {
|
||||
return validateSettings(vsl.GetInt64SettingsMap(),
|
||||
func(s *ValidInt64) bool {
|
||||
return s.Valid
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ValidateCurrencySettings() error {
|
||||
return validateSettings(vsl.GetCurrencySettingsMap(),
|
||||
func(s *ValidCurrency) bool {
|
||||
return s.Valid
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ValidateStringSettings() error {
|
||||
return validateSettings(vsl.GetStringSettingsMap(),
|
||||
func(s *ValidString) bool {
|
||||
return s.Valid
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ValidateBoolSettings() error {
|
||||
return validateSettings(vsl.GetBoolSettingsMap(),
|
||||
func(s *ValidBool) bool {
|
||||
return s.Valid
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ValidateFloat32Settings() error {
|
||||
return validateSettings(vsl.GetFloat32SettingsMap(),
|
||||
func(s *ValidFloat32) bool {
|
||||
return s.Valid
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ValidateTimeSettings() error {
|
||||
return validateSettings(vsl.GetTimeSettingsMap(),
|
||||
func(s *ValidTime) bool {
|
||||
return s.Valid
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ValidateAllSettings() error {
|
||||
var errs []string
|
||||
validators := []func() error{
|
||||
vsl.ValidateInt64Settings,
|
||||
vsl.ValidateCurrencySettings,
|
||||
vsl.ValidateStringSettings,
|
||||
vsl.ValidateBoolSettings,
|
||||
vsl.ValidateFloat32Settings,
|
||||
vsl.ValidateTimeSettings,
|
||||
vsl.CustomValidationSettings,
|
||||
}
|
||||
|
||||
for _, validator := range validators {
|
||||
if err := validator(); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
return errors.New(strings.Join(errs, "; "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vsl *ValidSettingList) ConvertAllSettings() []Setting {
|
||||
totalCap := vsl.GetTotalSettings()
|
||||
all := make([]Setting, 0, totalCap)
|
||||
|
||||
all = append(all, vsl.ConvertInt64Settings()...)
|
||||
all = append(all, vsl.ConvertCurrencySettings()...)
|
||||
all = append(all, vsl.ConvertStringSettings()...)
|
||||
all = append(all, vsl.ConvertBoolSettings()...)
|
||||
all = append(all, vsl.ConvertFloat32Settings()...)
|
||||
all = append(all, vsl.ConvertTimeSettings()...)
|
||||
|
||||
return all
|
||||
}
|
||||
|
||||
func ConvertDBGlobalSettingList(settings []dbgen.GlobalSetting) (SettingList, error) {
|
||||
var dbSettingList ValidSettingList
|
||||
|
||||
for _, setting := range settings {
|
||||
if err := dbSettingList.SetSetting(setting.Key, setting.Value); err != nil {
|
||||
if err == ErrSettingNotFound {
|
||||
MongoDBLogger.Warn("unknown setting found on database", zap.String("setting", setting.Key))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := dbSettingList.ValidateAllSettings(); err != nil {
|
||||
fmt.Printf("setting validation error: %v \n", err)
|
||||
MongoDBLogger.Warn("setting validation error", zap.Error(err))
|
||||
return SettingList{}, err
|
||||
}
|
||||
|
||||
settingList := dbSettingList.ToSettingList()
|
||||
|
||||
return settingList, nil
|
||||
}
|
||||
|
||||
func ConvertDBOverrideSettingList(settings []dbgen.GetOverrideSettingsRow) (SettingList, error) {
|
||||
var dbSettingList ValidSettingList
|
||||
|
||||
for _, setting := range settings {
|
||||
if err := dbSettingList.SetSetting(setting.Key, setting.Value); err != nil {
|
||||
if err == ErrSettingNotFound {
|
||||
MongoDBLogger.Warn("unknown setting found on database", zap.String("setting", setting.Key))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := dbSettingList.ValidateAllSettings(); err != nil {
|
||||
fmt.Printf("setting validation error: %v \n", err)
|
||||
MongoDBLogger.Warn("setting validation error", zap.Error(err))
|
||||
return SettingList{}, err
|
||||
}
|
||||
|
||||
settingList := dbSettingList.ToSettingList()
|
||||
|
||||
return settingList, nil
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ package domain
|
|||
|
||||
import (
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
)
|
||||
|
||||
type Setting struct {
|
||||
|
|
@ -11,68 +13,44 @@ type Setting struct {
|
|||
}
|
||||
|
||||
type SettingRes struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
type CompanySetting struct {
|
||||
Key string
|
||||
Value string
|
||||
CompanyID int64
|
||||
UpdatedAt time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type SettingList struct {
|
||||
SMSProvider SMSProvider `json:"sms_provider"`
|
||||
MaxNumberOfOutcomes int64 `json:"max_number_of_outcomes"`
|
||||
BetAmountLimit Currency `json:"bet_amount_limit"`
|
||||
DailyTicketPerIP int64 `json:"daily_ticket_limit"`
|
||||
TotalWinningLimit Currency `json:"total_winning_limit"`
|
||||
AmountForBetReferral Currency `json:"amount_for_bet_referral"`
|
||||
CashbackAmountCap Currency `json:"cashback_amount_cap"`
|
||||
type CompanySettingRes struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
type DBSettingList struct {
|
||||
SMSProvider ValidString
|
||||
MaxNumberOfOutcomes ValidInt64
|
||||
BetAmountLimit ValidInt64
|
||||
DailyTicketPerIP ValidInt64
|
||||
TotalWinningLimit ValidInt64
|
||||
AmountForBetReferral ValidInt64
|
||||
CashbackAmountCap ValidInt64
|
||||
func ConvertSetting(setting Setting) SettingRes {
|
||||
return SettingRes(setting)
|
||||
}
|
||||
|
||||
func ConvertInt64SettingsMap(dbSettingList *DBSettingList) map[string]*ValidInt64 {
|
||||
return map[string]*ValidInt64{
|
||||
"max_number_of_outcomes": &dbSettingList.MaxNumberOfOutcomes,
|
||||
"bet_amount_limit": &dbSettingList.BetAmountLimit,
|
||||
"daily_ticket_limit": &dbSettingList.DailyTicketPerIP,
|
||||
"total_winnings_limit": &dbSettingList.TotalWinningLimit,
|
||||
"amount_for_bet_referral": &dbSettingList.AmountForBetReferral,
|
||||
"cashback_amount_cap": &dbSettingList.CashbackAmountCap,
|
||||
func ConvertCompanySetting(companySetting dbgen.CompanySetting) CompanySetting {
|
||||
return CompanySetting{
|
||||
Key: companySetting.Key,
|
||||
Value: companySetting.Value,
|
||||
CompanyID: companySetting.CompanyID,
|
||||
UpdatedAt: companySetting.UpdatedAt.Time,
|
||||
CreatedAt: companySetting.CreatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertStringSettingsMap(dbSettingList *DBSettingList) map[string]*ValidString {
|
||||
return map[string]*ValidString{
|
||||
"sms_provider": &dbSettingList.SMSProvider,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertBoolSettingsMap(dbSettingList *DBSettingList) map[string]*ValidBool {
|
||||
return map[string]*ValidBool{}
|
||||
}
|
||||
|
||||
func ConvertFloat32SettingsMap(dbSettingList *DBSettingList) map[string]*ValidFloat32 {
|
||||
return map[string]*ValidFloat32{}
|
||||
}
|
||||
|
||||
func ConvertTimeSettingsMap(dbSettingList *DBSettingList) map[string]*ValidTime {
|
||||
return map[string]*ValidTime{}
|
||||
}
|
||||
|
||||
func ConvertDBSetting(dbSettingList DBSettingList) SettingList {
|
||||
return SettingList{
|
||||
SMSProvider: SMSProvider(dbSettingList.SMSProvider.Value),
|
||||
MaxNumberOfOutcomes: dbSettingList.MaxNumberOfOutcomes.Value,
|
||||
BetAmountLimit: Currency(dbSettingList.BetAmountLimit.Value),
|
||||
DailyTicketPerIP: dbSettingList.DailyTicketPerIP.Value,
|
||||
TotalWinningLimit: Currency(dbSettingList.TotalWinningLimit.Value),
|
||||
AmountForBetReferral: Currency(dbSettingList.AmountForBetReferral.Value),
|
||||
CashbackAmountCap: Currency(dbSettingList.CashbackAmountCap.Value),
|
||||
func ConvertCompanySettings(settings []dbgen.CompanySetting) []CompanySetting {
|
||||
result := make([]CompanySetting, 0, len(settings))
|
||||
for _, setting := range settings {
|
||||
result = append(result, ConvertCompanySetting(setting))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ type Ticket struct {
|
|||
ID int64
|
||||
Amount Currency
|
||||
TotalOdds float32
|
||||
CompanyID int64
|
||||
}
|
||||
|
||||
type GetTicket struct {
|
||||
|
|
@ -46,12 +47,14 @@ type GetTicket struct {
|
|||
Amount Currency
|
||||
TotalOdds float32
|
||||
Outcomes []TicketOutcome
|
||||
CompanyID int64
|
||||
}
|
||||
|
||||
type CreateTicket struct {
|
||||
Amount Currency
|
||||
TotalOdds float32
|
||||
IP string
|
||||
CompanyID int64
|
||||
}
|
||||
|
||||
type CreateTicketOutcomeReq struct {
|
||||
|
|
@ -80,4 +83,9 @@ type TicketRes struct {
|
|||
Outcomes []TicketOutcome `json:"outcomes"`
|
||||
Amount float32 `json:"amount" example:"100.0"`
|
||||
TotalOdds float32 `json:"total_odds" example:"4.22"`
|
||||
CompanyID int64 `json:"company_id" example:"1"`
|
||||
}
|
||||
|
||||
type TicketFilter struct {
|
||||
CompanyID ValidInt64
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,24 +10,20 @@ var (
|
|||
)
|
||||
|
||||
type User struct {
|
||||
ID int64
|
||||
FirstName string
|
||||
LastName string
|
||||
Email string `json:"email"`
|
||||
PhoneNumber string `json:"phone_number"`
|
||||
Password []byte
|
||||
Role Role
|
||||
//
|
||||
ID int64
|
||||
FirstName string
|
||||
LastName string
|
||||
Email string `json:"email"`
|
||||
PhoneNumber string `json:"phone_number"`
|
||||
Password []byte
|
||||
Role Role
|
||||
EmailVerified bool
|
||||
PhoneVerified bool
|
||||
//
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
//
|
||||
SuspendedAt time.Time
|
||||
Suspended bool
|
||||
//
|
||||
CompanyID ValidInt64
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
SuspendedAt time.Time
|
||||
Suspended bool
|
||||
CompanyID ValidInt64 //This should be null
|
||||
}
|
||||
|
||||
type UserFilter struct {
|
||||
|
|
@ -39,10 +35,7 @@ type UserFilter struct {
|
|||
CreatedBefore ValidTime
|
||||
CreatedAfter ValidTime
|
||||
}
|
||||
type ValidRole struct {
|
||||
Value Role
|
||||
Valid bool
|
||||
}
|
||||
|
||||
|
||||
type RegisterUserReq struct {
|
||||
FirstName string
|
||||
|
|
@ -54,6 +47,7 @@ type RegisterUserReq struct {
|
|||
Otp string
|
||||
ReferralCode string `json:"referral_code"`
|
||||
OtpMedium OtpMedium
|
||||
CompanyID ValidInt64
|
||||
}
|
||||
type CreateUserReq struct {
|
||||
FirstName string
|
||||
|
|
|
|||
245
internal/domain/validtypes.go
Normal file
245
internal/domain/validtypes.go
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
// Valid Int64
|
||||
type ValidInt64 struct {
|
||||
Value int64
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (v ValidInt64) ToPG() pgtype.Int8 {
|
||||
return pgtype.Int8{
|
||||
Int64: v.Value,
|
||||
Valid: v.Valid,
|
||||
}
|
||||
}
|
||||
|
||||
func (n *ValidInt64) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(data, &s); err == nil {
|
||||
if s == "" {
|
||||
n.Valid = false
|
||||
return nil
|
||||
}
|
||||
v, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.Value, n.Valid = v, true
|
||||
return nil
|
||||
}
|
||||
|
||||
var v int64
|
||||
if err := json.Unmarshal(data, &v); err == nil {
|
||||
n.Value, n.Valid = v, true
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("invalid int64 value: %s", string(data))
|
||||
}
|
||||
|
||||
func ConvertInt64Ptr(value *int64) ValidInt64 {
|
||||
if value == nil {
|
||||
return ValidInt64{}
|
||||
}
|
||||
return ValidInt64{
|
||||
Value: *value,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Valid Int
|
||||
type ValidInt struct {
|
||||
Value int
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (v ValidInt) ToPG() pgtype.Int4 {
|
||||
return pgtype.Int4{
|
||||
Int32: int32(v.Value),
|
||||
Valid: v.Valid,
|
||||
}
|
||||
}
|
||||
func ConvertIntPtr(value *int) ValidInt {
|
||||
if value == nil {
|
||||
return ValidInt{}
|
||||
}
|
||||
return ValidInt{
|
||||
Value: *value,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Valid Int32
|
||||
type ValidInt32 struct {
|
||||
Value int32
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (v ValidInt32) ToPG() pgtype.Int4 {
|
||||
return pgtype.Int4{
|
||||
Int32: v.Value,
|
||||
Valid: v.Valid,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertInt32Ptr(value *int32) ValidInt32 {
|
||||
if value == nil {
|
||||
return ValidInt32{}
|
||||
}
|
||||
return ValidInt32{
|
||||
Value: *value,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Valid Float32
|
||||
type ValidFloat32 struct {
|
||||
Value float32
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (v ValidFloat32) ToPG() pgtype.Float4 {
|
||||
return pgtype.Float4{
|
||||
Float32: v.Value,
|
||||
Valid: v.Valid,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertFloat32Ptr(value *float32) ValidFloat32 {
|
||||
if value == nil {
|
||||
return ValidFloat32{}
|
||||
}
|
||||
return ValidFloat32{
|
||||
Value: *value,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Valid String
|
||||
type ValidString struct {
|
||||
Value string
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (v ValidString) ToPG() pgtype.Text {
|
||||
return pgtype.Text{
|
||||
String: v.Value,
|
||||
Valid: v.Valid,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertStringPtr(value *string) ValidString {
|
||||
if value == nil {
|
||||
return ValidString{}
|
||||
}
|
||||
return ValidString{
|
||||
Value: *value,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Valid Time
|
||||
type ValidTime struct {
|
||||
Value time.Time
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (v ValidTime) ToPG() pgtype.Timestamp {
|
||||
return pgtype.Timestamp{
|
||||
Time: v.Value,
|
||||
Valid: v.Valid,
|
||||
}
|
||||
}
|
||||
|
||||
// Valid Bool
|
||||
type ValidBool struct {
|
||||
Value bool
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (v ValidBool) ToPG() pgtype.Bool {
|
||||
return pgtype.Bool{
|
||||
Bool: v.Value,
|
||||
Valid: v.Valid,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertBoolPtr(value *bool) ValidBool {
|
||||
if value == nil {
|
||||
return ValidBool{}
|
||||
}
|
||||
return ValidBool{
|
||||
Value: *value,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Valid Currency
|
||||
type ValidCurrency struct {
|
||||
Value Currency
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (v ValidCurrency) ToPG() pgtype.Int8 {
|
||||
return pgtype.Int8{
|
||||
Int64: int64(v.Value),
|
||||
Valid: v.Valid,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCurrencyPtr(value *Currency) ValidCurrency {
|
||||
if value == nil {
|
||||
return ValidCurrency{}
|
||||
}
|
||||
|
||||
return ValidCurrency{
|
||||
Value: *value,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertFloat32PtrToCurrency(value *float32) ValidCurrency {
|
||||
if value == nil {
|
||||
return ValidCurrency{}
|
||||
}
|
||||
|
||||
converted := ToCurrency(*value)
|
||||
|
||||
return ValidCurrency{
|
||||
Value: converted,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Valid Role
|
||||
type ValidRole struct {
|
||||
Value Role
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (v ValidRole) ToPG() pgtype.Text {
|
||||
return pgtype.Text{
|
||||
String: string(v.Value),
|
||||
Valid: v.Valid,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertRolePtr(value *Role) ValidRole {
|
||||
if value == nil {
|
||||
return ValidRole{}
|
||||
}
|
||||
|
||||
return ValidRole{
|
||||
Value: *value,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
42
internal/pkgs/helpers/slug.go
Normal file
42
internal/pkgs/helpers/slug.go
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package helpers
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
var (
|
||||
// keep letters, numbers, spaces, and hyphens
|
||||
slugRegex = regexp.MustCompile(`[^a-z0-9\s-]`)
|
||||
spaceRe = regexp.MustCompile(`\s+`)
|
||||
dashRe = regexp.MustCompile(`-+`)
|
||||
)
|
||||
|
||||
// GenerateSlug creates a URL-safe slug from a given string (e.g. company name).
|
||||
func GenerateSlug(name string) string {
|
||||
// lowercase
|
||||
slug := strings.ToLower(name)
|
||||
|
||||
// normalize unicode accents (é -> e, ü -> u, etc.)
|
||||
slug = strings.Map(func(r rune) rune {
|
||||
if unicode.IsLetter(r) || unicode.IsDigit(r) || unicode.IsSpace(r) || r == '-' {
|
||||
return r
|
||||
}
|
||||
return -1
|
||||
}, slug)
|
||||
|
||||
// remove unwanted chars
|
||||
slug = slugRegex.ReplaceAllString(slug, "")
|
||||
|
||||
// replace spaces with dash
|
||||
slug = spaceRe.ReplaceAllString(slug, "-")
|
||||
|
||||
// collapse multiple dashes
|
||||
slug = dashRe.ReplaceAllString(slug, "-")
|
||||
|
||||
// trim leading/trailing dash
|
||||
slug = strings.Trim(slug, "-")
|
||||
|
||||
return slug
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
func (s *Store) GetUserByEmailPhone(ctx context.Context, email, phone string) (domain.User, error) {
|
||||
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,
|
||||
|
|
@ -21,6 +21,7 @@ func (s *Store) GetUserByEmailPhone(ctx context.Context, email, phone string) (d
|
|||
String: phone,
|
||||
Valid: true,
|
||||
},
|
||||
CompanyID: companyID.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
|
|
|
|||
|
|
@ -19,115 +19,14 @@ var (
|
|||
mongoLogger *zap.Logger
|
||||
)
|
||||
|
||||
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),
|
||||
UserID: bet.UserID,
|
||||
IsShopBet: bet.IsShopBet,
|
||||
CashedOut: bet.CashedOut,
|
||||
FastCode: bet.FastCode,
|
||||
CreatedAt: bet.CreatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
func convertDBBetOutcomes(outcome dbgen.BetOutcome) domain.BetOutcome {
|
||||
return domain.BetOutcome{
|
||||
ID: outcome.ID,
|
||||
BetID: outcome.BetID,
|
||||
SportID: outcome.SportID,
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
func convertDBBetWithOutcomes(bet dbgen.BetWithOutcome) domain.GetBet {
|
||||
var outcomes []domain.BetOutcome = make([]domain.BetOutcome, 0, len(bet.Outcomes))
|
||||
|
||||
for _, outcome := range bet.Outcomes {
|
||||
outcomes = append(outcomes, convertDBBetOutcomes(outcome))
|
||||
}
|
||||
|
||||
return domain.GetBet{
|
||||
ID: bet.ID,
|
||||
Amount: domain.Currency(bet.Amount),
|
||||
TotalOdds: bet.TotalOdds,
|
||||
Status: domain.OutcomeStatus(bet.Status),
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
func convertDBFlag(flag dbgen.Flag) domain.Flag {
|
||||
return domain.Flag{
|
||||
ID: flag.ID,
|
||||
BetID: flag.BetID.Int64,
|
||||
OddID: flag.OddID.Int64,
|
||||
Reason: flag.Reason.String,
|
||||
FlaggedAt: flag.FlaggedAt.Time,
|
||||
Resolved: flag.Resolved.Bool,
|
||||
}
|
||||
}
|
||||
|
||||
func convertDBCreateBetOutcome(betOutcome domain.CreateBetOutcome) dbgen.CreateBetOutcomeParams {
|
||||
return dbgen.CreateBetOutcomeParams{
|
||||
BetID: betOutcome.BetID,
|
||||
EventID: betOutcome.EventID,
|
||||
SportID: betOutcome.SportID,
|
||||
OddID: betOutcome.OddID,
|
||||
HomeTeamName: betOutcome.HomeTeamName,
|
||||
AwayTeamName: betOutcome.AwayTeamName,
|
||||
MarketID: betOutcome.MarketID,
|
||||
MarketName: betOutcome.MarketName,
|
||||
Odd: betOutcome.Odd,
|
||||
OddName: betOutcome.OddName,
|
||||
OddHeader: betOutcome.OddHeader,
|
||||
OddHandicap: betOutcome.OddHandicap,
|
||||
Expires: pgtype.Timestamp{
|
||||
Time: betOutcome.Expires,
|
||||
Valid: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func convertCreateBet(bet domain.CreateBet) dbgen.CreateBetParams {
|
||||
return dbgen.CreateBetParams{
|
||||
Amount: int64(bet.Amount),
|
||||
TotalOdds: bet.TotalOdds,
|
||||
Status: int32(bet.Status),
|
||||
UserID: bet.UserID,
|
||||
IsShopBet: bet.IsShopBet,
|
||||
OutcomesHash: bet.OutcomesHash,
|
||||
FastCode: bet.FastCode,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Store) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) {
|
||||
newBet, err := s.queries.CreateBet(ctx, convertCreateBet(bet))
|
||||
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 convertDBBet(newBet), err
|
||||
return domain.ConvertDBBet(newBet), err
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +34,7 @@ func (s *Store) CreateBetOutcome(ctx context.Context, outcomes []domain.CreateBe
|
|||
var dbParams []dbgen.CreateBetOutcomeParams = make([]dbgen.CreateBetOutcomeParams, 0, len(outcomes))
|
||||
|
||||
for _, outcome := range outcomes {
|
||||
dbParams = append(dbParams, convertDBCreateBetOutcome(outcome))
|
||||
dbParams = append(dbParams, domain.ConvertDBCreateBetOutcome(outcome))
|
||||
}
|
||||
|
||||
rows, err := s.queries.CreateBetOutcome(ctx, dbParams)
|
||||
|
|
@ -157,7 +56,7 @@ func (s *Store) CreateFlag(ctx context.Context, flag domain.CreateFlagReq) (doma
|
|||
Int64: flag.BetID,
|
||||
Valid: flag.BetID != 0,
|
||||
},
|
||||
OddID: pgtype.Int8{
|
||||
OddsMarketID: pgtype.Int8{
|
||||
Int64: flag.OddID,
|
||||
Valid: flag.OddID != 0,
|
||||
},
|
||||
|
|
@ -177,7 +76,7 @@ func (s *Store) CreateFlag(ctx context.Context, flag domain.CreateFlagReq) (doma
|
|||
return domain.Flag{}, err
|
||||
}
|
||||
|
||||
return convertDBFlag(f), nil
|
||||
return domain.ConvertDBFlag(f), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetBetByID(ctx context.Context, id int64) (domain.GetBet, error) {
|
||||
|
|
@ -190,35 +89,18 @@ func (s *Store) GetBetByID(ctx context.Context, id int64) (domain.GetBet, error)
|
|||
return domain.GetBet{}, err
|
||||
}
|
||||
|
||||
return convertDBBetWithOutcomes(bet), nil
|
||||
return domain.ConvertDBBetWithOutcomes(bet), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]domain.GetBet, error) {
|
||||
bets, err := s.queries.GetAllBets(ctx, dbgen.GetAllBetsParams{
|
||||
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,
|
||||
},
|
||||
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,
|
||||
},
|
||||
UserID: filter.UserID.ToPG(),
|
||||
CompanyID: filter.CompanyID.ToPG(),
|
||||
CashedOut: filter.CashedOut.ToPG(),
|
||||
IsShopBet: filter.IsShopBet.ToPG(),
|
||||
Query: filter.Query.ToPG(),
|
||||
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
domain.MongoDBLogger.Error("failed to get all bets",
|
||||
|
|
@ -230,7 +112,7 @@ func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]doma
|
|||
|
||||
var result []domain.GetBet = make([]domain.GetBet, 0, len(bets))
|
||||
for _, bet := range bets {
|
||||
result = append(result, convertDBBetWithOutcomes(bet))
|
||||
result = append(result, domain.ConvertDBBetWithOutcomes(bet))
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
|
@ -245,7 +127,7 @@ func (s *Store) GetBetByUserID(ctx context.Context, UserID int64) ([]domain.GetB
|
|||
|
||||
var result []domain.GetBet = make([]domain.GetBet, 0, len(bets))
|
||||
for _, bet := range bets {
|
||||
result = append(result, convertDBBetWithOutcomes(bet))
|
||||
result = append(result, domain.ConvertDBBetWithOutcomes(bet))
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
|
@ -258,7 +140,7 @@ func (s *Store) GetBetByFastCode(ctx context.Context, fastcode string) (domain.G
|
|||
return domain.GetBet{}, err
|
||||
}
|
||||
|
||||
return convertDBBetWithOutcomes(bet), nil
|
||||
return domain.ConvertDBBetWithOutcomes(bet), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetBetsForCashback(ctx context.Context) ([]domain.GetBet, error) {
|
||||
|
|
@ -270,7 +152,7 @@ func (s *Store) GetBetsForCashback(ctx context.Context) ([]domain.GetBet, error)
|
|||
}
|
||||
|
||||
for _, bet := range bets {
|
||||
cashbackBet := convertDBBetWithOutcomes(bet)
|
||||
cashbackBet := domain.ConvertDBBetWithOutcomes(bet)
|
||||
res = append(res, cashbackBet)
|
||||
}
|
||||
|
||||
|
|
@ -361,7 +243,7 @@ func (s *Store) GetBetOutcomeByEventID(ctx context.Context, eventID int64, is_fi
|
|||
|
||||
var result []domain.BetOutcome = make([]domain.BetOutcome, 0, len(outcomes))
|
||||
for _, outcome := range outcomes {
|
||||
result = append(result, convertDBBetOutcomes(outcome))
|
||||
result = append(result, domain.ConvertDBBetOutcomes(outcome))
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
|
@ -378,7 +260,7 @@ func (s *Store) GetBetOutcomeByBetID(ctx context.Context, betID int64) ([]domain
|
|||
|
||||
var result []domain.BetOutcome = make([]domain.BetOutcome, 0, len(outcomes))
|
||||
for _, outcome := range outcomes {
|
||||
result = append(result, convertDBBetOutcomes(outcome))
|
||||
result = append(result, domain.ConvertDBBetOutcomes(outcome))
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
|
@ -397,7 +279,7 @@ func (s *Store) UpdateBetOutcomeStatus(ctx context.Context, id int64, status dom
|
|||
return domain.BetOutcome{}, err
|
||||
}
|
||||
|
||||
res := convertDBBetOutcomes(update)
|
||||
res := domain.ConvertDBBetOutcomes(update)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
|
|
@ -415,7 +297,7 @@ func (s *Store) UpdateBetOutcomeStatusByBetID(ctx context.Context, id int64, sta
|
|||
return domain.BetOutcome{}, err
|
||||
}
|
||||
|
||||
res := convertDBBetOutcomes(update)
|
||||
res := domain.ConvertDBBetOutcomes(update)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
|
|
@ -436,7 +318,7 @@ func (s *Store) UpdateBetOutcomeStatusForEvent(ctx context.Context, eventID int6
|
|||
|
||||
var result []domain.BetOutcome = make([]domain.BetOutcome, 0, len(outcomes))
|
||||
for _, outcome := range outcomes {
|
||||
result = append(result, convertDBBetOutcomes(outcome))
|
||||
result = append(result, domain.ConvertDBBetOutcomes(outcome))
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
|
||||
func (s *Store) CreateBranch(ctx context.Context, branch domain.CreateBranch) (domain.Branch, error) {
|
||||
|
||||
dbBranch, err := s.queries.CreateBranch(ctx, domain.ConvertCreateBranch(branch))
|
||||
|
|
@ -53,26 +52,11 @@ func (s *Store) GetBranchByCompanyID(ctx context.Context, companyID int64) ([]do
|
|||
|
||||
func (s *Store) GetAllBranches(ctx context.Context, filter domain.BranchFilter) ([]domain.BranchDetail, error) {
|
||||
dbBranches, err := s.queries.GetAllBranches(ctx, dbgen.GetAllBranchesParams{
|
||||
CompanyID: pgtype.Int8{
|
||||
Int64: filter.CompanyID.Value,
|
||||
Valid: filter.CompanyID.Valid,
|
||||
},
|
||||
BranchManagerID: pgtype.Int8{
|
||||
Int64: filter.BranchManagerID.Value,
|
||||
Valid: filter.BranchManagerID.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,
|
||||
},
|
||||
CompanyID: filter.CompanyID.ToPG(),
|
||||
BranchManagerID: filter.BranchManagerID.ToPG(),
|
||||
Query: filter.Query.ToPG(),
|
||||
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -2,14 +2,36 @@ package repository
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/pkgs/helpers"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
|
||||
func (s *Store) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) {
|
||||
dbCompany, err := s.queries.CreateCompany(ctx, domain.ConvertCreateCompany(company))
|
||||
baseSlug := helpers.GenerateSlug(company.Name)
|
||||
uniqueSlug := baseSlug
|
||||
i := 1
|
||||
|
||||
for {
|
||||
_, err := s.queries.GetCompanyIDUsingSlug(ctx, uniqueSlug)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
// slug is unique
|
||||
break
|
||||
} else {
|
||||
// real DB error
|
||||
return domain.Company{}, err
|
||||
}
|
||||
}
|
||||
uniqueSlug = fmt.Sprintf("%s-%d", baseSlug, i)
|
||||
i++
|
||||
}
|
||||
|
||||
dbCompany, err := s.queries.CreateCompany(ctx, domain.ConvertCreateCompany(company, uniqueSlug))
|
||||
if err != nil {
|
||||
return domain.Company{}, err
|
||||
}
|
||||
|
|
@ -56,6 +78,15 @@ func (s *Store) GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany
|
|||
return domain.ConvertDBCompanyDetails(dbCompany), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetCompanyIDBySlug(ctx context.Context, slug string) (int64, error) {
|
||||
dbCompanyID, err := s.queries.GetCompanyIDUsingSlug(ctx, slug)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return dbCompanyID, nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error) {
|
||||
dbCompany, err := s.queries.UpdateCompany(ctx, domain.ConvertUpdateCompany(company))
|
||||
|
||||
|
|
|
|||
105
internal/repository/custom_odds.go
Normal file
105
internal/repository/custom_odds.go
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
package repository
|
||||
|
||||
// import (
|
||||
// "context"
|
||||
|
||||
// dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
// )
|
||||
|
||||
// func (s *Store) InsertCustomOdds(ctx context.Context, odd domain.CreateCustomOdd) (domain.CustomOdd, error) {
|
||||
// convertedCustomOdd, err := domain.ConvertCreateCustomOdd(odd)
|
||||
// if err != nil {
|
||||
// return domain.CustomOdd{}, err
|
||||
// }
|
||||
// dbCustomOdd, err := s.queries.InsertCustomOdd(ctx, convertedCustomOdd)
|
||||
|
||||
// if err != nil {
|
||||
// return domain.CustomOdd{}, err
|
||||
// }
|
||||
|
||||
// convertDbCustomOdd, err := domain.ConvertDBCustomOdd(dbCustomOdd)
|
||||
|
||||
// if err != nil {
|
||||
// return domain.CustomOdd{}, err
|
||||
// }
|
||||
|
||||
// return convertDbCustomOdd, nil
|
||||
// }
|
||||
|
||||
// func (s *Store) GetAllCustomOdds(ctx context.Context, filter domain.CustomOddFilter) ([]domain.CustomOdd, error) {
|
||||
// dbCustomOdds, err := s.queries.GetAllCustomOdds(ctx, filter.CompanyID.ToPG())
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// convertDbCustomOdds, err := domain.ConvertDbCustomOdds(dbCustomOdds)
|
||||
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// return convertDbCustomOdds, nil
|
||||
// }
|
||||
|
||||
// func (s *Store) GetCustomOddByID(ctx context.Context, id int64) (domain.CustomOdd, error) {
|
||||
// dbCustomOdd, err := s.queries.GetCustomOddByID(ctx, id)
|
||||
// if err != nil {
|
||||
// return domain.CustomOdd{}, nil
|
||||
// }
|
||||
|
||||
// convertedDBCustomOdd, err := domain.ConvertDBCustomOdd(dbCustomOdd)
|
||||
// if err != nil {
|
||||
// return domain.CustomOdd{}, nil
|
||||
// }
|
||||
|
||||
// return convertedDBCustomOdd, nil
|
||||
// }
|
||||
|
||||
// func (s *Store) GetCustomOddByOddID(ctx context.Context, oddId int64, companyID int64) (domain.CustomOdd, error) {
|
||||
// dbCustomOdd, err := s.queries.GetCustomOddByOddID(ctx, dbgen.GetCustomOddByOddIDParams{
|
||||
// OddID: oddId,
|
||||
// CompanyID: companyID,
|
||||
// })
|
||||
|
||||
// if err != nil {
|
||||
// return domain.CustomOdd{}, nil
|
||||
// }
|
||||
|
||||
// convertedDBCustomOdd, err := domain.ConvertDBCustomOdd(dbCustomOdd)
|
||||
// if err != nil {
|
||||
// return domain.CustomOdd{}, nil
|
||||
// }
|
||||
|
||||
// return convertedDBCustomOdd, nil
|
||||
// }
|
||||
|
||||
// func (s *Store) DeleteCustomOddByID(ctx context.Context, id int64) error {
|
||||
// err := s.queries.DeleteCustomOddsByID(ctx, id)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// func (s *Store) DeleteCustomOddsByOddID(ctx context.Context, oddId int64, companyID int64) error {
|
||||
// err := s.queries.DeleteCustomOddsByOddID(ctx, dbgen.DeleteCustomOddsByOddIDParams{
|
||||
// OddID: oddId,
|
||||
// CompanyID: companyID,
|
||||
// })
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// func (s *Store) DeleteCustomOddByEventID(ctx context.Context, eventID string) error {
|
||||
// err := s.queries.DeleteCustomOddByEventID(ctx, eventID)
|
||||
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// return nil
|
||||
// }
|
||||
68
internal/repository/disabled_odds.go
Normal file
68
internal/repository/disabled_odds.go
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
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
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
|
|
@ -13,90 +12,29 @@ import (
|
|||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
func (s *Store) SaveEvent(ctx context.Context, e domain.Event) error {
|
||||
parsedTime, err := time.Parse(time.RFC3339, e.StartTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.queries.InsertEvent(ctx, dbgen.InsertEventParams{
|
||||
ID: e.ID,
|
||||
SportID: pgtype.Int4{Int32: e.SportID, Valid: true},
|
||||
MatchName: pgtype.Text{String: e.MatchName, Valid: true},
|
||||
HomeTeam: pgtype.Text{String: e.HomeTeam, Valid: true},
|
||||
AwayTeam: pgtype.Text{String: e.AwayTeam, Valid: true},
|
||||
HomeTeamID: pgtype.Int4{Int32: e.HomeTeamID, Valid: true},
|
||||
AwayTeamID: pgtype.Int4{Int32: e.AwayTeamID, Valid: true},
|
||||
HomeKitImage: pgtype.Text{String: e.HomeKitImage, Valid: true},
|
||||
AwayKitImage: pgtype.Text{String: e.AwayKitImage, Valid: true},
|
||||
LeagueID: pgtype.Int4{Int32: e.LeagueID, Valid: true},
|
||||
LeagueName: pgtype.Text{String: e.LeagueName, Valid: true},
|
||||
LeagueCc: pgtype.Text{String: e.LeagueCC, Valid: true},
|
||||
StartTime: pgtype.Timestamp{Time: parsedTime, Valid: true},
|
||||
Score: pgtype.Text{String: e.Score, Valid: true},
|
||||
MatchMinute: pgtype.Int4{Int32: int32(e.MatchMinute), Valid: true},
|
||||
TimerStatus: pgtype.Text{String: e.TimerStatus, Valid: true},
|
||||
AddedTime: pgtype.Int4{Int32: int32(e.AddedTime), Valid: true},
|
||||
MatchPeriod: pgtype.Int4{Int32: int32(e.MatchPeriod), Valid: true},
|
||||
IsLive: pgtype.Bool{Bool: e.IsLive, Valid: true},
|
||||
Status: pgtype.Text{String: e.Status, Valid: true},
|
||||
Source: pgtype.Text{String: e.Source, Valid: true},
|
||||
})
|
||||
func (s *Store) SaveEvent(ctx context.Context, e domain.CreateEvent) error {
|
||||
return s.queries.InsertEvent(ctx, domain.ConvertCreateEvent(e))
|
||||
}
|
||||
func (s *Store) SaveUpcomingEvent(ctx context.Context, e domain.UpcomingEvent) error {
|
||||
return s.queries.InsertUpcomingEvent(ctx, dbgen.InsertUpcomingEventParams{
|
||||
ID: e.ID,
|
||||
SportID: pgtype.Int4{Int32: e.SportID, Valid: true},
|
||||
MatchName: pgtype.Text{String: e.MatchName, Valid: true},
|
||||
HomeTeam: pgtype.Text{String: e.HomeTeam, Valid: true},
|
||||
AwayTeam: pgtype.Text{String: e.AwayTeam, Valid: true},
|
||||
HomeTeamID: pgtype.Int4{Int32: e.HomeTeamID, Valid: true},
|
||||
AwayTeamID: pgtype.Int4{Int32: e.AwayTeamID, Valid: true},
|
||||
HomeKitImage: pgtype.Text{String: e.HomeKitImage, Valid: true},
|
||||
AwayKitImage: pgtype.Text{String: e.AwayKitImage, Valid: true},
|
||||
LeagueID: pgtype.Int4{Int32: e.LeagueID, Valid: true},
|
||||
LeagueName: pgtype.Text{String: e.LeagueName, Valid: true},
|
||||
LeagueCc: pgtype.Text{String: e.LeagueCC, Valid: true},
|
||||
StartTime: pgtype.Timestamp{Time: e.StartTime, Valid: true},
|
||||
Source: pgtype.Text{String: e.Source, Valid: true},
|
||||
})
|
||||
|
||||
func (s *Store) InsertEventSettings(ctx context.Context, eventSetting domain.CreateEventSettings) error {
|
||||
return s.queries.InsertEventSettings(ctx, domain.ConvertCreateEventSettings(eventSetting))
|
||||
}
|
||||
|
||||
func (s *Store) GetLiveEventIDs(ctx context.Context) ([]string, error) {
|
||||
return s.queries.ListLiveEvents(ctx)
|
||||
}
|
||||
func (s *Store) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error) {
|
||||
|
||||
func (s *Store) GetAllUpcomingEvents(ctx context.Context) ([]domain.BaseEvent, error) {
|
||||
events, err := s.queries.GetAllUpcomingEvents(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
upcomingEvents := make([]domain.UpcomingEvent, len(events))
|
||||
for i, e := range events {
|
||||
upcomingEvents[i] = domain.UpcomingEvent{
|
||||
ID: e.ID,
|
||||
SportID: e.SportID.Int32,
|
||||
MatchName: e.MatchName.String,
|
||||
HomeTeam: e.HomeTeam.String,
|
||||
AwayTeam: e.AwayTeam.String,
|
||||
HomeTeamID: e.HomeTeamID.Int32,
|
||||
AwayTeamID: e.AwayTeamID.Int32,
|
||||
HomeKitImage: e.HomeKitImage.String,
|
||||
AwayKitImage: e.AwayKitImage.String,
|
||||
LeagueID: e.LeagueID.Int32,
|
||||
LeagueName: e.LeagueName.String,
|
||||
LeagueCC: e.LeagueCc.String,
|
||||
StartTime: e.StartTime.Time.UTC(),
|
||||
Source: e.Source.String,
|
||||
Status: domain.EventStatus(e.Status.String),
|
||||
IsFeatured: e.IsFeatured,
|
||||
}
|
||||
}
|
||||
return upcomingEvents, nil
|
||||
return domain.ConvertDBEvents(events), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, error) {
|
||||
events, err := s.queries.GetExpiredUpcomingEvents(ctx, pgtype.Text{
|
||||
func (s *Store) GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, error) {
|
||||
events, err := s.queries.GetExpiredEvents(ctx, pgtype.Text{
|
||||
String: filter.MatchStatus.Value,
|
||||
Valid: filter.MatchStatus.Valid,
|
||||
})
|
||||
|
|
@ -104,163 +42,98 @@ func (s *Store) GetExpiredUpcomingEvents(ctx context.Context, filter domain.Even
|
|||
return nil, err
|
||||
}
|
||||
|
||||
upcomingEvents := make([]domain.UpcomingEvent, len(events))
|
||||
for i, e := range events {
|
||||
upcomingEvents[i] = domain.UpcomingEvent{
|
||||
ID: e.ID,
|
||||
SportID: e.SportID.Int32,
|
||||
MatchName: e.MatchName.String,
|
||||
HomeTeam: e.HomeTeam.String,
|
||||
AwayTeam: e.AwayTeam.String,
|
||||
HomeTeamID: e.HomeTeamID.Int32,
|
||||
AwayTeamID: e.AwayTeamID.Int32,
|
||||
HomeKitImage: e.HomeKitImage.String,
|
||||
AwayKitImage: e.AwayKitImage.String,
|
||||
LeagueID: e.LeagueID.Int32,
|
||||
LeagueName: e.LeagueName.String,
|
||||
LeagueCC: e.LeagueCc.String,
|
||||
StartTime: e.StartTime.Time.UTC(),
|
||||
Source: e.Source.String,
|
||||
Status: domain.EventStatus(e.Status.String),
|
||||
IsFeatured: e.IsFeatured,
|
||||
IsActive: e.IsActive,
|
||||
}
|
||||
}
|
||||
return upcomingEvents, nil
|
||||
return domain.ConvertDBEvents(events), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, int64, error) {
|
||||
func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error) {
|
||||
|
||||
events, err := s.queries.GetPaginatedUpcomingEvents(ctx, dbgen.GetPaginatedUpcomingEventsParams{
|
||||
LeagueID: pgtype.Int4{
|
||||
Int32: int32(filter.LeagueID.Value),
|
||||
Valid: filter.LeagueID.Valid,
|
||||
},
|
||||
SportID: pgtype.Int4{
|
||||
Int32: int32(filter.SportID.Value),
|
||||
Valid: filter.SportID.Valid,
|
||||
},
|
||||
Query: pgtype.Text{
|
||||
String: filter.Query.Value,
|
||||
Valid: filter.Query.Valid,
|
||||
},
|
||||
Limit: pgtype.Int4{
|
||||
Int32: int32(filter.Limit.Value),
|
||||
Valid: filter.Limit.Valid,
|
||||
},
|
||||
Offset: pgtype.Int4{
|
||||
Int32: int32(filter.Offset.Value * filter.Limit.Value),
|
||||
Valid: filter.Offset.Valid,
|
||||
},
|
||||
FirstStartTime: pgtype.Timestamp{
|
||||
Time: filter.FirstStartTime.Value.UTC(),
|
||||
Valid: filter.FirstStartTime.Valid,
|
||||
},
|
||||
LastStartTime: pgtype.Timestamp{
|
||||
Time: filter.LastStartTime.Value.UTC(),
|
||||
Valid: filter.LastStartTime.Valid,
|
||||
},
|
||||
CountryCode: pgtype.Text{
|
||||
String: filter.CountryCode.Value,
|
||||
Valid: filter.CountryCode.Valid,
|
||||
},
|
||||
IsFeatured: pgtype.Bool{
|
||||
Bool: filter.Featured.Valid,
|
||||
Valid: filter.Featured.Valid,
|
||||
},
|
||||
LeagueID: filter.LeagueID.ToPG(),
|
||||
SportID: filter.SportID.ToPG(),
|
||||
Query: filter.Query.ToPG(),
|
||||
Limit: filter.Limit.ToPG(),
|
||||
Offset: filter.Offset.ToPG(),
|
||||
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||
LastStartTime: filter.LastStartTime.ToPG(),
|
||||
CountryCode: filter.CountryCode.ToPG(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
upcomingEvents := make([]domain.UpcomingEvent, len(events))
|
||||
for i, e := range events {
|
||||
upcomingEvents[i] = domain.UpcomingEvent{
|
||||
ID: e.ID,
|
||||
SportID: e.SportID.Int32,
|
||||
MatchName: e.MatchName.String,
|
||||
HomeTeam: e.HomeTeam.String,
|
||||
AwayTeam: e.AwayTeam.String,
|
||||
HomeTeamID: e.HomeTeamID.Int32,
|
||||
AwayTeamID: e.AwayTeamID.Int32,
|
||||
HomeKitImage: e.HomeKitImage.String,
|
||||
AwayKitImage: e.AwayKitImage.String,
|
||||
LeagueID: e.LeagueID.Int32,
|
||||
LeagueName: e.LeagueName.String,
|
||||
LeagueCC: e.LeagueCc.String,
|
||||
StartTime: e.StartTime.Time.UTC(),
|
||||
Source: e.Source.String,
|
||||
Status: domain.EventStatus(e.Status.String),
|
||||
IsFeatured: e.IsFeatured,
|
||||
IsActive: e.IsActive,
|
||||
}
|
||||
}
|
||||
|
||||
totalCount, err := s.queries.GetTotalEvents(ctx, dbgen.GetTotalEventsParams{
|
||||
LeagueID: pgtype.Int4{
|
||||
Int32: int32(filter.LeagueID.Value),
|
||||
Valid: filter.LeagueID.Valid,
|
||||
},
|
||||
SportID: pgtype.Int4{
|
||||
Int32: int32(filter.SportID.Value),
|
||||
Valid: filter.SportID.Valid,
|
||||
},
|
||||
Query: pgtype.Text{
|
||||
String: filter.Query.Value,
|
||||
Valid: filter.Query.Valid,
|
||||
},
|
||||
FirstStartTime: pgtype.Timestamp{
|
||||
Time: filter.FirstStartTime.Value.UTC(),
|
||||
Valid: filter.FirstStartTime.Valid,
|
||||
},
|
||||
LastStartTime: pgtype.Timestamp{
|
||||
Time: filter.LastStartTime.Value.UTC(),
|
||||
Valid: filter.LastStartTime.Valid,
|
||||
},
|
||||
CountryCode: pgtype.Text{
|
||||
String: filter.CountryCode.Value,
|
||||
Valid: filter.CountryCode.Valid,
|
||||
},
|
||||
IsFeatured: pgtype.Bool{
|
||||
Bool: filter.Featured.Valid,
|
||||
Valid: filter.Featured.Valid,
|
||||
},
|
||||
LeagueID: filter.LeagueID.ToPG(),
|
||||
SportID: filter.SportID.ToPG(),
|
||||
Query: filter.Query.ToPG(),
|
||||
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||
LastStartTime: filter.LastStartTime.ToPG(),
|
||||
CountryCode: filter.CountryCode.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
numberOfPages := math.Ceil(float64(totalCount) / float64(filter.Limit.Value))
|
||||
return upcomingEvents, int64(numberOfPages), nil
|
||||
return domain.ConvertDBEvents(events), int64(numberOfPages), nil
|
||||
}
|
||||
func (s *Store) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) {
|
||||
event, err := s.queries.GetUpcomingByID(ctx, ID)
|
||||
|
||||
func (s *Store) GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error) {
|
||||
events, err := s.queries.GetEventsWithSettings(ctx, dbgen.GetEventsWithSettingsParams{
|
||||
CompanyID: companyID,
|
||||
LeagueID: filter.LeagueID.ToPG(),
|
||||
SportID: filter.SportID.ToPG(),
|
||||
Query: filter.Query.ToPG(),
|
||||
Limit: filter.Limit.ToPG(),
|
||||
Offset: filter.Offset.ToPG(),
|
||||
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||
LastStartTime: filter.LastStartTime.ToPG(),
|
||||
CountryCode: filter.CountryCode.ToPG(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return domain.UpcomingEvent{}, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return domain.UpcomingEvent{
|
||||
ID: event.ID,
|
||||
SportID: event.SportID.Int32,
|
||||
MatchName: event.MatchName.String,
|
||||
HomeTeam: event.HomeTeam.String,
|
||||
AwayTeam: event.AwayTeam.String,
|
||||
HomeTeamID: event.HomeTeamID.Int32,
|
||||
AwayTeamID: event.AwayTeamID.Int32,
|
||||
HomeKitImage: event.HomeKitImage.String,
|
||||
AwayKitImage: event.AwayKitImage.String,
|
||||
LeagueID: event.LeagueID.Int32,
|
||||
LeagueName: event.LeagueName.String,
|
||||
LeagueCC: event.LeagueCc.String,
|
||||
StartTime: event.StartTime.Time.UTC(),
|
||||
Source: event.Source.String,
|
||||
Status: domain.EventStatus(event.Status.String),
|
||||
IsFeatured: event.IsFeatured,
|
||||
}, nil
|
||||
totalCount, err := s.queries.GetTotalCompanyEvents(ctx, dbgen.GetTotalCompanyEventsParams{
|
||||
CompanyID: companyID,
|
||||
LeagueID: filter.LeagueID.ToPG(),
|
||||
SportID: filter.SportID.ToPG(),
|
||||
Query: filter.Query.ToPG(),
|
||||
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||
LastStartTime: filter.LastStartTime.ToPG(),
|
||||
CountryCode: filter.CountryCode.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
numberOfPages := math.Ceil(float64(totalCount) / float64(filter.Limit.Value))
|
||||
return domain.ConvertDBEventWithSettings(events), int64(numberOfPages), nil
|
||||
}
|
||||
func (s *Store) GetUpcomingEventByID(ctx context.Context, ID string) (domain.BaseEvent, error) {
|
||||
event, err := s.queries.GetUpcomingByID(ctx, ID)
|
||||
if err != nil {
|
||||
return domain.BaseEvent{}, err
|
||||
}
|
||||
|
||||
return domain.ConvertDBEvent(event), nil
|
||||
}
|
||||
func (s *Store) GetEventWithSettingByID(ctx context.Context, ID string, companyID int64) (domain.EventWithSettings, error) {
|
||||
event, err := s.queries.GetEventWithSettingByID(ctx, dbgen.GetEventWithSettingByIDParams{
|
||||
ID: ID,
|
||||
CompanyID: companyID,
|
||||
})
|
||||
if err != nil {
|
||||
return domain.EventWithSettings{}, err
|
||||
}
|
||||
|
||||
return domain.ConvertDBEventWithSetting(event), nil
|
||||
}
|
||||
func (s *Store) UpdateFinalScore(ctx context.Context, eventID, fullScore string, status domain.EventStatus) error {
|
||||
params := dbgen.UpdateMatchResultParams{
|
||||
Score: pgtype.Text{String: fullScore, Valid: true},
|
||||
Status: pgtype.Text{String: string(status), Valid: true},
|
||||
Status: string(status),
|
||||
ID: eventID,
|
||||
}
|
||||
|
||||
|
|
@ -274,11 +147,8 @@ func (s *Store) UpdateFinalScore(ctx context.Context, eventID, fullScore string,
|
|||
|
||||
func (s *Store) UpdateEventStatus(ctx context.Context, eventID string, status domain.EventStatus) error {
|
||||
params := dbgen.UpdateMatchResultParams{
|
||||
Status: pgtype.Text{
|
||||
String: string(status),
|
||||
Valid: true,
|
||||
},
|
||||
ID: eventID,
|
||||
Status: string(status),
|
||||
ID: eventID,
|
||||
}
|
||||
|
||||
err := s.queries.UpdateMatchResult(ctx, params)
|
||||
|
|
@ -290,13 +160,25 @@ func (s *Store) UpdateEventStatus(ctx context.Context, eventID string, status do
|
|||
|
||||
}
|
||||
|
||||
func (s *Store) UpdateFeatured(ctx context.Context, eventID string, isFeatured bool) error {
|
||||
return s.queries.UpdateFeatured(ctx, dbgen.UpdateFeaturedParams{
|
||||
ID: eventID,
|
||||
IsFeatured: isFeatured,
|
||||
func (s *Store) IsEventMonitored(ctx context.Context, eventID string) (bool, error) {
|
||||
isMonitored, err := s.queries.IsEventMonitored(ctx, eventID)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return isMonitored, err
|
||||
}
|
||||
func (s *Store) UpdateEventMonitored(ctx context.Context, eventID string, IsMonitored bool) error {
|
||||
return s.queries.UpdateEventMonitored(ctx, dbgen.UpdateEventMonitoredParams{
|
||||
ID: eventID,
|
||||
IsMonitored: IsMonitored,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Store) UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error {
|
||||
return s.queries.UpdateEventSettings(ctx, domain.ConvertUpdateEventSettings(event))
|
||||
}
|
||||
|
||||
func (s *Store) DeleteEvent(ctx context.Context, eventID string) error {
|
||||
err := s.queries.DeleteEvent(ctx, eventID)
|
||||
if err != nil {
|
||||
|
|
|
|||
55
internal/repository/event_history.go
Normal file
55
internal/repository/event_history.go
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
)
|
||||
|
||||
func (s *Store) InsertEventHistory(ctx context.Context, eventHistory domain.CreateEventHistory) (domain.EventHistory, error) {
|
||||
dbEventHistory, err := s.queries.InsertEventHistory(ctx, domain.ConvertCreateEventHistory(eventHistory))
|
||||
|
||||
if err != nil {
|
||||
return domain.EventHistory{}, fmt.Errorf("InsertEventHistory failed: %w", err)
|
||||
}
|
||||
|
||||
return domain.ConvertDBEventHistory(dbEventHistory), nil
|
||||
}
|
||||
|
||||
func convertEventHistory(list []dbgen.EventHistory) []domain.EventHistory {
|
||||
result := make([]domain.EventHistory, 0, len(list))
|
||||
for _, item := range list {
|
||||
result = append(result, domain.ConvertDBEventHistory(item))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *Store) GetAllEventHistory(ctx context.Context, filter domain.EventHistoryFilter) ([]domain.EventHistory, error) {
|
||||
dbEventHistories, err := s.queries.GetAllEventHistory(ctx, dbgen.GetAllEventHistoryParams{
|
||||
EventID: filter.EventID.ToPG(),
|
||||
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetAllEventHistory failed: %w", err)
|
||||
}
|
||||
|
||||
return convertEventHistory(dbEventHistories), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetInitialEventPerDay(ctx context.Context, filter domain.EventHistoryFilter) ([]domain.EventHistory, error) {
|
||||
dbEventHistories, err := s.queries.GetInitialEventPerDay(ctx, dbgen.GetInitialEventPerDayParams{
|
||||
EventID: filter.EventID.ToPG(),
|
||||
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetInitialEventPerDay failed: %w", err)
|
||||
}
|
||||
|
||||
return convertEventHistory(dbEventHistories), nil
|
||||
}
|
||||
|
|
@ -8,36 +8,18 @@ import (
|
|||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
func (s *Store) SaveLeague(ctx context.Context, l domain.League) error {
|
||||
return s.queries.InsertLeague(ctx, dbgen.InsertLeagueParams{
|
||||
ID: l.ID,
|
||||
Name: l.Name,
|
||||
CountryCode: pgtype.Text{String: l.CountryCode, Valid: true},
|
||||
Bet365ID: pgtype.Int4{Int32: l.Bet365ID, Valid: true},
|
||||
IsActive: pgtype.Bool{Bool: l.IsActive, Valid: true},
|
||||
IsFeatured: pgtype.Bool{Bool: l.IsFeatured, Valid: true},
|
||||
SportID: l.SportID,
|
||||
})
|
||||
func (s *Store) SaveLeague(ctx context.Context, league domain.CreateLeague) error {
|
||||
return s.queries.InsertLeague(ctx, domain.ConvertCreateLeague(league))
|
||||
}
|
||||
|
||||
func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.League, error) {
|
||||
func (s *Store) SaveLeagueSettings(ctx context.Context, leagueSettings domain.CreateLeagueSettings) error {
|
||||
return s.queries.InsertLeagueSettings(ctx, domain.ConvertCreateLeagueSettings(leagueSettings))
|
||||
}
|
||||
|
||||
func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, error) {
|
||||
l, err := s.queries.GetAllLeagues(ctx, dbgen.GetAllLeaguesParams{
|
||||
CountryCode: pgtype.Text{
|
||||
String: filter.CountryCode.Value,
|
||||
Valid: filter.CountryCode.Valid,
|
||||
},
|
||||
SportID: pgtype.Int4{
|
||||
Int32: filter.SportID.Value,
|
||||
Valid: filter.SportID.Valid,
|
||||
},
|
||||
IsActive: pgtype.Bool{
|
||||
Bool: filter.IsActive.Value,
|
||||
Valid: filter.IsActive.Valid,
|
||||
},
|
||||
IsFeatured: pgtype.Bool{
|
||||
Bool: filter.IsFeatured.Value,
|
||||
Valid: filter.IsFeatured.Valid,
|
||||
},
|
||||
CountryCode: filter.CountryCode.ToPG(),
|
||||
SportID: filter.SportID.ToPG(),
|
||||
Limit: pgtype.Int4{
|
||||
Int32: int32(filter.Limit.Value),
|
||||
Valid: filter.Limit.Valid,
|
||||
|
|
@ -51,85 +33,38 @@ func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) (
|
|||
return nil, err
|
||||
}
|
||||
|
||||
leagues := make([]domain.League, len(l))
|
||||
for i, league := range l {
|
||||
leagues[i] = domain.League{
|
||||
ID: league.ID,
|
||||
Name: league.Name,
|
||||
CountryCode: league.CountryCode.String,
|
||||
Bet365ID: league.Bet365ID.Int32,
|
||||
IsActive: league.IsActive.Bool,
|
||||
IsFeatured: league.IsFeatured.Bool,
|
||||
SportID: league.SportID,
|
||||
}
|
||||
}
|
||||
return leagues, nil
|
||||
return domain.ConvertDBBaseLeagues(l), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetFeaturedLeagues(ctx context.Context) ([]domain.League, error) {
|
||||
l, err := s.queries.GetFeaturedLeagues(ctx)
|
||||
func (s *Store) GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, error) {
|
||||
l, err := s.queries.GetAllLeaguesWithSettings(ctx, dbgen.GetAllLeaguesWithSettingsParams{
|
||||
CompanyID: companyID,
|
||||
CountryCode: filter.CountryCode.ToPG(),
|
||||
SportID: filter.SportID.ToPG(),
|
||||
Limit: pgtype.Int4{
|
||||
Int32: int32(filter.Limit.Value),
|
||||
Valid: filter.Limit.Valid,
|
||||
},
|
||||
Offset: pgtype.Int4{
|
||||
Int32: int32(filter.Offset.Value * filter.Limit.Value),
|
||||
Valid: filter.Offset.Valid,
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
leagues := make([]domain.League, len(l))
|
||||
for i, league := range l {
|
||||
leagues[i] = domain.League{
|
||||
ID: league.ID,
|
||||
Name: league.Name,
|
||||
CountryCode: league.CountryCode.String,
|
||||
Bet365ID: league.Bet365ID.Int32,
|
||||
IsActive: league.IsActive.Bool,
|
||||
|
||||
SportID: league.SportID,
|
||||
}
|
||||
}
|
||||
return leagues, nil
|
||||
return domain.ConvertDBLeagueWithSettings(l), nil
|
||||
}
|
||||
|
||||
func (s *Store) CheckLeagueSupport(ctx context.Context, leagueID int64) (bool, error) {
|
||||
return s.queries.CheckLeagueSupport(ctx, leagueID)
|
||||
}
|
||||
|
||||
func (s *Store) SetLeagueActive(ctx context.Context, leagueId int64, isActive bool) error {
|
||||
return s.queries.SetLeagueActive(ctx, dbgen.SetLeagueActiveParams{
|
||||
ID: leagueId,
|
||||
IsActive: pgtype.Bool{
|
||||
Bool: isActive,
|
||||
Valid: true,
|
||||
},
|
||||
func (s *Store) CheckLeagueSupport(ctx context.Context, leagueID int64, companyID int64) (bool, error) {
|
||||
return s.queries.CheckLeagueSupport(ctx, dbgen.CheckLeagueSupportParams{
|
||||
LeagueID: leagueID,
|
||||
CompanyID: companyID,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Store) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
||||
err := s.queries.UpdateLeague(ctx, dbgen.UpdateLeagueParams{
|
||||
ID: league.ID,
|
||||
Name: pgtype.Text{
|
||||
String: league.Name.Value,
|
||||
Valid: league.Name.Valid,
|
||||
},
|
||||
CountryCode: pgtype.Text{
|
||||
String: league.CountryCode.Value,
|
||||
Valid: league.CountryCode.Valid,
|
||||
},
|
||||
Bet365ID: pgtype.Int4{
|
||||
Int32: league.Bet365ID.Value,
|
||||
Valid: league.Bet365ID.Valid,
|
||||
},
|
||||
IsActive: pgtype.Bool{
|
||||
Bool: league.IsActive.Value,
|
||||
Valid: league.IsActive.Valid,
|
||||
},
|
||||
IsFeatured: pgtype.Bool{
|
||||
Bool: league.IsFeatured.Value,
|
||||
Valid: league.IsFeatured.Valid,
|
||||
},
|
||||
SportID: pgtype.Int4{
|
||||
Int32: league.SportID.Value,
|
||||
Valid: league.SportID.Valid,
|
||||
},
|
||||
})
|
||||
|
||||
return err
|
||||
return s.queries.UpdateLeague(ctx, domain.ConvertUpdateLeague(league))
|
||||
}
|
||||
|
|
|
|||
53
internal/repository/odd_history.go
Normal file
53
internal/repository/odd_history.go
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
)
|
||||
|
||||
func (s *Store) InsertOddHistory(ctx context.Context, odd domain.CreateOddHistory) (domain.OddHistory, error) {
|
||||
dbOddHistory, err := s.queries.InsertOddHistory(ctx, domain.ConvertCreateOddHistory(odd))
|
||||
|
||||
if err != nil {
|
||||
return domain.OddHistory{}, fmt.Errorf("InsertOddHistory failed: %w", err)
|
||||
}
|
||||
|
||||
return domain.ConvertDBOddHistory(dbOddHistory), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetAllOddHistory(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error) {
|
||||
dbOddHistories, err := s.queries.GetAllOddHistory(ctx, dbgen.GetAllOddHistoryParams{
|
||||
OddID: filter.OddID.ToPG(),
|
||||
MarketID: filter.MarketID.ToPG(),
|
||||
RawOddID: filter.RawOddID.ToPG(),
|
||||
EventID: filter.EventID.ToPG(),
|
||||
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetAllOddHistory failed: %w", err)
|
||||
}
|
||||
|
||||
return domain.ConvertOddHistories(dbOddHistories), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetInitialOddPerDay(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error) {
|
||||
dbOddHistories, err := s.queries.GetInitialOddPerDay(ctx, dbgen.GetInitialOddPerDayParams{
|
||||
OddID: filter.OddID.ToPG(),
|
||||
MarketID: filter.MarketID.ToPG(),
|
||||
RawOddID: filter.RawOddID.ToPG(),
|
||||
EventID: filter.EventID.ToPG(),
|
||||
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||
DateTrunc: "day",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetInitialOddPerDay failed: %w", err)
|
||||
}
|
||||
return domain.ConvertOddHistories(dbOddHistories), nil
|
||||
}
|
||||
|
|
@ -13,55 +13,26 @@ import (
|
|||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
func (s *Store) SaveNonLiveMarket(ctx context.Context, m domain.Market) error {
|
||||
func (s *Store) SaveOddMarket(ctx context.Context, m domain.CreateOddMarket) error {
|
||||
if len(m.Odds) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, item := range m.Odds {
|
||||
var name string
|
||||
var oddsVal float64
|
||||
params, err := domain.ConvertCreateOddMarket(m)
|
||||
|
||||
if m.Source == "bwin" {
|
||||
nameValue := getMap(item["name"])
|
||||
name = getString(nameValue["value"])
|
||||
oddsVal = getFloat(item["odds"])
|
||||
} else {
|
||||
name = getString(item["name"])
|
||||
oddsVal = getConvertedFloat(item["odds"])
|
||||
}
|
||||
handicap := getString(item["handicap"])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rawOddsBytes, _ := json.Marshal(m.Odds)
|
||||
|
||||
params := dbgen.InsertNonLiveOddParams{
|
||||
EventID: pgtype.Text{String: m.EventID, Valid: m.EventID != ""},
|
||||
Fi: pgtype.Text{String: m.FI, Valid: m.FI != ""},
|
||||
MarketType: m.MarketType,
|
||||
MarketName: pgtype.Text{String: m.MarketName, Valid: m.MarketName != ""},
|
||||
MarketCategory: pgtype.Text{String: m.MarketCategory, Valid: m.MarketCategory != ""},
|
||||
MarketID: pgtype.Text{String: m.MarketID, Valid: m.MarketID != ""},
|
||||
Name: pgtype.Text{String: name, Valid: name != ""},
|
||||
Handicap: pgtype.Text{String: handicap, Valid: handicap != ""},
|
||||
OddsValue: pgtype.Float8{Float64: oddsVal, Valid: oddsVal != 0},
|
||||
Section: m.MarketCategory,
|
||||
Category: pgtype.Text{Valid: false},
|
||||
RawOdds: rawOddsBytes,
|
||||
IsActive: pgtype.Bool{Bool: true, Valid: true},
|
||||
Source: pgtype.Text{String: m.Source, Valid: true},
|
||||
FetchedAt: pgtype.Timestamp{Time: time.Now(), Valid: true},
|
||||
}
|
||||
|
||||
err := s.queries.InsertNonLiveOdd(ctx, params)
|
||||
if err != nil {
|
||||
_ = writeFailedMarketLog(m, err)
|
||||
continue
|
||||
}
|
||||
err = s.queries.InsertOddsMarket(ctx, params)
|
||||
if err != nil {
|
||||
_ = writeFailedMarketLog(m, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeFailedMarketLog(m domain.Market, err error) error {
|
||||
func writeFailedMarketLog(m domain.CreateOddMarket, err error) error {
|
||||
logDir := "logs"
|
||||
logFile := logDir + "/failed_markets.log"
|
||||
|
||||
|
|
@ -76,9 +47,9 @@ func writeFailedMarketLog(m domain.Market, err error) error {
|
|||
defer f.Close()
|
||||
|
||||
entry := struct {
|
||||
Time string `json:"time"`
|
||||
Error string `json:"error"`
|
||||
Record domain.Market `json:"record"`
|
||||
Time string `json:"time"`
|
||||
Error string `json:"error"`
|
||||
Record domain.CreateOddMarket `json:"record"`
|
||||
}{
|
||||
Time: time.Now().Format(time.RFC3339),
|
||||
Error: err.Error(),
|
||||
|
|
@ -90,196 +61,130 @@ func writeFailedMarketLog(m domain.Market, err error) error {
|
|||
return writeErr
|
||||
}
|
||||
|
||||
func (s *Store) GetPrematchOdds(ctx context.Context, eventID string) ([]domain.Odd, error) {
|
||||
odds, err := s.queries.GetPrematchOdds(ctx)
|
||||
func (s *Store) GetAllOdds(ctx context.Context, filter domain.OddMarketFilter) ([]domain.OddMarket, error) {
|
||||
rows, err := s.queries.GetAllOdds(ctx, dbgen.GetAllOddsParams{
|
||||
Offset: filter.Offset.ToPG(),
|
||||
Limit: filter.Limit.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
domainOdds := make([]domain.Odd, len(odds))
|
||||
for i, odd := range odds {
|
||||
domainOdds[i] = domain.Odd{
|
||||
EventID: odd.EventID.String,
|
||||
Fi: odd.Fi.String,
|
||||
MarketType: odd.MarketType,
|
||||
MarketName: odd.MarketName.String,
|
||||
MarketCategory: odd.MarketCategory.String,
|
||||
MarketID: odd.MarketID.String,
|
||||
Name: odd.Name.String,
|
||||
Handicap: odd.Handicap.String,
|
||||
OddsValue: odd.OddsValue.Float64,
|
||||
Section: odd.Section,
|
||||
Category: odd.Category.String,
|
||||
RawOdds: func() []domain.RawMessage {
|
||||
var rawOdds []domain.RawMessage
|
||||
if err := json.Unmarshal(odd.RawOdds, &rawOdds); err != nil {
|
||||
rawOdds = nil
|
||||
}
|
||||
return rawOdds
|
||||
}(),
|
||||
FetchedAt: odd.FetchedAt.Time,
|
||||
Source: odd.Source.String,
|
||||
IsActive: odd.IsActive.Bool,
|
||||
}
|
||||
domainOdds, err := domain.ConvertDBOddMarkets(rows)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return domainOdds, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetALLPrematchOdds(ctx context.Context) ([]domain.Odd, error) {
|
||||
rows, err := s.queries.GetALLPrematchOdds(ctx)
|
||||
func (s *Store) GetAllOddsWithSettings(ctx context.Context, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error) {
|
||||
odds, err := s.queries.GetAllOddsWithSettings(ctx, dbgen.GetAllOddsWithSettingsParams{
|
||||
CompanyID: companyID,
|
||||
Offset: filter.Offset.ToPG(),
|
||||
Limit: filter.Limit.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
domainOdds := make([]domain.Odd, len(rows))
|
||||
for i, row := range rows {
|
||||
domainOdds[i] = domain.Odd{
|
||||
// ID: int64(row.ID),
|
||||
EventID: row.EventID.String,
|
||||
Fi: row.Fi.String,
|
||||
MarketType: row.MarketType,
|
||||
MarketName: row.MarketName.String,
|
||||
MarketCategory: row.MarketCategory.String,
|
||||
MarketID: row.MarketID.String,
|
||||
Name: row.Name.String,
|
||||
Handicap: row.Handicap.String,
|
||||
OddsValue: row.OddsValue.Float64,
|
||||
Section: row.Section,
|
||||
Category: row.Category.String,
|
||||
RawOdds: func() []domain.RawMessage {
|
||||
var rawOdds []domain.RawMessage
|
||||
if err := json.Unmarshal(row.RawOdds, &rawOdds); err != nil {
|
||||
rawOdds = nil
|
||||
}
|
||||
return rawOdds
|
||||
}(),
|
||||
FetchedAt: row.FetchedAt.Time,
|
||||
Source: row.Source.String,
|
||||
IsActive: row.IsActive.Bool,
|
||||
}
|
||||
domainOdds, err := domain.ConvertDBOddMarketWithSettings(odds)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return domainOdds, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetRawOddsByMarketID(ctx context.Context, rawOddsID string, upcomingID string) (domain.RawOddsByMarketID, error) {
|
||||
params := dbgen.GetRawOddsByMarketIDParams{
|
||||
MarketID: pgtype.Text{String: rawOddsID, Valid: true},
|
||||
Fi: pgtype.Text{String: upcomingID, Valid: true},
|
||||
}
|
||||
func (s *Store) GetOddsByMarketID(ctx context.Context, marketID string, eventID string) (domain.OddMarket, error) {
|
||||
|
||||
odds, err := s.queries.GetRawOddsByMarketID(ctx, params)
|
||||
odds, err := s.queries.GetOddsByMarketID(ctx, dbgen.GetOddsByMarketIDParams{
|
||||
MarketID: marketID,
|
||||
EventID: eventID,
|
||||
})
|
||||
if err != nil {
|
||||
return domain.RawOddsByMarketID{}, err
|
||||
return domain.OddMarket{}, err
|
||||
}
|
||||
|
||||
var rawOdds []json.RawMessage
|
||||
if err := json.Unmarshal(odds.RawOdds, &rawOdds); err != nil {
|
||||
return domain.RawOddsByMarketID{}, err
|
||||
}
|
||||
convertedOdd, err := domain.ConvertDBOddMarket(odds)
|
||||
|
||||
return domain.RawOddsByMarketID{
|
||||
ID: int64(odds.ID),
|
||||
MarketName: odds.MarketName.String,
|
||||
Handicap: odds.Handicap.String,
|
||||
RawOdds: func() []domain.RawMessage {
|
||||
converted := make([]domain.RawMessage, len(rawOdds))
|
||||
for i, r := range rawOdds {
|
||||
converted[i] = domain.RawMessage(r)
|
||||
}
|
||||
return converted
|
||||
}(),
|
||||
FetchedAt: odds.FetchedAt.Time,
|
||||
}, nil
|
||||
if err != nil {
|
||||
return domain.OddMarket{}, err
|
||||
}
|
||||
return convertedOdd, nil
|
||||
}
|
||||
func (s *Store) GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, upcomingID string, limit domain.ValidInt64, offset domain.ValidInt64) ([]domain.Odd, error) {
|
||||
odds, err := s.queries.GetPaginatedPrematchOddsByUpcomingID(ctx, dbgen.GetPaginatedPrematchOddsByUpcomingIDParams{
|
||||
ID: upcomingID,
|
||||
Limit: pgtype.Int4{
|
||||
Int32: int32(limit.Value),
|
||||
Valid: limit.Valid,
|
||||
|
||||
func (s *Store) GetOddsWithSettingsByMarketID(ctx context.Context, marketID string, eventID string, companyID int64) (domain.OddMarketWithSettings, error) {
|
||||
|
||||
odds, err := s.queries.GetOddsWithSettingsByMarketID(ctx, dbgen.GetOddsWithSettingsByMarketIDParams{
|
||||
MarketID: marketID,
|
||||
EventID: eventID,
|
||||
CompanyID: companyID,
|
||||
})
|
||||
if err != nil {
|
||||
return domain.OddMarketWithSettings{}, err
|
||||
}
|
||||
|
||||
convertedOdd, err := domain.ConvertDBOddMarketWithSetting(odds)
|
||||
|
||||
if err != nil {
|
||||
return domain.OddMarketWithSettings{}, err
|
||||
}
|
||||
return convertedOdd, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetOddsByEventID(ctx context.Context, upcomingID string, filter domain.OddMarketWithEventFilter) ([]domain.OddMarket, error) {
|
||||
odds, err := s.queries.GetOddsByEventID(ctx, dbgen.GetOddsByEventIDParams{
|
||||
EventID: upcomingID,
|
||||
Limit: filter.Limit.ToPG(),
|
||||
Offset: filter.Offset.ToPG(),
|
||||
IsLive: pgtype.Bool{
|
||||
Bool: false,
|
||||
Valid: true,
|
||||
},
|
||||
Offset: pgtype.Int4{
|
||||
Int32: int32(offset.Value),
|
||||
Valid: offset.Valid,
|
||||
Status: pgtype.Text{
|
||||
String: string(domain.STATUS_PENDING),
|
||||
Valid: true,
|
||||
},
|
||||
Source: pgtype.Text{},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Map the results to domain.Odd
|
||||
domainOdds := make([]domain.Odd, len(odds))
|
||||
for i, odd := range odds {
|
||||
var rawOdds []domain.RawMessage
|
||||
if err := json.Unmarshal(odd.RawOdds, &rawOdds); err != nil {
|
||||
rawOdds = nil
|
||||
}
|
||||
|
||||
domainOdds[i] = domain.Odd{
|
||||
EventID: odd.EventID.String,
|
||||
Fi: odd.Fi.String,
|
||||
MarketType: odd.MarketType,
|
||||
MarketName: odd.MarketName.String,
|
||||
MarketCategory: odd.MarketCategory.String,
|
||||
MarketID: odd.MarketID.String,
|
||||
Name: odd.Name.String,
|
||||
Handicap: odd.Handicap.String,
|
||||
OddsValue: odd.OddsValue.Float64,
|
||||
Section: odd.Section,
|
||||
Category: odd.Category.String,
|
||||
RawOdds: rawOdds,
|
||||
FetchedAt: odd.FetchedAt.Time,
|
||||
Source: odd.Source.String,
|
||||
IsActive: odd.IsActive.Bool,
|
||||
}
|
||||
domainOdds, err := domain.ConvertDBOddMarkets(odds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return domainOdds, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetPrematchOddsByUpcomingID(ctx context.Context, upcomingID string) ([]domain.Odd, error) {
|
||||
func (s *Store) GetOddsWithSettingsByEventID(ctx context.Context, upcomingID string, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error) {
|
||||
|
||||
odds, err := s.queries.GetPrematchOddsByUpcomingID(ctx, upcomingID)
|
||||
odds, err := s.queries.GetOddsWithSettingsByEventID(ctx, dbgen.GetOddsWithSettingsByEventIDParams{
|
||||
EventID: upcomingID,
|
||||
CompanyID: companyID,
|
||||
Offset: filter.Offset.ToPG(),
|
||||
Limit: filter.Limit.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Map the results to domain.Odd
|
||||
domainOdds := make([]domain.Odd, len(odds))
|
||||
for i, odd := range odds {
|
||||
var rawOdds []domain.RawMessage
|
||||
if err := json.Unmarshal(odd.RawOdds, &rawOdds); err != nil {
|
||||
rawOdds = nil
|
||||
}
|
||||
|
||||
domainOdds[i] = domain.Odd{
|
||||
EventID: odd.EventID.String,
|
||||
Fi: odd.Fi.String,
|
||||
MarketType: odd.MarketType,
|
||||
MarketName: odd.MarketName.String,
|
||||
MarketCategory: odd.MarketCategory.String,
|
||||
MarketID: odd.MarketID.String,
|
||||
Name: odd.Name.String,
|
||||
Handicap: odd.Handicap.String,
|
||||
OddsValue: odd.OddsValue.Float64,
|
||||
Section: odd.Section,
|
||||
Category: odd.Category.String,
|
||||
RawOdds: rawOdds,
|
||||
FetchedAt: odd.FetchedAt.Time,
|
||||
Source: odd.Source.String,
|
||||
IsActive: odd.IsActive.Bool,
|
||||
}
|
||||
domainOdds, err := domain.ConvertDBOddMarketWithSettings(odds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return domainOdds, nil
|
||||
}
|
||||
|
||||
func (s *Store) DeleteOddsForEvent(ctx context.Context, eventID string) error {
|
||||
return s.queries.DeleteOddsForEvent(ctx, pgtype.Text{
|
||||
String: eventID,
|
||||
Valid: true,
|
||||
})
|
||||
return s.queries.DeleteOddsForEvent(ctx, eventID)
|
||||
}
|
||||
|
||||
func getString(v interface{}) string {
|
||||
|
|
|
|||
|
|
@ -8,93 +8,34 @@ import (
|
|||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
func convertDBResult(result dbgen.Result) domain.Result {
|
||||
scores := make(map[string]domain.Score)
|
||||
return domain.Result{
|
||||
ID: result.ID,
|
||||
BetOutcomeID: result.BetOutcomeID,
|
||||
EventID: result.EventID,
|
||||
OddID: result.OddID,
|
||||
MarketID: result.MarketID,
|
||||
Status: domain.OutcomeStatus(result.Status),
|
||||
Score: result.Score.String,
|
||||
FullTimeScore: result.FullTimeScore.String,
|
||||
HalfTimeScore: result.HalfTimeScore.String,
|
||||
SS: result.Ss.String,
|
||||
Scores: scores,
|
||||
CreatedAt: result.CreatedAt.Time,
|
||||
UpdatedAt: result.UpdatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
func convertCreateResult(result domain.CreateResult) dbgen.CreateResultParams {
|
||||
return dbgen.CreateResultParams{
|
||||
BetOutcomeID: result.BetOutcomeID,
|
||||
EventID: result.EventID,
|
||||
OddID: result.OddID,
|
||||
MarketID: result.MarketID,
|
||||
Status: int32(result.Status),
|
||||
Score: pgtype.Text{String: result.Score},
|
||||
}
|
||||
}
|
||||
|
||||
func convertResult(result domain.Result) dbgen.InsertResultParams {
|
||||
return dbgen.InsertResultParams{
|
||||
BetOutcomeID: result.BetOutcomeID,
|
||||
EventID: result.EventID,
|
||||
OddID: result.OddID,
|
||||
MarketID: result.MarketID,
|
||||
Status: int32(result.Status),
|
||||
Score: pgtype.Text{String: result.Score},
|
||||
FullTimeScore: pgtype.Text{String: result.FullTimeScore},
|
||||
HalfTimeScore: pgtype.Text{String: result.HalfTimeScore},
|
||||
Ss: pgtype.Text{String: result.SS},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Store) CreateResult(ctx context.Context, result domain.CreateResult) (domain.Result, error) {
|
||||
dbResult, err := s.queries.CreateResult(ctx, convertCreateResult(result))
|
||||
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 {
|
||||
return domain.Result{}, err
|
||||
return domain.ResultLog{}, err
|
||||
}
|
||||
return convertDBResult(dbResult), nil
|
||||
return domain.ConvertDBResultLog(dbResult), nil
|
||||
}
|
||||
|
||||
func (s *Store) InsertResult(ctx context.Context, result domain.Result) error {
|
||||
return s.queries.InsertResult(ctx, convertResult(result))
|
||||
}
|
||||
|
||||
func (s *Store) GetResultByBetOutcomeID(ctx context.Context, betOutcomeID int64) (domain.Result, error) {
|
||||
dbResult, err := s.queries.GetResultByBetOutcomeID(ctx, betOutcomeID)
|
||||
if err != nil {
|
||||
return domain.Result{}, err
|
||||
}
|
||||
return convertDBResult(dbResult), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetPendingBetOutcomes(ctx context.Context) ([]domain.BetOutcome, error) {
|
||||
dbOutcomes, err := s.queries.GetPendingBetOutcomes(ctx)
|
||||
func (s *Store) GetAllResultLog(ctx context.Context, filter domain.ResultFilter) ([]domain.ResultLog, error) {
|
||||
dbResultLogs, err := s.queries.GetAllResultLog(ctx, dbgen.GetAllResultLogParams{
|
||||
CreatedBefore: pgtype.Timestamp{
|
||||
Time: filter.CreatedBefore.Value,
|
||||
Valid: filter.CreatedBefore.Valid,
|
||||
},
|
||||
CreatedAfter: pgtype.Timestamp{
|
||||
Time: filter.CreatedAfter.Value,
|
||||
Valid: filter.CreatedAfter.Valid,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outcomes := make([]domain.BetOutcome, 0, len(dbOutcomes))
|
||||
for _, dbOutcome := range dbOutcomes {
|
||||
outcomes = append(outcomes, domain.BetOutcome{
|
||||
ID: dbOutcome.ID,
|
||||
BetID: dbOutcome.BetID,
|
||||
EventID: dbOutcome.EventID,
|
||||
OddID: dbOutcome.OddID,
|
||||
HomeTeamName: dbOutcome.HomeTeamName,
|
||||
AwayTeamName: dbOutcome.AwayTeamName,
|
||||
MarketID: dbOutcome.MarketID,
|
||||
MarketName: dbOutcome.MarketName,
|
||||
Odd: dbOutcome.Odd,
|
||||
OddName: dbOutcome.OddName,
|
||||
OddHeader: dbOutcome.OddHeader,
|
||||
OddHandicap: dbOutcome.OddHandicap,
|
||||
Status: domain.OutcomeStatus(dbOutcome.Status),
|
||||
Expires: dbOutcome.Expires.Time,
|
||||
})
|
||||
result := make([]domain.ResultLog, 0, len(dbResultLogs))
|
||||
for _, dbResultLog := range dbResultLogs {
|
||||
result = append(result, domain.ConvertDBResultLog(dbResultLog))
|
||||
}
|
||||
return outcomes, nil
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,116 +2,24 @@ package repository
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func GetDBSettingList(settings []dbgen.Setting) (domain.SettingList, error) {
|
||||
var dbSettingList domain.DBSettingList
|
||||
|
||||
var int64SettingsMap = domain.ConvertInt64SettingsMap(&dbSettingList)
|
||||
var stringSettingsMap = domain.ConvertStringSettingsMap(&dbSettingList)
|
||||
var boolSettingsMap = domain.ConvertBoolSettingsMap(&dbSettingList)
|
||||
var float32SettingsMap = domain.ConvertFloat32SettingsMap(&dbSettingList)
|
||||
var timeSettingsMap = domain.ConvertTimeSettingsMap(&dbSettingList)
|
||||
|
||||
for _, setting := range settings {
|
||||
is_setting_unknown := true
|
||||
for key, dbSetting := range int64SettingsMap {
|
||||
if setting.Key == key {
|
||||
value, err := strconv.ParseInt(setting.Value, 10, 64)
|
||||
if err != nil {
|
||||
return domain.SettingList{}, err
|
||||
}
|
||||
*dbSetting = domain.ValidInt64{
|
||||
Value: value,
|
||||
Valid: true,
|
||||
}
|
||||
is_setting_unknown = false
|
||||
}
|
||||
}
|
||||
|
||||
for key, dbSetting := range stringSettingsMap {
|
||||
if setting.Key == key {
|
||||
*dbSetting = domain.ValidString{
|
||||
Value: setting.Value,
|
||||
Valid: true,
|
||||
}
|
||||
is_setting_unknown = false
|
||||
}
|
||||
}
|
||||
|
||||
for key, dbSetting := range boolSettingsMap {
|
||||
if setting.Key == key {
|
||||
value, err := strconv.ParseBool(setting.Value)
|
||||
if err != nil {
|
||||
return domain.SettingList{}, err
|
||||
}
|
||||
*dbSetting = domain.ValidBool{
|
||||
Value: value,
|
||||
Valid: true,
|
||||
}
|
||||
is_setting_unknown = false
|
||||
}
|
||||
}
|
||||
|
||||
for key, dbSetting := range float32SettingsMap {
|
||||
if setting.Key == key {
|
||||
value, err := strconv.ParseFloat(setting.Value, 32)
|
||||
if err != nil {
|
||||
return domain.SettingList{}, err
|
||||
}
|
||||
*dbSetting = domain.ValidFloat32{
|
||||
Value: float32(value),
|
||||
Valid: true,
|
||||
}
|
||||
is_setting_unknown = false
|
||||
}
|
||||
}
|
||||
for key, dbSetting := range timeSettingsMap {
|
||||
if setting.Key == key {
|
||||
value, err := time.Parse(time.RFC3339, setting.Value)
|
||||
if err != nil {
|
||||
return domain.SettingList{}, err
|
||||
}
|
||||
*dbSetting = domain.ValidTime{
|
||||
Value: value,
|
||||
Valid: true,
|
||||
}
|
||||
is_setting_unknown = false
|
||||
}
|
||||
}
|
||||
|
||||
if is_setting_unknown {
|
||||
domain.MongoDBLogger.Warn("unknown setting found on database", zap.String("setting", setting.Key))
|
||||
}
|
||||
}
|
||||
|
||||
for key, dbSetting := range int64SettingsMap {
|
||||
if !dbSetting.Valid {
|
||||
fmt.Printf("setting value not found on database: %v \n", key)
|
||||
domain.MongoDBLogger.Warn("setting value not found on database", zap.String("setting", key))
|
||||
}
|
||||
}
|
||||
|
||||
return domain.ConvertDBSetting(dbSettingList), nil
|
||||
}
|
||||
func (s *Store) GetSettingList(ctx context.Context) (domain.SettingList, error) {
|
||||
settings, err := s.queries.GetSettings(ctx)
|
||||
func (s *Store) GetGlobalSettingList(ctx context.Context) (domain.SettingList, error) {
|
||||
settings, err := s.queries.GetGlobalSettings(ctx)
|
||||
if err != nil {
|
||||
domain.MongoDBLogger.Error("failed to get all settings", zap.Error(err))
|
||||
return domain.SettingList{}, err
|
||||
}
|
||||
|
||||
return GetDBSettingList(settings)
|
||||
return domain.ConvertDBGlobalSettingList(settings)
|
||||
}
|
||||
|
||||
func (s *Store) GetSettings(ctx context.Context) ([]domain.Setting, error) {
|
||||
settings, err := s.queries.GetSettings(ctx)
|
||||
func (s *Store) GetGlobalSettings(ctx context.Context) ([]domain.Setting, error) {
|
||||
settings, err := s.queries.GetGlobalSettings(ctx)
|
||||
|
||||
if err != nil {
|
||||
domain.MongoDBLogger.Error("failed to get all settings", zap.Error(err))
|
||||
|
|
@ -129,8 +37,8 @@ func (s *Store) GetSettings(ctx context.Context) ([]domain.Setting, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetSetting(ctx context.Context, key string) (domain.Setting, error) {
|
||||
dbSetting, err := s.queries.GetSetting(ctx, key)
|
||||
func (s *Store) GetGlobalSetting(ctx context.Context, key string) (domain.Setting, error) {
|
||||
dbSetting, err := s.queries.GetGlobalSetting(ctx, key)
|
||||
|
||||
if err != nil {
|
||||
domain.MongoDBLogger.Error("failed to get all settings", zap.Error(err))
|
||||
|
|
@ -145,23 +53,121 @@ func (s *Store) GetSetting(ctx context.Context, key string) (domain.Setting, err
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Store) SaveSetting(ctx context.Context, key, value string) (domain.Setting, error) {
|
||||
dbSetting, err := s.queries.SaveSetting(ctx, dbgen.SaveSettingParams{
|
||||
func (s *Store) UpdateGlobalSetting(ctx context.Context, key, value string) error {
|
||||
err := s.queries.UpdateGlobalSetting(ctx, dbgen.UpdateGlobalSettingParams{
|
||||
Key: key,
|
||||
Value: value,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
domain.MongoDBLogger.Error("failed to update setting", zap.String("key", key), zap.String("value", value), zap.Error(err))
|
||||
domain.MongoDBLogger.Error("failed to update setting",
|
||||
zap.String("key", key),
|
||||
zap.String("value", value),
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
return domain.Setting{}, err
|
||||
return err
|
||||
}
|
||||
|
||||
setting := domain.Setting{
|
||||
Key: dbSetting.Key,
|
||||
Value: dbSetting.Value,
|
||||
}
|
||||
|
||||
return setting, err
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
func (s *Store) UpdateGlobalSettingList(ctx context.Context, settingList domain.ValidSettingList) error {
|
||||
convertedSettings := settingList.ConvertAllSettings()
|
||||
|
||||
for _, setting := range convertedSettings {
|
||||
err := s.UpdateGlobalSetting(ctx, setting.Key, setting.Value)
|
||||
if err != nil {
|
||||
domain.MongoDBLogger.Warn("failed to update setting list", zap.String("key", setting.Key), zap.Error(err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) InsertCompanySetting(ctx context.Context, key, value string, companyID int64) error {
|
||||
err := s.queries.InsertCompanySetting(ctx, dbgen.InsertCompanySettingParams{
|
||||
CompanyID: companyID,
|
||||
Key: key,
|
||||
Value: value,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) InsertCompanySettingList(ctx context.Context, settingList domain.ValidSettingList, companyID int64) error {
|
||||
convertedSettings := settingList.ConvertAllSettings()
|
||||
|
||||
for _, setting := range convertedSettings {
|
||||
err := s.InsertCompanySetting(ctx, setting.Key, setting.Value, companyID)
|
||||
if err != nil {
|
||||
domain.MongoDBLogger.Warn("failed to update setting list", zap.String("key", setting.Key), zap.Error(err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) GetAllCompanySettings(ctx context.Context) ([]domain.CompanySetting, error) {
|
||||
settings, err := s.queries.GetAllCompanySettings(ctx)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return domain.ConvertCompanySettings(settings), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetCompanySettingsByKey(ctx context.Context, key string) ([]domain.CompanySetting, error) {
|
||||
settings, err := s.queries.GetCompanySettingsByKey(ctx, key)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return domain.ConvertCompanySettings(settings), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetOverrideSettings(ctx context.Context, companyID int64) ([]domain.Setting, error) {
|
||||
settings, err := s.queries.GetOverrideSettings(ctx, companyID)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]domain.Setting, 0, len(settings))
|
||||
for _, setting := range settings {
|
||||
result = append(result, domain.Setting{
|
||||
Key: setting.Key,
|
||||
Value: setting.Value,
|
||||
UpdatedAt: setting.UpdatedAt.Time,
|
||||
})
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetOverrideSettingsList(ctx context.Context, companyID int64) (domain.SettingList, error) {
|
||||
settings, err := s.queries.GetOverrideSettings(ctx, companyID)
|
||||
|
||||
if err != nil {
|
||||
return domain.SettingList{}, err
|
||||
}
|
||||
|
||||
return domain.ConvertDBOverrideSettingList(settings)
|
||||
}
|
||||
|
||||
func (s *Store) DeleteCompanySetting(ctx context.Context, companyID int64, key string) error {
|
||||
return s.queries.DeleteCompanySetting(ctx, dbgen.DeleteCompanySettingParams{
|
||||
CompanyID: companyID,
|
||||
Key: key,
|
||||
})
|
||||
}
|
||||
func (s *Store) DeleteAllCompanySetting(ctx context.Context, companyID int64,) error {
|
||||
return s.queries.DeleteAllCompanySetting(ctx, companyID)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ func convertDBShopBetDetail(bet dbgen.ShopBetDetail) domain.ShopBetDetail {
|
|||
var outcomes []domain.BetOutcome = make([]domain.BetOutcome, 0, len(bet.Outcomes))
|
||||
|
||||
for _, outcome := range bet.Outcomes {
|
||||
outcomes = append(outcomes, convertDBBetOutcomes(outcome))
|
||||
outcomes = append(outcomes, domain.ConvertDBBetOutcomes(outcome))
|
||||
}
|
||||
return domain.ShopBetDetail{
|
||||
ID: bet.ID,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ func convertDBTicket(ticket dbgen.Ticket) domain.Ticket {
|
|||
ID: ticket.ID,
|
||||
Amount: domain.Currency(ticket.Amount),
|
||||
TotalOdds: ticket.TotalOdds,
|
||||
CompanyID: ticket.CompanyID,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +72,7 @@ func convertCreateTicket(ticket domain.CreateTicket) dbgen.CreateTicketParams {
|
|||
Amount: int64(ticket.Amount),
|
||||
TotalOdds: ticket.TotalOdds,
|
||||
Ip: ticket.IP,
|
||||
CompanyID: ticket.CompanyID,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,8 +112,8 @@ func (s *Store) GetTicketByID(ctx context.Context, id int64) (domain.GetTicket,
|
|||
return convertDBTicketOutcomes(ticket), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetAllTickets(ctx context.Context) ([]domain.GetTicket, error) {
|
||||
tickets, err := s.queries.GetAllTickets(ctx)
|
||||
func (s *Store) GetAllTickets(ctx context.Context, filter domain.TicketFilter) ([]domain.GetTicket, error) {
|
||||
tickets, err := s.queries.GetAllTickets(ctx, filter.CompanyID.ToPG())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ func (s *Store) CreateUser(ctx context.Context, user domain.User, usedOtpId int6
|
|||
Time: time.Now(),
|
||||
Valid: true,
|
||||
},
|
||||
CompanyID: user.CompanyID.ToPG(),
|
||||
Suspended: user.Suspended,
|
||||
})
|
||||
if err != nil {
|
||||
return domain.User{}, err
|
||||
|
|
@ -57,6 +59,15 @@ func (s *Store) CreateUser(ctx context.Context, user domain.User, usedOtpId int6
|
|||
Email: userRes.Email.String,
|
||||
PhoneNumber: userRes.PhoneNumber.String,
|
||||
Role: domain.Role(userRes.Role),
|
||||
CompanyID: domain.ValidInt64{
|
||||
Value: userRes.CompanyID.Int64,
|
||||
Valid: userRes.CompanyID.Valid,
|
||||
},
|
||||
EmailVerified: userRes.EmailVerified,
|
||||
PhoneVerified: userRes.PhoneVerified,
|
||||
CreatedAt: userRes.CreatedAt.Time,
|
||||
UpdatedAt: userRes.UpdatedAt.Time,
|
||||
Suspended: userRes.Suspended,
|
||||
}, nil
|
||||
}
|
||||
func (s *Store) GetUserByID(ctx context.Context, id int64) (domain.User, error) {
|
||||
|
|
@ -247,18 +258,14 @@ func (s *Store) GetCashiersByBranch(ctx context.Context, branchID int64) ([]doma
|
|||
func (s *Store) SearchUserByNameOrPhone(ctx context.Context, searchString string, role *domain.Role, companyID domain.ValidInt64) ([]domain.User, error) {
|
||||
|
||||
query := dbgen.SearchUserByNameOrPhoneParams{
|
||||
Column1: pgtype.Text{
|
||||
CompanyID: companyID.ToPG(),
|
||||
Column2: pgtype.Text{
|
||||
String: searchString,
|
||||
Valid: true,
|
||||
},
|
||||
CompanyID: pgtype.Int8{
|
||||
Int64: companyID.Value,
|
||||
Valid: companyID.Valid,
|
||||
},
|
||||
}
|
||||
|
||||
if role != nil {
|
||||
|
||||
query.Role = pgtype.Text{
|
||||
String: string(*role),
|
||||
Valid: true,
|
||||
|
|
@ -340,7 +347,7 @@ func (s *Store) DeleteUser(ctx context.Context, id int64) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
func (s *Store) CheckPhoneEmailExist(ctx context.Context, phoneNum, email string) (bool, bool, error) {
|
||||
func (s *Store) CheckPhoneEmailExist(ctx context.Context, phoneNum, email string, companyID domain.ValidInt64) (bool, bool, error) {
|
||||
|
||||
row, err := s.queries.CheckPhoneEmailExist(ctx, dbgen.CheckPhoneEmailExistParams{
|
||||
PhoneNumber: pgtype.Text{
|
||||
|
|
@ -352,6 +359,7 @@ func (s *Store) CheckPhoneEmailExist(ctx context.Context, phoneNum, email string
|
|||
|
||||
Valid: email != "",
|
||||
},
|
||||
CompanyID: companyID.ToPG(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
@ -360,10 +368,13 @@ func (s *Store) CheckPhoneEmailExist(ctx context.Context, phoneNum, email string
|
|||
return row.EmailExists, row.PhoneExists, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetUserByEmail(ctx context.Context, email string) (domain.User, error) {
|
||||
user, err := s.queries.GetUserByEmail(ctx, pgtype.Text{
|
||||
String: email,
|
||||
Valid: true,
|
||||
func (s *Store) GetUserByEmail(ctx context.Context, email string, companyID domain.ValidInt64) (domain.User, error) {
|
||||
user, err := s.queries.GetUserByEmail(ctx, dbgen.GetUserByEmailParams{
|
||||
Email: pgtype.Text{
|
||||
String: email,
|
||||
Valid: true,
|
||||
},
|
||||
CompanyID: companyID.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
|
|
@ -386,10 +397,13 @@ func (s *Store) GetUserByEmail(ctx context.Context, email string) (domain.User,
|
|||
SuspendedAt: user.SuspendedAt.Time,
|
||||
}, nil
|
||||
}
|
||||
func (s *Store) GetUserByPhone(ctx context.Context, phoneNum string) (domain.User, error) {
|
||||
user, err := s.queries.GetUserByPhone(ctx, pgtype.Text{
|
||||
String: phoneNum,
|
||||
Valid: true,
|
||||
func (s *Store) GetUserByPhone(ctx context.Context, phoneNum string, companyID domain.ValidInt64) (domain.User, error) {
|
||||
user, err := s.queries.GetUserByPhone(ctx, dbgen.GetUserByPhoneParams{
|
||||
PhoneNumber: pgtype.Text{
|
||||
String: phoneNum,
|
||||
Valid: true,
|
||||
},
|
||||
CompanyID: companyID.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ type LoginSuccess struct {
|
|||
CompanyID domain.ValidInt64
|
||||
}
|
||||
|
||||
func (s *Service) Login(ctx context.Context, email, phone string, password string) (LoginSuccess, error) {
|
||||
user, err := s.userStore.GetUserByEmailPhone(ctx, email, phone)
|
||||
func (s *Service) Login(ctx context.Context, email, phone string, password string, companyID domain.ValidInt64) (LoginSuccess, error) {
|
||||
user, err := s.userStore.GetUserByEmailPhone(ctx, email, phone, companyID)
|
||||
if err != nil {
|
||||
return LoginSuccess{}, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
)
|
||||
|
||||
type UserStore interface {
|
||||
GetUserByEmailPhone(ctx context.Context, email, phone string) (domain.User, error)
|
||||
GetUserByEmailPhone(ctx context.Context, email, phone string, companyID domain.ValidInt64) (domain.User, error)
|
||||
}
|
||||
type TokenStore interface {
|
||||
CreateRefreshToken(ctx context.Context, rt domain.RefreshToken) error
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ func (s *Service) GenerateBetOutcome(ctx context.Context, eventID int64, marketI
|
|||
return domain.CreateBetOutcome{}, ErrEventHasNotEnded
|
||||
}
|
||||
|
||||
odds, err := s.prematchSvc.GetRawOddsByMarketID(ctx, marketIDStr, eventIDStr)
|
||||
odds, err := s.prematchSvc.GetOddsByMarketID(ctx, marketIDStr, eventIDStr)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error("failed to get raw odds by market ID",
|
||||
zap.Int64("event_id", eventID),
|
||||
|
|
@ -215,8 +215,8 @@ func (s *Service) GenerateBetOutcome(ctx context.Context, eventID int64, marketI
|
|||
return newOutcome, nil
|
||||
}
|
||||
|
||||
func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID int64, role domain.Role, companyID domain.ValidInt64) (domain.CreateBetRes, error) {
|
||||
settingsList, err := s.settingSvc.GetSettingList(ctx)
|
||||
func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID int64, role domain.Role, companyID int64) (domain.CreateBetRes, error) {
|
||||
settingsList, err := s.settingSvc.GetOverrideSettingsList(ctx, companyID)
|
||||
|
||||
if err != nil {
|
||||
return domain.CreateBetRes{}, err
|
||||
|
|
@ -297,6 +297,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
|||
OutcomesHash: outcomesHash,
|
||||
FastCode: fastCode,
|
||||
UserID: userID,
|
||||
CompanyID: companyID,
|
||||
}
|
||||
|
||||
switch role {
|
||||
|
|
@ -347,7 +348,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
|||
return domain.CreateBetRes{}, err
|
||||
}
|
||||
|
||||
if companyID.Valid && branch.CompanyID == companyID.Value {
|
||||
if branch.CompanyID == companyID {
|
||||
s.mongoLogger.Warn("unauthorized company",
|
||||
zap.Int64("branch_id", *req.BranchID),
|
||||
zap.Error(err),
|
||||
|
|
@ -375,6 +376,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
|||
)
|
||||
return domain.CreateBetRes{}, err
|
||||
}
|
||||
//
|
||||
default:
|
||||
s.mongoLogger.Error("unknown role type",
|
||||
zap.String("role", string(role)),
|
||||
|
|
@ -477,7 +479,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
|||
}
|
||||
}
|
||||
|
||||
res := domain.ConvertCreateBet(bet, rows)
|
||||
res := domain.ConvertCreateBetRes(bet, rows)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
|
@ -581,7 +583,7 @@ func (s *Service) GenerateRandomBetOutcomes(ctx context.Context, eventID string,
|
|||
var newOdds []domain.CreateBetOutcome
|
||||
var totalOdds float32 = 1
|
||||
|
||||
markets, err := s.prematchSvc.GetPrematchOddsByUpcomingID(ctx, eventID)
|
||||
markets, err := s.prematchSvc.GetOddsByEventID(ctx, eventID, domain.OddMarketWithEventFilter{})
|
||||
if err != nil {
|
||||
s.logger.Error("failed to get odds for event", "event id", eventID, "error", err)
|
||||
s.mongoLogger.Error("failed to get odds for event",
|
||||
|
|
@ -603,7 +605,7 @@ func (s *Service) GenerateRandomBetOutcomes(ctx context.Context, eventID string,
|
|||
return nil, 0, fmt.Errorf("empty odds or event %v", eventID)
|
||||
}
|
||||
|
||||
var selectedMarkets []domain.Odd
|
||||
var selectedMarkets []domain.OddMarket
|
||||
numMarkets = min(numMarkets, len(markets))
|
||||
for i := 0; i < numMarkets; i++ {
|
||||
randomIndex := random.Intn(len(markets))
|
||||
|
|
@ -714,7 +716,7 @@ func (s *Service) GenerateRandomBetOutcomes(ctx context.Context, eventID string,
|
|||
return newOdds, totalOdds, nil
|
||||
}
|
||||
|
||||
func (s *Service) PlaceRandomBet(ctx context.Context, userID, branchID int64, leagueID, sportID domain.ValidInt32, firstStartTime, lastStartTime domain.ValidTime) (domain.CreateBetRes, error) {
|
||||
func (s *Service) PlaceRandomBet(ctx context.Context, userID, branchID, companyID int64, leagueID domain.ValidInt64, sportID domain.ValidInt32, firstStartTime, lastStartTime domain.ValidTime) (domain.CreateBetRes, error) {
|
||||
|
||||
// Get a unexpired event id
|
||||
|
||||
|
|
@ -742,7 +744,7 @@ func (s *Service) PlaceRandomBet(ctx context.Context, userID, branchID int64, le
|
|||
}
|
||||
|
||||
// TODO: Add the option of passing number of created events
|
||||
var selectedUpcomingEvents []domain.UpcomingEvent
|
||||
var selectedUpcomingEvents []domain.BaseEvent
|
||||
numEventsPerBet := min(random.Intn(4)+1, len(events)) //Eliminate the option of 0
|
||||
|
||||
for i := 0; i < int(numEventsPerBet); i++ {
|
||||
|
|
@ -816,6 +818,7 @@ func (s *Service) PlaceRandomBet(ctx context.Context, userID, branchID int64, le
|
|||
TotalOdds: totalOdds,
|
||||
Status: domain.OUTCOME_STATUS_PENDING,
|
||||
UserID: userID,
|
||||
CompanyID: companyID,
|
||||
IsShopBet: true,
|
||||
FastCode: fastCode,
|
||||
}
|
||||
|
|
@ -842,7 +845,7 @@ func (s *Service) PlaceRandomBet(ctx context.Context, userID, branchID int64, le
|
|||
return domain.CreateBetRes{}, err
|
||||
}
|
||||
|
||||
res := domain.ConvertCreateBet(bet, rows)
|
||||
res := domain.ConvertCreateBetRes(bet, rows)
|
||||
|
||||
s.mongoLogger.Info("Random bets placed successfully",
|
||||
zap.Int64("userID", userID),
|
||||
|
|
@ -987,6 +990,8 @@ func (s *Service) SendWinningStatusNotification(ctx context.Context, status doma
|
|||
|
||||
betNotification := &domain.Notification{
|
||||
RecipientID: userID,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
IsRead: false,
|
||||
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
||||
Level: domain.NotificationLevelSuccess,
|
||||
Reciever: domain.NotificationRecieverSideCustomer,
|
||||
|
|
@ -1028,6 +1033,8 @@ func (s *Service) SendLosingStatusNotification(ctx context.Context, status domai
|
|||
|
||||
betNotification := &domain.Notification{
|
||||
RecipientID: userID,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
IsRead: false,
|
||||
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
||||
Level: domain.NotificationLevelSuccess,
|
||||
Reciever: domain.NotificationRecieverSideCustomer,
|
||||
|
|
@ -1070,6 +1077,8 @@ func (s *Service) SendErrorStatusNotification(ctx context.Context, status domain
|
|||
|
||||
betNotification := &domain.Notification{
|
||||
RecipientID: userID,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
IsRead: false,
|
||||
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
||||
Level: domain.NotificationLevelSuccess,
|
||||
Reciever: domain.NotificationRecieverSideCustomer,
|
||||
|
|
@ -1104,11 +1113,15 @@ func (s *Service) SendAdminErrorAlertNotification(ctx context.Context, status do
|
|||
|
||||
switch status {
|
||||
case domain.OUTCOME_STATUS_ERROR, domain.OUTCOME_STATUS_PENDING:
|
||||
headline = "There was an error with your bet"
|
||||
message = "We have encounter an error with your bet. We will fix it as soon as we can"
|
||||
headline = "There was an error processing bet"
|
||||
message = "We have encounter an error with bet. We will fix it as soon as we can"
|
||||
}
|
||||
|
||||
errorSeverity := domain.NotificationErrorSeverityHigh
|
||||
betNotification := &domain.Notification{
|
||||
ErrorSeverity: &errorSeverity,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
IsRead: false,
|
||||
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
||||
Level: domain.NotificationLevelSuccess,
|
||||
Reciever: domain.NotificationRecieverSideCustomer,
|
||||
|
|
@ -1300,7 +1313,7 @@ func (s *Service) SetBetToRemoved(ctx context.Context, id int64) error {
|
|||
}
|
||||
|
||||
func (s *Service) ProcessBetCashback(ctx context.Context) error {
|
||||
settingsList, err := s.settingSvc.GetSettingList(ctx)
|
||||
|
||||
bets, err := s.betStore.GetBetsForCashback(ctx)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error("failed to fetch bets",
|
||||
|
|
@ -1309,6 +1322,7 @@ func (s *Service) ProcessBetCashback(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
|
||||
for _, bet := range bets {
|
||||
shouldProcess := true
|
||||
loseCount := 0
|
||||
|
|
@ -1349,6 +1363,8 @@ func (s *Service) ProcessBetCashback(ctx context.Context) error {
|
|||
)
|
||||
continue
|
||||
}
|
||||
|
||||
settingsList, err := s.settingSvc.GetOverrideSettingsList(ctx, bet.CompanyID)
|
||||
cashbackAmount := math.Min(float64(settingsList.CashbackAmountCap.Float32()), float64(calculateCashbackAmount(bet.Amount.Float32(), bet.TotalOdds)))
|
||||
|
||||
_, err = s.walletSvc.AddToWallet(ctx, wallets.StaticID, domain.ToCurrency(float32(cashbackAmount)), domain.ValidInt64{}, domain.TRANSFER_DIRECT,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ type CompanyStore interface {
|
|||
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)
|
||||
GetCompanyIDBySlug(ctx context.Context, slug string) (int64, error)
|
||||
UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error)
|
||||
DeleteCompany(ctx context.Context, id int64) error
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ func (s *Service) GetAllCompanies(ctx context.Context, filter domain.CompanyFilt
|
|||
func (s *Service) GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error) {
|
||||
return s.companyStore.GetCompanyByID(ctx, id)
|
||||
}
|
||||
func (s *Service) GetCompanyIDBySlug(ctx context.Context, slug string) (int64, error){
|
||||
return s.companyStore.GetCompanyIDBySlug(ctx, slug)
|
||||
}
|
||||
|
||||
func (s *Service) SearchCompanyByName(ctx context.Context, name string) ([]domain.GetCompany, error) {
|
||||
return s.companyStore.SearchCompanyByName(ctx, name)
|
||||
|
|
|
|||
|
|
@ -7,14 +7,18 @@ import (
|
|||
)
|
||||
|
||||
type Service interface {
|
||||
FetchLiveEvents(ctx context.Context) error
|
||||
// FetchLiveEvents(ctx context.Context) error
|
||||
FetchUpcomingEvents(ctx context.Context) error
|
||||
GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error)
|
||||
GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, error)
|
||||
GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, int64, error)
|
||||
GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error)
|
||||
GetAllUpcomingEvents(ctx context.Context) ([]domain.BaseEvent, error)
|
||||
GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, error)
|
||||
GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error)
|
||||
GetUpcomingEventByID(ctx context.Context, ID string) (domain.BaseEvent, error)
|
||||
// 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
|
||||
UpdateFeatured(ctx context.Context, eventID string, flagged bool) error
|
||||
IsEventMonitored(ctx context.Context, eventID string) (bool, error)
|
||||
UpdateEventMonitored(ctx context.Context, eventID string, IsMonitored bool) error
|
||||
GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error)
|
||||
GetEventWithSettingByID(ctx context.Context, ID string, companyID int64) (domain.EventWithSettings, error)
|
||||
UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,162 +32,162 @@ func New(token string, store *repository.Store, mongoLogger *zap.Logger) Service
|
|||
}
|
||||
}
|
||||
|
||||
func (s *service) FetchLiveEvents(ctx context.Context) error {
|
||||
var wg sync.WaitGroup
|
||||
urls := []struct {
|
||||
name string
|
||||
source string
|
||||
}{
|
||||
{"https://api.b365api.com/v1/bet365/inplay?sport_id=%d&token=%s", "bet365"},
|
||||
{"https://api.b365api.com/v1/betfair/sb/inplay?sport_id=%d&token=%s", "betfair"},
|
||||
{"https://api.b365api.com/v1/1xbet/inplay?sport_id=%d&token=%s", "1xbet"},
|
||||
}
|
||||
// func (s *service) FetchLiveEvents(ctx context.Context) error {
|
||||
// var wg sync.WaitGroup
|
||||
// urls := []struct {
|
||||
// name string
|
||||
// source string
|
||||
// }{
|
||||
// {"https://api.b365api.com/v1/bet365/inplay?sport_id=%d&token=%s", "bet365"},
|
||||
// {"https://api.b365api.com/v1/betfair/sb/inplay?sport_id=%d&token=%s", "betfair"},
|
||||
// {"https://api.b365api.com/v1/1xbet/inplay?sport_id=%d&token=%s", "1xbet"},
|
||||
// }
|
||||
|
||||
for _, url := range urls {
|
||||
wg.Add(1)
|
||||
// for _, url := range urls {
|
||||
// wg.Add(1)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
s.fetchLiveEvents(ctx, url.name, url.source)
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
// go func() {
|
||||
// defer wg.Done()
|
||||
// s.fetchLiveEvents(ctx, url.name, url.source)
|
||||
// }()
|
||||
// }
|
||||
// wg.Wait()
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func (s *service) fetchLiveEvents(ctx context.Context, url, source string) error {
|
||||
sportIDs := []int{1, 13, 78, 18, 91, 16, 17, 14, 12, 3, 2, 4, 83, 15, 92, 94, 8, 19, 36, 66, 9, 75, 90, 95, 110, 107, 151, 162, 148}
|
||||
// func (s *service) fetchLiveEvents(ctx context.Context, url, source string) error {
|
||||
// sportIDs := []int{1, 13, 78, 18, 91, 16, 17, 14, 12, 3, 2, 4, 83, 15, 92, 94, 8, 19, 36, 66, 9, 75, 90, 95, 110, 107, 151, 162, 148}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
// var wg sync.WaitGroup
|
||||
|
||||
for _, sportID := range sportIDs {
|
||||
wg.Add(1)
|
||||
go func(sportID int) {
|
||||
defer wg.Done()
|
||||
// for _, sportID := range sportIDs {
|
||||
// wg.Add(1)
|
||||
// go func(sportID int) {
|
||||
// defer wg.Done()
|
||||
|
||||
url := fmt.Sprintf(url, sportID, s.token)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
fmt.Printf(" Failed request for sport_id=%d: %v\n", sportID, err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
// url := fmt.Sprintf(url, sportID, s.token)
|
||||
// resp, err := http.Get(url)
|
||||
// if err != nil {
|
||||
// fmt.Printf(" Failed request for sport_id=%d: %v\n", sportID, err)
|
||||
// return
|
||||
// }
|
||||
// defer resp.Body.Close()
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
// body, _ := io.ReadAll(resp.Body)
|
||||
|
||||
events := []domain.Event{}
|
||||
switch source {
|
||||
case "bet365":
|
||||
events = handleBet365prematch(body, sportID, source)
|
||||
case "betfair":
|
||||
events = handleBetfairprematch(body, sportID, source)
|
||||
case "1xbet":
|
||||
// betfair and 1xbet have the same result structure
|
||||
events = handleBetfairprematch(body, sportID, source)
|
||||
}
|
||||
// events := []domain.Event{}
|
||||
// switch source {
|
||||
// case "bet365":
|
||||
// events = handleBet365prematch(body, sportID, source)
|
||||
// case "betfair":
|
||||
// events = handleBetfairprematch(body, sportID, source)
|
||||
// case "1xbet":
|
||||
// // betfair and 1xbet have the same result structure
|
||||
// events = handleBetfairprematch(body, sportID, source)
|
||||
// }
|
||||
|
||||
for _, event := range events {
|
||||
if err := s.store.SaveEvent(ctx, event); err != nil {
|
||||
fmt.Printf("Could not store live event [id=%s]: %v\n", event.ID, err)
|
||||
}
|
||||
}
|
||||
}(sportID)
|
||||
}
|
||||
// for _, event := range events {
|
||||
// if err := s.store.SaveEvent(ctx, event); err != nil {
|
||||
// fmt.Printf("Could not store live event [id=%s]: %v\n", event.ID, err)
|
||||
// }
|
||||
// }
|
||||
// }(sportID)
|
||||
// }
|
||||
|
||||
wg.Wait()
|
||||
fmt.Println("All live events fetched and stored.")
|
||||
return nil
|
||||
// wg.Wait()
|
||||
// fmt.Println("All live events fetched and stored.")
|
||||
// return nil
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
func handleBet365prematch(body []byte, sportID int, source string) []domain.Event {
|
||||
var data struct {
|
||||
Success int `json:"success"`
|
||||
Results [][]map[string]interface{} `json:"results"`
|
||||
}
|
||||
// func handleBet365prematch(body []byte, sportID int, source string) []domain.Event {
|
||||
// var data struct {
|
||||
// Success int `json:"success"`
|
||||
// Results [][]map[string]interface{} `json:"results"`
|
||||
// }
|
||||
|
||||
events := []domain.Event{}
|
||||
if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
||||
fmt.Printf("%s: Decode failed for sport_id=%d\nRaw: %s\n", source, sportID, string(body))
|
||||
return events
|
||||
}
|
||||
// events := []domain.Event{}
|
||||
// if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
||||
// fmt.Printf("%s: Decode failed for sport_id=%d\nRaw: %s\n", source, sportID, string(body))
|
||||
// return events
|
||||
// }
|
||||
|
||||
for _, group := range data.Results {
|
||||
for _, ev := range group {
|
||||
if getString(ev["type"]) != "EV" {
|
||||
continue
|
||||
}
|
||||
// for _, group := range data.Results {
|
||||
// for _, ev := range group {
|
||||
// if getString(ev["type"]) != "EV" {
|
||||
// continue
|
||||
// }
|
||||
|
||||
event := domain.Event{
|
||||
ID: getString(ev["ID"]),
|
||||
SportID: int32(sportID),
|
||||
MatchName: getString(ev["NA"]),
|
||||
Score: getString(ev["SS"]),
|
||||
MatchMinute: getInt(ev["TM"]),
|
||||
TimerStatus: getString(ev["TT"]),
|
||||
HomeTeamID: getInt32(ev["HT"]),
|
||||
AwayTeamID: getInt32(ev["AT"]),
|
||||
HomeKitImage: getString(ev["K1"]),
|
||||
AwayKitImage: getString(ev["K2"]),
|
||||
LeagueName: getString(ev["CT"]),
|
||||
LeagueID: getInt32(ev["C2"]),
|
||||
LeagueCC: getString(ev["CB"]),
|
||||
StartTime: time.Now().UTC().Format(time.RFC3339),
|
||||
IsLive: true,
|
||||
Status: "live",
|
||||
MatchPeriod: getInt(ev["MD"]),
|
||||
AddedTime: getInt(ev["TA"]),
|
||||
Source: source,
|
||||
}
|
||||
// event := domain.Event{
|
||||
// ID: getString(ev["ID"]),
|
||||
// SportID: int32(sportID),
|
||||
// MatchName: getString(ev["NA"]),
|
||||
// Score: getString(ev["SS"]),
|
||||
// MatchMinute: getInt(ev["TM"]),
|
||||
// TimerStatus: getString(ev["TT"]),
|
||||
// HomeTeamID: getInt32(ev["HT"]),
|
||||
// AwayTeamID: getInt32(ev["AT"]),
|
||||
// HomeKitImage: getString(ev["K1"]),
|
||||
// AwayKitImage: getString(ev["K2"]),
|
||||
// LeagueName: getString(ev["CT"]),
|
||||
// LeagueID: getInt32(ev["C2"]),
|
||||
// LeagueCC: getString(ev["CB"]),
|
||||
// StartTime: time.Now().UTC().Format(time.RFC3339),
|
||||
// IsLive: true,
|
||||
// Status: "live",
|
||||
// MatchPeriod: getInt(ev["MD"]),
|
||||
// AddedTime: getInt(ev["TA"]),
|
||||
// Source: source,
|
||||
// }
|
||||
|
||||
events = append(events, event)
|
||||
}
|
||||
}
|
||||
// events = append(events, event)
|
||||
// }
|
||||
// }
|
||||
|
||||
return events
|
||||
}
|
||||
// return events
|
||||
// }
|
||||
|
||||
func handleBetfairprematch(body []byte, sportID int, source string) []domain.Event {
|
||||
var data struct {
|
||||
Success int `json:"success"`
|
||||
Results []map[string]interface{} `json:"results"`
|
||||
}
|
||||
// func handleBetfairprematch(body []byte, sportID int, source string) []domain.Event {
|
||||
// var data struct {
|
||||
// Success int `json:"success"`
|
||||
// Results []map[string]interface{} `json:"results"`
|
||||
// }
|
||||
|
||||
events := []domain.Event{}
|
||||
if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
||||
fmt.Printf("%s: Decode failed for sport_id=%d\nRaw: %s\n", source, sportID, string(body))
|
||||
return events
|
||||
}
|
||||
// events := []domain.Event{}
|
||||
// if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
||||
// fmt.Printf("%s: Decode failed for sport_id=%d\nRaw: %s\n", source, sportID, string(body))
|
||||
// return events
|
||||
// }
|
||||
|
||||
for _, ev := range data.Results {
|
||||
homeRaw, _ := ev["home"].(map[string]interface{})
|
||||
awayRaw, _ := ev["home"].(map[string]interface{})
|
||||
// for _, ev := range data.Results {
|
||||
// homeRaw, _ := ev["home"].(map[string]interface{})
|
||||
// awayRaw, _ := ev["home"].(map[string]interface{})
|
||||
|
||||
event := domain.Event{
|
||||
ID: getString(ev["id"]),
|
||||
SportID: int32(sportID),
|
||||
TimerStatus: getString(ev["time_status"]),
|
||||
HomeTeamID: getInt32(homeRaw["id"]),
|
||||
AwayTeamID: getInt32(awayRaw["id"]),
|
||||
StartTime: time.Now().UTC().Format(time.RFC3339),
|
||||
IsLive: true,
|
||||
Status: "live",
|
||||
Source: source,
|
||||
}
|
||||
// event := domain.Event{
|
||||
// ID: getString(ev["id"]),
|
||||
// SportID: int32(sportID),
|
||||
// TimerStatus: getString(ev["time_status"]),
|
||||
// HomeTeamID: getInt32(homeRaw["id"]),
|
||||
// AwayTeamID: getInt32(awayRaw["id"]),
|
||||
// StartTime: time.Now().UTC().Format(time.RFC3339),
|
||||
// IsLive: true,
|
||||
// Status: "live",
|
||||
// Source: source,
|
||||
// }
|
||||
|
||||
events = append(events, event)
|
||||
}
|
||||
// events = append(events, event)
|
||||
// }
|
||||
|
||||
return events
|
||||
}
|
||||
// return events
|
||||
// }
|
||||
|
||||
func (s *service) FetchUpcomingEvents(ctx context.Context) error {
|
||||
var wg sync.WaitGroup
|
||||
urls := []struct {
|
||||
name string
|
||||
source string
|
||||
source domain.EventSource
|
||||
}{
|
||||
{"https://api.b365api.com/v1/bet365/upcoming?sport_id=%d&token=%s&page=%d", "bet365"},
|
||||
{"https://api.b365api.com/v1/bet365/upcoming?sport_id=%d&token=%s&page=%d", domain.EVENT_SOURCE_BET365},
|
||||
// {"https://api.b365api.com/v1/betfair/sb/upcoming?sport_id=%d&token=%s&page=%d", "betfair"},
|
||||
// {"https://api.b365api.com/v1/1xbet/upcoming?sport_id=%d&token=%s&page=%d", "1xbet"},
|
||||
}
|
||||
|
|
@ -205,83 +205,70 @@ func (s *service) FetchUpcomingEvents(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_url, source string) {
|
||||
func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_url string, source domain.EventSource) {
|
||||
const pageLimit int = 200
|
||||
sportIDs := []int{1, 18, 17, 3, 83, 15, 12, 19, 8, 16, 91}
|
||||
// sportIDs := []int{1}
|
||||
// TODO: Add the league skipping again when we have dynamic leagues
|
||||
|
||||
// b, err := os.OpenFile("logs/skipped_leagues.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
// if err != nil {
|
||||
// log.Printf("❌ Failed to open leagues file %v", err)
|
||||
// return
|
||||
// }
|
||||
for sportIndex, sportID := range sportIDs {
|
||||
var totalPages int = 1
|
||||
var page int = 0
|
||||
var limit int = 200
|
||||
var count int = 0
|
||||
var skippedLeague []string
|
||||
var totalEvents = 0
|
||||
logger := s.mongoLogger.With(
|
||||
zap.String("source", string(source)),
|
||||
zap.Int("sport_id", sportID),
|
||||
zap.String("sport_name", domain.Sport(sportID).String()),
|
||||
zap.Int("count", count),
|
||||
zap.Int("totalEvents", totalEvents),
|
||||
zap.Int("Skipped leagues", len(skippedLeague)),
|
||||
)
|
||||
for page <= totalPages {
|
||||
page = page + 1
|
||||
url := fmt.Sprintf(source_url, sportID, s.token, page)
|
||||
log.Printf("📡 Fetching data from %s - sport %d (%d/%d), for event data page (%d/%d)",
|
||||
source, sportID, sportIndex+1, len(sportIDs), page, totalPages)
|
||||
|
||||
eventLogger := logger.With(
|
||||
zap.Int("page", page),
|
||||
zap.Int("total_pages", totalPages),
|
||||
)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"Failed to fetch event data for page",
|
||||
zap.String("source", source),
|
||||
zap.Int("sport_id", sportID),
|
||||
zap.Int("page", page),
|
||||
zap.Int("total_pages", totalPages),
|
||||
zap.Error(err),
|
||||
)
|
||||
eventLogger.Error("Failed to fetch event data for page", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
var data domain.BetResult
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
eventLogger.Error("Failed to read event response body", zap.Error(err))
|
||||
continue
|
||||
|
||||
}
|
||||
var data domain.B365UpcomingRes
|
||||
|
||||
if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
||||
s.mongoLogger.Error(
|
||||
"Failed to parse event json data",
|
||||
zap.String("source", source),
|
||||
zap.Int("sport_id", sportID),
|
||||
zap.Int("page", page),
|
||||
zap.Int("total_pages", totalPages),
|
||||
zap.Error(err),
|
||||
)
|
||||
eventLogger.Error("Failed to parse event json data", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
for _, ev := range data.Results {
|
||||
startUnix, err := strconv.ParseInt(ev.Time, 10, 64)
|
||||
dataLogger := eventLogger.With(
|
||||
zap.String("time", ev.Time),
|
||||
zap.String("leagueID", ev.League.ID),
|
||||
zap.String("leagueName", ev.League.Name),
|
||||
)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"Invalid time",
|
||||
zap.String("time", ev.Time),
|
||||
zap.String("source", source),
|
||||
zap.Int("sport_id", sportID),
|
||||
zap.Int("page", page),
|
||||
zap.Int("total_pages", totalPages),
|
||||
zap.Error(err),
|
||||
)
|
||||
dataLogger.Error("Invalid time", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
leagueID, err := strconv.ParseInt(ev.League.ID, 10, 64)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"Invalid league id",
|
||||
zap.String("leagueID", ev.League.ID),
|
||||
zap.String("source", source),
|
||||
zap.Int("sport_id", sportID),
|
||||
zap.Int("page", page),
|
||||
zap.Int("total_pages", totalPages),
|
||||
zap.Error(err),
|
||||
)
|
||||
dataLogger.Error("Invalid league id", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -289,74 +276,67 @@ 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.League{
|
||||
ID: leagueID,
|
||||
Name: ev.League.Name,
|
||||
IsActive: true,
|
||||
IsFeatured: slices.Contains(domain.FeaturedLeagues, leagueID),
|
||||
SportID: convertInt32(ev.SportID),
|
||||
err = s.store.SaveLeague(ctx, domain.CreateLeague{
|
||||
ID: leagueID,
|
||||
Name: ev.League.Name,
|
||||
DefaultIsActive: true,
|
||||
DefaultIsFeatured: slices.Contains(domain.FeaturedLeagues, leagueID),
|
||||
SportID: convertInt32(ev.SportID),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"error while saving league",
|
||||
zap.String("leagueID", ev.League.ID),
|
||||
zap.String("leagueName", ev.League.Name),
|
||||
zap.String("source", source),
|
||||
zap.Int("sport_id", sportID),
|
||||
zap.Int("page", page),
|
||||
zap.Int("total_pages", totalPages),
|
||||
zap.Error(err),
|
||||
)
|
||||
dataLogger.Error("error while saving league", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
if supported, err := s.store.CheckLeagueSupport(ctx, leagueID); !supported || err != nil {
|
||||
s.mongoLogger.Warn(
|
||||
"Skipping league",
|
||||
zap.String("league", ev.League.Name),
|
||||
zap.Bool("is_supported", supported),
|
||||
zap.Error(err),
|
||||
)
|
||||
skippedLeague = append(skippedLeague, ev.League.Name)
|
||||
continue
|
||||
}
|
||||
// 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 {
|
||||
// dataLogger.Warn(
|
||||
// "Skipping league",
|
||||
// zap.Bool("is_supported", supported),
|
||||
// zap.Error(err),
|
||||
// )
|
||||
// skippedLeague = append(skippedLeague, ev.League.Name)
|
||||
// continue
|
||||
// }
|
||||
|
||||
event := domain.UpcomingEvent{
|
||||
ID: ev.ID,
|
||||
SportID: convertInt32(ev.SportID),
|
||||
MatchName: "",
|
||||
HomeTeam: ev.Home.Name,
|
||||
AwayTeam: "", // handle nil safely
|
||||
HomeTeamID: convertInt32(ev.Home.ID),
|
||||
AwayTeamID: 0,
|
||||
HomeKitImage: "",
|
||||
AwayKitImage: "",
|
||||
LeagueID: convertInt32(ev.League.ID),
|
||||
LeagueName: ev.League.Name,
|
||||
LeagueCC: "",
|
||||
StartTime: time.Unix(startUnix, 0).UTC(),
|
||||
Source: source,
|
||||
event := domain.CreateEvent{
|
||||
ID: ev.ID,
|
||||
SportID: convertInt32(ev.SportID),
|
||||
MatchName: "",
|
||||
HomeTeam: ev.Home.Name,
|
||||
AwayTeam: "", // handle nil safely
|
||||
HomeTeamID: convertInt64(ev.Home.ID),
|
||||
AwayTeamID: 0,
|
||||
HomeTeamImage: "",
|
||||
AwayTeamImage: "",
|
||||
LeagueID: convertInt64(ev.League.ID),
|
||||
LeagueName: ev.League.Name,
|
||||
StartTime: time.Unix(startUnix, 0).UTC(),
|
||||
Source: source,
|
||||
IsLive: false,
|
||||
Status: domain.STATUS_PENDING,
|
||||
}
|
||||
|
||||
if ev.Away != nil {
|
||||
dataLogger.Info("event away is empty")
|
||||
event.AwayTeam = ev.Away.Name
|
||||
event.AwayTeamID = convertInt32(ev.Away.ID)
|
||||
event.AwayTeamID = convertInt64(ev.Away.ID)
|
||||
event.MatchName = ev.Home.Name + " vs " + ev.Away.Name
|
||||
}
|
||||
ok, err := s.CheckAndInsertEventHistory(ctx, event)
|
||||
|
||||
err = s.store.SaveUpcomingEvent(ctx, event)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"failed to save upcoming event",
|
||||
zap.String("leagueID", ev.League.ID),
|
||||
zap.String("leagueName", ev.League.Name),
|
||||
zap.String("source", source),
|
||||
zap.Int("sport_id", sportID),
|
||||
zap.Int("page", page),
|
||||
zap.Int("total_pages", totalPages),
|
||||
zap.Error(err),
|
||||
)
|
||||
dataLogger.Error("failed to check and insert event history", zap.Error(err))
|
||||
}
|
||||
|
||||
if ok {
|
||||
dataLogger.Info("event history has been recorded")
|
||||
}
|
||||
|
||||
err = s.store.SaveEvent(ctx, event)
|
||||
if err != nil {
|
||||
dataLogger.Error("failed to save upcoming event", zap.Error(err))
|
||||
}
|
||||
totalEvents += 1
|
||||
}
|
||||
|
|
@ -366,7 +346,7 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
|
|||
|
||||
totalPages = data.Pager.Total / data.Pager.PerPage
|
||||
|
||||
if count >= limit {
|
||||
if count >= pageLimit {
|
||||
break
|
||||
}
|
||||
if page > totalPages {
|
||||
|
|
@ -376,7 +356,7 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
|
|||
}
|
||||
s.mongoLogger.Info(
|
||||
"Successfully fetched upcoming events",
|
||||
zap.String("source", source),
|
||||
zap.String("source", string(source)),
|
||||
zap.Int("totalEvents", totalEvents),
|
||||
zap.Int("sport_id", sportID),
|
||||
zap.String("sport_name", domain.Sport(sportID).String()),
|
||||
|
|
@ -388,6 +368,49 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
|
|||
}
|
||||
}
|
||||
|
||||
func (s *service) CheckAndInsertEventHistory(ctx context.Context, event domain.CreateEvent) (bool, error) {
|
||||
isEventMonitored, err := s.store.IsEventMonitored(ctx, event.ID)
|
||||
|
||||
eventLogger := s.mongoLogger.With(
|
||||
zap.String("eventID", event.ID),
|
||||
zap.Int64("leagueID", event.LeagueID),
|
||||
zap.String("leagueName", event.LeagueName),
|
||||
zap.Int32("sport_id", event.SportID),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
eventLogger.Error("failed to get event is_monitored", zap.Error(err))
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !isEventMonitored {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
oldEvent, err := s.GetUpcomingEventByID(ctx, event.ID)
|
||||
|
||||
if err != nil {
|
||||
eventLogger.Error("failed to get event by id", zap.Error(err))
|
||||
return false, err
|
||||
}
|
||||
|
||||
if oldEvent.Status != event.Status {
|
||||
_, err := s.store.InsertEventHistory(ctx, domain.CreateEventHistory{
|
||||
EventID: event.ID,
|
||||
Status: string(event.Status),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
eventLogger.Error("failed to get event by id", zap.Error(err))
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func getString(v interface{}) string {
|
||||
if str, ok := v.(string); ok {
|
||||
return str
|
||||
|
|
@ -415,19 +438,25 @@ func convertInt32(num string) int32 {
|
|||
}
|
||||
return 0
|
||||
}
|
||||
func (s *service) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error) {
|
||||
func convertInt64(num string) int64 {
|
||||
if n, err := strconv.Atoi(num); err == nil {
|
||||
return int64(n)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func (s *service) GetAllUpcomingEvents(ctx context.Context) ([]domain.BaseEvent, error) {
|
||||
return s.store.GetAllUpcomingEvents(ctx)
|
||||
}
|
||||
|
||||
func (s *service) GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, error) {
|
||||
func (s *service) GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, error) {
|
||||
return s.store.GetExpiredUpcomingEvents(ctx, filter)
|
||||
}
|
||||
|
||||
func (s *service) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, int64, error) {
|
||||
func (s *service) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error) {
|
||||
return s.store.GetPaginatedUpcomingEvents(ctx, filter)
|
||||
}
|
||||
|
||||
func (s *service) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) {
|
||||
func (s *service) GetUpcomingEventByID(ctx context.Context, ID string) (domain.BaseEvent, error) {
|
||||
return s.store.GetUpcomingEventByID(ctx, ID)
|
||||
}
|
||||
|
||||
|
|
@ -438,41 +467,20 @@ func (s *service) UpdateEventStatus(ctx context.Context, eventID string, status
|
|||
return s.store.UpdateEventStatus(ctx, eventID, status)
|
||||
}
|
||||
|
||||
func (s *service) UpdateFeatured(ctx context.Context, eventID string, flagged bool) error {
|
||||
return s.store.UpdateFeatured(ctx, eventID, flagged)
|
||||
func (s *service) IsEventMonitored(ctx context.Context, eventID string) (bool, error) {
|
||||
return s.store.IsEventMonitored(ctx, eventID)
|
||||
}
|
||||
func (s *service) UpdateEventMonitored(ctx context.Context, eventID string, IsMonitored bool) error {
|
||||
return s.store.UpdateEventMonitored(ctx, eventID, IsMonitored)
|
||||
}
|
||||
|
||||
// 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)
|
||||
func (s *service) GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error) {
|
||||
return s.store.GetEventsWithSettings(ctx, companyID, filter)
|
||||
}
|
||||
|
||||
// resp, err := http.Get(url)
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("failed to fetch result: %w", err)
|
||||
// }
|
||||
// defer resp.Body.Close()
|
||||
|
||||
// body, _ := io.ReadAll(resp.Body)
|
||||
|
||||
// // Parse the API response
|
||||
// var apiResp struct {
|
||||
// Results []struct {
|
||||
// ID string `json:"id"`
|
||||
// Ss string `json:"ss"` // Full-time score
|
||||
// Status string `json:"time_status"`
|
||||
// } `json:"results"`
|
||||
// }
|
||||
|
||||
// err = json.Unmarshal(body, &apiResp)
|
||||
// if err != nil || len(apiResp.Results) == 0 {
|
||||
// return fmt.Errorf("invalid response or no results found")
|
||||
// }
|
||||
|
||||
// result := apiResp.Results[0]
|
||||
|
||||
// err = s.store.UpdateFinalScore(ctx, result.ID, result.Ss, result.Status)
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("failed to update final score in database: %w", err)
|
||||
// }
|
||||
|
||||
// return nil
|
||||
// }
|
||||
func (s *service) GetEventWithSettingByID(ctx context.Context, ID string, companyID int64) (domain.EventWithSettings, error) {
|
||||
return s.store.GetEventWithSettingByID(ctx, ID, companyID)
|
||||
}
|
||||
func (s *service) UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error {
|
||||
return s.store.UpdateEventSettings(ctx, event)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@ import (
|
|||
)
|
||||
|
||||
type Service interface {
|
||||
SaveLeague(ctx context.Context, l domain.League) error
|
||||
GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.League, error)
|
||||
GetFeaturedLeagues(ctx context.Context) ([]domain.League, error)
|
||||
SetLeagueActive(ctx context.Context, leagueId int64, isActive bool) error
|
||||
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, error)
|
||||
GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, error)
|
||||
CheckLeagueSupport(ctx context.Context, leagueID int64, companyID int64) (bool, error)
|
||||
UpdateLeague(ctx context.Context, league domain.UpdateLeague) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,20 +17,24 @@ func New(store *repository.Store) Service {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *service) SaveLeague(ctx context.Context, l domain.League) error {
|
||||
return s.store.SaveLeague(ctx, l)
|
||||
func (s *service) SaveLeague(ctx context.Context, league domain.CreateLeague) error {
|
||||
return s.store.SaveLeague(ctx, league)
|
||||
}
|
||||
|
||||
func (s *service) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.League, error) {
|
||||
func (s *service) SaveLeagueSettings(ctx context.Context, leagueSettings domain.CreateLeagueSettings) error {
|
||||
return s.store.SaveLeagueSettings(ctx, leagueSettings)
|
||||
}
|
||||
|
||||
func (s *service) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, error) {
|
||||
return s.store.GetAllLeagues(ctx, filter)
|
||||
}
|
||||
|
||||
func (s *service) GetFeaturedLeagues(ctx context.Context) ([]domain.League, error) {
|
||||
return s.store.GetFeaturedLeagues(ctx)
|
||||
func (s *service) GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, error) {
|
||||
return s.store.GetAllLeaguesByCompany(ctx, companyID, filter)
|
||||
}
|
||||
|
||||
func (s *service) SetLeagueActive(ctx context.Context, leagueId int64, isActive bool) error {
|
||||
return s.store.SetLeagueActive(ctx, leagueId, isActive)
|
||||
func (s *service) CheckLeagueSupport(ctx context.Context, leagueID int64, companyID int64) (bool, error) {
|
||||
return s.store.CheckLeagueSupport(ctx, leagueID, companyID)
|
||||
}
|
||||
|
||||
func (s *service) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
||||
|
|
|
|||
|
|
@ -15,12 +15,24 @@ var (
|
|||
ErrSMSProviderNotFound = errors.New("SMS Provider Not Found")
|
||||
)
|
||||
|
||||
func (s *Service) SendSMS(ctx context.Context, receiverPhone, message string) error {
|
||||
// If the company id is valid, it is a company based notification else its a global notification (by the super admin)
|
||||
func (s *Service) SendSMS(ctx context.Context, receiverPhone, message string, companyID domain.ValidInt64) error {
|
||||
|
||||
settingsList, err := s.settingSvc.GetSettingList(ctx)
|
||||
var settingsList domain.SettingList
|
||||
var err error
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
if companyID.Valid {
|
||||
settingsList, err = s.settingSvc.GetOverrideSettingsList(ctx, companyID.Value)
|
||||
if err != nil {
|
||||
// TODO: Send a log about the error
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
settingsList, err = s.settingSvc.GetGlobalSettingList(ctx)
|
||||
if err != nil {
|
||||
// TODO: Send a log about the error
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch settingsList.SMSProvider {
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ func (s *Service) SendNotificationSMS(ctx context.Context, recipientID int64, me
|
|||
if user.PhoneNumber == "" {
|
||||
return fmt.Errorf("Phone Number is invalid")
|
||||
}
|
||||
err = s.messengerSvc.SendSMS(ctx, user.PhoneNumber, message)
|
||||
err = s.messengerSvc.SendSMS(ctx, user.PhoneNumber, message, user.CompanyID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
29
internal/services/odds/custom_odds.go
Normal file
29
internal/services/odds/custom_odds.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package odds
|
||||
|
||||
// import (
|
||||
// "context"
|
||||
|
||||
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
// )
|
||||
|
||||
// func (s *ServiceImpl) InsertCustomOdds(ctx context.Context, odd domain.CreateCustomOdd) (domain.CustomOdd, error) {
|
||||
// return s.store.InsertCustomOdds(ctx, odd)
|
||||
// }
|
||||
// func (s *ServiceImpl) GetAllCustomOdds(ctx context.Context, filter domain.CustomOddFilter) ([]domain.CustomOdd, error){
|
||||
// return s.store.GetAllCustomOdds(ctx, filter)
|
||||
// }
|
||||
// func (s *ServiceImpl) GetCustomOddByID(ctx context.Context, id int64) (domain.CustomOdd, error){
|
||||
// return s.store.GetCustomOddByID(ctx, id)
|
||||
// }
|
||||
// func (s *ServiceImpl) GetCustomOddByOddID(ctx context.Context, oddId int64, companyID int64) (domain.CustomOdd, error){
|
||||
// return s.store.GetCustomOddByOddID(ctx, oddId, companyID)
|
||||
// }
|
||||
// func (s *ServiceImpl) DeleteCustomOddByID(ctx context.Context, id int64) error{
|
||||
// return s.store.DeleteCustomOddByID(ctx, id)
|
||||
// }
|
||||
// func (s *ServiceImpl) DeleteCustomOddsByOddID(ctx context.Context, oddId int64, companyID int64) error{
|
||||
// return s.store.DeleteCustomOddsByOddID(ctx, oddId, companyID)
|
||||
// }
|
||||
// func (s *ServiceImpl) DeleteCustomOddByEventID(ctx context.Context, eventID string) error{
|
||||
// return s.store.DeleteCustomOddByEventID(ctx, eventID)
|
||||
// }
|
||||
28
internal/services/odds/disabled_odd.go
Normal file
28
internal/services/odds/disabled_odd.go
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
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)
|
||||
}
|
||||
|
||||
15
internal/services/odds/odds_history.go
Normal file
15
internal/services/odds/odds_history.go
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package odds
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
)
|
||||
|
||||
func (s *ServiceImpl) GetAllOddHistory(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error) {
|
||||
return s.store.GetAllOddHistory(ctx, filter)
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) GetInitialOddPerDay(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error) {
|
||||
return s.store.GetInitialOddPerDay(ctx, filter)
|
||||
}
|
||||
|
|
@ -11,10 +11,32 @@ type Service interface {
|
|||
FetchNonLiveOdds(ctx context.Context) error
|
||||
FetchNonLiveOddsByEventID(ctx context.Context, eventIDStr string) (domain.BaseNonLiveOddResponse, error)
|
||||
ParseOddSections(ctx context.Context, res json.RawMessage, sportID int64) (domain.ParseOddSectionsRes, error)
|
||||
GetPrematchOdds(ctx context.Context, eventID string) ([]domain.Odd, error)
|
||||
GetPrematchOddsByUpcomingID(ctx context.Context, upcomingID string) ([]domain.Odd, error)
|
||||
GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, upcomingID string, limit domain.ValidInt64, offset domain.ValidInt64) ([]domain.Odd, error)
|
||||
GetALLPrematchOdds(ctx context.Context) ([]domain.Odd, error)
|
||||
GetRawOddsByMarketID(ctx context.Context, marketID string, upcomingID string) (domain.RawOddsByMarketID, error)
|
||||
GetPrematchOdds(ctx context.Context, eventID string) ([]domain.OddMarket, error)
|
||||
GetPrematchOddsByUpcomingID(ctx context.Context, upcomingID string) ([]domain.OddMarket, error)
|
||||
GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, upcomingID string, limit domain.ValidInt64, offset domain.ValidInt64) ([]domain.OddMarket, error)
|
||||
GetALLPrematchOdds(ctx context.Context) ([]domain.OddMarket, error)
|
||||
// GetRawOddsByMarketID(ctx context.Context, marketID string, upcomingID string) (domain.OddMarket, error)
|
||||
DeleteOddsForEvent(ctx context.Context, eventID string) 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)
|
||||
|
||||
// Disabling Odds
|
||||
InsertDisabledOdd(ctx context.Context, odd domain.CreateDisabledOdd) (domain.DisabledOdd, error)
|
||||
GetAllDisabledOdds(ctx context.Context) ([]domain.DisabledOdd, error)
|
||||
GetDisabledOddByRawOddID(ctx context.Context, rawOddID int64) (domain.DisabledOdd, error)
|
||||
GetDisabledOddByID(ctx context.Context, id int64) (domain.DisabledOdd, error)
|
||||
DeleteDisabledOddsByID(ctx context.Context, id int64) error
|
||||
DeleteDisabledOddsByRawOddID(ctx context.Context, id int64) error
|
||||
|
||||
// Custom Odds
|
||||
// InsertCustomOdds(ctx context.Context, odd domain.CreateCustomOdd) (domain.CustomOdd, error)
|
||||
// GetAllCustomOdds(ctx context.Context, filter domain.CustomOddFilter) ([]domain.CustomOdd, error)
|
||||
// GetCustomOddByID(ctx context.Context, id int64) (domain.CustomOdd, error)
|
||||
// GetCustomOddByOddID(ctx context.Context, oddId int64, companyID int64) (domain.CustomOdd, error)
|
||||
// DeleteCustomOddByID(ctx context.Context, id int64) error
|
||||
// DeleteCustomOddsByOddID(ctx context.Context, oddId int64, companyID int64) error
|
||||
// DeleteCustomOddByEventID(ctx context.Context, eventID string) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,21 +16,24 @@ 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/services/event"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type ServiceImpl struct {
|
||||
store *repository.Store
|
||||
config *config.Config
|
||||
eventSvc event.Service
|
||||
logger *slog.Logger
|
||||
mongoLogger *zap.Logger
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
func New(store *repository.Store, cfg *config.Config, logger *slog.Logger, mongoLogger *zap.Logger) *ServiceImpl {
|
||||
func New(store *repository.Store, cfg *config.Config, eventSvc event.Service, logger *slog.Logger, mongoLogger *zap.Logger) *ServiceImpl {
|
||||
return &ServiceImpl{
|
||||
store: store,
|
||||
config: cfg,
|
||||
eventSvc: eventSvc,
|
||||
logger: logger,
|
||||
mongoLogger: mongoLogger,
|
||||
client: &http.Client{Timeout: 10 * time.Second},
|
||||
|
|
@ -76,7 +79,7 @@ func (s *ServiceImpl) FetchNonLiveOdds(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (s *ServiceImpl) fetchBet365Odds(ctx context.Context) error {
|
||||
eventIDs, err := s.store.GetAllUpcomingEvents(ctx)
|
||||
eventIDs, err := s.eventSvc.GetAllUpcomingEvents(ctx)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"Failed to fetch upcoming event IDs",
|
||||
|
|
@ -161,115 +164,117 @@ func (s *ServiceImpl) fetchBet365Odds(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) fetchBwinOdds(ctx context.Context) error {
|
||||
// getting odds for a specific event is not possible for bwin, most specific we can get is fetch odds on a single sport
|
||||
// so instead of having event and odds fetched separetly event will also be fetched along with the odds
|
||||
sportIds := []int{4, 12, 7}
|
||||
for _, sportId := range sportIds {
|
||||
url := fmt.Sprintf("https://api.b365api.com/v1/bwin/prematch?sport_id=%d&token=%s", sportId, s.config.Bet365Token)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"Failed to create request for sportId",
|
||||
zap.Int("sportID", sportId),
|
||||
zap.Error(err),
|
||||
)
|
||||
continue
|
||||
}
|
||||
// func (s *ServiceImpl) fetchBwinOdds(ctx context.Context) error {
|
||||
// // getting odds for a specific event is not possible for bwin, most specific we can get is fetch odds on a single sport
|
||||
// // so instead of having event and odds fetched separetly event will also be fetched along with the odds
|
||||
// sportIds := []int{4, 12, 7}
|
||||
// for _, sportId := range sportIds {
|
||||
// url := fmt.Sprintf("https://api.b365api.com/v1/bwin/prematch?sport_id=%d&token=%s", sportId, s.config.Bet365Token)
|
||||
// req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
// if err != nil {
|
||||
// s.mongoLogger.Error(
|
||||
// "Failed to create request for sportId",
|
||||
// zap.Int("sportID", sportId),
|
||||
// zap.Error(err),
|
||||
// )
|
||||
// continue
|
||||
// }
|
||||
|
||||
resp, err := s.client.Do(req)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"Failed to fetch request for sportId",
|
||||
zap.Int("sportID", sportId),
|
||||
zap.Error(err),
|
||||
)
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
// resp, err := s.client.Do(req)
|
||||
// if err != nil {
|
||||
// s.mongoLogger.Error(
|
||||
// "Failed to fetch request for sportId",
|
||||
// zap.Int("sportID", sportId),
|
||||
// zap.Error(err),
|
||||
// )
|
||||
// continue
|
||||
// }
|
||||
// defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"Failed to read response body for sportId",
|
||||
zap.Int("sportID", sportId),
|
||||
zap.Error(err),
|
||||
)
|
||||
continue
|
||||
}
|
||||
// body, err := io.ReadAll(resp.Body)
|
||||
// if err != nil {
|
||||
// s.mongoLogger.Error(
|
||||
// "Failed to read response body for sportId",
|
||||
// zap.Int("sportID", sportId),
|
||||
// zap.Error(err),
|
||||
// )
|
||||
// continue
|
||||
// }
|
||||
|
||||
var data struct {
|
||||
Success int `json:"success"`
|
||||
Results []map[string]interface{} `json:"results"`
|
||||
}
|
||||
// var data struct {
|
||||
// Success int `json:"success"`
|
||||
// Results []map[string]interface{} `json:"results"`
|
||||
// }
|
||||
|
||||
if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
||||
fmt.Printf("Decode failed for sport_id=%d\nRaw: %s\n", sportId, string(body))
|
||||
s.mongoLogger.Error(
|
||||
"Failed to decode BWin response body",
|
||||
zap.Int("sportID", sportId),
|
||||
zap.Error(err),
|
||||
)
|
||||
continue
|
||||
}
|
||||
// if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
||||
// fmt.Printf("Decode failed for sport_id=%d\nRaw: %s\n", sportId, string(body))
|
||||
// s.mongoLogger.Error(
|
||||
// "Failed to decode BWin response body",
|
||||
// zap.Int("sportID", sportId),
|
||||
// zap.Error(err),
|
||||
// )
|
||||
// continue
|
||||
// }
|
||||
|
||||
for _, res := range data.Results {
|
||||
if getInt(res["Id"]) == -1 {
|
||||
continue
|
||||
}
|
||||
// for _, res := range data.Results {
|
||||
// if getInt(res["Id"]) == -1 {
|
||||
// continue
|
||||
// }
|
||||
|
||||
event := domain.Event{
|
||||
ID: strconv.Itoa(getInt(res["Id"])),
|
||||
SportID: int32(getInt(res["SportId"])),
|
||||
LeagueID: int32(getInt(res["LeagueId"])),
|
||||
LeagueName: getString(res["Leaguename"]),
|
||||
HomeTeam: getString(res["HomeTeam"]),
|
||||
HomeTeamID: int32(getInt(res["HomeTeamId"])),
|
||||
AwayTeam: getString(res["AwayTeam"]),
|
||||
AwayTeamID: int32(getInt(res["AwayTeamId"])),
|
||||
StartTime: time.Now().UTC().Format(time.RFC3339),
|
||||
TimerStatus: "1",
|
||||
IsLive: true,
|
||||
Status: "live",
|
||||
Source: "bwin",
|
||||
}
|
||||
// event := domain.CreateEvent{
|
||||
// ID: strconv.Itoa(getInt(res["Id"])),
|
||||
// SportID: int32(getInt(res["SportId"])),
|
||||
// LeagueID: int64(getInt(res["LeagueId"])),
|
||||
// LeagueName: getString(res["Leaguename"]),
|
||||
// HomeTeam: getString(res["HomeTeam"]),
|
||||
// HomeTeamID: int64(getInt(res["HomeTeamId"])),
|
||||
// AwayTeam: getString(res["AwayTeam"]),
|
||||
// AwayTeamID: int64(getInt(res["AwayTeamId"])),
|
||||
// StartTime: time.Now().UTC(),
|
||||
// IsLive: true,
|
||||
// Status: domain.STATUS_IN_PLAY,
|
||||
// Source: domain.EVENT_SOURCE_BWIN,
|
||||
// MatchName: "",
|
||||
// HomeTeamImage: "",
|
||||
// AwayTeamImage: "",
|
||||
// }
|
||||
|
||||
if err := s.store.SaveEvent(ctx, event); err != nil {
|
||||
fmt.Printf("Could not store live event [id=%s]: %v\n", event.ID, err)
|
||||
s.mongoLogger.Error(
|
||||
"Could not store live event",
|
||||
zap.Int("sportID", sportId),
|
||||
zap.String("eventID", event.ID),
|
||||
zap.Error(err),
|
||||
)
|
||||
continue
|
||||
}
|
||||
// if err := s.store.SaveEvent(ctx, event); err != nil {
|
||||
// fmt.Printf("Could not store live event [id=%s]: %v\n", event.ID, err)
|
||||
// s.mongoLogger.Error(
|
||||
// "Could not store live event",
|
||||
// zap.Int("sportID", sportId),
|
||||
// zap.String("eventID", event.ID),
|
||||
// zap.Error(err),
|
||||
// )
|
||||
// continue
|
||||
// }
|
||||
|
||||
for _, market := range []string{"Markets, optionMarkets"} {
|
||||
for _, m := range getMapArray(res[market]) {
|
||||
name := getMap(m["name"])
|
||||
marketName := getString(name["value"])
|
||||
// for _, market := range []string{"Markets, optionMarkets"} {
|
||||
// for _, m := range getMapArray(res[market]) {
|
||||
// name := getMap(m["name"])
|
||||
// marketName := getString(name["value"])
|
||||
|
||||
market := domain.Market{
|
||||
EventID: event.ID,
|
||||
MarketID: getString(m["id"]),
|
||||
MarketCategory: getString(m["category"]),
|
||||
MarketName: marketName,
|
||||
Source: "bwin",
|
||||
}
|
||||
// market := domain.CreateOddMarket{
|
||||
// EventID: event.ID,
|
||||
// MarketID: getString(m["id"]),
|
||||
// MarketCategory: getString(m["category"]),
|
||||
// MarketName: marketName,
|
||||
|
||||
results := getMapArray(m["results"])
|
||||
market.Odds = results
|
||||
// }
|
||||
|
||||
s.store.SaveNonLiveMarket(ctx, market)
|
||||
// results := getMapArray(m["results"])
|
||||
// market.Odds = results
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// s.store.SaveOddMarket(ctx, market)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func (s *ServiceImpl) FetchNonLiveOddsByEventID(ctx context.Context, eventIDStr string) (domain.BaseNonLiveOddResponse, error) {
|
||||
|
||||
|
|
@ -542,7 +547,7 @@ func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName
|
|||
}
|
||||
|
||||
// Check if the market id is a string
|
||||
marketIDint := market.ID.Int64
|
||||
marketIDint := market.ID.Value
|
||||
// if err != nil {
|
||||
// s.mongoLogger.Error(
|
||||
// "Invalid market id",
|
||||
|
|
@ -576,9 +581,8 @@ func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName
|
|||
continue
|
||||
}
|
||||
|
||||
marketRecord := domain.Market{
|
||||
marketRecord := domain.CreateOddMarket{
|
||||
EventID: eventID,
|
||||
FI: fi,
|
||||
MarketCategory: sectionName,
|
||||
MarketType: marketType,
|
||||
MarketName: market.Name,
|
||||
|
|
@ -586,10 +590,20 @@ func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName
|
|||
UpdatedAt: updatedAt,
|
||||
Odds: marketOdds,
|
||||
// bwin won't reach this code so bet365 is hardcoded for now
|
||||
Source: "bet365",
|
||||
}
|
||||
|
||||
err = s.store.SaveNonLiveMarket(ctx, marketRecord)
|
||||
if err := s.CheckAndInsertOddHistory(ctx, marketRecord); err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"failed to check and insert odd history",
|
||||
zap.String("market_id", marketIDstr),
|
||||
zap.String("market_name", market.Name),
|
||||
zap.String("eventID", eventID),
|
||||
zap.Error(err),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
err = s.store.SaveOddMarket(ctx, marketRecord)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"failed to save market",
|
||||
|
|
@ -598,7 +612,7 @@ func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName
|
|||
zap.String("eventID", eventID),
|
||||
zap.Error(err),
|
||||
)
|
||||
errs = append(errs, fmt.Errorf("market %s: %w", market.ID, err))
|
||||
errs = append(errs, fmt.Errorf("market %v: %w", market.ID, err))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
|
@ -609,29 +623,111 @@ func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) GetPrematchOdds(ctx context.Context, eventID string) ([]domain.Odd, error) {
|
||||
return s.store.GetPrematchOdds(ctx, eventID)
|
||||
}
|
||||
func (s *ServiceImpl) CheckAndInsertOddHistory(ctx context.Context, market domain.CreateOddMarket) error {
|
||||
isEventMonitored, err := s.eventSvc.IsEventMonitored(ctx, market.EventID)
|
||||
|
||||
func (s *ServiceImpl) GetALLPrematchOdds(ctx context.Context) ([]domain.Odd, error) {
|
||||
return s.store.GetALLPrematchOdds(ctx)
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) GetRawOddsByMarketID(ctx context.Context, marketID string, upcomingID string) (domain.RawOddsByMarketID, error) {
|
||||
rows, err := s.store.GetRawOddsByMarketID(ctx, marketID, upcomingID)
|
||||
marketLogger := s.mongoLogger.With(
|
||||
zap.String("market_id", market.MarketID),
|
||||
zap.String("market_name", market.MarketName),
|
||||
zap.String("eventID", market.EventID),
|
||||
)
|
||||
if err != nil {
|
||||
return domain.RawOddsByMarketID{}, err
|
||||
marketLogger.Error("failed to get is_monitored", zap.Error(err))
|
||||
}
|
||||
|
||||
if !isEventMonitored {
|
||||
return nil
|
||||
}
|
||||
|
||||
oldOdds, err := s.store.GetOddsByMarketID(ctx, market.MarketID, market.EventID)
|
||||
|
||||
if err != nil {
|
||||
marketLogger.Error("failed to get raw odds by market id", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
if len(oldOdds.RawOdds) != len(market.Odds) {
|
||||
marketLogger.Error("new odds data does not match old odds data", zap.Error(err))
|
||||
return fmt.Errorf("new odds data does not match old odds data")
|
||||
}
|
||||
|
||||
oldRawOdds, err := convertRawMessage(oldOdds.RawOdds)
|
||||
|
||||
if err != nil {
|
||||
marketLogger.Error("failed to convert raw odds to map", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
for _, oddData := range market.Odds {
|
||||
newRawOddID := getInt(oddData["id"])
|
||||
newOddsVal := getFloat(oddData["odds"])
|
||||
isFound := false
|
||||
for _, oldOddData := range oldRawOdds {
|
||||
oldRawOddID := getInt(oldOddData["id"])
|
||||
oldOddsVal := getFloat(oldOddData["odds"])
|
||||
if newRawOddID == oldRawOddID {
|
||||
if newOddsVal != oldOddsVal {
|
||||
_, err := s.store.InsertOddHistory(ctx, domain.CreateOddHistory{
|
||||
OddID: oldOdds.ID,
|
||||
MarketID: market.MarketID,
|
||||
RawOddID: int64(newRawOddID),
|
||||
EventID: market.EventID,
|
||||
OddValue: newOddsVal,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
s.mongoLogger.Error(
|
||||
"failed to insert odd history",
|
||||
zap.String("market_id", market.MarketID),
|
||||
zap.String("market_name", market.MarketName),
|
||||
zap.String("eventID", market.EventID),
|
||||
zap.Int64("odd_id", oldOdds.ID),
|
||||
zap.Int("raw_odd_id", newRawOddID),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
}
|
||||
isFound = true
|
||||
}
|
||||
}
|
||||
if !isFound {
|
||||
fmt.Printf("raw odd id %d not found", newRawOddID)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) GetAllOdds(ctx context.Context, filter domain.OddMarketFilter) ([]domain.OddMarket, error) {
|
||||
return s.store.GetAllOdds(ctx, filter)
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) GetAllOddsWithSettings(ctx context.Context, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error) {
|
||||
return s.store.GetAllOddsWithSettings(ctx, companyID, filter)
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) GetOddsByMarketID(ctx context.Context, marketID string, eventID string) (domain.OddMarket, error) {
|
||||
rows, err := s.store.GetOddsByMarketID(ctx, marketID, eventID)
|
||||
if err != nil {
|
||||
return domain.OddMarket{}, err
|
||||
}
|
||||
|
||||
return rows, nil
|
||||
}
|
||||
func (s *ServiceImpl) GetOddsWithSettingsByMarketID(ctx context.Context, marketID string, eventID string, companyID int64) (domain.OddMarketWithSettings, error) {
|
||||
rows, err := s.store.GetOddsWithSettingsByMarketID(ctx, marketID, eventID, companyID)
|
||||
if err != nil {
|
||||
return domain.OddMarketWithSettings{}, err
|
||||
}
|
||||
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) GetPrematchOddsByUpcomingID(ctx context.Context, upcomingID string) ([]domain.Odd, error) {
|
||||
return s.store.GetPrematchOddsByUpcomingID(ctx, upcomingID)
|
||||
func (s *ServiceImpl) GetOddsByEventID(ctx context.Context, upcomingID string, filter domain.OddMarketWithEventFilter) ([]domain.OddMarket, error) {
|
||||
return s.store.GetOddsByEventID(ctx, upcomingID, filter)
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, upcomingID string, limit, offset domain.ValidInt64) ([]domain.Odd, error) {
|
||||
return s.store.GetPaginatedPrematchOddsByUpcomingID(ctx, upcomingID, limit, offset)
|
||||
func (s *ServiceImpl) GetOddsWithSettingsByEventID(ctx context.Context, upcomingID string, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error) {
|
||||
return s.store.GetOddsWithSettingsByEventID(ctx, upcomingID, companyID, filter)
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) DeleteOddsForEvent(ctx context.Context, eventID string) error {
|
||||
|
|
@ -651,6 +747,12 @@ func getInt(v interface{}) int {
|
|||
}
|
||||
return -1
|
||||
}
|
||||
func getFloat(v interface{}) float64 {
|
||||
if n, ok := v.(float64); ok {
|
||||
return n
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func getMap(v interface{}) map[string]interface{} {
|
||||
if m, ok := v.(map[string]interface{}); ok {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
type ReferralStore interface {
|
||||
GenerateReferralCode() (string, error)
|
||||
CreateReferral(ctx context.Context, userID int64) error
|
||||
ProcessReferral(ctx context.Context, referredID, referralCode string) error
|
||||
ProcessReferral(ctx context.Context, referredPhone, referralCode string, companyID int64) error
|
||||
ProcessDepositBonus(ctx context.Context, userID string, amount float64) error
|
||||
GetReferralStats(ctx context.Context, userID string) (*domain.ReferralStats, error)
|
||||
CreateReferralSettings(ctx context.Context, req domain.ReferralSettingsReq) error
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ func (s *Service) CreateReferral(ctx context.Context, userID int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) ProcessReferral(ctx context.Context, referredPhone, referralCode string) error {
|
||||
func (s *Service) ProcessReferral(ctx context.Context, referredPhone, referralCode string, companyID int64) error {
|
||||
s.logger.Info("Processing referral", "referredPhone", referredPhone, "referralCode", referralCode)
|
||||
|
||||
referral, err := s.repo.GetReferralByCode(ctx, referralCode)
|
||||
|
|
@ -121,7 +121,10 @@ func (s *Service) ProcessReferral(ctx context.Context, referredPhone, referralCo
|
|||
return ErrInvalidReferral
|
||||
}
|
||||
|
||||
user, err := s.store.GetUserByPhone(ctx, referredPhone)
|
||||
user, err := s.store.GetUserByPhone(ctx, referredPhone, domain.ValidInt64{
|
||||
Value: companyID,
|
||||
Valid: true,
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, domain.ErrUserNotFound) {
|
||||
s.logger.Warn("User not found for referral", "referredPhone", referredPhone)
|
||||
|
|
|
|||
|
|
@ -2,9 +2,16 @@ package result
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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.ResultFilter) ([]domain.ResultLog, error)
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user